Added a dictionary so all front end text can be configured

This commit is contained in:
wolf
2025-08-01 15:39:41 -05:00
parent 402df54dcf
commit 86025fa19a
13 changed files with 235 additions and 104 deletions

View File

@@ -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;
}

View File

@@ -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,11 +19,15 @@ 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() {

View File

@@ -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<Dictionary>, 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 = "<aqua><bold>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 = "<blue>Replicator GUI";
public String replicatorLore = "<gray>Open the single-item dupe GUI.";
public String inventoryName = "<yellow>Inventory GUI";
public String inventoryLore = "<gray>Open a mirror of your own inventory.";
public String chestName = "<green>Chest GUI";
public String chestLore = "<gray>Open the multi-item dupe GUI.";
public String noDupeGuiName = "<dark_red>Unavailable GUI";
public List<String> noDupeGuiLore = List.of(
"",
"<red>You lack the permission to",
"<red>use the <italic>{0}</italic> 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 = "<gradient:#cc22ff:#cc99ff><bold>REPLICATOR</gradient>";
public String uniqueItemWarning = "Your {0} is or contains a unique item!";
public String inputItemDisplayName = "<gold>Replicator Input";
public List<String> inputItemLoreCooldown = List.of("Replicator input on cooldown.");
public List<String> inputItemLoreNoItemSelected = List.of("<gray>No item selected.", "<dark_red>Drag an item into this slot.");
public List<String> inputItemLoreItemSelected = List.of("<white>Set Item: {0}", "<dark_green>Replication Ready!");
}
public class DictGuiInventory {
public String title = "<gradient:#cc22ff:#cc99ff><bold>YOUR INVENTORY</gradient>";
}
public class DictGuiChest {
public String title = "<gradient:#cc22ff:#cc99ff><bold>DUPE CHEST</gradient>";
}
public class DictCommonItems {
public String refillName = "<yellow>Item Refilling...";
public String uniqueName = "<red>UNIQUE ITEM";
public String uniqueLore = "<gray>You are unable to dupe <white>{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.";
}
}

View File

@@ -40,8 +40,6 @@ public class DupeConfig implements JsonSerializable<DupeConfig>, DupeContext {
ItemTag.INFINITE, "<dark_green><bold>|</bold><green> Finite"
));
public boolean blockDupePlus = false;
public List<GlobalRule> globalRules = new ArrayList<>();
public Replicator replicator = new Replicator();

View File

@@ -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<Component> 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;

View File

@@ -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);
}
}

View File

@@ -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()));
}
}

View File

@@ -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);
}
}

View File

@@ -30,19 +30,19 @@ public interface CommonItems extends DupeContext {
return EMPTY().withType(display);
}
default ItemStack BACK() {
return ItemBuilder.of(Material.ARROW)
.displayName("<yellow><bold>← Back</bold>")
.modifyMeta(meta->{
meta.getPersistentDataContainer().set(CANCEL_CLICK(), PersistentDataType.BOOLEAN,Boolean.TRUE);
return meta;
})
.build();
}
default ItemStack BACK() {
return ItemBuilder.of(Material.ARROW)
.displayName("<yellow><bold>← Back</bold>")
.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("<yellow>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("<red><bold>UNIQUE ITEM")
.loreMiniMessage("<gray>You are unable to dupe <white>" + FormatUtils.formatEnum(clone.getType()))
.displayName(dict().guiDupe.commonItems.uniqueName)
.loreMiniMessage(dict().guiDupe.commonItems.uniqueLore.replace("{0}",FormatUtils.formatEnum(clone.getType())))
.build();
return clone;
}

View File

@@ -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("<aqua><bold>Available GUIs")
.titleMini(dict().guiDupe.title)
.item(20,
permissionItem(
player,
"dupealias.gui.replicator",
ItemBuilder.of(Material.DISPENSER)
.displayName("<blue>Replicator GUI")
.loreMiniMessage("<gray>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("<yellow>Inventory GUI")
.loreMiniMessage("<gray>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("<green>Chest GUI")
.loreMiniMessage("<gray>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("<dark_red>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);
}
}
}

View File

@@ -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<DupeChestGui.ChestSession> {
private int delayTicks;
public ChestSession(Player owner) {
super(owner, "<gradient:#cc22ff:#cc99ff><bold>DUPE CHEST</gradient>", 6);
super(owner, DupeAlias.getDupeAlias().getDictionary().guiDupe.guiChest.title, 6);
this.delayTicks = getDupe().getPermissionValue(owner, "dupealias.gui.chest.refresh.", getConfig().chest.baseRefreshDelayTicks,false);
}

View File

@@ -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 AbstractDupeGui<DupeInventoryGui.Inventory
private int delayTicks;
public InventorySession(Player owner) {
super(owner, "<gradient:#cc22ff:#cc99ff><bold>YOUR INVENTORY</gradient>", 6);
super(owner, DupeAlias.getDupeAlias().getDictionary().guiDupe.guiInventory.title, 6);
this.delayTicks = getDupe().getPermissionValue(owner, "dupealias.gui.inventory.refresh.", getConfig().inventory.baseRefreshDelayTicks,false);
}

View File

@@ -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<DupeReplicatorGui.ReplicatorSession> {
import java.util.List;
import java.util.stream.Collectors;
public class DupeReplicatorGui extends AbstractDupeGui<DupeReplicatorGui.ReplicatorSession> 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};
@@ -46,7 +51,7 @@ public class DupeReplicatorGui extends AbstractDupeGui<DupeReplicatorGui.Replica
private boolean ready = false;
public ReplicatorSession(Player owner, ItemStack input) {
super(owner, "<gradient:#cc22ff:#cc99ff><bold>REPLICATOR</gradient>", 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);
@@ -165,7 +170,7 @@ public class DupeReplicatorGui extends AbstractDupeGui<DupeReplicatorGui.Replica
public boolean setInput(ItemStack newInput) {
if (getDupe().isUnique(newInput)) {
SoundPlayer.play(getOwner(), Sound.ENTITY_VILLAGER_NO, 1, 0.8F);
warningAny(getOwner(), "Your {0} is or contains a unique item!", FormatUtils.formatEnum(newInput.getType()));
warningAny(getOwner(), dict().guiDupe.guiReplicator.uniqueItemWarning, FormatUtils.formatEnum(newInput.getType()));
getGui().getInventory().setItem(11, createInputItem(this.input, 1));
return false;
}
@@ -205,22 +210,22 @@ public class DupeReplicatorGui extends AbstractDupeGui<DupeReplicatorGui.Replica
private ItemStack createInputItem(ItemStack input, double cooldownProgress) {
if (cooldownProgress < 1) {
return ItemBuilder.of(EMPTY(Material.BARRIER))
.displayName("<gold>Replicator 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("<gold>Replicator Input")
.loreMiniMessage("<gray>No item selected.")
.loreMiniMessage("<dark_red>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("<gold>Replicator Input")
.loreMiniMessage("<white>Set Item: " + FormatUtils.formatEnum(input.getType()))
.loreMiniMessage("<dark_green>Replication Ready!")
.displayName(dict().guiDupe.guiReplicator.inputItemDisplayName)
.loreMiniMessage(dict().guiDupe.guiReplicator.inputItemLoreItemSelected.stream()
.map(line->line.replace("{0}", FormatUtils.formatEnum(input.getType())))
.toList())
.build();
}
}