From 9d4322d5237a439f8f2a91a1a337559b3b290cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=BDingor?= Date: Sat, 18 Jun 2022 17:15:04 +0200 Subject: [PATCH] Rewrite in progress --- build.gradle | 17 +---- .../chestnetworks/ChestNetCommand.java | 19 +++++ .../chestnetworks/ChestNetworksPlugin.java | 20 +++++ .../eu/zhincore/chestnetworks/Database.java | 2 +- .../chestnetworks/networks/ChestNetwork.java | 76 ++++++++++--------- .../networks/ChestNetworkManager.java | 21 ++++- .../chestnetworks/networks/NetworkChest.java | 11 +++ .../chestnetworks/util/ChestNetMessages.java | 13 ++++ .../chestnetworks/util/ChestNetSorter.java | 27 ++++++- .../chestnetworks/util/ChestNetUtils.java | 12 --- src/main/resources/lang_en.yml | 1 + 11 files changed, 150 insertions(+), 69 deletions(-) create mode 100644 src/main/java/eu/zhincore/chestnetworks/ChestNetCommand.java create mode 100644 src/main/java/eu/zhincore/chestnetworks/util/ChestNetMessages.java create mode 100644 src/main/resources/lang_en.yml diff --git a/build.gradle b/build.gradle index 8f058b2..9cc5b5a 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ repositories { dependencies { compileOnly paper('1.18.2-R0.1-SNAPSHOT') - // implementation 'co.aikar:acf-paper:0.5.1-SNAPSHOT' + implementation 'co.aikar:acf-paper:0.5.1-SNAPSHOT' // implementation 'co.aikar:taskchain-bukkit:3.7.2' } @@ -29,22 +29,11 @@ spigot { softDepends 'ChestSort' apiVersion '1.18' excludeLibraries('acf-paper', 'ChestSortAPI') - - commands { - chestnet { - aliases = ['cnet', 'chestnetwork', 'chestnetworks'] - description = 'Create or edit chest sort networks' - usage = 'Use / help for help' - } - } - permissions { - - } } shadowJar { - // relocate 'co.aikar.commands', 'eu.zhincore.chestnetworks.acf' - // relocate 'co.aikar.locales', 'eu.zhincore.chestnetworks.locales' + relocate 'co.aikar.commands', 'eu.zhincore.chestnetworks.acf' + relocate 'co.aikar.locales', 'eu.zhincore.chestnetworks.locales' // relocate 'co.aikar.taskchain', 'eu.zhincore.chestnetworks.taskchain' archiveClassifier = "shadowed" } diff --git a/src/main/java/eu/zhincore/chestnetworks/ChestNetCommand.java b/src/main/java/eu/zhincore/chestnetworks/ChestNetCommand.java new file mode 100644 index 0000000..5e9fd07 --- /dev/null +++ b/src/main/java/eu/zhincore/chestnetworks/ChestNetCommand.java @@ -0,0 +1,19 @@ +package eu.zhincore.chestnetworks; + +import org.bukkit.entity.Player; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.MessageType; +import co.aikar.commands.annotation.*; + +@CommandAlias("cnet|chestnetworks") +@CommandPermission("chestnetworks.command") +public class ChestNetCommand extends BaseCommand { + @Dependency + private ChestNetworksPlugin plugin; + + @Subcommand("list") + public void listNets(Player player) { + var networks = plugin.database.networkManager.networks.row(player.getUniqueId()); + ; + } +} diff --git a/src/main/java/eu/zhincore/chestnetworks/ChestNetworksPlugin.java b/src/main/java/eu/zhincore/chestnetworks/ChestNetworksPlugin.java index 8c5e366..42898b1 100644 --- a/src/main/java/eu/zhincore/chestnetworks/ChestNetworksPlugin.java +++ b/src/main/java/eu/zhincore/chestnetworks/ChestNetworksPlugin.java @@ -1,13 +1,33 @@ package eu.zhincore.chestnetworks; +import java.io.IOException; +import java.util.Locale; +import org.bukkit.Bukkit; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.plugin.java.JavaPlugin; +import co.aikar.commands.PaperCommandManager; +import eu.zhincore.chestnetworks.util.ChestNetMessages; public class ChestNetworksPlugin extends JavaPlugin { public Database database = new Database(this); + public PaperCommandManager manager = new PaperCommandManager(this); + public ChestNetMessages messages; @Override public void onEnable() { database.load(); + + var locales = manager.getLocales(); + try { + locales.loadYamlLanguageFile("lang_en.yml", Locale.ENGLISH); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + Bukkit.getPluginManager().disablePlugin(this); + return; + } + messages = new ChestNetMessages(locales); + + manager.registerCommand(new ChestNetCommand()); } @Override diff --git a/src/main/java/eu/zhincore/chestnetworks/Database.java b/src/main/java/eu/zhincore/chestnetworks/Database.java index 1491e1f..f18bb40 100644 --- a/src/main/java/eu/zhincore/chestnetworks/Database.java +++ b/src/main/java/eu/zhincore/chestnetworks/Database.java @@ -40,7 +40,7 @@ public ChestNetworkManager load() { } catch (Exception ex) { ex.printStackTrace(); } - return networkManager = new ChestNetworkManager(); + return networkManager = new ChestNetworkManager(plugin); } public void scheduleSave() { diff --git a/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetwork.java b/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetwork.java index 0c63b25..8690ca7 100644 --- a/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetwork.java +++ b/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetwork.java @@ -4,18 +4,16 @@ import java.util.HashSet; import java.util.List; import java.util.UUID; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import com.google.common.collect.ArrayListMultimap; import eu.zhincore.chestnetworks.ChestNetworksPlugin; import eu.zhincore.chestnetworks.networks.NetworkChest.ChestType; import eu.zhincore.chestnetworks.util.ChestNetSorter; -import eu.zhincore.chestnetworks.util.ChestNetUtils; import eu.zhincore.chestnetworks.util.SchedulableTask; public class ChestNetwork { - public String name; public UUID ownerId; + public String name; public boolean sort = true; public List chests = new ArrayList<>(); private ChestNetworksPlugin plugin; @@ -23,9 +21,9 @@ public class ChestNetwork { private transient ArrayListMultimap, NetworkChest> indexByContent = ArrayListMultimap.create(); private transient SchedulableTask indexingTask = new SchedulableTask(plugin, () -> this.rebuildIndex()); - public ChestNetwork(String name, UUID ownerId) { - this.name = name; + public ChestNetwork(UUID ownerId, String name) { this.ownerId = ownerId; + this.name = name; } public void addChest(NetworkChest chest) { @@ -43,6 +41,7 @@ public void removeChest(NetworkChest chest) { public void rebuildIndex() { indexByContent.clear(); + // Create index for (var chest : chests) { indexByContent.get(chest.content).add(chest); } @@ -54,50 +53,60 @@ public void update() { } } - public HashSet update(NetworkChest chest) { - var chestBlock = ChestNetUtils.getChestByLocation(chest.location); - if (chestBlock == null) { + public HashSet update(NetworkChest chest) { + var inventory = chest.getInventory(); + if (inventory == null) { // The chest doesn't exist anymore, remove it removeChest(chest); return null; } - - var inventory = chestBlock.getInventory(); - var updatedInvs = new HashSet(); + var updatedChests = new HashSet(); switch (chest.type) { case INPUT: for (var stack : inventory.getStorageContents()) { if (stack == null) continue; - updatedInvs.add(storeItemStack(stack, inventory)); + updatedChests.add(storeItemStack(stack, chest)); } break; case STORAGE: for (var stack : inventory.getStorageContents()) { if (stack == null || !chest.content.contains(stack.getType().toString())) continue; - updatedInvs.add(storeItemStack(stack, inventory)); + updatedChests.add(storeItemStack(stack, chest)); } // If a change happened, update input chests in case new spot was made - if (!updatedInvs.isEmpty()) { + if (!updatedChests.isEmpty()) { updateInputChests(); } break; } - if (!updatedInvs.isEmpty()) { - ChestNetSorter.sortInventories(inventory); - for (var updatedInv : updatedInvs) { - ChestNetSorter.sortInventories(updatedInv); - } + if (sort && !updatedChests.isEmpty()) { + updatedChests.add(chest); + sortChests(updatedChests.toArray(new NetworkChest[0])); } - return updatedInvs; + return updatedChests; + } + + public void sortChests(NetworkChest... chests) { + var contentDone = new HashSet>(); + + // Sort RAID0s + for (var chest : chests) { + if (!contentDone.add(chest.content)) continue; + + var raid0 = indexByContent.get(chest.content); + raid0.sort((a, b) -> a.priority - b.priority); + + ChestNetSorter.sort(raid0.toArray(new NetworkChest[0])); + } } - private HashSet updateInputChests() { - var updatedInvs = new HashSet(); + private HashSet updateInputChests() { + var updatedInvs = new HashSet(); for (var chest : chests) { if (chest.type == ChestType.INPUT) { @@ -107,27 +116,22 @@ private HashSet updateInputChests() { return updatedInvs; } - public Inventory storeItemStack(ItemStack stack) { + public NetworkChest storeItemStack(ItemStack stack) { return storeItemStack(stack, null); } - private Inventory storeItemStack(ItemStack stack, Inventory originInventory) { - return storeItemStack(stack, originInventory, false); + private NetworkChest storeItemStack(ItemStack stack, NetworkChest originChest) { + return storeItemStack(stack, originChest, false); } - private Inventory storeItemStack(ItemStack stack, Inventory originInventory, boolean useMisc) { + private NetworkChest storeItemStack(ItemStack stack, NetworkChest originChest, boolean useMisc) { for (var chest : chests) { - if (chest.type != ChestType.STORAGE + if (chest == originChest || chest.type != ChestType.STORAGE || !(chest.content.isEmpty() ? useMisc : chest.content.contains(stack.getType().toString()))) continue; - var targetChest = ChestNetUtils.getChestByLocation(chest.location); - if (targetChest == null) continue; - - var destination = targetChest.getInventory(); - - // Item is already in suitable destination - if (destination.equals(originInventory)) return destination; + var destination = chest.getInventory(); + if (destination == null) continue; var overflow = destination.addItem(stack.clone()); @@ -137,10 +141,10 @@ private Inventory storeItemStack(ItemStack stack, Inventory originInventory, boo } stack.setAmount(remains); - return destination; + return chest; } - if (!useMisc) return storeItemStack(stack, originInventory, true); + if (!useMisc) return storeItemStack(stack, originChest, true); return null; } } diff --git a/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetworkManager.java b/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetworkManager.java index 36aee6e..c8d5e49 100644 --- a/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetworkManager.java +++ b/src/main/java/eu/zhincore/chestnetworks/networks/ChestNetworkManager.java @@ -1,17 +1,30 @@ package eu.zhincore.chestnetworks.networks; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.UUID; import org.bukkit.inventory.Inventory; +import com.google.common.collect.HashBasedTable; +import eu.zhincore.chestnetworks.ChestNetworksPlugin; public class ChestNetworkManager { - public Map networks = new HashMap<>(); + public HashBasedTable networks = HashBasedTable.create(); + private ChestNetworksPlugin plugin; + + public ChestNetworkManager(ChestNetworksPlugin plugin) { + this.plugin = plugin; + } + + public boolean create(UUID playerId, String netName) { + var playerNets = networks.row(playerId); + if (playerNets.containsKey(netName)) return false; + playerNets.put(netName, new ChestNetwork(playerId, netName)); + plugin.database.scheduleSave(); + return true; + } public boolean update(UUID playerId, String netName) { - var network = networks.get(playerId); + var network = networks.row(playerId).get(netName); if (network == null) return false; network.update(); return true; diff --git a/src/main/java/eu/zhincore/chestnetworks/networks/NetworkChest.java b/src/main/java/eu/zhincore/chestnetworks/networks/NetworkChest.java index 2f8a790..a5faad0 100644 --- a/src/main/java/eu/zhincore/chestnetworks/networks/NetworkChest.java +++ b/src/main/java/eu/zhincore/chestnetworks/networks/NetworkChest.java @@ -2,6 +2,9 @@ import java.util.List; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Chest; +import org.bukkit.inventory.Inventory; public class NetworkChest { public ChestType type; @@ -17,6 +20,14 @@ public NetworkChest(ChestType type, Location location, ChestNetwork network, Lis this.content = content; } + public Inventory getInventory() { + var block = location.getBlock(); + if (block.getType() != Material.CHEST) return null; + + var chest = (Chest) block.getState(); + return chest.getInventory(); + } + static enum ChestType { STORAGE, INPUT } diff --git a/src/main/java/eu/zhincore/chestnetworks/util/ChestNetMessages.java b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetMessages.java new file mode 100644 index 0000000..041fcdb --- /dev/null +++ b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetMessages.java @@ -0,0 +1,13 @@ +package eu.zhincore.chestnetworks.util; + +import co.aikar.commands.BukkitLocales; + +public class ChestNetMessages { + BukkitLocales locales; + + public ChestNetMessages(BukkitLocales locales) { + this.locales = locales; + } + + +} diff --git a/src/main/java/eu/zhincore/chestnetworks/util/ChestNetSorter.java b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetSorter.java index b1a7b9e..7cb9732 100644 --- a/src/main/java/eu/zhincore/chestnetworks/util/ChestNetSorter.java +++ b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetSorter.java @@ -1,10 +1,13 @@ package eu.zhincore.chestnetworks.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.List; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import eu.zhincore.chestnetworks.networks.NetworkChest; public class ChestNetSorter { private static final Comparator defaultComparator = new Comparator<>() { @@ -14,7 +17,24 @@ public int compare(ItemStack stack1, ItemStack stack2) { } }; - public static void sortInventories(Inventory... inventories) { + public static void sort(NetworkChest... chests) { + var contents = new ArrayList(); + var inventories = new ArrayList(); + + for (var chest : chests) { + var inventory = chest.getInventory(); + inventories.add(inventory); + + for (var stack : inventory.getContents()) { + if (stack != null) contents.add(stack); + } + inventory.clear(); + } + + sort(inventories, contents); + } + + public static void sort(Inventory... inventories) { var contents = new ArrayList(); for (var inventory : inventories) { for (var stack : inventory.getContents()) { @@ -23,8 +43,11 @@ public static void sortInventories(Inventory... inventories) { inventory.clear(); } - Collections.sort(contents, defaultComparator); + sort(Arrays.asList(inventories), contents); + } + private static void sort(List inventories, List contents) { + Collections.sort(contents, defaultComparator); int i = 0; int leftItems = contents.size(); diff --git a/src/main/java/eu/zhincore/chestnetworks/util/ChestNetUtils.java b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetUtils.java index ec37025..8602a8f 100644 --- a/src/main/java/eu/zhincore/chestnetworks/util/ChestNetUtils.java +++ b/src/main/java/eu/zhincore/chestnetworks/util/ChestNetUtils.java @@ -1,22 +1,11 @@ package eu.zhincore.chestnetworks.util; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.Chest; import org.bukkit.block.DoubleChest; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; public class ChestNetUtils { - public static Chest getChestByLocation(Location location) { - Block target = location.getBlock(); - if (target.getType() == Material.CHEST) { - return (Chest) target.getState(); - } - return null; - } - public static Chest[] getChests(Inventory inventory) { InventoryHolder holder = inventory.getHolder(); if (holder instanceof DoubleChest) { @@ -27,5 +16,4 @@ public static Chest[] getChests(Inventory inventory) { } return null; } - } diff --git a/src/main/resources/lang_en.yml b/src/main/resources/lang_en.yml new file mode 100644 index 0000000..47739e3 --- /dev/null +++ b/src/main/resources/lang_en.yml @@ -0,0 +1 @@ +network_list: "You have created these networks:"