fancyholograms-v3: Refactor storage system

This commit is contained in:
Oliver
2025-05-17 20:44:58 +02:00
parent f483de0386
commit 98df9cf763
7 changed files with 142 additions and 39 deletions

View File

@@ -23,6 +23,7 @@ public class HologramData implements YamlData {
private final String name;
private final HologramType type;
private String filePath;
private Location location;
private boolean hasChanges = false;
private int visibilityDistance = DEFAULT_VISIBILITY_DISTANCE;
@@ -50,6 +51,16 @@ public class HologramData implements YamlData {
return type;
}
@ApiStatus.Internal
public String getFilePath() {
return filePath;
}
@ApiStatus.Internal
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public @NotNull Location getLocation() {
return location.clone();
}

View File

@@ -7,8 +7,6 @@ import de.oliver.fancyholograms.converter.FHConversionRegistry;
import de.oliver.fancyholograms.converter.HologramConversionSession;
import de.oliver.fancyholograms.main.FancyHologramsPlugin;
import de.oliver.fancylib.MessageHelper;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@@ -48,12 +46,10 @@ public final class FancyHologramsCMD extends Command {
this.plugin.getHologramConfiguration().reload(plugin);
this.plugin.getRegistry().clear();
for (World world : Bukkit.getWorlds()) {
Collection<HologramData> hologramData = this.plugin.getStorage().loadAll("worlds/"+world.getName());
for (HologramData data : hologramData) {
Hologram hologram = this.plugin.getHologramFactory().apply(data);
this.plugin.getRegistry().register(hologram);
}
Collection<HologramData> hologramData = this.plugin.getStorage().loadAll();
for (HologramData data : hologramData) {
Hologram hologram = this.plugin.getHologramFactory().apply(data);
this.plugin.getRegistry().register(hologram);
}
MessageHelper.success(sender, "Reloaded config and holograms");

View File

@@ -73,6 +73,7 @@ public class CreateCMD implements Subcommand {
displayData.setBillboard(Display.Billboard.FIXED);
}
}
displayData.setFilePath(name);
final var holo = FancyHologramsPlugin.get().getHologramFactory().apply(displayData);
if (!new HologramCreateEvent(holo, player).callEvent()) {

View File

@@ -41,7 +41,6 @@ import de.oliver.fancysitula.api.IFancySitula;
import de.oliver.fancysitula.api.utils.ServerVersion;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -193,12 +192,10 @@ public final class FancyHologramsPlugin extends JavaPlugin implements FancyHolog
new StorageMigrator().migrate();
for (World world : Bukkit.getWorlds()) {
Collection<HologramData> data = storage.loadAll("worlds/"+world.getName());
for (HologramData d : data) {
Hologram hologram = hologramFactory.apply(d);
registry.register(hologram);
}
Collection<HologramData> data = storage.loadAll();
for (HologramData d : data) {
Hologram hologram = hologramFactory.apply(d);
registry.register(hologram);
}
controller.initRefreshTask();

View File

@@ -28,10 +28,17 @@ public interface HologramStorage {
void delete(HologramData hologram);
/**
* Loads all holograms from a specific world
* Loads all holograms from the specified path (recursive).
*
* @param world The world to load the holograms from.
* @param path The relative path to the plugin/FancyHolograms/data/holograms directory.
* @return A collection of all loaded holograms.
*/
Collection<HologramData> loadAll(String world);
Collection<HologramData> loadAll(String path);
/**
* Loads all holograms from the default path
*/
default Collection<HologramData> loadAll() {
return loadAll("");
}
}

View File

@@ -3,8 +3,6 @@ package de.oliver.fancyholograms.storage;
import de.oliver.fancyholograms.api.data.HologramData;
import de.oliver.fancyholograms.api.hologram.Hologram;
import de.oliver.fancyholograms.main.FancyHologramsPlugin;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.util.Collection;
@@ -19,13 +17,12 @@ public class StorageMigrator {
FancyHologramsPlugin.get().getFancyLogger().info("Migrating holograms.yml to JSON format...");
HologramStorage yamlStorage = new YamlHologramStorage();
for (World world : Bukkit.getWorlds()) {
Collection<HologramData> data = yamlStorage.loadAll(world.getName());
for (HologramData d : data) {
Hologram hologram = FancyHologramsPlugin.get().getHologramFactory().apply(d);
FancyHologramsPlugin.get().getRegistry().register(hologram);
FancyHologramsPlugin.get().getFancyLogger().info("Migrated hologram " + hologram.getData().getName());
}
Collection<HologramData> data = yamlStorage.loadAll();
for (HologramData d : data) {
d.setFilePath("migrated/" + d.getName());
Hologram hologram = FancyHologramsPlugin.get().getHologramFactory().apply(d);
FancyHologramsPlugin.get().getRegistry().register(hologram);
FancyHologramsPlugin.get().getFancyLogger().info("Migrated hologram " + hologram.getData().getName());
}
if (!YamlHologramStorage.HOLOGRAMS_CONFIG_FILE.renameTo(YamlHologramStorage.HOLOGRAMS_CONFIG_FILE.getParentFile().toPath().resolve("holograms-old.yml").toFile())) {

View File

@@ -9,6 +9,7 @@ import de.oliver.fancyholograms.storage.HologramStorage;
import de.oliver.fancyholograms.storage.json.model.JsonDataUnion;
import de.oliver.jdb.JDB;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -16,10 +17,12 @@ import java.util.List;
public class JsonStorage implements HologramStorage {
private static final String DATA_DIR_PATH = "plugins/FancyHolograms/data/holograms";
private static final File DATA_DIR = new File(DATA_DIR_PATH);
private final JDB jdb;
public JsonStorage() {
this.jdb = new JDB("plugins/FancyHolograms/data/holograms");
this.jdb = new JDB(DATA_DIR_PATH);
}
@Override
@@ -31,6 +34,11 @@ public class JsonStorage implements HologramStorage {
@Override
public void save(HologramData hologram) {
if (hologram.getFilePath() == null || hologram.getFilePath().isEmpty()) {
FancyHolograms.get().getFancyLogger().error("Hologram " + hologram.getName() + " has no file path set");
return;
}
JsonDataUnion union = switch (hologram.getType()) {
case TEXT -> JsonAdapter.toUnion((TextHologramData) hologram);
case ITEM -> JsonAdapter.toUnion((ItemHologramData) hologram);
@@ -38,7 +46,24 @@ public class JsonStorage implements HologramStorage {
};
try {
jdb.set(getKey(hologram), union);
JsonDataUnion[] existing = jdb.get(hologram.getFilePath(), JsonDataUnion[].class);
if (existing == null) {
existing = new JsonDataUnion[0];
}
for (int i = 0; i < existing.length; i++) {
JsonDataUnion u = existing[i];
if (u.hologram_data().name().equals(hologram.getName())) {
existing[i] = union;
jdb.set(hologram.getFilePath(), existing);
return;
}
}
JsonDataUnion[] newArray = new JsonDataUnion[existing.length + 1];
System.arraycopy(existing, 0, newArray, 0, existing.length);
newArray[existing.length] = union;
jdb.set(hologram.getFilePath(), newArray);
} catch (IOException e) {
FancyHolograms.get().getFancyLogger().error("Failed to save hologram " + hologram.getName());
FancyHolograms.get().getFancyLogger().error(e);
@@ -47,25 +72,94 @@ public class JsonStorage implements HologramStorage {
@Override
public void delete(HologramData hologram) {
jdb.delete(getKey(hologram));
try {
JsonDataUnion[] existing = jdb.get(hologram.getFilePath(), JsonDataUnion[].class);
if (existing == null) {
return;
}
ArrayList<JsonDataUnion> newArray = new ArrayList<>();
for (JsonDataUnion u : existing) {
if (u.hologram_data().name().equals(hologram.getName())) {
continue;
}
newArray.add(u);
}
if (newArray.size() == existing.length) {
FancyHolograms.get().getFancyLogger().warn("Hologram " + hologram.getName() + " not found in file " + hologram.getFilePath());
return;
}
if (newArray.isEmpty()) {
jdb.delete(hologram.getFilePath());
return;
}
jdb.set(hologram.getFilePath(), newArray.toArray(new JsonDataUnion[0]));
} catch (IOException e) {
FancyHolograms.get().getFancyLogger().error("Failed to save hologram " + hologram.getName());
FancyHolograms.get().getFancyLogger().error(e);
}
}
@Override
public Collection<HologramData> loadAll(String subdir) {
public Collection<HologramData> loadAll(String path) {
List<HologramData> holograms = new ArrayList<>();
try {
List<JsonDataUnion> allTextUnions = jdb.getAll(subdir, JsonDataUnion.class);
allTextUnions.forEach(u -> holograms.add(JsonAdapter.fromJson(u)));
} catch (IOException e) {
FancyHolograms.get().getFancyLogger().error("Failed to load all holograms from " + subdir);
FancyHolograms.get().getFancyLogger().error(e);
File dir = new File(DATA_DIR, path);
if (!dir.isDirectory()) {
return holograms;
}
File[] files = dir.listFiles();
if (files == null) {
return holograms;
}
for (File file : files) {
String fileName = file.getName();
if (file.isDirectory()) {
holograms.addAll(loadAll(path + "/" + fileName));
continue;
}
// Skip hidden files
if (fileName.startsWith(".") || fileName.startsWith("_")) {
continue;
}
// Check if the file is a JSON file
if (fileName.endsWith(".json")) {
holograms.addAll(loadFile(path + "/" + fileName.substring(0, fileName.length() - 5)));
} else {
FancyHolograms.get().getFancyLogger().warn("File " + fileName + " is not a valid hologram file");
}
}
return holograms;
}
public String getKey(HologramData data) {
return "worlds/" + data.getLocation().getWorld().getName() + "/" + data.getName();
public Collection<HologramData> loadFile(String path) {
List<HologramData> holograms = new ArrayList<>();
try {
JsonDataUnion[] allTextUnions = jdb.get(path, JsonDataUnion[].class);
if (allTextUnions == null) {
FancyHolograms.get().getFancyLogger().debug("File " + path + " is empty or does not exist");
return holograms;
}
for (JsonDataUnion union : allTextUnions) {
HologramData data = JsonAdapter.fromJson(union);
data.setFilePath(path);
holograms.add(data);
}
} catch (IOException e) {
FancyHolograms.get().getFancyLogger().error("Failed to load all holograms from " + path);
FancyHolograms.get().getFancyLogger().error(e);
}
return holograms;
}
}