From ddf5c070e880379fa833563c27024888ff89271c Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Sat, 23 Jan 2021 15:38:47 +0100 Subject: [PATCH] VirtualInventory serialization --- .../java/de/studiocode/invgui/InvGui.java | 17 ++-- .../virtualinventory/VirtualInventory.java | 41 ++++++++-- .../VirtualInventoryManager.java | 82 +++++++++++++++++++ .../invgui/window/WindowManager.java | 12 +-- 4 files changed, 129 insertions(+), 23 deletions(-) create mode 100644 src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventoryManager.java diff --git a/src/main/java/de/studiocode/invgui/InvGui.java b/src/main/java/de/studiocode/invgui/InvGui.java index 6ca3309..193ddca 100644 --- a/src/main/java/de/studiocode/invgui/InvGui.java +++ b/src/main/java/de/studiocode/invgui/InvGui.java @@ -1,32 +1,37 @@ package de.studiocode.invgui; -import de.studiocode.invgui.window.WindowManager; import org.bukkit.plugin.Plugin; +import java.util.ArrayList; +import java.util.List; + public class InvGui { private static InvGui instance; + private final List disableHandlers = new ArrayList<>(); private Plugin plugin; public static InvGui getInstance() { return instance == null ? instance = new InvGui() : instance; } + public void setPlugin(Plugin plugin) { + this.plugin = plugin; + } + public Plugin getPlugin() { if (plugin == null) throw new IllegalStateException("Please set your plugin using InvGui.getInstance().setPlugin"); return plugin; } - public void setPlugin(Plugin plugin) { - this.plugin = plugin; + public void addDisableHandler(Runnable runnable) { + disableHandlers.add(runnable); } public void onDisable() { - if (WindowManager.hasInstance()) - WindowManager.getInstance().getWindows() - .forEach(w -> w.close(true)); + disableHandlers.forEach(Runnable::run); } } diff --git a/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java index 3dd3be5..5867528 100644 --- a/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java +++ b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java @@ -3,22 +3,29 @@ package de.studiocode.invgui.virtualinventory; import de.studiocode.invgui.InvGui; import de.studiocode.invgui.window.Window; import org.bukkit.Bukkit; +import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; -public class VirtualInventory { +public class VirtualInventory implements ConfigurationSerializable { - private transient final Set windows = new HashSet<>(); + private final Set windows = new HashSet<>(); + private final UUID uuid; private int size; private ItemStack[] items; - public VirtualInventory(int size) { + public VirtualInventory(@Nullable UUID uuid, int size, @NotNull ItemStack[] items) { + this.uuid = uuid; this.size = size; - this.items = new ItemStack[size]; + this.items = items; + } + + public VirtualInventory(@Nullable UUID uuid, int size) { + this(uuid, size, new ItemStack[size]); } public int getSize() { @@ -125,4 +132,24 @@ public class VirtualInventory { windows.forEach(window -> window.handleVirtualInventoryUpdate(this))); } + public UUID getUuid() { + return uuid; + } + + @NotNull + @Override + public Map serialize() { + Map result = new LinkedHashMap<>(); + result.put("uuid", uuid.toString()); + result.put("size", size); + result.put("items", items); + return result; + } + + public static VirtualInventory deserialize(@NotNull Map args) { + //noinspection unchecked + return new VirtualInventory(UUID.fromString((String) args.get("uuid")), + (int) args.get("size"), ((ArrayList) args.get("items")).toArray(new ItemStack[0])); + } + } diff --git a/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventoryManager.java b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventoryManager.java new file mode 100644 index 0000000..1f7c8b1 --- /dev/null +++ b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventoryManager.java @@ -0,0 +1,82 @@ +package de.studiocode.invgui.virtualinventory; + +import de.studiocode.invgui.InvGui; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Automatically serializes and deserializes {@link VirtualInventory}s + * when the server reloads / restarts. + */ +public class VirtualInventoryManager { + + private static final File SAVE_DIR = new File("plugins/InvGui/VirtualInventory/"); + + private static VirtualInventoryManager instance; + + private final Map inventories = new HashMap<>(); + + private VirtualInventoryManager() { + ConfigurationSerialization.registerClass(VirtualInventory.class); + InvGui.getInstance().addDisableHandler(this::serializeAll); + deserializeAll(); + } + + public static VirtualInventoryManager getInstance() { + return instance == null ? instance = new VirtualInventoryManager() : instance; + } + + public VirtualInventory createNew(@NotNull UUID uuid, int size) { + if (inventories.containsKey(uuid)) + throw new IllegalArgumentException("A VirtualInventory with that UUID already exists"); + + VirtualInventory virtualInventory = new VirtualInventory(uuid, size); + inventories.put(uuid, virtualInventory); + + return virtualInventory; + } + + public VirtualInventory getByUuid(@NotNull UUID uuid) { + return inventories.get(uuid); + } + + public VirtualInventory getOrCreate(UUID uuid, int size) { + VirtualInventory virtualInventory = getByUuid(uuid); + return virtualInventory == null ? createNew(uuid, size) : virtualInventory; + } + + private void deserializeAll() { + if (SAVE_DIR.exists()) { + Arrays.stream(SAVE_DIR.listFiles()) + .filter(file -> file.getName().endsWith(".vi")) + .forEach(file -> { + YamlConfiguration config = YamlConfiguration.loadConfiguration(file); + VirtualInventory virtualInventory = config.getSerializable("vi", VirtualInventory.class); + + inventories.put(virtualInventory.getUuid(), virtualInventory); + }); + } + } + + private void serializeAll() { + inventories.values().forEach(virtualInventory -> { + try { + File file = new File(SAVE_DIR, virtualInventory.getUuid() + ".vi"); + YamlConfiguration config = new YamlConfiguration(); + config.set("vi", virtualInventory); + config.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + +} diff --git a/src/main/java/de/studiocode/invgui/window/WindowManager.java b/src/main/java/de/studiocode/invgui/window/WindowManager.java index 8962bdc..8c0483e 100644 --- a/src/main/java/de/studiocode/invgui/window/WindowManager.java +++ b/src/main/java/de/studiocode/invgui/window/WindowManager.java @@ -24,6 +24,7 @@ public class WindowManager implements Listener { Bukkit.getPluginManager().registerEvents(this, InvGui.getInstance().getPlugin()); Bukkit.getScheduler().scheduleSyncRepeatingTask(InvGui.getInstance().getPlugin(), () -> windows.forEach(Window::handleTick), 0, 1); + InvGui.getInstance().addDisableHandler(() -> windows.forEach(w -> w.close(true))); } /** @@ -32,16 +33,7 @@ public class WindowManager implements Listener { * @return The {@link WindowManager} instance */ public static WindowManager getInstance() { - return !hasInstance() ? instance = new WindowManager() : instance; - } - - /** - * Gets if the {@link WindowManager} already has an instance. - * - * @return if the {@link WindowManager} already has an instance - */ - public static boolean hasInstance() { - return instance != null; + return instance == null ? instance = new WindowManager() : instance; } /**