From 86025fa19a8e5195e54eb66ea2837314a6de6041 Mon Sep 17 00:00:00 2001 From: wolf Date: Fri, 1 Aug 2025 15:39:41 -0500 Subject: [PATCH] Added a dictionary so all front end text can be configured --- .../java/me/trouper/dupealias/DupeAlias.java | 5 + .../me/trouper/dupealias/DupeContext.java | 11 ++- .../dupealias/data/files/Dictionary.java | 97 +++++++++++++++++++ .../dupealias/data/files/DupeConfig.java | 2 - .../trouper/dupealias/server/DupeManager.java | 38 ++++++-- .../server/commands/DupeCommand.java | 16 +-- .../server/events/InfiniteItemEvents.java | 2 +- .../server/events/ItemModificationEvents.java | 56 +++++------ .../dupealias/server/gui/CommonItems.java | 26 ++--- .../dupealias/server/gui/dupe/DupeGui.java | 35 ++++--- .../server/gui/dupe/sub/DupeChestGui.java | 3 +- .../server/gui/dupe/sub/DupeInventoryGui.java | 3 +- .../gui/dupe/sub/DupeReplicatorGui.java | 45 +++++---- 13 files changed, 235 insertions(+), 104 deletions(-) create mode 100644 src/main/java/me/trouper/dupealias/data/files/Dictionary.java diff --git a/src/main/java/me/trouper/dupealias/DupeAlias.java b/src/main/java/me/trouper/dupealias/DupeAlias.java index eb65afb..25b8474 100644 --- a/src/main/java/me/trouper/dupealias/DupeAlias.java +++ b/src/main/java/me/trouper/dupealias/DupeAlias.java @@ -4,6 +4,7 @@ import me.trouper.alias.AliasContext; import me.trouper.alias.AliasContextProvider; import me.trouper.alias.data.Common; import me.trouper.dupealias.data.files.CommonConfig; +import me.trouper.dupealias.data.files.Dictionary; import me.trouper.dupealias.data.files.DupeConfig; import me.trouper.dupealias.server.DupeManager; import org.bukkit.plugin.java.JavaPlugin; @@ -60,6 +61,10 @@ public final class DupeAlias extends JavaPlugin { return alias.getDataManager().get(DupeConfig.class); } + public Dictionary getDictionary() { + return alias.getDataManager().get(Dictionary.class); + } + public DupeManager getDupe() { return dupe; } diff --git a/src/main/java/me/trouper/dupealias/DupeContext.java b/src/main/java/me/trouper/dupealias/DupeContext.java index 866ce46..5b4e637 100644 --- a/src/main/java/me/trouper/dupealias/DupeContext.java +++ b/src/main/java/me/trouper/dupealias/DupeContext.java @@ -3,6 +3,7 @@ package me.trouper.dupealias; import me.trouper.alias.server.ContextAware; import me.trouper.alias.server.events.listeners.GuiInputListener; import me.trouper.dupealias.data.files.CommonConfig; +import me.trouper.dupealias.data.files.Dictionary; import me.trouper.dupealias.data.files.DupeConfig; import me.trouper.dupealias.server.DupeManager; import org.bukkit.plugin.java.JavaPlugin; @@ -18,13 +19,17 @@ public interface DupeContext extends ContextAware { } default CommonConfig getCommonConfig() { - return getDataManager().get(CommonConfig.class); + return getInstance().getCommonConfig(); } default DupeConfig getConfig() { - return getDataManager().get(DupeConfig.class); + return getInstance().getDupeConfig(); } - + + default Dictionary dict() { + return getInstance().getDictionary(); + } + default GuiInputListener getGuiListener() { return getContext().getGuiInputListener(); } diff --git a/src/main/java/me/trouper/dupealias/data/files/Dictionary.java b/src/main/java/me/trouper/dupealias/data/files/Dictionary.java new file mode 100644 index 0000000..b0c3ba3 --- /dev/null +++ b/src/main/java/me/trouper/dupealias/data/files/Dictionary.java @@ -0,0 +1,97 @@ +package me.trouper.dupealias.data.files; + +import me.trouper.alias.data.JsonSerializable; +import me.trouper.dupealias.DupeContext; + +import java.io.File; +import java.util.List; + +public class Dictionary implements JsonSerializable, DupeContext { + + + @Override + public File getFile() { + return new File(getInstance().getDataFolder(), "dictionary.json"); + } + + public DictGuiDupe guiDupe = new DictGuiDupe(); + public DictItemModificationEvents itemModificationEvents = new DictItemModificationEvents(); + public DictDupeCommand dupeCommand = new DictDupeCommand(); + + public class DictGuiDupe { + public String title = "Available GUIs"; + public String noPermission = "You do not have permission to use the main dupe gui."; + public String noSpecificPermission = "You do not have permission to use that GUI."; + public String replicatorName = "Replicator GUI"; + public String replicatorLore = "Open the single-item dupe GUI."; + public String inventoryName = "Inventory GUI"; + public String inventoryLore = "Open a mirror of your own inventory."; + public String chestName = "Chest GUI"; + public String chestLore = "Open the multi-item dupe GUI."; + public String noDupeGuiName = "Unavailable GUI"; + public List noDupeGuiLore = List.of( + "", + "You lack the permission to", + "use the {0} gui." + ); + public String noDefaultGui = "There is currently no default Dupe GUI."; + + public DictGuiReplicator guiReplicator = new DictGuiReplicator(); + public DictGuiInventory guiInventory = new DictGuiInventory(); + public DictGuiChest guiChest = new DictGuiChest(); + public DictCommonItems commonItems = new DictCommonItems(); + + public class DictGuiReplicator { + public String title = "REPLICATOR"; + public String uniqueItemWarning = "Your {0} is or contains a unique item!"; + public String inputItemDisplayName = "Replicator Input"; + public List inputItemLoreCooldown = List.of("Replicator input on cooldown."); + public List inputItemLoreNoItemSelected = List.of("No item selected.", "Drag an item into this slot."); + public List inputItemLoreItemSelected = List.of("Set Item: {0}", "Replication Ready!"); + } + + public class DictGuiInventory { + public String title = "YOUR INVENTORY"; + } + + public class DictGuiChest { + public String title = "DUPE CHEST"; + } + + public class DictCommonItems { + public String refillName = "Item Refilling..."; + public String uniqueName = "UNIQUE ITEM"; + public String uniqueLore = "You are unable to dupe {0}"; + } + } + + public class DictItemModificationEvents { + public String dropInfiniteItem = "You have dropped your infinite {0}!"; + public String craftProtectedItem = "You cannot craft protected items!"; + public String modifyFinalItem = "You cannot modify final items!"; + public String useProtectedItem = "You cannot use protected items!"; + public String placeProtectedItem = "You cannot place protected items!"; + public String placeFinalBanner = "You cannot place final banners!"; + public String fillFinalItem = "You cannot fill final items!"; + public String drainFinalBucket = "You cannot drain final buckets!"; + public String drainProtectedBucket = "You cannot drain protected buckets!"; + public String fillFinalBucket = "You cannot fill final buckets!"; + public String fillProtectedBucket = "You cannot fill protected buckets!"; + public String fishFinalBucket = "You cannot fish with final buckets!"; + public String fishProtectedBucket = "You cannot fish with protected buckets!"; + public String consumeProtectedItem = "You cannot consume protected items!"; + public String useFinalBow = "You cannot use final bows!"; + public String shootProtectedItem = "You cannot shoot protected items!"; + } + + public class DictDupeCommand { + public String noPermission = "You are not allowed to dupe via commands."; + public String onCooldown = "You can command dupe again in {0}."; + public String dupeLimitExceeded = "Your maximum permitted dupe amplifier is {0}!"; + public String noItemHeld = "You must hold an item to duplicate it with commands."; + public String uniqueItemWarning = "Your {0} is or contains a unique item that cannot be duped!"; + public String inventoryFull = "Your inventory is now full."; + public String successMessage = "You have duplicated {0} items!"; + public String invalidNumber = "{0} is not a valid number."; + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/dupealias/data/files/DupeConfig.java b/src/main/java/me/trouper/dupealias/data/files/DupeConfig.java index 24e8cf2..d70b18e 100644 --- a/src/main/java/me/trouper/dupealias/data/files/DupeConfig.java +++ b/src/main/java/me/trouper/dupealias/data/files/DupeConfig.java @@ -40,8 +40,6 @@ public class DupeConfig implements JsonSerializable, DupeContext { ItemTag.INFINITE, "| Finite" )); - public boolean blockDupePlus = false; - public List globalRules = new ArrayList<>(); public Replicator replicator = new Replicator(); diff --git a/src/main/java/me/trouper/dupealias/server/DupeManager.java b/src/main/java/me/trouper/dupealias/server/DupeManager.java index a900274..f09c840 100644 --- a/src/main/java/me/trouper/dupealias/server/DupeManager.java +++ b/src/main/java/me/trouper/dupealias/server/DupeManager.java @@ -20,21 +20,34 @@ import java.util.List; public class DupeManager implements DupeContext { + + /** + * Runs a recursive check on the item to see if it is tagged as UNIQUE. + */ public boolean isUnique(ItemStack item) { if (item == null || item.isEmpty()) return false; return !new UniqueCheck().passes(item); } + /** + * Checks if the input item has the requested tag. + */ public boolean hasIndividualTag(ItemStack input, ItemTag tag) { return input.hasItemMeta() && input.getPersistentDataContainer().has(tag.getKey()); } + /** + * Checks the value of the individual tag. Throws IllegalArgumentException if the item does not have the tag. + */ public boolean checkIndividualTag(ItemStack input, ItemTag tag) { boolean set = hasIndividualTag(input,tag); if (!set) throw new IllegalArgumentException("Tried to check a tag which was not set, this may produce unexpected behavior!"); return Boolean.TRUE.equals(input.getPersistentDataContainer().get(tag.getKey(), PersistentDataType.BOOLEAN)); } + /** + * Compares individual and global rules to see if the selected tag is applicable for the item. + */ public boolean checkEffectiveTag(ItemStack input, ItemTag tag) { if (tag == null || input == null) return false; if (input.isEmpty()) return false; @@ -42,10 +55,8 @@ public class DupeManager implements DupeContext { boolean set = hasIndividualTag(input,tag); boolean individual = set && Boolean.TRUE.equals(input.getPersistentDataContainer().get(tag.getKey(), PersistentDataType.BOOLEAN)); - // Check individual tag first if (set) return individual; - // Check global rules return checkGlobalRuleTag(input, tag); } @@ -143,6 +154,9 @@ public class DupeManager implements DupeContext { return true; } + /** + * Adds the selected tag to the item, updating its lore too. + */ public boolean addTag(ItemStack item, ItemTag tag) { if (hasIndividualTag(item, tag) && getDupe().checkIndividualTag(item, tag)) return false; @@ -158,6 +172,9 @@ public class DupeManager implements DupeContext { return true; } + /** + * Removes the selected tag from the item, updating its lore too. + */ public boolean removeTag(ItemStack item, ItemTag tag) { ItemBuilder builder = ItemBuilder.of(item); @@ -185,6 +202,10 @@ public class DupeManager implements DupeContext { return true; } + + /** + * Sets the selected tag to the exact value, updating the lore too. + */ public void setTag(ItemStack item, ItemTag tag, boolean value) { ItemBuilder builder = ItemBuilder.of(item); @@ -210,6 +231,9 @@ public class DupeManager implements DupeContext { item.setItemMeta(result.getItemMeta()); } + /** + * Removes the selected tag from the item meta and lore. + */ public void removeTagLore(ItemMeta meta, ItemTag tag) { List lore = meta.lore(); if (lore != null) { @@ -232,13 +256,9 @@ public class DupeManager implements DupeContext { } } - public ItemTag getTag(NamespacedKey key) { - for (ItemTag value : ItemTag.values()) { - if (value.getKey().equals(key)) return value; - } - throw new IllegalArgumentException("Invalid NameSpacedKey '%s'".formatted(key.value())); - } - + /** + * Checks the player's permission from the root node (ending in a dot), taking the highest or lowest value found. + */ public int getPermissionValue(Player player, String rootPermission, int fallback, boolean takeHighest) { int result = takeHighest ? Integer.MIN_VALUE : Integer.MAX_VALUE; diff --git a/src/main/java/me/trouper/dupealias/server/commands/DupeCommand.java b/src/main/java/me/trouper/dupealias/server/commands/DupeCommand.java index 79485aa..843a993 100644 --- a/src/main/java/me/trouper/dupealias/server/commands/DupeCommand.java +++ b/src/main/java/me/trouper/dupealias/server/commands/DupeCommand.java @@ -62,7 +62,7 @@ public class DupeCommand implements QuickCommand, DupeContext { dupeGui.openDefaultGui(player); } } catch (NumberFormatException e) { - warningAny(player,"{0} is not a valid number.", args.get(0).toString()); + warningAny(player, dict().dupeCommand.invalidNumber, args.get(0).toString()); } } @@ -75,17 +75,17 @@ public class DupeCommand implements QuickCommand, DupeContext { private boolean verifyDupe(Player player, int amount) { if (!player.hasPermission("dupealias.dupe")) { - warningAny(player,"You are not allowed to dupe via commands."); + warningAny(player, dict().dupeCommand.noPermission); return false; } if (dupeCooldown.isOnCooldown(player.getUniqueId())) { - warningAny(player,"You can command dupe again in {0}.", dupeCooldown.formatLong(player.getUniqueId())); + warningAny(player, dict().dupeCommand.onCooldown, dupeCooldown.formatLong(player.getUniqueId())); return false; } int playerMax = getDupe().getPermissionValue(player,"dupealias.dupe.limit.",Integer.MAX_VALUE,true); if (amount > playerMax) { - warningAny(player,"Your maximum permitted dupe amplifier is {0}!", playerMax); + warningAny(player, dict().dupeCommand.dupeLimitExceeded, playerMax); return false; } @@ -93,13 +93,13 @@ public class DupeCommand implements QuickCommand, DupeContext { ItemStack offHand = player.getInventory().getItemInOffHand(); if (toDupe.isEmpty() && offHand.isEmpty()) { - warningAny(player,"You must hold an item to duplicate it with commands."); + warningAny(player, dict().dupeCommand.noItemHeld); return false; } if (toDupe.isEmpty() || getDupe().isUnique(toDupe)) { if (getDupe().isUnique(offHand)) { - warningAny(player,"Your {0} is or contains a unique item that cannot be duped!", toDupe.getType()); + warningAny(player, dict().dupeCommand.uniqueItemWarning, toDupe.getType()); return false; } else { toDupe = offHand; @@ -129,13 +129,13 @@ public class DupeCommand implements QuickCommand, DupeContext { batch.setAmount(stackAmt); if (!player.getInventory().addItem(batch).isEmpty()) { - infoAny(player,"Your inventory is now full."); + infoAny(player, dict().dupeCommand.inventoryFull); return; } } } int totalGiven = baseCount * ((1 << amount) - 1); - successAny(player,"You have duplicated {0} items!", totalGiven); + successAny(player, dict().dupeCommand.successMessage, totalGiven); } } diff --git a/src/main/java/me/trouper/dupealias/server/events/InfiniteItemEvents.java b/src/main/java/me/trouper/dupealias/server/events/InfiniteItemEvents.java index 6f18032..70091b2 100644 --- a/src/main/java/me/trouper/dupealias/server/events/InfiniteItemEvents.java +++ b/src/main/java/me/trouper/dupealias/server/events/InfiniteItemEvents.java @@ -44,7 +44,7 @@ public class InfiniteItemEvents implements QuickListener, DupeContext { stack.setItemMeta(stackMeta); e.getItemDrop().setItemStack(stack); } else { - infoAny(player,"You have dropped your infinite {0}!", FormatUtils.formatEnum(stack.getType())); + infoAny(player,dict().itemModificationEvents.dropInfiniteItem, FormatUtils.formatEnum(stack.getType())); } } diff --git a/src/main/java/me/trouper/dupealias/server/events/ItemModificationEvents.java b/src/main/java/me/trouper/dupealias/server/events/ItemModificationEvents.java index fbf46fd..1fc7140 100644 --- a/src/main/java/me/trouper/dupealias/server/events/ItemModificationEvents.java +++ b/src/main/java/me/trouper/dupealias/server/events/ItemModificationEvents.java @@ -42,7 +42,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(result, ItemTag.PROTECTED)) { event.getInventory().setResult(null); - warningAny(Audience.audience(event.getViewers()), "You cannot craft protected items!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.craftProtectedItem); return; } @@ -51,13 +51,13 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(ingredient, ItemTag.FINAL)) { if (isModifyingCraft(ingredient, result)) { event.getInventory().setResult(null); - warningAny(Audience.audience(event.getViewers()), "You cannot modify final items!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.modifyFinalItem); return; } } if (getDupe().checkEffectiveTag(ingredient, ItemTag.PROTECTED)) { event.getInventory().setResult(null); - warningAny(Audience.audience(event.getViewers()), "You cannot use protected items!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.useProtectedItem); return; } } @@ -92,7 +92,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.FINAL)) { event.setCancelled(true); - warningAny(event.getEnchanter(), "You cannot modify final items!"); + warningAny(event.getEnchanter(), dict().itemModificationEvents.modifyFinalItem); } } @@ -249,41 +249,41 @@ public class ItemModificationEvents implements QuickListener, DupeContext { switch (inv) { case LoomInventory loom -> { if (getDupe().checkEffectiveTag(loom.getItem(1), ItemTag.PROTECTED) || getDupe().checkEffectiveTag(loom.getItem(2), ItemTag.PROTECTED)) { - warningAny(Audience.audience(event.getViewers()), "You cannot use a protected item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.useProtectedItem); event.getInventory().close(); } if (getDupe().checkEffectiveTag(loom.getItem(0), ItemTag.FINAL)) { - warningAny(Audience.audience(event.getViewers()), "You cannot modify a final item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.modifyFinalItem); event.getInventory().close(); } } case CartographyInventory carto -> { if (getDupe().checkEffectiveTag(carto.getResult(), ItemTag.PROTECTED)) { - warningAny(Audience.audience(event.getViewers()), "You cannot use a protected item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.useProtectedItem); event.getInventory().close(); } if (getDupe().checkEffectiveTag(carto.getItem(0), ItemTag.FINAL) || getDupe().checkEffectiveTag(carto.getItem(1), ItemTag.FINAL)) { - warningAny(Audience.audience(event.getViewers()), "You cannot modify a final item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.modifyFinalItem); event.getInventory().close(); } } case GrindstoneInventory grind -> { if (getDupe().checkEffectiveTag(grind.getResult(), ItemTag.PROTECTED)) { - warningAny(Audience.audience(event.getViewers()), "You cannot use a protected item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.useProtectedItem); event.getInventory().close(); } if (getDupe().checkEffectiveTag(grind.getItem(0), ItemTag.FINAL) || getDupe().checkEffectiveTag(grind.getItem(1), ItemTag.FINAL)) { - warningAny(Audience.audience(event.getViewers()), "You cannot modify a final item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.modifyFinalItem); event.getInventory().close(); } } case StonecutterInventory stone -> { if (getDupe().checkEffectiveTag(stone.getResult(), ItemTag.PROTECTED)) { - warningAny(Audience.audience(event.getViewers()), "You cannot use a protected item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.useProtectedItem); event.getInventory().close(); } if (getDupe().checkEffectiveTag(stone.getItem(0), ItemTag.FINAL)) { - warningAny(Audience.audience(event.getViewers()), "You cannot modify a final item!"); + warningAny(Audience.audience(event.getViewers()), dict().itemModificationEvents.modifyFinalItem); event.getInventory().close(); } } @@ -314,12 +314,12 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (main.getType().equals(Material.BUCKET) || main.getType().equals(Material.GLASS_BOTTLE) || main.getType().name().contains("BANNER") || main.getType().name().contains("ARMOR")) { if (getDupe().checkEffectiveTag(main, ItemTag.FINAL) || getDupe().checkEffectiveTag(main, ItemTag.FINAL)) { event.setCancelled(true); - warningAny(player, "That item is final and cannot be modified!"); + warningAny(player, dict().itemModificationEvents.modifyFinalItem); } } else if (off.getType().equals(Material.BUCKET) || off.getType().equals(Material.GLASS_BOTTLE) || off.getType().name().contains("BANNER") || off.getType().name().contains("ARMOR")) { if (getDupe().checkEffectiveTag(off, ItemTag.FINAL) || getDupe().checkEffectiveTag(off, ItemTag.FINAL)) { event.setCancelled(true); - warningAny(player, "That item is final and cannot be modified!"); + warningAny(player, dict().itemModificationEvents.modifyFinalItem); } } @@ -338,7 +338,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { for (String finalCommandRegex : getConfig().finalCommandRegex) { if (command.matches(finalCommandRegex)) { e.setCancelled(true); - warningAny(e.getPlayer(), "That item is final and cannot be modified!"); + warningAny(e.getPlayer(), dict().itemModificationEvents.modifyFinalItem); return; } } @@ -363,11 +363,11 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(event.getPlayer(), "You cannot place protected items!"); + warningAny(event.getPlayer(), dict().itemModificationEvents.placeProtectedItem); } if (item.getItemMeta() instanceof BannerMeta && getDupe().checkEffectiveTag(item, ItemTag.FINAL)) { event.setCancelled(true); - warningAny(event.getPlayer(), "You cannot place final banners!"); + warningAny(event.getPlayer(), dict().itemModificationEvents.placeFinalBanner); } } @@ -378,14 +378,14 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(event.getPlayer(), "You cannot use protected items!"); + warningAny(event.getPlayer(), dict().itemModificationEvents.useProtectedItem); } Block targetBlock = event.getPlayer().getTargetBlockExact(4, FluidCollisionMode.ALWAYS); if (targetBlock != null && targetBlock.getType() == Material.WATER) { if (getDupe().checkEffectiveTag(item, ItemTag.FINAL) && item != null && (item.getType().equals(Material.GLASS_BOTTLE) || item.getType().equals(Material.BUCKET))) { event.setCancelled(true); - warningAny(event.getPlayer(), "You cannot fill final items!"); + warningAny(event.getPlayer(), dict().itemModificationEvents.fillFinalItem); } } } @@ -397,7 +397,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { boolean isFinal = getDupe().checkEffectiveTag(item, ItemTag.FINAL); boolean isProtected = getDupe().checkEffectiveTag(item, ItemTag.PROTECTED); if (isProtected || isFinal) { - String message = isFinal ? "You cannot drain final buckets!" : "You cannot drain protected buckets!"; + String message = isFinal ? dict().itemModificationEvents.drainFinalBucket : dict().itemModificationEvents.drainProtectedBucket; warningAny(event.getPlayer(), message); event.setCancelled(true); } @@ -410,7 +410,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { boolean isFinal = getDupe().checkEffectiveTag(item, ItemTag.FINAL); boolean isProtected = getDupe().checkEffectiveTag(item, ItemTag.PROTECTED); if (isProtected || isFinal) { - String message = isFinal ? "You cannot fill final buckets!" : "You cannot fill protected buckets!"; + String message = isFinal ? dict().itemModificationEvents.fillFinalBucket : dict().itemModificationEvents.fillProtectedBucket; warningAny(event.getPlayer(), message); event.setCancelled(true); } @@ -423,7 +423,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { boolean isFinal = getDupe().checkEffectiveTag(item, ItemTag.FINAL); boolean isProtected = getDupe().checkEffectiveTag(item, ItemTag.PROTECTED); if (isProtected || isFinal) { - String message = isFinal ? "You cannot fish with final buckets!" : "You cannot fish with protected buckets!"; + String message = isFinal ? dict().itemModificationEvents.fishFinalBucket : dict().itemModificationEvents.fishProtectedBucket; warningAny(event.getPlayer(), message); event.setCancelled(true); } @@ -445,7 +445,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(event.getPlayer(), "You cannot consume protected items!"); + warningAny(event.getPlayer(), dict().itemModificationEvents.consumeProtectedItem); } } @@ -462,7 +462,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { event.setCancelled(true); if (event.getEntity() instanceof Player player) { if (consumable != null) player.getInventory().addItem(consumable); - String message = isFinal ? "You cannot use final bows!" : "You cannot shoot protected items!"; + String message = isFinal ? dict().itemModificationEvents.useFinalBow : dict().itemModificationEvents.shootProtectedItem; warningAny(player, message); } } @@ -480,7 +480,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(player, "You cannot use protected items!"); + warningAny(player, dict().itemModificationEvents.useProtectedItem); } } } @@ -493,7 +493,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(player, "You cannot use protected items!"); + warningAny(player, dict().itemModificationEvents.useProtectedItem); } } } @@ -506,7 +506,7 @@ public class ItemModificationEvents implements QuickListener, DupeContext { if (getDupe().checkEffectiveTag(item, ItemTag.PROTECTED)) { event.setCancelled(true); - warningAny(player, "You cannot use protected items!"); + warningAny(player, dict().itemModificationEvents.useProtectedItem); } } @@ -677,4 +677,4 @@ public class ItemModificationEvents implements QuickListener, DupeContext { return false; } -} +} \ No newline at end of file diff --git a/src/main/java/me/trouper/dupealias/server/gui/CommonItems.java b/src/main/java/me/trouper/dupealias/server/gui/CommonItems.java index b34035e..2bb61e0 100644 --- a/src/main/java/me/trouper/dupealias/server/gui/CommonItems.java +++ b/src/main/java/me/trouper/dupealias/server/gui/CommonItems.java @@ -30,19 +30,19 @@ public interface CommonItems extends DupeContext { return EMPTY().withType(display); } - default ItemStack BACK() { - return ItemBuilder.of(Material.ARROW) - .displayName("← Back") - .modifyMeta(meta->{ - meta.getPersistentDataContainer().set(CANCEL_CLICK(), PersistentDataType.BOOLEAN,Boolean.TRUE); - return meta; - }) - .build(); - } + default ItemStack BACK() { + return ItemBuilder.of(Material.ARROW) + .displayName("← Back") + .modifyMeta(meta->{ + meta.getPersistentDataContainer().set(CANCEL_CLICK(), PersistentDataType.BOOLEAN,Boolean.TRUE); + return meta; + }) + .build(); + } default boolean shouldBlockClick(ItemStack item) { if (item == null || item.isEmpty()) return false; - return (item.hasItemMeta() + return (item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(CANCEL_CLICK(),PersistentDataType.BOOLEAN) && Boolean.TRUE.equals(item.getItemMeta().getPersistentDataContainer().get(CANCEL_CLICK(), PersistentDataType.BOOLEAN))); } @@ -50,15 +50,15 @@ public interface CommonItems extends DupeContext { default ItemStack createPopulatedItem(ItemStack item, double progress) { if (progress < 1) { return ItemBuilder.of(EMPTY(Material.RED_STAINED_GLASS_PANE)) - .displayName("Item Refilling...") + .displayName(dict().guiDupe.commonItems.refillName) .loreComponent(getTextSystem().createProgressBar(progress,(char) '|',20, TextColor.color(0x5AFF89),TextColor.color(0x6F6F6F))) .build(); } if (item == null || item.isEmpty()) return EMPTY(Material.GRAY_STAINED_GLASS_PANE); ItemStack clone = item.clone(); if (getDupe().isUnique(clone)) return ItemBuilder.of(EMPTY(Material.BARRIER)) - .displayName("UNIQUE ITEM") - .loreMiniMessage("You are unable to dupe " + FormatUtils.formatEnum(clone.getType())) + .displayName(dict().guiDupe.commonItems.uniqueName) + .loreMiniMessage(dict().guiDupe.commonItems.uniqueLore.replace("{0}",FormatUtils.formatEnum(clone.getType()))) .build(); return clone; } diff --git a/src/main/java/me/trouper/dupealias/server/gui/dupe/DupeGui.java b/src/main/java/me/trouper/dupealias/server/gui/dupe/DupeGui.java index 0a8c738..1437a7d 100644 --- a/src/main/java/me/trouper/dupealias/server/gui/dupe/DupeGui.java +++ b/src/main/java/me/trouper/dupealias/server/gui/dupe/DupeGui.java @@ -8,9 +8,6 @@ import me.trouper.dupealias.server.gui.dupe.sub.AbstractDupeGui; import me.trouper.dupealias.server.gui.dupe.sub.DupeChestGui; import me.trouper.dupealias.server.gui.dupe.sub.DupeInventoryGui; import me.trouper.dupealias.server.gui.dupe.sub.DupeReplicatorGui; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -23,20 +20,20 @@ public class DupeGui implements DupeContext, CommonItems { public void openMainGui(Player player) { if (!player.hasPermission("dupealias.gui")) { - warningAny(player,"You do not have permission to use the main dupe gui."); + warningAny(player,dict().guiDupe.noPermission); return; } QuickGui gui = QuickGui.create() .rows(5) - .titleMini("Available GUIs") + .titleMini(dict().guiDupe.title) .item(20, permissionItem( player, "dupealias.gui.replicator", ItemBuilder.of(Material.DISPENSER) - .displayName("Replicator GUI") - .loreMiniMessage("Open the single-item dupe GUI.") + .displayName(dict().guiDupe.replicatorName) + .loreMiniMessage(dict().guiDupe.replicatorLore) ), openSession(replicatorGui,"dupealias.gui.replicator")) @@ -44,8 +41,8 @@ public class DupeGui implements DupeContext, CommonItems { player, "dupealias.gui.inventory", ItemBuilder.of(Material.NETHERITE_CHESTPLATE) - .displayName("Inventory GUI") - .loreMiniMessage("Open a mirror of your own inventory.") + .displayName(dict().guiDupe.inventoryName) + .loreMiniMessage(dict().guiDupe.inventoryLore) ), openSession(inventoryGui,"dupealias.gui.inventory")) @@ -53,8 +50,8 @@ public class DupeGui implements DupeContext, CommonItems { player, "dupealias.gui.chest", ItemBuilder.of(Material.ENDER_CHEST) - .displayName("Chest GUI") - .loreMiniMessage("Open the multi-item dupe GUI.") + .displayName(dict().guiDupe.chestName) + .loreMiniMessage(dict().guiDupe.chestLore) ), openSession(chestGui,"dupealias.gui.chest")) @@ -69,11 +66,13 @@ public class DupeGui implements DupeContext, CommonItems { if (player.hasPermission(permission)) { return builder.build(); } else { - Component name = builder.build().effectiveName(); - return builder.displayName("Unavailable GUI") - .loreMiniMessage() - .loreComponent(Component.text("You lack the permission to",NamedTextColor.RED),Component.text("use the ", NamedTextColor.RED).decoration(TextDecoration.ITALIC,false).append(name).append(Component.text("."))) - .build().withType(Material.BARRIER); + return builder.displayName(dict().guiDupe.noDupeGuiName) + .loreMiniMessage( + dict().guiDupe.noDupeGuiLore + .stream() + .map(line->line.replace("{0}",permission.replace("dupealias.gui.",""))) + .toList() + ).build().withType(Material.BARRIER); } } @@ -94,7 +93,7 @@ public class DupeGui implements DupeContext, CommonItems { } } else { player.closeInventory(); - warningAny(player,"You do not have permission to use that GUI."); + warningAny(player,dict().guiDupe.noSpecificPermission); } } @@ -105,7 +104,7 @@ public class DupeGui implements DupeContext, CommonItems { case "CHEST" -> openIfPermission(player,chestGui,"dupealias.gui.chest"); case "MENU" -> openMainGui(player); default -> { - infoAny(player,"There is currently no default Dupe GUI."); + infoAny(player,dict().guiDupe.noDefaultGui); } } } diff --git a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeChestGui.java b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeChestGui.java index 7dedbfb..4e62a51 100644 --- a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeChestGui.java +++ b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeChestGui.java @@ -1,6 +1,7 @@ package me.trouper.dupealias.server.gui.dupe.sub; import me.trouper.alias.server.systems.gui.QuickGui; +import me.trouper.dupealias.DupeAlias; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -31,7 +32,7 @@ public class DupeChestGui extends AbstractDupeGui { private int delayTicks; public ChestSession(Player owner) { - super(owner, "DUPE CHEST", 6); + super(owner, DupeAlias.getDupeAlias().getDictionary().guiDupe.guiChest.title, 6); this.delayTicks = getDupe().getPermissionValue(owner, "dupealias.gui.chest.refresh.", getConfig().chest.baseRefreshDelayTicks,false); } diff --git a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeInventoryGui.java b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeInventoryGui.java index 203d8f3..0d6ef52 100644 --- a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeInventoryGui.java +++ b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeInventoryGui.java @@ -1,6 +1,7 @@ package me.trouper.dupealias.server.gui.dupe.sub; import me.trouper.alias.server.systems.gui.QuickGui; +import me.trouper.dupealias.DupeAlias; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -28,7 +29,7 @@ public class DupeInventoryGui extends AbstractDupeGuiYOUR INVENTORY", 6); + super(owner, DupeAlias.getDupeAlias().getDictionary().guiDupe.guiInventory.title, 6); this.delayTicks = getDupe().getPermissionValue(owner, "dupealias.gui.inventory.refresh.", getConfig().inventory.baseRefreshDelayTicks,false); } diff --git a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeReplicatorGui.java b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeReplicatorGui.java index 5d13020..ee2b89b 100644 --- a/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeReplicatorGui.java +++ b/src/main/java/me/trouper/dupealias/server/gui/dupe/sub/DupeReplicatorGui.java @@ -4,6 +4,8 @@ import me.trouper.alias.server.systems.gui.QuickGui; import me.trouper.alias.utils.FormatUtils; import me.trouper.alias.utils.ItemBuilder; import me.trouper.alias.utils.SoundPlayer; +import me.trouper.dupealias.DupeAlias; +import me.trouper.dupealias.DupeContext; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; @@ -13,7 +15,10 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -public class DupeReplicatorGui extends AbstractDupeGui { +import java.util.List; +import java.util.stream.Collectors; + +public class DupeReplicatorGui extends AbstractDupeGui implements DupeContext { private final int[] inputRing = {1, 2, 3, 12, 21, 20, 19, 10}; private final int[] outputRing = {5, 6, 7, 16, 25, 24, 23, 14}; @@ -42,11 +47,11 @@ public class DupeReplicatorGui extends AbstractDupeGuiREPLICATOR", 3); + super(owner, DupeAlias.getDupeAlias().getDictionary().guiDupe.guiReplicator.title, 3); getVerbose().send("Creating a new replicator with input of {0}", input.getType().name()); setInput(input); this.delayTicks = getDupe().getPermissionValue(owner, "dupealias.gui.replicator.refresh.", getConfig().replicator.baseRefreshDelayTicks,false); @@ -71,11 +76,11 @@ public class DupeReplicatorGui extends AbstractDupeGui close()) .build(); } - + @Override protected void tick() { timer++; - + Inventory inv = getGui().getInventory(); - + if (timer % 2 == 0) for (int i = 0; i < outputRing.length; i++) { int currentSlot = outputRing[i]; int nextSlot = outputRing[(i+1) % outputRing.length]; @@ -123,7 +128,7 @@ public class DupeReplicatorGui extends AbstractDupeGui 1) { @@ -134,7 +139,7 @@ public class DupeReplicatorGui extends AbstractDupeGuiReplicator Input") + .displayName(dict().guiDupe.guiReplicator.inputItemDisplayName) .loreComponent(getTextSystem().createProgressBar(cooldownProgress, '|',30, TextColor.color(0xFF895A),TextColor.color(0x6F6F6F))) - .loreComponent(Component.text("Replicator input on cooldown.", NamedTextColor.DARK_RED)) + .loreMiniMessage(dict().guiDupe.guiReplicator.inputItemLoreCooldown) .build(); } if (input == null || input.getType() == Material.AIR) { return ItemBuilder.headOfTexture("http://textures.minecraft.net/texture/86bd920b402815ad89018df82977be9f7ea19e799ecf016f7f0da4ab47ca23c5") - .displayName("Replicator Input") - .loreMiniMessage("No item selected.") - .loreMiniMessage("Drag an item into this slot.") + .displayName(dict().guiDupe.guiReplicator.inputItemDisplayName) + .loreMiniMessage(dict().guiDupe.guiReplicator.inputItemLoreNoItemSelected) .build(); } else { return ItemBuilder.headOfTexture("http://textures.minecraft.net/texture/32d250f5336449b32bfe990bdfd307a1b39ae5ca07e9a1593b1bb6ed33ec14ba") - .displayName("Replicator Input") - .loreMiniMessage("Set Item: " + FormatUtils.formatEnum(input.getType())) - .loreMiniMessage("Replication Ready!") + .displayName(dict().guiDupe.guiReplicator.inputItemDisplayName) + .loreMiniMessage(dict().guiDupe.guiReplicator.inputItemLoreItemSelected.stream() + .map(line->line.replace("{0}", FormatUtils.formatEnum(input.getType()))) + .toList()) .build(); } }