From cfe05597996df1331e477c163c08ea810b79a247 Mon Sep 17 00:00:00 2001 From: Tim Southwick Date: Sat, 12 Sep 2020 19:45:27 -0400 Subject: [PATCH] Added support for custom sort keys --- pom.xml | 2 +- .../ChestSort/ChestSortListener.java | 10 +++ .../ChestSort/ChestSortOrganizer.java | 78 ++++++++++++------- 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index c9b704d..7485745 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,7 @@ de.jeff_media ChestSortAPI - 1.0.0 + 1.1.0 compile diff --git a/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java b/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java index 83e6100..0d73b11 100644 --- a/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java +++ b/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java @@ -25,6 +25,10 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; public class ChestSortListener implements Listener { @@ -535,6 +539,12 @@ public class ChestSortListener implements Listener { ChestSortEvent chestSortEvent = new ChestSortEvent(e.getInventory()); chestSortEvent.setLocation(e.getWhoClicked().getLocation()); + + chestSortEvent.setSortableMaps(new HashMap>()); + for (ItemStack item : e.getInventory().getContents()) { + chestSortEvent.getSortableMaps().put(item, plugin.organizer.getSortableMap(item)); + } + Bukkit.getPluginManager().callEvent(chestSortEvent); if (chestSortEvent.isCancelled()) { return; diff --git a/src/main/java/de/jeff_media/ChestSort/ChestSortOrganizer.java b/src/main/java/de/jeff_media/ChestSort/ChestSortOrganizer.java index 711f919..66e23dd 100644 --- a/src/main/java/de/jeff_media/ChestSort/ChestSortOrganizer.java +++ b/src/main/java/de/jeff_media/ChestSort/ChestSortOrganizer.java @@ -341,17 +341,16 @@ public class ChestSortOrganizer { return new CategoryLinePair((plugin.debug) ? "~category~" : emptyPlaceholderString, (short) 0); } - // This puts together the sortable item name, the category, the color, and - // whether the item is a block or a "regular item" - String getSortableString(ItemStack item) { - char blocksFirst; - char itemsFirst; + // Generate a map of "{placeholder}", "sortString" pairs for an ItemStack + Map getSortableMap(ItemStack item) { + String blocksFirst; + String itemsFirst; if (item.getType().isBlock()) { - blocksFirst = '!'; // ! is before # in ASCII - itemsFirst = '#'; + blocksFirst = "!"; // ! is before # in ASCII + itemsFirst = "#"; } else { - blocksFirst = '#'; - itemsFirst = '!'; + blocksFirst = "#"; + itemsFirst = "!"; } String[] typeAndColor = getTypeAndColor(item.getType().name()); @@ -416,20 +415,33 @@ public class ChestSortOrganizer { // Put enchanted items before unenchanted ones typeName = typeName + String.format("%05d", 10000 - getNumberOfEnchantments(item)); - // Generate the strings that finally are used for sorting. - // They are generated according to the config.yml's sorting-method option + // Generate the map of string replacements used to generate a sortableString. + // This map can be edited by ChestSortEvent handlers. See ChestSortEvent.getSortableMaps() + Map sortableMap = new HashMap(); + sortableMap.put("{itemsFirst}", String.valueOf(itemsFirst)); + sortableMap.put("{blocksFirst}", String.valueOf(blocksFirst)); + sortableMap.put("{name}", typeName + potionEffect); + sortableMap.put("{color}", color); + sortableMap.put("{category}", categorySticky); + sortableMap.put("{keepCategoryOrder}", lineNumber); + sortableMap.put("{customName}", customName); + sortableMap.put("{lore}", lore); + + return sortableMap; + } + + // This puts together the sortable item name, the category, the color, and + // whether the item is a block or a "regular item" + String getSortableString(ItemStack item, Map sortableMap) { String sortableString = plugin.sortingMethod.replaceAll(",", "|"); - sortableString = sortableString.replace("{itemsFirst}", String.valueOf(itemsFirst)); - sortableString = sortableString.replace("{blocksFirst}", String.valueOf(blocksFirst)); - sortableString = sortableString.replace("{name}", typeName + potionEffect); - sortableString = sortableString.replace("{color}", color); - sortableString = sortableString.replace("{category}", categorySticky); - sortableString = sortableString.replace("{keepCategoryOrder}", lineNumber); - sortableString = sortableString.replace("{customName}", customName); - sortableString = sortableString.replace("{lore}", lore); + + for (Map.Entry entry : sortableMap.entrySet()) { + String placeholder = entry.getKey(); + String sortableValue = entry.getValue(); + sortableString = sortableString.replace(placeholder, sortableValue); + } return sortableString; - } // Sort a complete inventory @@ -441,16 +453,12 @@ public class ChestSortOrganizer { void sortInventory(@NotNull Inventory inv, int startSlot, int endSlot) { if(inv==null) return; Class invClass = inv.getClass(); + de.jeff_media.ChestSortAPI.ChestSortEvent chestSortEvent = new de.jeff_media.ChestSortAPI.ChestSortEvent(inv); try { if (invClass.getMethod("getLocation", null) != null) { // This whole try/catch fixes MethodNotFoundException when using inv.getLocation in Spigot 1.8. - } - if (inv.getLocation() != null) { - de.jeff_media.ChestSortAPI.ChestSortEvent chestSortEvent = new de.jeff_media.ChestSortAPI.ChestSortEvent(inv); - chestSortEvent.setLocation(inv.getLocation()); - Bukkit.getPluginManager().callEvent(chestSortEvent); - if (chestSortEvent.isCancelled()) { - return; + if (inv.getLocation() != null) { + chestSortEvent.setLocation(inv.getLocation()); } } } catch (Throwable throwable) { @@ -461,6 +469,16 @@ public class ChestSortOrganizer { } + chestSortEvent.setSortableMaps(new HashMap>()); + for (ItemStack item : inv.getContents()) { + chestSortEvent.getSortableMaps().put(item, getSortableMap(item)); + } + + Bukkit.getPluginManager().callEvent(chestSortEvent); + if (chestSortEvent.isCancelled()) { + return; + } + if (plugin.debug) { System.out.println(" "); @@ -525,7 +543,9 @@ public class ChestSortOrganizer { ItemStack[] nonNullItems = nonNullItemsList.toArray(new ItemStack[0]); // Sort the array with ItemStacks according to each ItemStacks' sortable String - Arrays.sort(nonNullItems, Comparator.comparing(this::getSortableString)); + Arrays.sort(nonNullItems, Comparator.comparing((ItemStack item) -> { + // lambda expression used to pass extra parameter + return this.getSortableString(item, chestSortEvent.getSortableMaps().get(item));})); // Now, we put everything back in a temporary inventory to combine ItemStacks // even when using strict slot sorting @@ -541,7 +561,7 @@ public class ChestSortOrganizer { for (ItemStack item : nonNullItems) { if (plugin.debug) - System.out.println(getSortableString(item)); + System.out.println(getSortableString(item, chestSortEvent.getSortableMaps().get(item))); // Add the item to the temporary inventory tempInventory.addItem(item); }