diff --git a/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java b/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java index ca933d3..cd0b485 100644 --- a/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java +++ b/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java @@ -102,60 +102,9 @@ public class PlayersFile extends YamlConfiguration { public static Map> getAllSystems() { Map> allSystems = new HashMap<>(); - for (String playerUUID : getConfig().getConfigurationSection("players").getKeys(false)) { - List playersSystems = new ArrayList<>(); - for (String systemUUID : getConfig().getConfigurationSection("players." + playerUUID + ".systems").getKeys(false)) { - String systemPath = "players." + playerUUID + ".systems." + systemUUID + "."; - List drives = new ArrayList<>(); - - if (getConfig().contains(systemPath + "drives")) { - for (String driveUUID : getConfig().getConfigurationSection(systemPath + "drives").getKeys(false)) { - - Map items = new HashMap(); - if (getConfig().contains(systemPath + "drives." + driveUUID + ".items")) { - try { - JSONParser jsonParser = new JSONParser(); - JSONArray itemJsonArray = (JSONArray) jsonParser.parse(getConfig().getString(systemPath + "drives." + driveUUID + ".items")); - - for (int i = 0; i < itemJsonArray.size(); i++) { - JSONObject itemObject = (JSONObject) itemJsonArray.get(i); - - Map.Entry item = ItemSerialization.deserializeItem((String) itemObject.get("itemYAML")); - - items.put(item.getKey(), item.getValue()); - } - } catch (ParseException | InvalidConfigurationException e) { - e.printStackTrace(); - } - } - - int size = getConfig().getInt(systemPath + "drives." + driveUUID + ".size"); - - drives.add(new ESDrive(size, items)); - } - } - - List trustedUUIDs = new ArrayList<>(); - if (getConfig().contains(systemPath + "trustedUUIDs")) { - try { - JSONArray trustedJson = (JSONArray) new JSONParser().parse(getConfig().getString(systemPath + "trustedUUIDs")); - for (int i = 0; i < trustedJson.size(); i++) { - JSONObject object = (JSONObject) trustedJson.get(i); - - trustedUUIDs.add(UUID.fromString((String) object.get("UUID"))); - } - } catch (ParseException e) { - e.printStackTrace(); - } - } - - boolean isPublic = getConfig().getBoolean(systemPath + "public"); - - Location loc = Utils.convertStringToLocation(getConfig().getString(systemPath + "loc")); - playersSystems.add(new ESSystem(UUID.fromString(playerUUID), UUID.fromString(systemUUID), loc, drives, trustedUUIDs, isPublic)); - } - - allSystems.put(UUID.fromString(playerUUID), playersSystems); + for (String playerUUIDStr : getConfig().getConfigurationSection("players").getKeys(false)) { + UUID playerUUID = UUID.fromString(playerUUIDStr); + allSystems.put(playerUUID, getPlayersSystems(playerUUID)); } return allSystems; @@ -209,9 +158,10 @@ public class PlayersFile extends YamlConfiguration { } boolean isPublic = getConfig().getBoolean(systemPath + "public"); + ESSystem.SortOrder sortOrder = ESSystem.SortOrder.valueOf(getConfig().getString(systemPath + "sortOrder")); Location loc = Utils.convertStringToLocation(getConfig().getString(systemPath + "loc")); - systems.add(new ESSystem(uuid, UUID.fromString(systemUUID), loc, drives, trustedUUIDs, isPublic)); + systems.add(new ESSystem(uuid, UUID.fromString(systemUUID), loc, drives, trustedUUIDs, isPublic, sortOrder)); } return systems; @@ -222,6 +172,7 @@ public class PlayersFile extends YamlConfiguration { getConfig().set(systemPath + "loc", Utils.convertLocationToString(esSystem.getLocation())); getConfig().set(systemPath + "public", esSystem.isPublic()); + getConfig().set(systemPath + "sortOrder", esSystem.getSortOrder().toString()); try { JSONArray jsonArray = new JSONArray(); diff --git a/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java b/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java index a7a2c63..5312052 100644 --- a/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java +++ b/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java @@ -11,6 +11,7 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -88,6 +89,40 @@ public class ESTerminalGUI implements InventoryHolder, Listener { items = openSearches.get(player.getUniqueId()); } + List sortedKeys = new ArrayList<>(items.keySet()); + + switch (openSystem.getSortOrder()) { + case ALPHABETICAL: + sortedKeys.sort((i1, i2) -> { + ItemMeta im1 = i1.getItemMeta(); + ItemMeta im2 = i2.getItemMeta(); + + String name1 = im1 == null ? "" : im1.getDisplayName(); + if (name1.isEmpty()) { + name1 = i1.getType().name(); + } + + String name2 = im2 == null ? "" : im2.getDisplayName(); + if (name2.isEmpty()) { + name2 = i2.getType().name(); + } + + return name1.compareTo(name2); + }); + + + break; + case AMOUNT: + Map finalItems = items; + sortedKeys.sort((i1, i2) -> { + return finalItems.get(i2).compareTo(finalItems.get(i1)); + }); + break; + case ID: + sortedKeys.sort(Comparator.comparing(ItemStack::getType)); + break; + } + for (int i = 10; i < 44; i++) { // Ignore the borders if (i == 18 || i == 27 || i == 36 || i == 17 || i == 26 || i == 35) { @@ -102,8 +137,8 @@ public class ESTerminalGUI implements InventoryHolder, Listener { int itemIndex = i - (10 + lineIndex * 2) + pageIndex * 28; // The start of a new line is + 2 boxes, with each page showing 28 items. if (itemIndex < items.size()) { try { - ItemStack item = (ItemStack) items.keySet().toArray()[itemIndex]; - int amount = (int) items.values().toArray()[itemIndex]; + ItemStack item = sortedKeys.get(itemIndex); + int amount = items.get(item); ItemMeta itemMeta = item.getItemMeta(); if (itemMeta.hasLore()) { @@ -133,7 +168,6 @@ public class ESTerminalGUI implements InventoryHolder, Listener { inv.clear(i); } - inv.setItem(45, createGuiItem(Material.IRON_BARS, "Security")); // Create the lore for the drives @@ -169,6 +203,8 @@ public class ESTerminalGUI implements InventoryHolder, Listener { lore.add(ChatColor.BLUE + "Filled Items: " + spaceColor + filledSpace + ChatColor.BLUE + "/" + ChatColor.GREEN + maxSpace); lore.add(ChatColor.BLUE + "Filled Types: " + itemsColor + filledTypes + ChatColor.BLUE + "/" + ChatColor.GREEN + maxTypes); inv.setItem(46, createGuiItem(Material.CHEST, "Drives", lore)); + + inv.setItem(47, createGuiItem(Material.HOPPER, "Sort by " + openSystem.getSortOrder().toDisplayString())); } } @@ -338,6 +374,24 @@ public class ESTerminalGUI implements InventoryHolder, Listener { Reference.ES_SYSTEM_SECURITY_GUI.openInventory(player, openSystem); } else if (slot == 46) { // Drives Reference.ES_DRIVE_GUI.openInventory(player, openSystem); + } else if (slot == 47) { // Sort method + ESSystem.SortOrder sortOrder = openSystem.getSortOrder(); + + // Change sort order + switch (sortOrder) { + case ID: + sortOrder = ESSystem.SortOrder.ALPHABETICAL; + break; + case AMOUNT: + sortOrder = ESSystem.SortOrder.ID; + break; + case ALPHABETICAL: + sortOrder = ESSystem.SortOrder.AMOUNT; + break; + } + + openSystem.setSortOrder(sortOrder); + initializeItems(player, openSystem); } else { switch (clickType) { case SHIFT_IN: diff --git a/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java b/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java index 36f2f74..db04635 100644 --- a/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java +++ b/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java @@ -6,9 +6,15 @@ import net.seanomik.energeticstorage.utils.ItemSerialization; import net.seanomik.energeticstorage.utils.Reference; import net.seanomik.energeticstorage.utils.Utils; import org.apache.commons.text.StringEscapeUtils; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.material.MaterialData; +import org.jetbrains.annotations.NotNull; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -16,7 +22,7 @@ import org.json.simple.parser.ParseException; import java.util.*; -public class ESDrive implements Cloneable { +public class ESDrive implements Cloneable, ConfigurationSerializable { private UUID uuid; private int size; private Map items = new HashMap<>(); // Item, amount @@ -25,6 +31,12 @@ public class ESDrive implements Cloneable { this.size = size; } + protected ESDrive(UUID uuid, int size, Map items) { + this.uuid = uuid; + this.size = size; + this.items = items; + } + public ESDrive(int size, Map items) { this(size); uuid = UUID.randomUUID(); @@ -181,4 +193,45 @@ public class ESDrive implements Cloneable { return null; } + + // @TODO: Implement (has not been tested) + @NotNull + @Override + public Map serialize() { + Map result = new LinkedHashMap(); + result.put("uuid", uuid); + result.put("size", size); + + if (!items.isEmpty()) { + List itemsSerialized = new ArrayList<>(); + for (Map.Entry entry : items.entrySet()) { + Map itemSerialized = new LinkedHashMap<>(); + itemSerialized.put("amount", entry.getValue()); + itemSerialized.put("item", entry.getKey().serialize()); + itemsSerialized.add(itemSerialized); + } + result.put("items", itemsSerialized); + } + + return result; + } + + // @TODO: Implement (has not been tested) + @NotNull + public static ESDrive deserialize(@NotNull Map args) { + UUID uuid = (UUID) args.get("uuid"); + int size = ((Number)args.get("size")).intValue(); + Map items = new HashMap<>(); + + if (args.containsKey("items")) { + Object raw = args.get("items"); + if (raw instanceof Map) { + Map map = (Map)raw; + + items.put(ItemStack.deserialize((Map) map.get("item")), ((Number)map.get("amount")).intValue()); + } + } + + return new ESDrive(uuid, size, items); + } } diff --git a/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java b/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java index ef8e9e6..a5d5f94 100644 --- a/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java +++ b/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java @@ -1,19 +1,25 @@ package net.seanomik.energeticstorage.objects; import net.seanomik.energeticstorage.utils.Utils; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import java.io.Serializable; import java.util.*; -public class ESSystem implements Cloneable { +public class ESSystem implements Cloneable, ConfigurationSerializable { private UUID owner; private UUID uuid; private Location location; private List esDrives = new ArrayList<>(); private List trustedPlayers = new ArrayList<>(); private boolean isPublic; + private SortOrder sortOrder; public ESSystem(UUID owner, UUID uuid, Location location) { this.owner = owner; @@ -21,12 +27,13 @@ public class ESSystem implements Cloneable { this.location = location; } - public ESSystem(UUID owner, UUID uuid, Location location, List esDrives, List trustedPlayers, boolean isPublic) { + public ESSystem(UUID owner, UUID uuid, Location location, List esDrives, List trustedPlayers, boolean isPublic, SortOrder sortOrder) { this(owner, uuid, location); this.esDrives = esDrives; this.trustedPlayers = trustedPlayers; this.isPublic = isPublic; + this.sortOrder = sortOrder; } public void setEsDrives(List esDrives) { @@ -109,6 +116,9 @@ public class ESSystem implements Cloneable { this.location = location; } + public SortOrder getSortOrder() { return sortOrder; } + public void setSortOrder(SortOrder sortOrder) { this.sortOrder = sortOrder; } + public ESSystem clone() { try { ESSystem system = (ESSystem) super.clone(); @@ -172,23 +182,23 @@ public class ESSystem implements Cloneable { return items; } -public boolean addItem(ItemStack item) { - ESDrive drive = findItemInAvailableDrive(item); - - // If we failed to find the item in the next available drive, then find another drive. - if (drive == null) { - drive = getNextAvailableDrive(); + public boolean addItem(ItemStack item) { + ESDrive drive = findItemInAvailableDrive(item); + // If we failed to find the item in the next available drive, then find another drive. if (drive == null) { - return false; + drive = getNextAvailableDrive(); + + if (drive == null) { + return false; + } } + + boolean addReturn = drive.addItem(item); + + return addReturn; } - boolean addReturn = drive.addItem(item); - - return addReturn; -} - public ItemStack removeItem(ItemStack item) { // Find a drive that has this item to remove from. ESDrive drive = null; @@ -207,4 +217,64 @@ public boolean addItem(ItemStack item) { return drive.removeItem(item); } + + + // @TODO: Implement (has not been tested) + @NotNull + @Override + public Map serialize() { + Map result = new LinkedHashMap(); + result.put("uuid", uuid); + result.put("owner", owner); + result.put("location", location); + result.put("drives", esDrives); + result.put("trustedPlayers", trustedPlayers); + result.put("isPublic", isPublic); + result.put("sortOrder", sortOrder.toString()); + + return result; + } + + // @TODO: Implement (has not been tested) + @NotNull + public static ESSystem deserialize(@NotNull Map args) { + UUID owner = (UUID) args.get("owner"); + UUID uuid = (UUID) args.get("uuid"); + Location location = (Location) args.get("location"); + + List drives = new ArrayList<>(); + if (args.containsKey("drives")) { + Object raw = args.get("drives"); + if (raw instanceof List) { + Map map = (Map)raw; + + drives.add(ESDrive.deserialize((Map) map)); + } + } + + List trustedPlayers = (List) args.get("trustedPlayers"); + boolean isPublic = (boolean) args.get("isPublic"); + SortOrder sortOrder = SortOrder.valueOf((String)args.get("sortOrder")); + + return new ESSystem(owner, uuid, location, drives, trustedPlayers, isPublic, sortOrder); + } + + public enum SortOrder { + ALPHABETICAL, + AMOUNT, + ID; + + public String toDisplayString() { + switch (this) { + case ALPHABETICAL: + return "Alphabetical"; + case AMOUNT: + return "Amount"; + case ID: + return "ID"; + } + + return ""; + } + } }