Compare commits

...

12 commits

Author SHA1 Message Date
185a5bc8a2
more ui translations 2026-08-20 14:00:53 +02:00
8523607657
add lang debug command and fix found translation issue 2026-08-20 14:00:53 +02:00
e4dd806267
ask gui translatable 2026-08-20 14:00:53 +02:00
e1d8dd07ad
a lot of progress inside the ui 2026-08-20 14:00:53 +02:00
0ffe7c70f9
progress on translation system 2026-08-20 14:00:53 +02:00
19eccb5a08
fix small translation issue 2026-08-20 14:00:53 +02:00
7dacfbc303
rework multiline 2026-08-20 14:00:53 +02:00
3c3ee00a50
finished adding command text to trans file 2026-08-20 14:00:53 +02:00
e6ebdcdfc0
better translation system 2026-08-20 14:00:52 +02:00
da49e79dbf
translation key for load errors and warnings 2026-08-20 14:00:52 +02:00
fe9cc2402f
language backend logic 2026-08-20 14:00:52 +02:00
74d2e38272
fix bad handling for middle click
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-08-19 15:25:40 +02:00
62 changed files with 2222 additions and 697 deletions

View file

@ -21,7 +21,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "2.0.2" version = "2.1.0"
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true" val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"

View file

@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.dependency.util
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.inventory.ItemStack import org.bukkit.command.CommandSender
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
// Mostly made for paper, spigot and folia support // Mostly made for paper, spigot and folia support
@ -100,4 +100,39 @@ object PlatformUtil {
} }
} }
/**
* Try to send paper component to the player
*
* @param component The used component
* @return true if sent, else otherwise
*/
fun CommandSender.sendPaperMessage(component: Component): Boolean {
if(isPaper) {
this.sendMessage(component)
return true
}
return false
} /**
* Try to send paper component to the player
*
* @param component The used component
* @return true if sent, else otherwise
*/
/**
* Try to set component lore of an item
*
* @param components The used component lore
* @return true if sent, else otherwise
*/
fun ItemMeta.setPaperLore(components: List<Component>): Boolean {
if(isPaper) {
this.lore(components)
return true
}
return false
}
} }

View file

@ -10,13 +10,18 @@ import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
public abstract class AbstractAskGui extends ChestGui { public abstract class AbstractAskGui extends ChestGui {
protected PatternPane pane; protected PatternPane pane;
AbstractAskGui(int rows, @NotNull String name,
Gui backOnCancel){ AbstractAskGui(
super(rows, name, CustomAnvil.instance); int rows,
@NotNull Message name, @NotNull String param,
Gui backOnCancel
) {
super(rows, name.textHolder(param), CustomAnvil.instance);
Pattern pattern = getGuiPattern(); Pattern pattern = getGuiPattern();
this.pane = new PatternPane(0, 0, pattern.getLength(), pattern.getHeight(), pattern); this.pane = new PatternPane(0, 0, pattern.getLength(), pattern.getHeight(), pattern);

View file

@ -9,20 +9,27 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.MetricsUtil; import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgError;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.Arrays; import java.awt.*;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.Level; import java.util.logging.Level;
public class ConfirmActionGui extends AbstractAskGui { public class ConfirmActionGui extends AbstractAskGui {
public ConfirmActionGui(@NotNull String title, String actionDescription, public ConfirmActionGui(
Gui backOnCancel, Gui backOnConfirm, Supplier<Boolean> onConfirm, @NotNull Message title, @NotNull String titleParam,
boolean permanent) { @Nullable Message actionDescription, @NotNull String actionParam,
super(3, title, backOnCancel); Gui backOnCancel, Gui backOnConfirm, Supplier<Boolean> onConfirm,
boolean permanent
) {
super(3, title, titleParam, backOnCancel);
// Save item // Save item
this.pane.bindItem('S', new GuiItem( this.pane.bindItem('S', new GuiItem(
@ -33,7 +40,7 @@ public class ConfirmActionGui extends AbstractAskGui {
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
@ -41,13 +48,12 @@ public class ConfirmActionGui extends AbstractAskGui {
try { try {
success = onConfirm.get(); success = onConfirm.get();
} catch (Exception e) { } catch (Exception e) {
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e); CustomAnvil.Companion.logError(MsgError.INSTANCE.getCONFIRM_ACTION_GENERIC().unformatted(), e, true, Level.WARNING);
MetricsUtil.INSTANCE.trackError(e);
success = false; success = false;
} }
if (!success) { if (!success) {
event.getWhoClicked().sendMessage("§cAction could not be completed. "); MsgUI.INSTANCE.getCONFIRM_ACTION_FAILED().send(player);
} }
backOnConfirm.show(player); backOnConfirm.show(player);
@ -56,19 +62,23 @@ public class ConfirmActionGui extends AbstractAskGui {
// Info item // Info item
ItemStack infoItem = new ItemStack(Material.PAPER); ItemStack infoItem = new ItemStack(Material.PAPER);
ItemMeta infoMeta = infoItem.getItemMeta(); ItemMeta infoMeta = infoItem.getItemMeta();
assert infoMeta != null;
infoMeta.setDisplayName("§eAre you sure ?"); ComponentUtil.INSTANCE.setMessageName(infoMeta, MsgUI.INSTANCE.getCONFIRM_ACTION_ARE_YOU_SURE());
if(actionDescription != null){ if(actionDescription != null){
infoMeta.setLore(Arrays.asList(actionDescription.split("\n"))); ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(actionParam), infoMeta);
} }
infoItem.setItemMeta(infoMeta); infoItem.setItemMeta(infoMeta);
pane.bindItem('I', new GuiItem(infoItem, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); pane.bindItem('I', new GuiItem(infoItem, GuiGlobalActions.stayInPlace, CustomAnvil.instance));
} }
public ConfirmActionGui(@NotNull String title, String actionDescription, public ConfirmActionGui(
Gui backOnCancel, Gui backOnConfirm, Supplier<Boolean> onConfirm){ @NotNull Message title, @NotNull String titleParam,
this(title, actionDescription, backOnCancel, backOnConfirm, onConfirm, true); @Nullable Message actionDescription, @NotNull String actionParam,
Gui backOnCancel, Gui backOnConfirm, Supplier<Boolean> onConfirm
){
this(title, titleParam, actionDescription, actionParam, backOnCancel, backOnConfirm, onConfirm, true);
} }

View file

@ -9,24 +9,28 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import xyz.alexcrea.cuanvil.util.MaterialUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
public class SelectItemTypeGui extends AbstractAskGui { public class SelectItemTypeGui extends AbstractAskGui {
private ItemStack selectedItem; private ItemStack selectedItem;
public SelectItemTypeGui(@NotNull String title,
@NotNull String actionDescription, public SelectItemTypeGui(@NotNull Message title,
@NotNull String titleParam,
@NotNull Message actionDescription,
@NotNull String descriptionParam,
@NotNull Gui backOnCancel, @NotNull Gui backOnCancel,
@NotNull BiConsumer<ItemStack, HumanEntity> onSave, @NotNull BiConsumer<ItemStack, HumanEntity> onSave,
boolean materialOnly) { boolean materialOnly) {
super(3, title, backOnCancel); super(3, title, titleParam, backOnCancel);
this.selectedItem = null; this.selectedItem = null;
// Save item // Save item
@ -34,9 +38,9 @@ public class SelectItemTypeGui extends AbstractAskGui {
event.setCancelled(true); event.setCancelled(true);
HumanEntity player = event.getWhoClicked(); HumanEntity player = event.getWhoClicked();
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if(!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
@ -46,7 +50,7 @@ public class SelectItemTypeGui extends AbstractAskGui {
this.pane.bindItem('S', GuiGlobalItems.backgroundItem()); this.pane.bindItem('S', GuiGlobalItems.backgroundItem());
// Select item // Select item
ItemStack selectItem = setDisplayMeta(new ItemStack(Material.BARRIER), actionDescription); ItemStack selectItem = setDisplayMeta(new ItemStack(Material.BARRIER), actionDescription, descriptionParam);
AtomicReference<GuiItem> selectGuiItem = new AtomicReference<>(); AtomicReference<GuiItem> selectGuiItem = new AtomicReference<>();
selectGuiItem.set(new GuiItem(selectItem, event -> { selectGuiItem.set(new GuiItem(selectItem, event -> {
@ -56,9 +60,9 @@ public class SelectItemTypeGui extends AbstractAskGui {
if(MaterialUtil.INSTANCE.isAir(cursor)) return; if(MaterialUtil.INSTANCE.isAir(cursor)) return;
ItemStack finalItem; ItemStack finalItem;
if(materialOnly){ if(materialOnly) {
finalItem = setDisplayMeta(new ItemStack(cursor.getType()), actionDescription); finalItem = setDisplayMeta(new ItemStack(cursor.getType()), actionDescription, descriptionParam);
}else{ } else {
finalItem = cursor.clone(); finalItem = cursor.clone();
} }
this.selectedItem = finalItem.clone(); this.selectedItem = finalItem.clone();
@ -75,14 +79,19 @@ public class SelectItemTypeGui extends AbstractAskGui {
GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this); GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this);
this.pane.bindItem('s', temporaryLeave); this.pane.bindItem('s', temporaryLeave);
} }
private ItemStack setDisplayMeta(ItemStack item, String actionDescription){ @NotNull
private ItemStack setDisplayMeta(
@NotNull ItemStack item,
@NotNull Message actionDescription,
@NotNull String param
) {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.setDisplayName("§ePlace an item here"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getSELECT_ITEM_TYPE_PLACE_HERE());
meta.setLore(Arrays.asList(actionDescription.split("\n"))); ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(param), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
return item; return item;

View file

@ -9,6 +9,7 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -20,18 +21,18 @@ import java.util.function.Consumer;
* *
* @param <T> Type of the factory of the type of setting the gui should edit. * @param <T> Type of the factory of the type of setting the gui should edit.
*/ */
public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFactory> extends SettingGuiListConfigGui<CAEnchantment, T>{ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFactory> extends SettingGuiListConfigGui<CAEnchantment, T> {
/** /**
* Constructor for a gui displaying available enchantment to edit a enchantment setting. * Constructor for a gui displaying available enchantment to edit a enchantment setting.
* *
* @param title Title of the gui. * @param title Title of the gui.
*/ */
protected AbstractEnchantConfigGui(String title) { protected AbstractEnchantConfigGui(Message title) {
super(title); super(title);
} }
protected AbstractEnchantConfigGui(String title, Gui parent) { protected AbstractEnchantConfigGui(Message title, Gui parent) {
super(title, parent); super(title, parent);
} }
@ -46,7 +47,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
} }
@Override @Override
protected Pattern getBackgroundPattern(){ protected Pattern getBackgroundPattern() {
return new Pattern( return new Pattern(
GuiSharedConstant.UPPER_FILLER_FULL_PLANE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_FILLER_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
@ -68,7 +69,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
return; return;
} }
if(!this.factoryMap.containsKey(generic)){ if(!this.factoryMap.containsKey(generic)) {
// We need to sort elements again // We need to sort elements again
super.updateValueForGeneric(generic, false); super.updateValueForGeneric(generic, false);
@ -77,12 +78,12 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
this.pages.clear(); this.pages.clear();
this.pages.add(this.firstPage); this.pages.add(this.firstPage);
for (CAEnchantment enchantment : getDisplayableInstanceOfGeneric()) { for(CAEnchantment enchantment : getDisplayableInstanceOfGeneric()) {
GuiItem item = this.guiItemMap.get(enchantment); GuiItem item = this.guiItemMap.get(enchantment);
if(item == null) { if(item == null) {
updateValueForGeneric(enchantment, false, false); updateValueForGeneric(enchantment, false, false);
}else { } else {
addToPage(item); addToPage(item);
} }
@ -90,7 +91,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
if(shouldUpdate) update(); if(shouldUpdate) update();
}else{ } else {
super.updateValueForGeneric(generic, shouldUpdate); super.updateValueForGeneric(generic, shouldUpdate);
} }
@ -108,6 +109,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
protected List<String> getCreateItemLore() { protected List<String> getCreateItemLore() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
protected Consumer<InventoryClickEvent> getCreateClickConsumer() { protected Consumer<InventoryClickEvent> getCreateClickConsumer() {
return null; return null;

View file

@ -14,7 +14,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil;
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager; import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
@ -24,10 +23,11 @@ import xyz.alexcrea.cuanvil.gui.config.settings.WorkPenaltyTypeSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
/** /**
* Global config to edit basic basic settings. * Global config to edit basic basic settings.
@ -42,11 +42,12 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
} }
private final PacketManager packetManager; private final PacketManager packetManager;
/** /**
* Constructor of this Global gui for basic settings. * Constructor of this Global gui for basic settings.
*/ */
public BasicConfigGui(PacketManager packetManager) { public BasicConfigGui(PacketManager packetManager) {
super(4, "§8Basic Config", CustomAnvil.instance); super(4, MsgUI.INSTANCE.getBASIC_TITLE().textHolder(), CustomAnvil.instance);
if(INSTANCE == null) INSTANCE = this; if(INSTANCE == null) INSTANCE = this;
this.packetManager = packetManager; this.packetManager = packetManager;
@ -101,61 +102,60 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
*/ */
protected void prepareValues() { protected void prepareValues() {
// cap anvil cost // cap anvil cost
this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory("§8Cap Anvil Cost ?", this, this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST,
"§7All anvil cost will be capped to §aMax Anvil Cost§7 if enabled.", null, MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DESCRIPTION()
"§7In other words:", );
"§7For any anvil cost greater than §aMax Anvil Cost§7, Cost will be set to §aMax Anvil Cost§7.");
// cap anvil cost not needed // cap anvil cost not needed
ItemStack item = new ItemStack(Material.BARRIER); ItemStack item = new ItemStack(Material.BARRIER);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§cCap Anvil Cost ?"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DISABLED_TITLE());
meta.setLore(Collections.singletonList("§7This config only work if §cLimit Repair Cost§7 is disabled.")); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DISABLED_DESCRIPTION().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
this.noCapRepairItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); this.noCapRepairItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
// repair cost item // repair cost item
IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE;
this.maxAnvilCost = new IntSettingsGui.IntSettingFactory("§8Max Anvil Cost", this, this.maxAnvilCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_TITLE(), this,
ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DESCRIPTION(),
"§7Max cost the Anvil can get to.",
"§7Valid values include §e0 §7to §e1000§7.",
"§7Cost will be displayed as §cToo Expensive§7:",
"§7- If Cost is above §e39",
"§7- And §eReplace Too Expensive§7 is disabled"
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_MAX_ANVIL_COST, ConfigOptions.DEFAULT_MAX_ANVIL_COST,
1, 5, 10); 1, 5, 10
);
// max anvil cost not needed // max anvil cost not needed
item = new ItemStack(Material.BARRIER); item = new ItemStack(Material.BARRIER);
meta = item.getItemMeta(); meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§cMax Anvil Cost"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DISABLED_TITLE());
meta.setLore(Collections.singletonList("§7This config only work if §cLimit Repair Cost§7 is disabled.")); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DISABLED_DESCRIPTION().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
this.noMaxCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); this.noMaxCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
// remove repair limit item // remove repair limit item
this.removeAnvilCostLimit = new BoolSettingsGui.BoolSettingFactory("§8Remove Anvil Cost Limit ?", this, this.removeAnvilCostLimit = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT,
"§7Whether the anvil's cost limit should be removed entirely.", null, MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_DESCRIPTION()
"§7The anvil will still visually display §cToo Expensive§7 if §eReplace Too Expensive§7 is disabled.", );
"§7However, the action will be completable if xp requirement is meet.");
// replace too expensive item // replace too expensive item
this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory("§8Replace Too Expensive ?", this, this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE,
getReplaceToExpensiveLore()); null, getReplaceToExpensiveLore()
);
// ------------ // ------------
// Cost config // Cost config
@ -163,132 +163,118 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
// item repair cost // item repair cost
range = ConfigOptions.REPAIR_COST_RANGE; range = ConfigOptions.REPAIR_COST_RANGE;
this.itemRepairCost = new IntSettingsGui.IntSettingFactory("§8Item Repair Cost", this, this.itemRepairCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_TITLE(), this,
ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_DESCRIPTION(),
"§7XP Level amount added to the anvil when the item",
"§7is repaired by another item of the same type."
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_ITEM_REPAIR_COST, ConfigOptions.DEFAULT_ITEM_REPAIR_COST,
1, 5, 10, 50, 100); 1, 5, 10, 50, 100
);
// unit repair cost // unit repair cost
this.unitRepairCost = new IntSettingsGui.IntSettingFactory("§8Unit Repair Cost", this, this.unitRepairCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_TITLE(), this,
ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_DESCRIPTION(),
"§7XP Level amount added to the anvil when the item is repaired by an §eunit§7.",
"§7For example: a Diamond on a Diamond Sword.",
"§7What's considered unit for what can be edited on the unit repair configuration."
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_UNIT_REPAIR_COST, ConfigOptions.DEFAULT_UNIT_REPAIR_COST,
1, 5, 10, 50, 100); 1, 5, 10, 50, 100
);
// item rename cost // item rename cost
range = ConfigOptions.ITEM_RENAME_COST_RANGE; range = ConfigOptions.ITEM_RENAME_COST_RANGE;
this.itemRenameCost = new IntSettingsGui.IntSettingFactory("§8Rename Cost", this, this.itemRenameCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_TITLE(), this,
ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_DESCRIPTION(),
"§7XP Level amount added to the anvil when the item is renamed."
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_ITEM_RENAME_COST, ConfigOptions.DEFAULT_ITEM_RENAME_COST,
1, 5, 10, 50, 100); 1, 5, 10, 50, 100
);
// sacrifice illegal enchant cost // sacrifice illegal enchant cost
range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE; range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE;
this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory("§8Sacrifice Illegal Enchant Cost", this, this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_TITLE(), this,
ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION(),
"§7XP Level amount added to the anvil when a sacrifice enchantment",
"§7conflict With one of the left item enchantment"
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST,
1, 5, 10, 50, 100); 1, 5, 10, 50, 100
);
// ------------- // -------------
// Color config // Color config
// ------------- // -------------
// Allow us of color code // Allow us of color code
this.allowColorCode = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Color Code ?", this, this.allowColorCode = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_COLOR_CODE_LIMIT_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE,
"§7Whether players can use color code.", null, MsgUI.INSTANCE.getBASIC_COLOR_CODE_LIMIT_DESCRIPTION()
"§7Color code a formatted like §a&a§7 and is used in the rename field of the anvil.", );
"§7Player may need permission to use color code if §ePlayer need permission to use color§7 is enabled.");
// Allow us of hexadecimal color // Allow us of hexadecimal color
this.allowHexColor = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Hexadecimal Color ?", this, this.allowHexColor = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_COLOR_HEX_LIMIT_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR,
"§7Whether players can use hexadecimal color.", null, MsgUI.INSTANCE.getBASIC_COLOR_HEX_LIMIT_DESCRIPTION()
"§7Color code a formatted like §2#012345 §7and is used in the rename field of the anvil.", );
"§7Player may need permission to use color code if §ePermission Needed For Color§7 is enabled.");
// Permission needed for color // Permission needed for color
this.permissionNeededForColor = new BoolSettingsGui.BoolSettingFactory("§8Need Permission To Use Color ?", this, this.permissionNeededForColor = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_TITLE(), this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR,
"§7Whether players should have permission to be able to use colors.", null, MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DESCRIPTION()
"§7Give player §eca.color.code§7 Permission to allow use of color code.", );
"§7Give player §eca.color.hex§7 Permission to allow use of hexadecimal color.");
// Permission needed for color not necessary // Permission needed for color not necessary
item = new ItemStack(Material.BARRIER); item = new ItemStack(Material.BARRIER);
meta = item.getItemMeta(); meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§cNeed Permission To Use Color ?"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DISABLED_TITLE());
meta.setLore(Arrays.asList("§7This config can do something only if one of the following config is enabled:", ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DISABLED_DESCRIPTION().formatted(), meta);
"§7- §aAllow Use Of Color Code",
"§7- §aAllow Use Of Hexadecimal Color"));
item.setItemMeta(meta); item.setItemMeta(meta);
this.noPermissionNeededItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); this.noPermissionNeededItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
// Cost of using color // Cost of using color
range = ConfigOptions.USE_OF_COLOR_COST_RANGE; range = ConfigOptions.USE_OF_COLOR_COST_RANGE;
this.useOfColorCost = new IntSettingsGui.IntSettingFactory("§8Cost Of Using Color", this, this.useOfColorCost = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getBASIC_COLOR_COST_TITLE(), this,
ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getBASIC_COLOR_COST_DESCRIPTION(),
"§7XP level cost when using color code or hexadecimal color using the anvil.",
"§7conflict With one of the left item enchantment"
),
range.getFirst(), range.getLast(), range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_USE_OF_COLOR_COST, ConfigOptions.DEFAULT_USE_OF_COLOR_COST,
1, 5, 10, 50, 100); 1, 5, 10, 50, 100
);
// Permission needed for color not necessary // Permission needed for color not necessary
item = new ItemStack(Material.BARRIER); item = new ItemStack(Material.BARRIER);
meta = item.getItemMeta(); meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§cCost Of Using Color"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_COLOR_COST_DISABLED_TITLE());
meta.setLore(Arrays.asList("§7This config can do something only if one of the following config is enabled:", ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_COLOR_COST_DISABLED_DESCRIPTION().formatted(), meta);
"§7- §aAllow Use Of Color Code",
"§7- §aAllow Use Of Hexadecimal Color"));
item.setItemMeta(meta); item.setItemMeta(meta);
this.noColorCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); this.noColorCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
} }
@NotNull @NotNull
private String[] getReplaceToExpensiveLore() { private Message[] getReplaceToExpensiveLore() {
ArrayList<String> lore = new ArrayList<>(); ArrayList<Message> lore = new ArrayList<>();
lore.add("§7Whenever anvil cost is above §e39§7 should display the true price and not §cToo Expensive§7."); lore.add(MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION());
lore.add("§7However, when bypassing §cToo Expensive§7, anvil price will be displayed as §aGreen§7.");
lore.add("§7Even if cost is displayed as §aGreen§7:");
lore.add("§7If the player do not have the required xp level, the action will not be completable.");
if(!this.packetManager.getCanSetInstantBuild()){ if(!this.packetManager.getCanSetInstantBuild())
lore.add(""); lore.add(MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION_NO_NMS());
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a paper server.");
lore.add("§cCurrently ProtocoLib is not detected.");
}
String[] loreAsArray = new String[lore.size()]; Message[] loreAsArray = new Message[lore.size()];
return lore.toArray(loreAsArray); return lore.toArray(loreAsArray);
} }
@ -297,9 +283,14 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
// limit and cap anvil cost item // limit and cap anvil cost item
GuiItem capAnvilCostItem; GuiItem capAnvilCostItem;
GuiItem maxAnvilCostItem; GuiItem maxAnvilCostItem;
if (!this.removeAnvilCostLimit.getConfiguredValue()) { if(!this.removeAnvilCostLimit.getConfiguredValue()) {
capAnvilCostItem = this.capAnvilCost.getItem("Cap Anvil Cost"); capAnvilCostItem = this.capAnvilCost.getItem(
maxAnvilCostItem = this.maxAnvilCost.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_ITEM()
);
maxAnvilCostItem = this.maxAnvilCost.getItem(
Material.EXPERIENCE_BOTTLE,
MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_ITEM()
);
} else { } else {
capAnvilCostItem = this.noCapRepairItem; capAnvilCostItem = this.noCapRepairItem;
maxAnvilCostItem = this.noMaxCostItem; maxAnvilCostItem = this.noMaxCostItem;
@ -309,7 +300,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
pane.bindItem('C', maxAnvilCostItem); pane.bindItem('C', maxAnvilCostItem);
// remove repair limit item // remove repair limit item
GuiItem removeRepairLimitItem = this.removeAnvilCostLimit.getItem("Remove Anvil Cost Limit"); GuiItem removeRepairLimitItem = this.removeAnvilCostLimit.getItem(
MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_ITEM()
);
pane.bindItem('R', removeRepairLimitItem); pane.bindItem('R', removeRepairLimitItem);
// replace too expensive item // replace too expensive item
@ -334,7 +327,11 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
pane.bindItem('S', illegalCostItem); pane.bindItem('S', illegalCostItem);
// work penalty type // work penalty type
GuiItem workPenaltyType = WorkPenaltyTypeSettingGui.getDisplayItem(this, Material.DAMAGED_ANVIL, "§aWork Penalty Type"); GuiItem workPenaltyType = WorkPenaltyTypeSettingGui.getDisplayItem(
this,
Material.DAMAGED_ANVIL,
MsgUI.INSTANCE.getBASIC_WORK_PENALTY_ITEM()
);
pane.bindItem('W', workPenaltyType); pane.bindItem('W', workPenaltyType);
// allow color code // allow color code
@ -346,20 +343,22 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
pane.bindItem('h', allowHexColorItem); pane.bindItem('h', allowHexColorItem);
// True if player could place color // True if player could place color
if(ConfigOptions.INSTANCE.getRenameColorPossible()){ if(ConfigOptions.INSTANCE.getRenameColorPossible()) {
// use permission for color // use permission for color
GuiItem permissionNeededItem = this.permissionNeededForColor.getItem(); GuiItem permissionNeededItem = this.permissionNeededForColor.getItem();
pane.bindItem('p', permissionNeededItem); pane.bindItem('p', permissionNeededItem);
// using color cost // using color cost
GuiItem useColorCostItem = this.useOfColorCost.getItem(Material.EXPERIENCE_BOTTLE, "Use color"); GuiItem useColorCostItem = this.useOfColorCost.getItem(
Material.EXPERIENCE_BOTTLE,
MsgUI.INSTANCE.getBASIC_COLOR_COST_ITEM()
);
pane.bindItem('P', useColorCostItem); pane.bindItem('P', useColorCostItem);
}else{ } else {
pane.bindItem('p', this.noPermissionNeededItem); pane.bindItem('p', this.noPermissionNeededItem);
pane.bindItem('P', this.noColorCostItem); pane.bindItem('P', this.noColorCostItem);
} }
update(); update();
} }

View file

@ -12,6 +12,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.CustomRecipeSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.CustomRecipeSubSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
@ -36,13 +37,13 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
} }
private CustomRecipeConfigGui() { private CustomRecipeConfigGui() {
super("Custom Recipe Config"); super(MsgUI.INSTANCE.getCUSTOM_RECIPE_TITLE());
init(); init();
} }
public CustomRecipeConfigGui(Gui parent) { public CustomRecipeConfigGui(Gui parent) {
super("Custom Recipe Config", parent); super(MsgUI.INSTANCE.getCUSTOM_RECIPE_TITLE(), parent);
} }
@Override @Override
@ -60,7 +61,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
ItemMeta meta = displayedItem.getItemMeta(); ItemMeta meta = displayedItem.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " §fCustom recipe"); meta.setDisplayName("<yellow>" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " <white>Custom recipe");//TODO MESSAGE
meta.addItemFlags(ItemFlag.values()); meta.addItemFlags(ItemFlag.values());
meta.setLore(getRecipeLore(recipe)); meta.setLore(getRecipeLore(recipe));
@ -72,7 +73,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
private static @NotNull ArrayList<String> getRecipeLore(AnvilCustomRecipe recipe) { private static @NotNull ArrayList<String> getRecipeLore(AnvilCustomRecipe recipe) {
boolean shouldWork = recipe.validate(); boolean shouldWork = recipe.validate();
ArrayList<String> lore = new ArrayList<>(); ArrayList<String> lore = new ArrayList<>();//TODO MESSAGE
lore.add("§7Is valid: §" + (shouldWork ? "aYes" : "cNo")); lore.add("§7Is valid: §" + (shouldWork ? "aYes" : "cNo"));
lore.add("§7Exact count: §" + (recipe.getExactCount() ? "aYes" : "cNo")); lore.add("§7Exact count: §" + (recipe.getExactCount() ? "aYes" : "cNo"));
lore.add("§7Recipe Level Cost: §e" + recipe.getLevelCostPerCraft()); lore.add("§7Recipe Level Cost: §e" + recipe.getLevelCostPerCraft());
@ -90,7 +91,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
@Override @Override
protected String genericDisplayedName() { protected String genericDisplayedName() {
return "custom recipe"; return "custom recipe";//TODO MESSAGE
} }
@Override @Override

View file

@ -14,6 +14,7 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.EnchantConflictSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.EnchantConflictSubSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
@ -38,11 +39,11 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
// Need to init myself // Need to init myself
public EnchantConflictGui(Gui parent) { public EnchantConflictGui(Gui parent) {
super("Conflict Config", parent); super(MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_TITLE(), parent);
} }
private EnchantConflictGui() { private EnchantConflictGui() {
super("Conflict Config"); super(MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_TITLE());
init(); init();
} }
@ -80,8 +81,8 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
assert meta != null; assert meta != null;
meta.addItemFlags(ItemFlag.values()); meta.addItemFlags(ItemFlag.values());
meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(conflict.toString()) + " §fConflict"); meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(conflict.toString()) + " §fConflict"); //TODO MESSAGE
meta.setLore(Arrays.asList( meta.setLore(Arrays.asList(//TODO MESSAGE
"§7Enchantment count: §e" + conflict.getEnchants().size(), "§7Enchantment count: §e" + conflict.getEnchants().size(),
"§7Group count: §e" + conflict.getCantConflictGroup().getGroups().size(), "§7Group count: §e" + conflict.getCantConflictGroup().getGroups().size(),
"§7Min enchantments count: §e" + conflict.getMinBeforeBlock() "§7Min enchantments count: §e" + conflict.getMinBeforeBlock()
@ -98,7 +99,7 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
@Override @Override
protected String genericDisplayedName() { protected String genericDisplayedName() {
return "conflict"; return "conflict";//TODO MESSAGE
} }
@Override @Override

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.gui.config.global;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -11,8 +12,12 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -36,7 +41,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
* Constructor of this Global gui for enchantment cost settings. * Constructor of this Global gui for enchantment cost settings.
*/ */
public EnchantCostConfigGui() { public EnchantCostConfigGui() {
super("§8Enchantment Level Cost"); super(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_TITLE());
if (INSTANCE == null) INSTANCE = this; if (INSTANCE == null) INSTANCE = this;
init(); init();
@ -46,7 +51,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
* Constructor of this Global gui for enchantment cost settings. * Constructor of this Global gui for enchantment cost settings.
*/ */
public EnchantCostConfigGui(Gui parent) { public EnchantCostConfigGui(Gui parent) {
super("§8Enchantment Level Cost", parent); super(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_TITLE(), parent);
} }
@Override @Override
@ -58,12 +63,10 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
String key = enchant.getKey().toString().toLowerCase(Locale.ENGLISH); String key = enchant.getKey().toString().toLowerCase(Locale.ENGLISH);
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_")); String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_"));
return new EnchantCostSettingsGui.EnchantCostSettingFactory(prettyKey + " Cost", parent, return new EnchantCostSettingsGui.EnchantCostSettingFactory(
MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_TITLE(), parent,
ENCHANT_VALUES_ROOT + '.' + key, ConfigHolder.DEFAULT_CONFIG, ENCHANT_VALUES_ROOT + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_DESCRIPTION(), prettyKey,
"§7How many level should " + prettyKey,
"§7cost when applied by book or by another item."
),
enchant, 0, 255, enchant, 0, 255,
1, 10, 50); 1, 10, 50);
} }
@ -73,26 +76,26 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
// Get item properties // Get item properties
int itemCost = factory.getConfiguredValue(); int itemCost = factory.getConfiguredValue();
int bookCost = factory.getConfiguredBookValue(); int bookCost = factory.getConfiguredBookValue();
String itemName = "§a" + factory.getTitle(); Message itemName = factory.getTitle();
// Create item // Create item
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta itemMeta = item.getItemMeta(); ItemMeta itemMeta = item.getItemMeta();
assert itemMeta != null; assert itemMeta != null;
// Prepare lore // Prepare lore
List<String> lore = new ArrayList<>(); List<Component> lore = new ArrayList<>();
lore.add("§7Item Cost: §e" + itemCost); lore.addAll(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST().formatted(itemCost));
lore.add("§7Book Cost: §e" + bookCost); lore.addAll(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST().formatted(bookCost));
List<String> displayLore = factory.getDisplayLore(); List<Message> displayLore = factory.getDisplayLore();
if (!displayLore.isEmpty()) { if (displayLore != null) {
lore.add(""); lore.add(Component.empty());
lore.addAll(displayLore); lore.addAll(ComponentUtil.INSTANCE.asComponents(displayLore, factory.getParam()));
} }
// Edit name and lore // Edit name and lore
itemMeta.setDisplayName(itemName); ComponentUtil.INSTANCE.setMessageName(itemMeta, itemName, factory.getParam());
itemMeta.setLore(lore); ComponentUtil.INSTANCE.applyLore(lore, itemMeta);
item.setItemMeta(itemMeta); item.setItemMeta(itemMeta);

View file

@ -9,6 +9,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Collections; import java.util.Collections;
@ -32,14 +33,14 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
* Constructor of this Global gui for enchantment level limit settings. * Constructor of this Global gui for enchantment level limit settings.
*/ */
public EnchantLimitConfigGui() { public EnchantLimitConfigGui() {
super("§8Enchantment Level Limit"); super(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_LIMIT_TITLE());
if(INSTANCE == null) INSTANCE = this; if(INSTANCE == null) INSTANCE = this;
init(); init();
} }
public EnchantLimitConfigGui(Gui parent) { public EnchantLimitConfigGui(Gui parent) {
super("§8Enchantment Level Limit", parent); super(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_LIMIT_TITLE(), parent);
} }
@Override @Override
@ -53,11 +54,10 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
var defaultValue = enchant.defaultMaxLevel(); var defaultValue = enchant.defaultMaxLevel();
return new IntSettingsGui.IntSettingFactory(prettyKey + " Limit", parent, return new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getENCHANTMENT_LEVEL_LIMIT_ELEMENT_TITLE(), parent,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Collections.singletonList( MsgUI.INSTANCE.getENCHANTMENT_LEVEL_LIMIT_ELEMENT_DESCRIPTION(), prettyKey,
"§7Maximum applied level of " + prettyKey
),
-1, 255, -1, -1, 255, -1,
1, 5, 10, 50, 100){ 1, 5, 10, 50, 100){
@ -87,7 +87,9 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
public GuiItem itemFromFactory(CAEnchantment enchantment, IntSettingsGui.IntSettingFactory inventoryFactory) { public GuiItem itemFromFactory(CAEnchantment enchantment, IntSettingsGui.IntSettingFactory inventoryFactory) {
return inventoryFactory.getItem( return inventoryFactory.getItem(
Material.ENCHANTED_BOOK, Material.ENCHANTED_BOOK,
inventoryFactory.getTitle()); inventoryFactory.getTitle(),
inventoryFactory.getParam()
);
} }
} }

View file

@ -9,6 +9,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
@ -29,7 +30,7 @@ public class EnchantMergeLimitConfigGui extends AbstractEnchantConfigGui<IntSett
* Constructor of this Global gui for enchantment level limit settings. * Constructor of this Global gui for enchantment level limit settings.
*/ */
public EnchantMergeLimitConfigGui() { public EnchantMergeLimitConfigGui() {
super("§8Enchantment Maximum Merge Level"); super(MsgUI.INSTANCE.getENCHANTMENT_MERGE_LIMIT_TITLE());
if(INSTANCE == null) INSTANCE = this; if(INSTANCE == null) INSTANCE = this;
init(); init();
@ -39,7 +40,7 @@ public class EnchantMergeLimitConfigGui extends AbstractEnchantConfigGui<IntSett
* Constructor of this Global gui for enchantment level limit settings. * Constructor of this Global gui for enchantment level limit settings.
*/ */
public EnchantMergeLimitConfigGui(Gui parent) { public EnchantMergeLimitConfigGui(Gui parent) {
super("§8Enchantment Maximum Merge Level", parent); super(MsgUI.INSTANCE.getENCHANTMENT_MERGE_LIMIT_TITLE(), parent);
} }
@ -52,18 +53,12 @@ public class EnchantMergeLimitConfigGui extends AbstractEnchantConfigGui<IntSett
String key = enchant.getKey().toString().toLowerCase(Locale.ROOT); String key = enchant.getKey().toString().toLowerCase(Locale.ROOT);
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_")); String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_"));
return new IntSettingsGui.IntSettingFactory(prettyKey + " Merge Limit", parent, return new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getENCHANTMENT_MERGE_LIMIT_ELEMENT_TITLE(), parent,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( MsgUI.INSTANCE.getENCHANTMENT_MERGE_LIMIT_ELEMENT_DESCRIPTION(), prettyKey,
"§7Maximum merge level for for " + prettyKey,
"",
"§7For example, if set to §e2§7, §alvl1 §7+ §alvl1 §7of will give a §alvl2",
"§7But §alvl2 §7+ §alvl2 §7will not give a §clv3§7.",
"§7Will still not merge above max enchantment level",
"§e-1 §7(default) will set the merge limit to enchantment's maximum level"
),
-1, 255, -1, -1, 255, -1,
1, 5, 10, 50, 100){ 1, 5, 10, 50, 100) {
@Override @Override
public int getConfiguredValue() { public int getConfiguredValue() {
@ -76,6 +71,8 @@ public class EnchantMergeLimitConfigGui extends AbstractEnchantConfigGui<IntSett
public GuiItem itemFromFactory(CAEnchantment enchantment, IntSettingsGui.IntSettingFactory inventoryFactory) { public GuiItem itemFromFactory(CAEnchantment enchantment, IntSettingsGui.IntSettingFactory inventoryFactory) {
return inventoryFactory.getItem( return inventoryFactory.getItem(
Material.ENCHANTED_BOOK, Material.ENCHANTED_BOOK,
inventoryFactory.getTitle()); inventoryFactory.getTitle(),
inventoryFactory.getParam()
);
} }
} }

View file

@ -15,6 +15,7 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.group.ItemGroupManager; import xyz.alexcrea.cuanvil.group.ItemGroupManager;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.LazyValue; import xyz.alexcrea.cuanvil.util.LazyValue;
@ -39,13 +40,13 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedG
} }
public GroupConfigGui() { public GroupConfigGui() {
super("Group Config"); super(MsgUI.INSTANCE.getMATERIAL_GROUP_TITLE());
init(); init();
} }
public GroupConfigGui(Gui parent) { public GroupConfigGui(Gui parent) {
super("Group Config", parent); super(MsgUI.INSTANCE.getMATERIAL_GROUP_TITLE(), parent);
} }
@Override @Override

View file

@ -13,6 +13,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.config.ask.SelectItemTypeGui; import xyz.alexcrea.cuanvil.gui.config.ask.SelectItemTypeGui;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui; import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.MaterialUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil;
@ -38,13 +39,13 @@ public class UnitRepairConfigGui extends
} }
private UnitRepairConfigGui() { private UnitRepairConfigGui() {
super("Unit Repair Config"); super(MsgUI.INSTANCE.getUNIT_REPAIR_TITLE());
init(); init();
} }
public UnitRepairConfigGui(Gui parent) { public UnitRepairConfigGui(Gui parent) {
super("Unit Repair Config", parent); super(MsgUI.INSTANCE.getUNIT_REPAIR_TITLE(), parent);
} }
@Override @Override
@ -128,9 +129,8 @@ public class UnitRepairConfigGui extends
clickEvent.setCancelled(true); clickEvent.setCancelled(true);
new SelectItemTypeGui( new SelectItemTypeGui(
"Select unit repair item.", MsgUI.INSTANCE.getUNIT_REPAIR_NEW_TITLE(), "",
"§7Click here with an item to set the item\n" + MsgUI.INSTANCE.getUNIT_REPAIR_NEW_DESCRIPTION(), "",
"§7You like to be an unit repair item",
this, this,
(itemStack, player) -> { (itemStack, player) -> {
NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack);

View file

@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -32,16 +33,18 @@ public abstract class ElementListConfigGui<T> extends ChestGui implements ValueU
public static final int LIST_FILLER_LENGTH = 7; public static final int LIST_FILLER_LENGTH = 7;
public static final int LIST_FILLER_HEIGHT = 4; public static final int LIST_FILLER_HEIGHT = 4;
private final String namePrefix; private final Message rawTitle;
private final String param;
protected PatternPane backgroundPane; protected PatternPane backgroundPane;
private Predicate<T> filter = (t) -> true; private Predicate<T> filter = (t) -> true;
private boolean hasDefaultFilter = true; private boolean hasDefaultFilter = true;
protected ElementListConfigGui(@NotNull String title, Gui parent) { protected ElementListConfigGui(@NotNull Message title, String param, Gui parent) {
super(6, title, CustomAnvil.instance); super(6, title.textHolder(param, "", ""), CustomAnvil.instance);
this.namePrefix = title; this.rawTitle = title;
this.param = param;
// Back item panel // Back item panel
Pattern pattern = getBackgroundPattern(); Pattern pattern = getBackgroundPattern();
@ -259,13 +262,10 @@ public abstract class ElementListConfigGui<T> extends ChestGui implements ValueU
// and add actual page // and add actual page
addPane(page); addPane(page);
// set title // intended parameter: (page/max_page) //TODO MESSAGE CHECK CHILDS
StringBuilder title = new StringBuilder(this.namePrefix);
int pagesSize = this.pages.size(); int pagesSize = this.pages.size();
if (pagesSize > 1) { var title = this.rawTitle.textHolder(param, pageID + 1, pagesSize);
title.append(" (").append(pageID + 1).append('/').append(pagesSize).append(')'); setTitle(title);
}
setTitle(title.toString());
super.show(humanEntity); super.show(humanEntity);

View file

@ -10,6 +10,8 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -19,14 +21,14 @@ public abstract class MappedElementListConfigGui<T, S> extends ElementListConfig
protected final HashMap<T, S> elementGuiMap; protected final HashMap<T, S> elementGuiMap;
protected MappedElementListConfigGui(@NotNull String title, @NotNull Gui parent) { protected MappedElementListConfigGui(@NotNull Message title, @NotNull String param, @NotNull Gui parent) {
super(title, parent); super(title, param, parent);
this.elementGuiMap = new HashMap<>(); this.elementGuiMap = new HashMap<>();
} }
protected MappedElementListConfigGui(@NotNull String title) { protected MappedElementListConfigGui(@NotNull Message title, @NotNull String param) {
this(title, MainConfigGui.getInstance()); this(title, param, MainConfigGui.getInstance());
} }
@Override @Override
@ -52,13 +54,12 @@ public abstract class MappedElementListConfigGui<T, S> extends ElementListConfig
// check permission // check permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
player.closeInventory(); player.closeInventory();
player.sendMessage("§eWrite the " + genericDisplayedName() + " name you want to create in the chat.\n" + MsgUI.INSTANCE.getELEMENT_LIST_INSTRUCTION_NEW().send(player, genericDisplayedName());
"§eOr write §ccancel §eto go back to " + genericDisplayedName() + " config menu");
CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player)); CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player));

View file

@ -8,6 +8,8 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.LazyValue; import xyz.alexcrea.cuanvil.util.LazyValue;
import java.util.Locale; import java.util.Locale;
@ -18,12 +20,20 @@ import java.util.function.Supplier;
public abstract class MappedGuiListConfigGui<T, S extends MappedGuiListConfigGui.LazyElement<?>> public abstract class MappedGuiListConfigGui<T, S extends MappedGuiListConfigGui.LazyElement<?>>
extends MappedElementListConfigGui<T, S> { extends MappedElementListConfigGui<T, S> {
protected MappedGuiListConfigGui(@NotNull String title) { protected MappedGuiListConfigGui(@NotNull Message title, @NotNull String param) {
super(title); super(title, param);
} }
protected MappedGuiListConfigGui(@NotNull String title, @NotNull Gui parent) { protected MappedGuiListConfigGui(@NotNull Message title, @NotNull String param, @NotNull Gui parent) {
super(title, parent); super(title, param, parent);
}
protected MappedGuiListConfigGui(@NotNull Message title) {
super(title, "");
}
protected MappedGuiListConfigGui(@NotNull Message title, @NotNull Gui parent) {
super(title, "", parent);
} }
@Override @Override
@ -69,13 +79,13 @@ public abstract class MappedGuiListConfigGui<T, S extends MappedGuiListConfigGui
// check permission // check permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
message = message.toLowerCase(Locale.ROOT); message = message.toLowerCase(Locale.ROOT);
if ("cancel".equalsIgnoreCase(message)) { if ("cancel".equalsIgnoreCase(message)) {
player.sendMessage(genericDisplayedName() + " creation cancelled..."); MsgUI.INSTANCE.getELEMENT_LIST_CANCELLED_NEW().send(player, genericDisplayedName());
show(player); show(player);
return; return;
} }
@ -86,7 +96,7 @@ public abstract class MappedGuiListConfigGui<T, S extends MappedGuiListConfigGui
// Not the most efficient on large number of conflict, but it should not run often. // Not the most efficient on large number of conflict, but it should not run often.
for (T generic : getDisplayableInstanceOfGeneric()) { for (T generic : getDisplayableInstanceOfGeneric()) {
if (generic.toString().equalsIgnoreCase(message)) { if (generic.toString().equalsIgnoreCase(message)) {
player.sendMessage("§cPlease enter a " + genericDisplayedName() + " name that do not already exist..."); MsgUI.INSTANCE.getELEMENT_LIST_DUPLICATED_NEW().send(player, genericDisplayedName());
// wait next message. // wait next message.
CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get()); CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get());
return; return;

View file

@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.lang.Message;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -20,16 +21,26 @@ public abstract class SettingGuiListConfigGui<T, S extends SettingGui.SettingGui
protected HashMap<T, GuiItem> guiItemMap; protected HashMap<T, GuiItem> guiItemMap;
protected HashMap<T, S> factoryMap; protected HashMap<T, S> factoryMap;
protected SettingGuiListConfigGui(@NotNull String title, Gui parent) { protected SettingGuiListConfigGui(@NotNull Message title, Gui parent) {
super(title, parent); super(title, "", parent);
this.guiItemMap = new HashMap<>(); this.guiItemMap = new HashMap<>();
this.factoryMap = new HashMap<>(); this.factoryMap = new HashMap<>();
} }
protected SettingGuiListConfigGui(@NotNull String title) { protected SettingGuiListConfigGui(@NotNull Message title) {
this(title, MainConfigGui.getInstance()); this(title, MainConfigGui.getInstance());
} }
protected SettingGuiListConfigGui(@NotNull Message title, @NotNull String param, Gui parent) {
super(title, param, parent);
this.guiItemMap = new HashMap<>();
this.factoryMap = new HashMap<>();
}
protected SettingGuiListConfigGui(@NotNull Message title, @NotNull String param) {
this(title, param, MainConfigGui.getInstance());
}
@Override @Override
protected GuiItem prepareCreateNewItem() { protected GuiItem prepareCreateNewItem() {
ItemStack createItem = new ItemStack(Material.PAPER); ItemStack createItem = new ItemStack(Material.PAPER);

View file

@ -18,6 +18,7 @@ import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui;
import xyz.alexcrea.cuanvil.gui.config.settings.DoubleSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.DoubleSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.MaterialUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil;
@ -32,12 +33,16 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
private boolean shouldWork = true; private boolean shouldWork = true;
private static String prettifiedName(NamespacedKey parentMaterial) {
return CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.getKey().toLowerCase());
}
public UnitRepairElementListGui(@NotNull NamespacedKey parentMaterial, public UnitRepairElementListGui(@NotNull NamespacedKey parentMaterial,
@NotNull UnitRepairConfigGui parentGui) { @NotNull UnitRepairConfigGui parentGui) {
super("§e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.getKey().toLowerCase()) + " §rUnit repair"); super(MsgUI.INSTANCE.getUNIT_REPAIR_ELEMENT_TITLE(), prettifiedName(parentMaterial));
this.parentMaterial = parentMaterial; this.parentMaterial = parentMaterial;
this.parentGui = parentGui; this.parentGui = parentGui;
this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.getKey().toLowerCase()); this.materialName = prettifiedName(parentMaterial);
GuiGlobalItems.addBackItem(this.backgroundPane, parentGui); GuiGlobalItems.addBackItem(this.backgroundPane, parentGui);
} }
@ -45,7 +50,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
// SettingGuiListConfigGui methods // SettingGuiListConfigGui methods
@Override @Override
protected List<String> getCreateItemLore() { protected List<String> getCreateItemLore() {
return Arrays.asList( return Arrays.asList(//TODO MESSAGE
"§7Select a new item to be repairable.", "§7Select a new item to be repairable.",
"§7You will be asked the material to use." "§7You will be asked the material to use."
); );
@ -55,26 +60,25 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
protected Consumer<InventoryClickEvent> getCreateClickConsumer() { protected Consumer<InventoryClickEvent> getCreateClickConsumer() {
return event -> { return event -> {
event.setCancelled(true); event.setCancelled(true);
if (!this.shouldWork) { if(!this.shouldWork) {
return; return;
} }
event.setCancelled(true); event.setCancelled(true);
new SelectItemTypeGui( new SelectItemTypeGui(
"Select item to be repaired.", MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_TITLE(), this.materialName,
"§7Click here with an item to set the item\n" + MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_DESCRIPTION(), this.materialName,
"§7You like to be repaired by " + this.materialName,
this, this,
(itemStack, player) -> { (itemStack, player) -> {
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack);
if (!(meta instanceof Damageable)) { if(!(meta instanceof Damageable)) {
player.sendMessage("§cThis item can't be damaged, so it can't be repaired."); MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR().send(player);
return; return;
} }
if (type.equals(this.parentMaterial)) { if(type.equals(this.parentMaterial)) {
player.sendMessage("§cItem can't repair something of the same type."); MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_SAME_TYPE().send(player);
return; return;
} }
@ -83,7 +87,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
// Add new material // Add new material
ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.toString().toLowerCase() + "." + materialName, 0.25); ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.toString().toLowerCase() + "." + materialName, 0.25);
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { if(GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
} }
@ -103,7 +107,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
@Override @Override
protected String createItemName() { protected String createItemName() {
return "§aAdd a new item reparable by " + this.materialName; return "§aAdd a new item reparable by " + this.materialName; //TODO MESSAGE ?
} }
@Override @Override
@ -111,14 +115,12 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
String materialDisplayName = CasedStringUtil.snakeToUpperSpacedCase(materialName.getKey()); String materialDisplayName = CasedStringUtil.snakeToUpperSpacedCase(materialName.getKey());
return new DoubleSettingGui.DoubleSettingFactory( return new DoubleSettingGui.DoubleSettingFactory(
"§0%§8" + materialDisplayName + " Repair", MsgUI.INSTANCE.getUNIT_REPAIR_ELEMENT_VALUE_TITLE(),
this, this,
ConfigHolder.UNIT_REPAIR_HOLDER, ConfigHolder.UNIT_REPAIR_HOLDER,
this.parentMaterial.toString().toLowerCase() + "." + materialName, this.parentMaterial.toString().toLowerCase() + "." + materialName,
Arrays.asList( MsgUI.INSTANCE.getUNIT_REPAIR_ELEMENT_VALUE_DESCRIPTION(),
"§7Click here to change how many §e% §7of §a" + materialDisplayName, materialDisplayName, this.materialName,
"§7Should get repaired by §e" + this.materialName
),
2, 2,
true, true, true, true,
0, 0,
@ -130,14 +132,18 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
@Override @Override
protected GuiItem itemFromFactory(NamespacedKey materialName, DoubleSettingGui.DoubleSettingFactory factory) { protected GuiItem itemFromFactory(NamespacedKey materialName, DoubleSettingGui.DoubleSettingFactory factory) {
return factory.getItem(materialFromName(materialName), return factory.getItem(
"§7%§a" + CasedStringUtil.snakeToUpperSpacedCase(materialName.getKey()) + " §erepaired by §a" + this.materialName); materialFromName(materialName),
MsgUI.INSTANCE.getUNIT_REPAIR_ITEM(),
CasedStringUtil.snakeToUpperSpacedCase(materialName.getKey()),
this.materialName
);
} }
@Override @Override
protected Collection<NamespacedKey> getEveryInstanceOfGeneric() { protected Collection<NamespacedKey> getEveryInstanceOfGeneric() {
Set<NamespacedKey> keys = new HashSet<>(); Set<NamespacedKey> keys = new HashSet<>();
if (!this.shouldWork) { if(!this.shouldWork) {
return keys; return keys;
} }
@ -151,10 +157,10 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
} }
private void addAllKeys(@Nullable ConfigurationSection section, @NotNull Set<NamespacedKey> keys) { private void addAllKeys(@Nullable ConfigurationSection section, @NotNull Set<NamespacedKey> keys) {
if (section == null) return; if(section == null) return;
for (var key : section.getKeys(false)) { for(var key : section.getKeys(false)) {
var material = NamespacedKey.fromString(key); var material = NamespacedKey.fromString(key);
if (material == null) continue; if(material == null) continue;
keys.add(material); keys.add(material);
} }
@ -162,7 +168,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
private Material materialFromName(NamespacedKey material) { private Material materialFromName(NamespacedKey material) {
Material mat = MaterialUtil.INSTANCE.getMatFromKey(material); Material mat = MaterialUtil.INSTANCE.getMatFromKey(material);
if (mat == null || mat.isAir()) return Material.BARRIER; if(mat == null || mat.isAir()) return Material.BARRIER;
return mat; return mat;
} }
@ -185,7 +191,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
this.backgroundPane.bindItem('L', GuiGlobalItems.backgroundItem(Material.BLACK_STAINED_GLASS_PANE)); this.backgroundPane.bindItem('L', GuiGlobalItems.backgroundItem(Material.BLACK_STAINED_GLASS_PANE));
this.backgroundPane.bindItem('R', GuiGlobalItems.backgroundItem(Material.BLACK_STAINED_GLASS_PANE)); this.backgroundPane.bindItem('R', GuiGlobalItems.backgroundItem(Material.BLACK_STAINED_GLASS_PANE));
for (HumanEntity viewer : getViewers()) { for(HumanEntity viewer : getViewers()) {
viewer.sendMessage("This config do not exist anymore"); viewer.sendMessage("This config do not exist anymore");
this.parentGui.show(viewer); this.parentGui.show(viewer);
} }
@ -198,7 +204,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<Namespaced
@Override @Override
public void show(@NotNull HumanEntity humanEntity) { public void show(@NotNull HumanEntity humanEntity) {
if (!this.shouldWork) { if(!this.shouldWork) {
humanEntity.closeInventory(); humanEntity.closeInventory();
return; return;
} }

View file

@ -19,10 +19,13 @@ import xyz.alexcrea.cuanvil.gui.config.settings.ItemSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager; import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.awt.*;
import java.util.Collections; import java.util.Collections;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -36,7 +39,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
public CustomRecipeSubSettingGui( public CustomRecipeSubSettingGui(
@NotNull CustomRecipeConfigGui parent, @NotNull CustomRecipeConfigGui parent,
@NotNull AnvilCustomRecipe anvilRecipe) { @NotNull AnvilCustomRecipe anvilRecipe) {
super(4, "§e" + CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString()) + " §8Config"); super(4, CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString()));
this.parent = parent; this.parent = parent;
this.anvilRecipe = anvilRecipe; this.anvilRecipe = anvilRecipe;
@ -73,65 +76,79 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
ItemMeta deleteMeta = deleteItem.getItemMeta(); ItemMeta deleteMeta = deleteItem.getItemMeta();
assert deleteMeta != null; assert deleteMeta != null;
deleteMeta.setDisplayName("§4DELETE RECIPE"); ComponentUtil.INSTANCE.setMessageName(deleteMeta, MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_NAME());
deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_LORE().formatted(), deleteMeta);
deleteItem.setItemMeta(deleteMeta); deleteItem.setItemMeta(deleteMeta);
this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance));
// Displayed item will be updated later // Displayed item will be updated later
IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE(); IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE();
this.exactCountFactory = new BoolSettingsGui.BoolSettingFactory("§8Exact count ?", this, this.exactCountFactory = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_EXACT_COUNT_TITLE(), this,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG); this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG,
null
);
this.removeExactLinearXpFactory = new BoolSettingsGui.BoolSettingFactory("§8Remove exact linear xp ?", this, this.removeExactLinearXpFactory = new BoolSettingsGui.BoolSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_LINEAR_XP_TITLE(), this,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
this.anvilRecipe + "." + AnvilCustomRecipe.REMOVE_EXACT_XP_CONFIG, AnvilCustomRecipe.DEFAULT_REMOVE_EXACT_XP_CONFIG); this.anvilRecipe + "." + AnvilCustomRecipe.REMOVE_EXACT_XP_CONFIG, AnvilCustomRecipe.DEFAULT_REMOVE_EXACT_XP_CONFIG,
null
);
ItemStack item = new ItemStack(Material.BARRIER); ItemStack item = new ItemStack(Material.BARRIER);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§cRemove exact linear xp ?"); ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_LINEAR_XP_NAME());
meta.setLore(Collections.singletonList("§7Not usable if linear cost is 0")); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_LINEAR_XP_LORE().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
this.noRemoveExactLinearXp = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); this.noRemoveExactLinearXp = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
this.levelCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Level Cost", this, this.levelCostFactory = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP(), this,
this.anvilRecipe + "." + AnvilCustomRecipe.XP_LEVEL_COST_CONFIG, this.anvilRecipe + "." + AnvilCustomRecipe.XP_LEVEL_COST_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
null, null,
costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_LEVEL_COST_CONFIG, 1, 5, 10); costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_LEVEL_COST_CONFIG, 1, 5, 10
);
this.linearXpCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Linear Xp Cost", this, this.linearXpCostFactory = new IntSettingsGui.IntSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP(), this,
this.anvilRecipe + "." + AnvilCustomRecipe.LINEAR_XP_COST_CONFIG, this.anvilRecipe + "." + AnvilCustomRecipe.LINEAR_XP_COST_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
null, null,
0, Integer.MAX_VALUE, AnvilCustomRecipe.DEFAULT_LINEAR_XP_COST_CONFIG, 1, 10, 100, 1000, 10000); 0, Integer.MAX_VALUE, AnvilCustomRecipe.DEFAULT_LINEAR_XP_COST_CONFIG, 1, 10, 100, 1000, 10000
);
// Right part of the gui // Right part of the gui
this.leftItemFactory = new ItemSettingGui.ItemSettingFactory("§eRecipe Left §8Item", this, this.leftItemFactory = new ItemSettingGui.ItemSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_LEFT_TITLE(), this,
this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG, this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(),
"§7Set the left item of the custom craft", MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION()
"§7\u25A0 + \u25A1 = \u25A1"); );
this.rightItemFactory = new ItemSettingGui.ItemSettingFactory("§eRecipe Right §8Item", this, this.rightItemFactory = new ItemSettingGui.ItemSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_TITLE(), this,
this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG, this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(),
"§7Set the right item of the custom craft", MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION()
"§7\u25A1 + \u25A0 = \u25A1"); );
this.resultItemFactory = new ItemSettingGui.ItemSettingFactory("§aRecipe Result §8Item", this, this.resultItemFactory = new ItemSettingGui.ItemSettingFactory(
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RESULT_TITLE(), this,
this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG, this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(),
"§7Set the result item of the custom craft", MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION()
"§7\u25A1 + \u25A1 = \u25A0"); );
// Now we update the items // Now we update the items
updateLocal(); updateLocal();
@ -162,8 +179,9 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
return success; return success;
}; };
return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.anvilRecipe.toString()) + "§c?", var type = CasedStringUtil.snakeToUpperSpacedCase(this.anvilRecipe.toString());
"§7Confirm that you want to delete this conflict.", return new ConfirmActionGui(MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_TITLE(), type,
MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION(), type,
this, this.parent, deleteSupplier this, this.parent, deleteSupplier
); );
} }

View file

@ -24,7 +24,9 @@ import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import xyz.alexcrea.cuanvil.util.MetricsUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil;
import java.util.*; import java.util.*;
@ -41,8 +43,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
public EnchantConflictSubSettingGui( public EnchantConflictSubSettingGui(
@NotNull EnchantConflictGui parent, @NotNull EnchantConflictGui parent,
@NotNull EnchantConflictGroup enchantConflict) { @NotNull EnchantConflictGroup enchantConflict) {
super(3, super(3, CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()));
"§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + " §8Config");
this.parent = parent; this.parent = parent;
this.enchantConflict = enchantConflict; this.enchantConflict = enchantConflict;
@ -71,8 +72,8 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
ItemMeta deleteMeta = deleteItem.getItemMeta(); ItemMeta deleteMeta = deleteItem.getItemMeta();
assert deleteMeta != null; assert deleteMeta != null;
deleteMeta.setDisplayName("§4DELETE CONFLICT"); ComponentUtil.INSTANCE.setMessageName(deleteMeta, MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_NAME());
deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_LORE().formatted(), deleteMeta);
deleteItem.setItemMeta(deleteMeta); deleteItem.setItemMeta(deleteMeta);
this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance));
@ -80,27 +81,26 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
// Displayed item will be updated later // Displayed item will be updated later
this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), event -> { this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), event -> {
event.setCancelled(true); event.setCancelled(true);
var type = CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString());
EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui( EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui(
"§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + "§5", MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS(), type,
this, this); this, this);
enchantGui.show(event.getWhoClicked()); enchantGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
this.groupSettingItem = new GuiItem(new ItemStack(Material.PAPER), event -> { this.groupSettingItem = new GuiItem(new ItemStack(Material.PAPER), event -> {
event.setCancelled(true); event.setCancelled(true);
var type = CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString());
GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( GroupSelectSettingGui enchantGui = new GroupSelectSettingGui(
"§e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + " §3Groups", MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS(), type,
this, this, 0); this, this, 0);
enchantGui.show(event.getWhoClicked()); enchantGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
this.minBeforeActiveSettingFactory = new IntSettingsGui.IntSettingFactory( this.minBeforeActiveSettingFactory = new IntSettingsGui.IntSettingFactory(
"§8Minimum enchantment count", MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE(),
this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER, this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER,
Arrays.asList( MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION(),
"§7Minimum enchantment count set to X mean only X enchantment can be put",
"§7on an item before the conflict is active."
),
0, 255, 0, 1 0, 255, 0, 1
); );
@ -137,8 +137,9 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
return success; return success;
}; };
return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + "§c?", var type = CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString());
"§7Confirm that you want to delete this conflict.", return new ConfirmActionGui(MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE(), type,
MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION(), type,
this, this.parent, deleteSupplier this, this.parent, deleteSupplier
); );
} }
@ -159,12 +160,12 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
// Prepare enchantment lore // Prepare enchantment lore
ArrayList<String> enchantLore = new ArrayList<>(); ArrayList<String> enchantLore = new ArrayList<>();
enchantLore.add("§7Allow you to select a list of §5Enchantments §7that this conflict should include"); enchantLore.add("§7Allow you to select a list of §5Enchantments §7that this conflict should include");//TODO MESSAGE
Set<CAEnchantment> enchants = getSelectedEnchantments(); Set<CAEnchantment> enchants = getSelectedEnchantments();
if (enchants.isEmpty()) { if (enchants.isEmpty()) {
enchantLore.add("§7There is no included enchantment for this conflict."); enchantLore.add("§7There is no included enchantment for this conflict.");//TODO MESSAGE
} else { } else {
enchantLore.add("§7List of included enchantment for this conflict:"); enchantLore.add("§7List of included enchantment for this conflict:");//TODO MESSAGE
Iterator<CAEnchantment> enchantIterator = enchants.iterator(); Iterator<CAEnchantment> enchantIterator = enchants.iterator();
boolean greaterThanMax = enchants.size() > 5; boolean greaterThanMax = enchants.size() > 5;
@ -175,7 +176,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
enchantLore.add("§7- §5" + formattedName); enchantLore.add("§7- §5" + formattedName);
} }
if (greaterThanMax) { if (greaterThanMax) {
enchantLore.add("§7And " + (enchants.size() - 4) + " more..."); enchantLore.add("§7And " + (enchants.size() - 4) + " more...");//TODO MESSAGE
} }
} }
@ -188,7 +189,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
ItemMeta enchantMeta = enchantItem.getItemMeta(); ItemMeta enchantMeta = enchantItem.getItemMeta();
assert enchantMeta != null; assert enchantMeta != null;
enchantMeta.setDisplayName("§aSelect included §5Enchantments §aSettings"); enchantMeta.setDisplayName("§aSelect included §5Enchantments §aSettings");//TODO MESSAGE
enchantMeta.setLore(enchantLore); enchantMeta.setLore(enchantLore);
enchantItem.setItemMeta(enchantMeta); enchantItem.setItemMeta(enchantMeta);
@ -200,15 +201,17 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
ItemMeta groupMeta = groupItem.getItemMeta(); ItemMeta groupMeta = groupItem.getItemMeta();
assert groupMeta != null; assert groupMeta != null;
groupMeta.setDisplayName("§aSelect Excluded §3Groups §aSettings"); groupMeta.setDisplayName("§aSelect Excluded §3Groups §aSettings");//TODO MESSAGE
groupMeta.setLore(groupLore); groupMeta.setLore(groupLore);
groupItem.setItemMeta(groupMeta); groupItem.setItemMeta(groupMeta);
this.groupSettingItem.setItem(groupItem); // Just in case this.groupSettingItem.setItem(groupItem); // Just in case
this.pane.bindItem('M', this.minBeforeActiveSettingFactory.getItem(Material.COMMAND_BLOCK, this.pane.bindItem('M', this.minBeforeActiveSettingFactory.getItem(
"Minimum Enchantment Count")); Material.COMMAND_BLOCK,
MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_ITEM()
));
update(); update();
} }
@ -246,7 +249,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
@Override @Override
public boolean setSelectedEnchantments(Set<CAEnchantment> enchantments) { public boolean setSelectedEnchantments(Set<CAEnchantment> enchantments) {
if (!this.shouldWork) { if (!this.shouldWork) {
CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict + " enchants but sub config is destroyed"); CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict + " enchants but sub config is destroyed");//TODO MESSAGE
return false; return false;
} }
@ -264,7 +267,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
try { try {
updateGuiValues(); updateGuiValues();
} catch (Exception e) { } catch (Exception e) {
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e); CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e);//TODO MESSAGE
MetricsUtil.INSTANCE.trackError(e); MetricsUtil.INSTANCE.trackError(e);
} }
@ -291,7 +294,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
@Override @Override
public boolean setSelectedGroups(Set<AbstractMaterialGroup> groups) { public boolean setSelectedGroups(Set<AbstractMaterialGroup> groups) {
if (!this.shouldWork) { if (!this.shouldWork) {
CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.toString() + " groups but sub config is destroyed"); CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.toString() + " groups but sub config is destroyed");//TODO MESSAGE
return false; return false;
} }
@ -309,7 +312,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
try { try {
updateGuiValues(); updateGuiValues();
} catch (Exception e) { } catch (Exception e) {
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e); CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e);//TODO MESSAGE
MetricsUtil.INSTANCE.trackError(e); MetricsUtil.INSTANCE.trackError(e);
} }

View file

@ -20,10 +20,11 @@ import xyz.alexcrea.cuanvil.gui.config.ask.ConfirmActionGui;
import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.GroupSelectSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.GroupSelectSettingGui;
import xyz.alexcrea.cuanvil.gui.config.settings.MaterialSelectSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.MaterialSelectSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -39,8 +40,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
public GroupConfigSubSettingGui( public GroupConfigSubSettingGui(
@NotNull GroupConfigGui parent, @NotNull GroupConfigGui parent,
@NotNull IncludeGroup group) { @NotNull IncludeGroup group) {
super(3, super(3, CasedStringUtil.snakeToUpperSpacedCase(group.getName()));
"§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " §rConfig");
this.parent = parent; this.parent = parent;
this.group = group; this.group = group;
@ -64,39 +64,49 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
// Delete item // Delete item
ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA); ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA);
ItemMeta deleteMeta = deleteItem.getItemMeta(); ItemMeta deleteMeta = deleteItem.getItemMeta();
assert deleteMeta != null;
deleteMeta.setDisplayName("§4DELETE GROUP"); ComponentUtil.INSTANCE.setMessageName(deleteMeta, MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME());
deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); ComponentUtil.INSTANCE.applyLore(
MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE().formatted(),
deleteMeta
);
deleteItem.setItemMeta(deleteMeta); deleteItem.setItemMeta(deleteMeta);
this.pane.bindItem('D', new GuiItem(deleteItem, openGuiAndCheckAction(), CustomAnvil.instance)); this.pane.bindItem('D', new GuiItem(deleteItem, openGuiAndCheckAction(), CustomAnvil.instance));
// Displayed item will be updated later // Displayed item will be updated later
String materialSelectionName = "§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " §rMaterials"; var materialSelectionName = MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS();
var name = CasedStringUtil.snakeToUpperSpacedCase(group.getName());
ItemStack selectItem = new ItemStack(Material.DIAMOND_SWORD); ItemStack selectItem = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta selectItemMeta = selectItem.getItemMeta(); ItemMeta selectItemMeta = selectItem.getItemMeta();
selectItemMeta.setDisplayName(materialSelectionName); assert selectItemMeta != null;
ComponentUtil.INSTANCE.setMessageName(selectItemMeta, materialSelectionName, name);
selectItem.setItemMeta(selectItemMeta); selectItem.setItemMeta(selectItemMeta);
this.materialSelection = new GuiItem(selectItem, (event) -> { this.materialSelection = new GuiItem(selectItem, (event) -> {
event.setCancelled(true); event.setCancelled(true);
MaterialSelectSettingGui selectGui = new MaterialSelectSettingGui(this, MaterialSelectSettingGui selectGui = new MaterialSelectSettingGui(this,
materialSelectionName materialSelectionName, name
, this); , this);
selectGui.show(event.getWhoClicked()); selectGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
String selectGroupName = "§e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.getName()) + " §rGroups"; var selectGroupName = MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS();
ItemStack selectGroup = new ItemStack(Material.CHEST); ItemStack selectGroup = new ItemStack(Material.CHEST);
ItemMeta selectGroupMeta = selectGroup.getItemMeta(); ItemMeta selectGroupMeta = selectGroup.getItemMeta();
selectGroupMeta.setDisplayName(selectGroupName); assert selectGroupMeta != null;
ComponentUtil.INSTANCE.setMessageName(selectGroupMeta, selectGroupName, name);
selectGroup.setItemMeta(selectGroupMeta); selectGroup.setItemMeta(selectGroupMeta);
this.groupSelection = new GuiItem(selectGroup, (event) -> { this.groupSelection = new GuiItem(selectGroup, (event) -> {
event.setCancelled(true); event.setCancelled(true);
GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( GroupSelectSettingGui enchantGui = new GroupSelectSettingGui(
selectGroupName, selectGroupName, name,
this, this, 0); this, this, 0);
enchantGui.show(event.getWhoClicked()); enchantGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
@ -113,7 +123,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
// Do not allow to open inventory if player do not have edit configuration permission // Do not allow to open inventory if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
// test if group is used & cancel & warn user if so // test if group is used & cancel & warn user if so
@ -151,8 +161,9 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
return success; return success;
}; };
return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.toString()) + "§c?", var type = CasedStringUtil.snakeToUpperSpacedCase(this.group.toString());
"§7Confirm that you want to delete this group.", return new ConfirmActionGui(MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_TITLE(), type,
MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION(), type,
this, this.parent, deleteSupplier this, this.parent, deleteSupplier
); );
} }
@ -225,7 +236,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
ItemStack matSelectItem = this.materialSelection.getItem(); ItemStack matSelectItem = this.materialSelection.getItem();
ItemMeta matSelectMeta = matSelectItem.getItemMeta(); ItemMeta matSelectMeta = matSelectItem.getItemMeta();
matSelectMeta.setDisplayName("§aSelect included §eMaterials §aSettings"); assert matSelectMeta != null;
matSelectMeta.setDisplayName("§aSelect included §eMaterials §aSettings");//TODO MESSAGE
matSelectMeta.setLore(matLore); matSelectMeta.setLore(matLore);
matSelectMeta.addItemFlags(ItemFlag.values()); matSelectMeta.addItemFlags(ItemFlag.values());
@ -237,7 +249,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
ItemStack groupSelectItem = this.groupSelection.getItem(); ItemStack groupSelectItem = this.groupSelection.getItem();
ItemMeta groupSelectMeta = groupSelectItem.getItemMeta(); ItemMeta groupSelectMeta = groupSelectItem.getItemMeta();
groupSelectMeta.setDisplayName("§aSelect included §3Groups §aSettings"); assert groupSelectMeta != null;
groupSelectMeta.setDisplayName("§aSelect included §3Groups §aSettings");//TODO MESSAGE
groupSelectMeta.setLore(groupLore); groupSelectMeta.setLore(groupLore);
groupSelectItem.setItemMeta(groupSelectMeta); groupSelectItem.setItemMeta(groupSelectMeta);

View file

@ -1,18 +1,18 @@
package xyz.alexcrea.cuanvil.gui.config.list.elements; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui { public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui {
protected MappedToListSubSettingGui( protected MappedToListSubSettingGui(
int rows, int rows,
@NotNull String title) { @NotNull String type) {
super(rows, title, CustomAnvil.instance); super(rows, MsgUI.INSTANCE.getSHARED_TYPED_CONFIG_TITLE().textHolder(type), CustomAnvil.instance);
} }
@Override @Override

View file

@ -11,14 +11,13 @@ import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.lang.Message;
/** /**
* An instance gui used to edit a setting. * An instance gui used to edit a setting.
*/ */
public abstract class AbstractSettingGui extends ChestGui implements SettingGui { public abstract class AbstractSettingGui extends ChestGui implements SettingGui {
public static final String CLICK_LORE = "§7Click Here to change the value";
private PatternPane pane; private PatternPane pane;
/** /**
@ -40,8 +39,8 @@ public abstract class AbstractSettingGui extends ChestGui implements SettingGui
* @param title Title of this gui. * @param title Title of this gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
*/ */
protected AbstractSettingGui(int rows, @NotNull String title, ValueUpdatableGui parent) { protected AbstractSettingGui(int rows, @NotNull Message title, ValueUpdatableGui parent) {
this(rows, StringHolder.of(title), parent); this(rows, title.textHolder(), parent);
} }
protected GuiItem saveItem; protected GuiItem saveItem;

View file

@ -5,16 +5,21 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -105,20 +110,21 @@ public class BoolSettingsGui extends AbstractSettingGui {
} }
// create & set Value item // create & set Value item
ArrayList<String> valueLore = new ArrayList<>(); ArrayList<Component> valueLore = new ArrayList<>();
if(!holder.displayLore.isEmpty()){ if(holder.displayLore != null){
valueLore.addAll(holder.displayLore); valueLore.addAll(ComponentUtil.INSTANCE.asComponents(holder.displayLore));
valueLore.add(""); valueLore.add(Component.empty());
} }
valueLore.add(AbstractSettingGui.CLICK_LORE); valueLore.addAll(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted());
ItemStack valueItemStack = new ItemStack(displayedMat); ItemStack valueItemStack = new ItemStack(displayedMat);
ItemMeta valueMeta = valueItemStack.getItemMeta(); ItemMeta valueMeta = valueItemStack.getItemMeta();
assert valueMeta != null; assert valueMeta != null;
valueMeta.setDisplayName(displayedName); valueMeta.setDisplayName(displayedName);//TODO MESSAGE ?
valueMeta.setLore(valueLore); ComponentUtil.INSTANCE.applyLore(valueLore, valueMeta);
valueItemStack.setItemMeta(valueMeta); valueItemStack.setItemMeta(valueMeta);
GuiItem resultItem = new GuiItem(valueItemStack, inverseNowConsumer(), CustomAnvil.instance); GuiItem resultItem = new GuiItem(valueItemStack, inverseNowConsumer(), CustomAnvil.instance);
pane.bindItem('v', resultItem); pane.bindItem('v', resultItem);
@ -166,13 +172,15 @@ public class BoolSettingsGui extends AbstractSettingGui {
*/ */
public static class BoolSettingFactory extends SettingGuiFactory { public static class BoolSettingFactory extends SettingGuiFactory {
@NotNull @NotNull
String title; Message title;
@NotNull @NotNull
ValueUpdatableGui parent; ValueUpdatableGui parent;
boolean defaultVal; boolean defaultVal;
@NotNull @Nullable
List<String> displayLore; List<Message> displayLore;
@Nullable
Object param;
/** /**
* Constructor for a boolean setting gui factory. * Constructor for a boolean setting gui factory.
@ -185,22 +193,25 @@ public class BoolSettingsGui extends AbstractSettingGui {
* @param displayLore Gui display item lore. * @param displayLore Gui display item lore.
*/ */
public BoolSettingFactory( public BoolSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull Message title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath,
boolean defaultVal, String... displayLore) { boolean defaultVal,
@Nullable Object param, @Nullable Message... displayLore) {
super(configPath, config); super(configPath, config);
this.title = title; this.title = title;
this.parent = parent; this.parent = parent;
this.defaultVal = defaultVal; this.defaultVal = defaultVal;
this.displayLore = Arrays.asList(displayLore);
this.displayLore = displayLore == null ? null : Arrays.asList(displayLore);
this.param = param;
} }
/** /**
* @return Get setting's gui title. * @return Get setting's gui title.
*/ */
@NotNull @NotNull
public String getTitle() { public Message getTitle() {
return title; return title;
} }
@ -225,25 +236,36 @@ public class BoolSettingsGui extends AbstractSettingGui {
* The item will have its value written in the lore part of the item. * The item will have its value written in the lore part of the item.
* *
* @param name Name of the item. * @param name Name of the item.
* @param params parameters for the given name.
* @return A formatted GuiItem that will create and open a GUI for the boolean setting. * @return A formatted GuiItem that will create and open a GUI for the boolean setting.
*/ */
public GuiItem getItem(String name){ public GuiItem getItem(
@NotNull Message name,
Object... params
){
// Get item properties // Get item properties
boolean value = getConfiguredValue(); boolean value = getConfiguredValue();
Material itemMat; Material itemMat;
StringBuilder itemName = new StringBuilder("§e"); Component itemName = name.formattedConcatenated(params);
String finalValue; String finalValue;
if (value) { if (value) {
itemMat = Material.GREEN_TERRACOTTA; itemMat = Material.GREEN_TERRACOTTA;
finalValue = "§aYes"; finalValue = "<green>Yes";//TODO MESSAGE
} else { } else {
itemMat = Material.RED_TERRACOTTA; itemMat = Material.RED_TERRACOTTA;
finalValue = "§cNo"; finalValue = "<red>No";//TODO MESSAGE
} }
itemName.append(name);
return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, finalValue, this.displayLore, false); return GuiGlobalItems.createGuiItemFromProperties(
this,
itemMat, itemName,
finalValue,
this.displayLore,
false,
this.param
);
} }
/** /**
@ -258,7 +280,7 @@ public class BoolSettingsGui extends AbstractSettingGui {
// Get item properties // Get item properties
String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath());
return getItem(CasedStringUtil.detectToUpperSpacedCase(configPath)); return getItem(MsgUI.INSTANCE.getSHARED_YELLOW_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath));
} }
} }

View file

@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -17,7 +18,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -166,7 +170,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
ItemMeta resultMeta = resultPaper.getItemMeta(); ItemMeta resultMeta = resultPaper.getItemMeta();
assert resultMeta != null; assert resultMeta != null;
resultMeta.setDisplayName("§fValue: §e" + displayValue(now)); resultMeta.setDisplayName("<white>Value: <yellow>" + displayValue(now));
resultPaper.setItemMeta(resultMeta); resultPaper.setItemMeta(resultMeta);
GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
@ -185,12 +189,12 @@ public class DoubleSettingGui extends AbstractSettingGui {
private GuiItem getSetValueItem(Material mat, BigDecimal planned, String numberPrefix){ private GuiItem getSetValueItem(Material mat, BigDecimal planned, String numberPrefix){
// Create set item lore // Create set item lore
ArrayList<String> setLoreItem = new ArrayList<>(); ArrayList<Component> setLoreItem = new ArrayList<>();
if(!holder.displayLore.isEmpty()){ if(holder.displayLore != null){
setLoreItem.addAll(holder.displayLore); setLoreItem.addAll(holder.displayLore.formatted(holder.param, holder.param2));
setLoreItem.add(""); setLoreItem.add(Component.empty());
} }
setLoreItem.add(AbstractSettingGui.CLICK_LORE); setLoreItem.addAll(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted());
// Create & return set value item // Create & return set value item
ItemStack item = new ItemStack(mat); ItemStack item = new ItemStack(mat);
@ -199,7 +203,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
meta.setDisplayName("§e" + displayValue(now) + " §f-> §e" + displayValue(planned) meta.setDisplayName("§e" + displayValue(now) + " §f-> §e" + displayValue(planned)
+ " §r(" + numberPrefix + (displayValue(planned.subtract(now).abs()) + "§r)")); + " §r(" + numberPrefix + (displayValue(planned.subtract(now).abs()) + "§r)"));
meta.setLore(setLoreItem); ComponentUtil.INSTANCE.applyLore(setLoreItem, meta);
item.setItemMeta(meta); item.setItemMeta(meta);
return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
@ -357,7 +361,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
*/ */
public static class DoubleSettingFactory extends SettingGuiFactory { public static class DoubleSettingFactory extends SettingGuiFactory {
@NotNull @NotNull
String title; Message title;
@NotNull @NotNull
ValueUpdatableGui parent; ValueUpdatableGui parent;
@ -369,8 +373,12 @@ public class DoubleSettingGui extends AbstractSettingGui {
BigDecimal defaultVal; BigDecimal defaultVal;
BigDecimal[] steps; BigDecimal[] steps;
@NotNull @Nullable
List<String> displayLore; Message displayLore;
@Nullable
Object param;
@Nullable
Object param2;
/** /**
* Constructor for a double setting gui factory. * Constructor for a double setting gui factory.
@ -392,10 +400,11 @@ public class DoubleSettingGui extends AbstractSettingGui {
* If step only contain 1 value, no step item should be displayed. * If step only contain 1 value, no step item should be displayed.
*/ */
public DoubleSettingFactory( public DoubleSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull Message title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config, @NotNull ConfigHolder config,
@NotNull String configPath, @NotNull String configPath,
@Nullable List<String> displayLore, @Nullable Message displayLore,
@Nullable Object param, @Nullable Object param2,
int scale, boolean asPercentage, boolean nullOnZero, int scale, boolean asPercentage, boolean nullOnZero,
double min, double max, double defaultVal, double... steps) { double min, double max, double defaultVal, double... steps) {
super(configPath, config); super(configPath, config);
@ -413,18 +422,16 @@ public class DoubleSettingGui extends AbstractSettingGui {
this.steps[i] = BigDecimal.valueOf(steps[i]).setScale(scale, RoundingMode.HALF_UP); this.steps[i] = BigDecimal.valueOf(steps[i]).setScale(scale, RoundingMode.HALF_UP);
} }
if(displayLore == null){ this.displayLore = displayLore;
this.displayLore = Collections.emptyList(); this.param = param;
}else { this.param2 = param2;
this.displayLore = displayLore;
}
} }
/** /**
* @return Get setting's gui title * @return Get setting's gui title
*/ */
@NotNull @NotNull
public String getTitle() { public Message getTitle() {
return title; return title;
} }
@ -448,21 +455,29 @@ public class DoubleSettingGui extends AbstractSettingGui {
} }
public GuiItem getItem(Material itemMat, String name){ public GuiItem getItem(
@NotNull Material itemMat,
@NotNull Message name,
Object... params
){
// Get item properties // Get item properties
BigDecimal value = getConfiguredValue(); BigDecimal value = getConfiguredValue();
StringBuilder itemName = new StringBuilder("§a").append(name);
return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, var itemName = name.formattedConcatenated(params);
"§e" + displayValue(value, this.asPercentage),
this.displayLore, true); return GuiGlobalItems.createGuiItemFromProperties(
this, itemMat, itemName,
"<yellow>" + displayValue(value, this.asPercentage), //TODO MESSAGE ? maybe ?
Collections.singletonList(this.displayLore), true,
this.param, this.param2
);
} }
public GuiItem getItem(Material itemMat){ public GuiItem getItem(Material itemMat){
// Get item properties // Get item properties
String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath());
return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); return getItem(itemMat, MsgUI.INSTANCE.getSHARED_GREEN_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath));
} }
} }

View file

@ -19,6 +19,9 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -150,7 +153,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
assert meta != null; assert meta != null;
meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§c-" + (nowBook - planned) + "§r)"); meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§c-" + (nowBook - planned) + "§r)");
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
minusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); minusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance);
@ -167,8 +170,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§a+" + (planned - nowBook) + "§r)"); meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§a+" + (planned - nowBook) + "§r)");//TODO MESSAGE
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
plusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); plusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance);
@ -182,9 +185,9 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
ItemMeta nowMeta = nowPaper.getItemMeta(); ItemMeta nowMeta = nowPaper.getItemMeta();
assert nowMeta != null; assert nowMeta != null;
nowMeta.setDisplayName("§fValue: §e" + nowBook); nowMeta.setDisplayName("<white>Value: <yellow>" + nowBook);//TODO MESSAGE
if (!holder.displayLore.isEmpty()) { if (holder.displayLore != null) {
nowMeta.setLore(holder.displayLore); ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(holder.displayLore, holder.param), nowMeta);
} }
nowPaper.setItemMeta(nowMeta); nowPaper.setItemMeta(nowMeta);
@ -263,15 +266,15 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
* If step only contain 1 value, no step item should be displayed. * If step only contain 1 value, no step item should be displayed.
*/ */
public EnchantCostSettingFactory( public EnchantCostSettingFactory(
@NotNull String title, ValueUpdatableGui parent, @NotNull Message title, ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config,
@Nullable List<String> displayLore, @Nullable Message displayLore, @Nullable Object param,
@NotNull CAEnchantment enchantment, @NotNull CAEnchantment enchantment,
int min, int max, int... steps) { int min, int max, int... steps) {
super(title, parent, super(title, parent,
configPath, config, configPath, config,
displayLore, displayLore, param,
min, max, enchantment.defaultRarity().getItemValue(), min, max, enchantment.defaultRarity().getItemValue(),
steps); steps);
@ -302,7 +305,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
return new EnchantCostSettingsGui(this, nowItem); return new EnchantCostSettingsGui(this, nowItem);
} }
public List<String> getDisplayLore() { @Nullable
public List<Message> getDisplayLore() {
return this.displayLore; return this.displayLore;
} }
} }

View file

@ -20,6 +20,7 @@ import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer;
import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.*; import java.util.*;
@ -35,8 +36,10 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui<CAEnchantme
private boolean displayUnselected; private boolean displayUnselected;
public EnchantSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer) { public EnchantSelectSettingGui(
super(title, parent instanceof Gui parentGui ? parentGui : MainConfigGui.getInstance()) ; @NotNull Message title, @NotNull String param,
ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer) {
super(title, param, parent instanceof Gui parentGui ? parentGui : MainConfigGui.getInstance()) ;
this.enchantContainer = enchantContainer; this.enchantContainer = enchantContainer;
this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments()); this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments());

View file

@ -15,6 +15,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -137,7 +138,7 @@ public class EnumSettingGui<T extends Enum<T> & EnumSettingGui.ConfigurableEnum>
*/ */
public abstract static class EnumSettingFactory<T extends Enum<T> & ConfigurableEnum> extends SettingGuiFactory { public abstract static class EnumSettingFactory<T extends Enum<T> & ConfigurableEnum> extends SettingGuiFactory {
@NotNull @NotNull
String title; Message title;
@NotNull @NotNull
ValueUpdatableGui parent; ValueUpdatableGui parent;
@ -150,7 +151,7 @@ public class EnumSettingGui<T extends Enum<T> & EnumSettingGui.ConfigurableEnum>
* @param config Configuration holder of this setting. * @param config Configuration holder of this setting.
*/ */
protected EnumSettingFactory( protected EnumSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull Message title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config) { @NotNull String configPath, @NotNull ConfigHolder config) {
super(configPath, config); super(configPath, config);
this.title = title; this.title = title;
@ -161,7 +162,7 @@ public class EnumSettingGui<T extends Enum<T> & EnumSettingGui.ConfigurableEnum>
* @return Get setting's gui title. * @return Get setting's gui title.
*/ */
@NotNull @NotNull
public String getTitle() { public Message getTitle() {
return title; return title;
} }

View file

@ -19,6 +19,7 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer;
import xyz.alexcrea.cuanvil.gui.config.list.ElementListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.ElementListConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Collections; import java.util.Collections;
@ -34,8 +35,10 @@ public class GroupSelectSettingGui extends AbstractSettingGui {
Set<AbstractMaterialGroup> selectedGroups; Set<AbstractMaterialGroup> selectedGroups;
public GroupSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectGroupContainer groupContainer, int page) { public GroupSelectSettingGui(
super(6, title, parent); @NotNull Message title, @NotNull String param,
ValueUpdatableGui parent, SelectGroupContainer groupContainer, int page) {
super(6, title.textHolder(param), parent);
this.groupContainer = groupContainer; this.groupContainer = groupContainer;
//Not used but planned //Not used but planned
this.page = page; this.page = page;

View file

@ -5,6 +5,9 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -16,7 +19,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -71,8 +77,8 @@ public class IntSettingsGui extends AbstractSettingGui {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§eReset to default value"); meta.setDisplayName("§eReset to default value");//TODO MESSAGE
meta.setLore(Collections.singletonList("§7Default value is §e" + meta.setLore(Collections.singletonList("§7Default value is §e" +//TODO MESSAGE
holder.valueDisplayName(ValueDisplayType.RESET, holder.defaultVal))); holder.valueDisplayName(ValueDisplayType.RESET, holder.defaultVal)));
item.setItemMeta(meta); item.setItemMeta(meta);
returnToDefault = new GuiItem(item, event -> { returnToDefault = new GuiItem(item, event -> {
@ -91,7 +97,7 @@ public class IntSettingsGui extends AbstractSettingGui {
// minus item // minus item
GuiItem minusItem; GuiItem minusItem;
if (now > holder.min) { if(now > holder.min) {
int planned = Math.max(holder.min, now - step); int planned = Math.max(holder.min, now - step);
minusItem = valueEditItem(Material.RED_TERRACOTTA, ValueDisplayType.REMOVE, planned); minusItem = valueEditItem(Material.RED_TERRACOTTA, ValueDisplayType.REMOVE, planned);
} else { } else {
@ -101,7 +107,7 @@ public class IntSettingsGui extends AbstractSettingGui {
//plus item //plus item
GuiItem plusItem; GuiItem plusItem;
if (now < holder.max) { if(now < holder.max) {
int planned = Math.min(holder.max, now + step); int planned = Math.min(holder.max, now + step);
plusItem = valueEditItem(Material.GREEN_TERRACOTTA, ValueDisplayType.ADD, planned); plusItem = valueEditItem(Material.GREEN_TERRACOTTA, ValueDisplayType.ADD, planned);
} else { } else {
@ -114,8 +120,9 @@ public class IntSettingsGui extends AbstractSettingGui {
ItemMeta resultMeta = resultPaper.getItemMeta(); ItemMeta resultMeta = resultPaper.getItemMeta();
assert resultMeta != null; assert resultMeta != null;
resultMeta.setDisplayName("§fValue: §e" + holder.valueDisplayName(ValueDisplayType.CURRENT, now)); resultMeta.setDisplayName("<white>Value: <yellow>" + holder.valueDisplayName(ValueDisplayType.CURRENT, now));//TODO MESSAGE
resultMeta.setLore(holder.displayLore); if(holder.displayLore != null)
ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(holder.displayLore, holder.param), resultMeta);
resultPaper.setItemMeta(resultMeta); resultPaper.setItemMeta(resultMeta);
@ -125,7 +132,7 @@ public class IntSettingsGui extends AbstractSettingGui {
// reset to default // reset to default
GuiItem returnToDefault; GuiItem returnToDefault;
if (now != holder.defaultVal) { if(now != holder.defaultVal) {
returnToDefault = this.returnToDefault; returnToDefault = this.returnToDefault;
} else { } else {
returnToDefault = GuiGlobalItems.backgroundItem(); returnToDefault = GuiGlobalItems.backgroundItem();
@ -142,9 +149,9 @@ public class IntSettingsGui extends AbstractSettingGui {
var nowDisplay = holder.valueDisplayName(type, now); var nowDisplay = holder.valueDisplayName(type, now);
var plannedDisplay = holder.valueDisplayName(type, planned); var plannedDisplay = holder.valueDisplayName(type, planned);
var deltaDisplay = holder.deltaDisplay(type, now, planned); var deltaDisplay = holder.deltaDisplay(type, now, planned);
meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)"); meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)");//TODO MESSAGE
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta);
item.setItemMeta(meta); item.setItemMeta(meta);
return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
} }
@ -170,7 +177,7 @@ public class IntSettingsGui extends AbstractSettingGui {
GuiItem background = GuiGlobalItems.backgroundItem(); GuiItem background = GuiGlobalItems.backgroundItem();
PatternPane pane = getPane(); PatternPane pane = getPane();
for (char i = 'a'; i < (getMidStepChar() - 'a') * 2 + 1; i++) { for(char i = 'a'; i < (getMidStepChar() - 'a') * 2 + 1; i++) {
pane.bindItem(i, background); pane.bindItem(i, background);
} }
// Then update legit step values // Then update legit step values
@ -181,7 +188,7 @@ public class IntSettingsGui extends AbstractSettingGui {
* Update steps items value. * Update steps items value.
*/ */
protected void updateStepValue() { protected void updateStepValue() {
if (holder.steps.length <= 1) return; if(holder.steps.length <= 1) return;
// We assume steps have a length of 2k+1 cause its more pretty // We assume steps have a length of 2k+1 cause its more pretty
char val = getMidStepChar(); char val = getMidStepChar();
// Offset to start (not the best way to do it) // Offset to start (not the best way to do it)
@ -189,7 +196,7 @@ public class IntSettingsGui extends AbstractSettingGui {
// Then place items // Then place items
PatternPane pane = getPane(); PatternPane pane = getPane();
for (int i = 0; i < holder.steps.length; i++) { for(int i = 0; i < holder.steps.length; i++) {
pane.bindItem(val + i, stepGuiItem(i)); pane.bindItem(val + i, stepGuiItem(i));
} }
@ -218,7 +225,7 @@ public class IntSettingsGui extends AbstractSettingGui {
StringBuilder stepName = new StringBuilder("§"); StringBuilder stepName = new StringBuilder("§");
List<String> stepLore; List<String> stepLore;
Consumer<InventoryClickEvent> clickEvent; Consumer<InventoryClickEvent> clickEvent;
if (stepValue == step) { if(stepValue == step) {
stepMat = Material.GREEN_STAINED_GLASS_PANE; stepMat = Material.GREEN_STAINED_GLASS_PANE;
stepName.append('a'); stepName.append('a');
stepLore = Collections.singletonList("§7Value is changing by " + stepValue); stepLore = Collections.singletonList("§7Value is changing by " + stepValue);
@ -261,7 +268,7 @@ public class IntSettingsGui extends AbstractSettingGui {
public boolean onSave() { public boolean onSave() {
holder.config.getConfig().set(holder.configPath, now); holder.config.getConfig().set(holder.configPath, now);
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { if(GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
} }
return true; return true;
@ -278,7 +285,7 @@ public class IntSettingsGui extends AbstractSettingGui {
public static class IntSettingFactory extends SettingGuiFactory { public static class IntSettingFactory extends SettingGuiFactory {
@NotNull @NotNull
String title; Message title;
@NotNull @NotNull
ValueUpdatableGui parent; ValueUpdatableGui parent;
int min; int min;
@ -286,8 +293,11 @@ public class IntSettingsGui extends AbstractSettingGui {
int defaultVal; int defaultVal;
int[] steps; int[] steps;
@NotNull @Nullable
List<String> displayLore; List<Message> displayLore;
@Nullable
Object param;
/** /**
* Constructor for an int setting gui factory. * Constructor for an int setting gui factory.
@ -306,9 +316,9 @@ public class IntSettingsGui extends AbstractSettingGui {
* If step only contain 1 value, no step item should be displayed. * If step only contain 1 value, no step item should be displayed.
*/ */
public IntSettingFactory( public IntSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull Message title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config,
@Nullable List<String> displayLore, @Nullable Message displayLore, @Nullable Object param,
int min, int max, int defaultVal, int... steps) { int min, int max, int defaultVal, int... steps) {
super(configPath, config); super(configPath, config);
this.title = title; this.title = title;
@ -317,19 +327,15 @@ public class IntSettingsGui extends AbstractSettingGui {
this.max = max; this.max = max;
this.defaultVal = defaultVal; this.defaultVal = defaultVal;
this.steps = steps; this.steps = steps;
this.displayLore = displayLore == null ? null : Collections.singletonList(displayLore);
if (displayLore == null) { this.param = param;
this.displayLore = Collections.emptyList();
} else {
this.displayLore = displayLore;
}
} }
/** /**
* @return Get setting's gui title * @return Get setting's gui title
*/ */
@NotNull @NotNull
public String getTitle() { public Message getTitle() {
return title; return title;
} }
@ -355,19 +361,24 @@ public class IntSettingsGui extends AbstractSettingGui {
* *
* @param itemMat Displayed material of the item. * @param itemMat Displayed material of the item.
* @param name Name of the item. * @param name Name of the item.
* @param params parameters for the given name.
* @return A formatted GuiItem that will create and open a GUI for the int setting. * @return A formatted GuiItem that will create and open a GUI for the int setting.
*/ */
public GuiItem getItem( public GuiItem getItem(
@NotNull Material itemMat, @NotNull Material itemMat,
@NotNull String name @NotNull Message name,
Object... params
) { ) {
// Get item properties // Get item properties
int value = getConfiguredValue(); int value = getConfiguredValue();
StringBuilder itemName = new StringBuilder("§a").append(name); var itemName = name.formattedConcatenated(params);
return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, return GuiGlobalItems.createGuiItemFromProperties(
"§e" + value, this, itemMat, itemName,
this.displayLore, true); "<yellow>" + value, //TODO MESSAGE ? maybe ?
this.displayLore, true,
this.param
);
} }
/** /**
@ -383,7 +394,7 @@ public class IntSettingsGui extends AbstractSettingGui {
@NotNull Material itemMat @NotNull Material itemMat
) { ) {
String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath());
return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); return getItem(itemMat, MsgUI.INSTANCE.getSHARED_GREEN_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath));
} }
protected String valueDisplayName(ValueDisplayType type, int value) { protected String valueDisplayName(ValueDisplayType type, int value) {
@ -392,10 +403,13 @@ public class IntSettingsGui extends AbstractSettingGui {
protected String deltaDisplay(ValueDisplayType type, int now, int planned) { protected String deltaDisplay(ValueDisplayType type, int now, int planned) {
var delta = planned - now; var delta = planned - now;
if (delta < 0) return "§c" + delta; if(delta < 0) return "§c" + delta;
else return "§a+" + delta; else return "§a+" + delta;
} }
public @Nullable Object getParam() {
return param;
}
} }
public enum ValueDisplayType { public enum ValueDisplayType {

View file

@ -17,8 +17,11 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.awt.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -168,13 +171,13 @@ public class ItemSettingGui extends AbstractSettingGui {
*/ */
public static class ItemSettingFactory extends SettingGuiFactory { public static class ItemSettingFactory extends SettingGuiFactory {
@NotNull @NotNull
String title; Message title;
@NotNull @NotNull
ValueUpdatableGui parent; ValueUpdatableGui parent;
@Nullable @Nullable
ItemStack defaultVal; ItemStack defaultVal;
@NotNull @NotNull
List<String> displayLore; List<Message> displayLore;
/** /**
* Constructor for an item setting gui factory. * Constructor for an item setting gui factory.
@ -187,10 +190,10 @@ public class ItemSettingGui extends AbstractSettingGui {
* @param displayLore Gui display item lore. * @param displayLore Gui display item lore.
*/ */
public ItemSettingFactory( public ItemSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull Message title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config,
@Nullable ItemStack defaultVal, @Nullable ItemStack defaultVal,
String... displayLore) { Message... displayLore) {
super(configPath, config); super(configPath, config);
this.title = title; this.title = title;
this.parent = parent; this.parent = parent;
@ -203,7 +206,7 @@ public class ItemSettingGui extends AbstractSettingGui {
* @return Get setting's gui title. * @return Get setting's gui title.
*/ */
@NotNull @NotNull
public String getTitle() { public Message getTitle() {
return title; return title;
} }
@ -215,7 +218,7 @@ public class ItemSettingGui extends AbstractSettingGui {
} }
@NotNull @NotNull
public List<String> getDisplayLore() { public List<Message> getDisplayLore() {
return this.displayLore; return this.displayLore;
} }
@ -245,8 +248,9 @@ public class ItemSettingGui extends AbstractSettingGui {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
assert meta != null; assert meta != null;
//TODO MESSAGE name ?
meta.setDisplayName("§a" + name); meta.setDisplayName("§a" + name);
meta.setLore(getDisplayLore()); ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(getDisplayLore()), meta);
meta.addItemFlags(ItemFlag.values()); meta.addItemFlags(ItemFlag.values());
item.setItemMeta(meta); item.setItemMeta(meta);

View file

@ -18,6 +18,8 @@ import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.MaterialUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil;
@ -37,9 +39,10 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Namespa
public MaterialSelectSettingGui( public MaterialSelectSettingGui(
@NotNull SelectMaterialContainer selector, @NotNull SelectMaterialContainer selector,
@NotNull String title, @NotNull Message title,
@NotNull String param,
@NotNull Gui backGui) { @NotNull Gui backGui) {
super(title); super(title, param);//TODO MESSAGE make param go down
this.selector = selector; this.selector = selector;
this.backGui = backGui; this.backGui = backGui;
this.instantRemove = false; this.instantRemove = false;
@ -156,7 +159,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Namespa
// Do not allow to save configuration if player do not have edit configuration permission // Do not allow to save configuration if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
if(testCantSave()) return; if(testCantSave()) return;
@ -236,8 +239,8 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Namespa
// Create and show confirm remove gui. // Create and show confirm remove gui.
ConfirmActionGui confirmGui = new ConfirmActionGui( ConfirmActionGui confirmGui = new ConfirmActionGui(
"Remove " + materialName, MsgUI.INSTANCE.getMATERIAL_SELECT_CONFIRM_TITLE(), materialName,
"§7Confirm Remove " + materialName.toLowerCase() + " from this list.", MsgUI.INSTANCE.getMATERIAL_SELECT_CONFIRM_DESCRIPTION(), materialName.toLowerCase(),
this, this, this, this,
() -> { () -> {
removeMaterial(material); removeMaterial(material);

View file

@ -15,54 +15,48 @@ import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.WorkPenaltyType; import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui; import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
private static final String INCREASING_EXPLANATION = "§eIncreasing§7: will penalty be increased (in item)";
private static final String ADDING_EXPLANATION = "§eAdditive§7: will penalty be added to the cost";
private static final String SHARED_EXPLANATION = "§eShared§7: Vanilla, shared penalty. it will be kept from before the plugin installation.";
private static final String EXCLUSIVE_EXPLANATION = "§eExclusive§7: Custom, per anvil use type penalty. it will be lost after plugin uninstallation";
private final @NotNull WorkPenaltyType currentType; private final @NotNull WorkPenaltyType currentType;
private final @NotNull Map<AnvilUseType, WorkPenaltyType.WorkPenaltyPart> items; private final @NotNull Map<AnvilUseType, WorkPenaltyType.WorkPenaltyPart> items;
public WorkPenaltyTypeSettingGui(@NotNull BasicConfigGui parent) { public WorkPenaltyTypeSettingGui(@NotNull BasicConfigGui parent) {
super(4, "§8Work Penalty Type", parent); super(4, MsgUI.INSTANCE.getBASIC_WORK_PENALTY_TITLE(), parent);
this.currentType = ConfigOptions.INSTANCE.getWorkPenaltyType(); this.currentType = ConfigOptions.INSTANCE.getWorkPenaltyType();
this.items = new EnumMap<>(this.currentType.getPartMap()); this.items = new EnumMap<>(this.currentType.getPartMap());
for (AnvilUseType type : useTypes.keySet()) { for(AnvilUseType type : useTypes.keySet()) {
updateGuiForType(type); updateGuiForType(type);
} }
} }
public static GuiItem getDisplayItem(@NotNull BasicConfigGui parent, public static GuiItem getDisplayItem(@NotNull BasicConfigGui parent,
@NotNull Material itemMat, @NotNull Material itemMat,
@NotNull String name) { @NotNull Message name) {
List<String> displayLore = new ArrayList<>(); var item = new ItemStack(itemMat);
displayLore.add("§7Work penalty increase the price for every anvil use."); var meta = item.getItemMeta();
displayLore.add("§7This config allow you to choose the comportment of work penalty."); assert meta != null;
displayLore.add(INCREASING_EXPLANATION);
displayLore.add(ADDING_EXPLANATION);
displayLore.add("");
displayLore.add("§7About shared/exclusive penalty:");
displayLore.add(SHARED_EXPLANATION);
displayLore.add(EXCLUSIVE_EXPLANATION);
ItemStack item = new ItemStack(itemMat); var lore = new ArrayList<Message>();
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_LORE());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_LORE_BREAK());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE());
ItemMeta meta = item.getItemMeta(); ComponentUtil.INSTANCE.setMessageName(meta, name);
meta.setDisplayName(name); ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta);
meta.setLore(displayLore);
item.setItemMeta(meta); item.setItemMeta(meta);
@ -71,9 +65,9 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
HumanEntity player = event.getWhoClicked(); HumanEntity player = event.getWhoClicked();
// Do not allow to open inventory if player do not have edit configuration permission // Do not allow to open inventory if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if(!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
new WorkPenaltyTypeSettingGui(parent).show(player); new WorkPenaltyTypeSettingGui(parent).show(player);
@ -110,6 +104,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
char exclusiveAdditive = typeVals.charAt(4); char exclusiveAdditive = typeVals.charAt(4);
WorkPenaltyType.WorkPenaltyPart part = items.get(type); WorkPenaltyType.WorkPenaltyPart part = items.get(type);
//TODO MESSAGE
String increasingStr = (part.penaltyIncrease() ? "§a" : "§c") + "Increasing"; String increasingStr = (part.penaltyIncrease() ? "§a" : "§c") + "Increasing";
String additiveStr = (part.penaltyAdditive() ? "§a" : "§c") + "Additive"; String additiveStr = (part.penaltyAdditive() ? "§a" : "§c") + "Additive";
String exclusiveIncreasingStr = (part.exclusivePenaltyIncrease() ? "§a" : "§c") + "Increasing"; String exclusiveIncreasingStr = (part.exclusivePenaltyIncrease() ? "§a" : "§c") + "Increasing";
@ -123,6 +118,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
displayLore.add("§eExclusive§7: " + exclusiveAdditiveStr + " §7| " + exclusiveIncreasingStr); displayLore.add("§eExclusive§7: " + exclusiveAdditiveStr + " §7| " + exclusiveIncreasingStr);
ItemMeta meta = displayItem.getItemMeta(); ItemMeta meta = displayItem.getItemMeta();
assert meta != null;
meta.setDisplayName("§e" + type.getDisplayName()); meta.setDisplayName("§e" + type.getDisplayName());
meta.setLore(displayLore); meta.setLore(displayLore);
displayItem.setItemMeta(meta); displayItem.setItemMeta(meta);
@ -136,9 +132,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
ItemStack incrementItem = new ItemStack(part.penaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); ItemStack incrementItem = new ItemStack(part.penaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA);
meta = incrementItem.getItemMeta(); meta = incrementItem.getItemMeta();
assert meta != null;
meta.setDisplayName(increasingStr); meta.setDisplayName(increasingStr);
meta.setLore(List.of(INCREASING_EXPLANATION));
meta.setLore(List.of(SHARED_EXPLANATION)); var lore = new ArrayList<Message>();
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED());
ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta);
incrementItem.setItemMeta(meta); incrementItem.setItemMeta(meta);
pane.bindItem(increment, new GuiItem(incrementItem, (event) -> { pane.bindItem(increment, new GuiItem(incrementItem, (event) -> {
@ -156,9 +157,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
ItemStack additiveItem = new ItemStack(part.penaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); ItemStack additiveItem = new ItemStack(part.penaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA);
meta = additiveItem.getItemMeta(); meta = additiveItem.getItemMeta();
assert meta != null;
meta.setDisplayName(additiveStr); meta.setDisplayName(additiveStr);
meta.setLore(List.of(ADDING_EXPLANATION));
meta.setLore(List.of(SHARED_EXPLANATION)); lore.clear();
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED());
ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta);
additiveItem.setItemMeta(meta); additiveItem.setItemMeta(meta);
pane.bindItem(additive, new GuiItem(additiveItem, (event) -> { pane.bindItem(additive, new GuiItem(additiveItem, (event) -> {
@ -176,9 +182,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
ItemStack exclusiveIncrementItem = new ItemStack(part.exclusivePenaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); ItemStack exclusiveIncrementItem = new ItemStack(part.exclusivePenaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA);
meta = exclusiveIncrementItem.getItemMeta(); meta = exclusiveIncrementItem.getItemMeta();
assert meta != null;
meta.setDisplayName(exclusiveIncreasingStr); meta.setDisplayName(exclusiveIncreasingStr);
meta.setLore(List.of(INCREASING_EXPLANATION));
meta.setLore(List.of(EXCLUSIVE_EXPLANATION)); lore.clear();
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE());
ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta);
exclusiveIncrementItem.setItemMeta(meta); exclusiveIncrementItem.setItemMeta(meta);
pane.bindItem(exclusiveIncrement, new GuiItem(exclusiveIncrementItem, (event) -> { pane.bindItem(exclusiveIncrement, new GuiItem(exclusiveIncrementItem, (event) -> {
@ -196,9 +207,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
ItemStack exclusiveAdditiveItem = new ItemStack(part.exclusivePenaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); ItemStack exclusiveAdditiveItem = new ItemStack(part.exclusivePenaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA);
meta = exclusiveAdditiveItem.getItemMeta(); meta = exclusiveAdditiveItem.getItemMeta();
assert meta != null;
meta.setDisplayName(exclusiveAdditiveStr); meta.setDisplayName(exclusiveAdditiveStr);
meta.setLore(List.of(ADDING_EXPLANATION));
meta.setLore(List.of(EXCLUSIVE_EXPLANATION)); lore.clear();
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE());
lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE());
ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta);
exclusiveAdditiveItem.setItemMeta(meta); exclusiveAdditiveItem.setItemMeta(meta);
pane.bindItem(exclusiveAdditive, new GuiItem(exclusiveAdditiveItem, (event) -> { pane.bindItem(exclusiveAdditive, new GuiItem(exclusiveAdditiveItem, (event) -> {
@ -223,9 +239,9 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
FileConfiguration config = configHolder.getConfig(); FileConfiguration config = configHolder.getConfig();
partEnum.forEach((key, value) -> { partEnum.forEach((key, value) -> {
String partPath = key.getPath(); String partPath = key.getPath();
if (key.getDefaultPenalty().equals(value)) { if(key.getDefaultPenalty().equals(value)) {
config.set(partPath, null); config.set(partPath, null);
return; return;
} }
@ -241,8 +257,8 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui {
@Override @Override
public boolean hadChange() { public boolean hadChange() {
for (AnvilUseType type : items.keySet()) { for(AnvilUseType type : items.keySet()) {
if (!currentType.getPenaltyInfo(type).equals(items.get(type))) { if(!currentType.getPenaltyInfo(type).equals(items.get(type))) {
return true; return true;
} }
} }

View file

@ -7,6 +7,7 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -17,8 +18,6 @@ import java.util.function.Consumer;
*/ */
public class GuiGlobalActions { public class GuiGlobalActions {
public static final String NO_EDIT_PERM = "§cYou do not have permission to edit the config";
/** /**
* A Consumer that should be used if the item goal is to do nothing on click. * A Consumer that should be used if the item goal is to do nothing on click.
*/ */
@ -44,7 +43,7 @@ public class GuiGlobalActions {
// Do not allow to open inventory if player do not have edit configuration permission // Do not allow to open inventory if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
try { try {
@ -102,7 +101,7 @@ public class GuiGlobalActions {
// Do not allow to open inventory if player do not have edit configuration permission // Do not allow to open inventory if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }
goal.show(player); goal.show(player);
@ -127,7 +126,7 @@ public class GuiGlobalActions {
// Do not allow to save configuration if player do not have edit configuration permission // Do not allow to save configuration if player do not have edit configuration permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) { if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.closeInventory(); player.closeInventory();
player.sendMessage(NO_EDIT_PERM); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player);
return; return;
} }

View file

@ -4,14 +4,20 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.lang.Message;
import xyz.alexcrea.cuanvil.lang.MsgUI;
import xyz.alexcrea.cuanvil.util.ComponentUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -184,9 +190,6 @@ public class GuiGlobalItems {
return new GuiItem(item, GuiGlobalActions.openSettingGuiAction(factory), CustomAnvil.instance); return new GuiItem(item, GuiGlobalActions.openSettingGuiAction(factory), CustomAnvil.instance);
} }
// Prefix of the one line lore that will be added to setting's item.
public static final String SETTING_ITEM_LORE_PREFIX = "§7value: ";
/** /**
* Create an arbitrary GuiItem from a unique setting and item's property. * Create an arbitrary GuiItem from a unique setting and item's property.
* *
@ -201,17 +204,23 @@ public class GuiGlobalItems {
public static GuiItem createGuiItemFromProperties( public static GuiItem createGuiItemFromProperties(
@NotNull SettingGui.SettingGuiFactory factory, @NotNull SettingGui.SettingGuiFactory factory,
@NotNull Material itemMat, @NotNull Material itemMat,
@NotNull StringBuilder itemName, @NotNull Component itemName,
@NotNull Object value, @NotNull Object value,//TODO ????
@NotNull List<String> displayLore, @Nullable List<Message> displayLore,
boolean displayValuePrefix boolean displayValuePrefix,
@Nullable Object... params
) { ) {
// Prepare lore // Prepare lore
ArrayList<String> lore = new ArrayList<>(); var loreHeader = (displayValuePrefix ?
lore.add((displayValuePrefix ? SETTING_ITEM_LORE_PREFIX : "") + value); MsgUI.INSTANCE.getGLOBAL_ITEM_ITEM_LORE_PREFIX() :
if(!displayLore.isEmpty()){ MsgUI.INSTANCE.getGLOBAL_ITEM_ITEM_LORE_PREFIX_ALONE());
lore.add("");
lore.addAll(displayLore); List<Component> lore = loreHeader.formatted(value);
if(displayLore != null){
lore.add(Component.empty());
for(Message message : displayLore) {
lore.addAll(message.formatted(params));
}
} }
// Create & initialise item // Create & initialise item
@ -219,8 +228,8 @@ public class GuiGlobalItems {
ItemMeta itemMeta = item.getItemMeta(); ItemMeta itemMeta = item.getItemMeta();
assert itemMeta != null; assert itemMeta != null;
itemMeta.setDisplayName(itemName.toString()); PlatformUtil.INSTANCE.setComponentDisplayName(itemMeta, itemName, null);
itemMeta.setLore(lore); ComponentUtil.INSTANCE.applyLore(lore, itemMeta);
itemMeta.addItemFlags(ItemFlag.values()); itemMeta.addItemFlags(ItemFlag.values());
item.setItemMeta(itemMeta); item.setItemMeta(itemMeta);

View file

@ -1,14 +1,13 @@
package io.delilaheve package io.delilaheve
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.configuration.file.YamlConfiguration
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent
import xyz.alexcrea.cuanvil.api.event.CAEnchantRegistryReadyEvent import xyz.alexcrea.cuanvil.api.event.CAEnchantRegistryReadyEvent
import xyz.alexcrea.cuanvil.command.CustomAnvilCommand import xyz.alexcrea.cuanvil.command.CustomAnvilCommand
import xyz.alexcrea.cuanvil.command.EditConfigExecutor
import xyz.alexcrea.cuanvil.command.ReloadExecutor
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
@ -17,6 +16,9 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
import xyz.alexcrea.cuanvil.lang.Lang
import xyz.alexcrea.cuanvil.lang.MsgError
import xyz.alexcrea.cuanvil.lang.MsgWarning
import xyz.alexcrea.cuanvil.listener.AnvilCloseListener import xyz.alexcrea.cuanvil.listener.AnvilCloseListener
import xyz.alexcrea.cuanvil.listener.AnvilResultListener import xyz.alexcrea.cuanvil.listener.AnvilResultListener
import xyz.alexcrea.cuanvil.listener.ChatEventListener import xyz.alexcrea.cuanvil.listener.ChatEventListener
@ -75,7 +77,7 @@ open class CustomAnvil : JavaPlugin() {
var latestVer: String? = null var latestVer: String? = null
// Debug // Debug
val debugStorageQueue = ArrayDeque<String>() val debugStorageQueue = ArrayDeque<Component>()
private fun addToLogQueue(message: String) { private fun addToLogQueue(message: String) {
if(debugStorageQueue.size >= 200) { if(debugStorageQueue.size >= 200) {
@ -83,7 +85,7 @@ open class CustomAnvil : JavaPlugin() {
debugStorageQueue.removeFirst() debugStorageQueue.removeFirst()
} }
debugStorageQueue.addLast(message) debugStorageQueue.addLast(Component.text(message))
} }
/** /**
@ -108,11 +110,23 @@ open class CustomAnvil : JavaPlugin() {
} }
} }
/**
* Error Logging handler
*/
@JvmStatic fun logError(message: String, throwable: Throwable? = null, track: Boolean = true, level: Level = Level.SEVERE) {
instance.logger.log(level, message, throwable)
addToLogQueue("Error: $message")
if(track) {
MetricsUtil.trackError(message, throwable)
}
}
} }
// stop plugin if we do not force a dirty start (true by default) // stop plugin if we do not force a dirty start (true by default)
// Return true if start was stopped // Return true if start was stopped
private fun tryDirtyStart(): Boolean { private fun tryDirtyStart(): Boolean {
if(ConfigHolder.DEFAULT_CONFIG == null) return false
if(!ConfigHolder.DEFAULT_CONFIG.config.getBoolean("dirty_start", false)) { if(!ConfigHolder.DEFAULT_CONFIG.config.getBoolean("dirty_start", false)) {
Bukkit.getPluginManager().disablePlugin(this) Bukkit.getPluginManager().disablePlugin(this)
return true return true
@ -123,6 +137,7 @@ open class CustomAnvil : JavaPlugin() {
// stop plugin if we force a safe start (false by default) // stop plugin if we force a safe start (false by default)
// Return true if start was stopped // Return true if start was stopped
private fun trySafeStart(): Boolean { private fun trySafeStart(): Boolean {
if(ConfigHolder.DEFAULT_CONFIG == null) return false
if(ConfigHolder.DEFAULT_CONFIG.config.getBoolean("safe_start", false)) { if(ConfigHolder.DEFAULT_CONFIG.config.getBoolean("safe_start", false)) {
Bukkit.getPluginManager().disablePlugin(this) Bukkit.getPluginManager().disablePlugin(this)
return true return true
@ -135,39 +150,45 @@ open class CustomAnvil : JavaPlugin() {
*/ */
override fun onEnable() { override fun onEnable() {
instance = this instance = this
try {
legacyCheck()
} catch (e: Exception) {
logger.log(Level.SEVERE, "error trying to check for legacy system", e)
MetricsUtil.trackError(e)
if(trySafeStart()) return
}
// Add commands
try {
CustomAnvilCommand(this)
} catch (e: Exception) {
logger.log(Level.SEVERE, "error trying to register commands", e)
MetricsUtil.trackError(e)
if(trySafeStart()) return
}
// Load default configuration // Load default configuration
try { try {
if(!ConfigHolder.loadDefaultConfig()) if(!ConfigHolder.loadDefaultConfig())
throw RuntimeException("Error loading configuration file") throw RuntimeException("Error loading configuration file")
} catch (e: Exception) { } catch (e: Exception) {
logger.log(Level.SEVERE, "error occurred loading default configuration", e) logError("error occurred loading default configuration", e)
MetricsUtil.trackError(e)
if(tryDirtyStart()) return if(tryDirtyStart()) return
} }
// Load language
try {
Lang.loadDefault()
} catch (e: Exception) {
logError("error occurred loading language file", e)
if(tryDirtyStart()) return
}
try {
legacyCheck()
} catch (e: Exception) {
MsgError.LOAD_LEGACY_FAILED.log(e)
if(trySafeStart()) return
}
// Add commands
try {
CustomAnvilCommand(this)
} catch (e: Exception) {
MsgError.LOAD_COMMAND_REGISTER.log(e)
if(trySafeStart()) return
}
// Load dependency // Load dependency
try { try {
DependencyManager.loadDependency() DependencyManager.loadDependency()
} catch (e: Exception) { } catch (e: Exception) {
logger.log(Level.SEVERE, "error loading dependency compatibility", e) MsgError.LOAD_COMPATIBILITY.log(e)
MetricsUtil.trackError(e)
if(tryDirtyStart()) return if(tryDirtyStart()) return
} }
@ -175,8 +196,7 @@ open class CustomAnvil : JavaPlugin() {
try { try {
registerListeners() registerListeners()
} catch (e: Exception) { } catch (e: Exception) {
logger.log(Level.SEVERE, "error registering listeners", e) MsgError.LOAD_LISTENERS.log(e)
MetricsUtil.trackError(e)
if(tryDirtyStart()) return if(tryDirtyStart()) return
} }
@ -192,33 +212,20 @@ open class CustomAnvil : JavaPlugin() {
MetricsUtil.shutdownMetrics() MetricsUtil.shutdownMetrics()
} }
private fun loadEnchantmentSystemDirty() {
try {
loadEnchantmentSystem()
} catch (e: Exception) {
logger.log(Level.SEVERE, "error initializing enchantment system", e)
MetricsUtil.trackError(e)
tryDirtyStart()
}
}
private fun legacyCheck() { private fun legacyCheck() {
// Disable old plugin name if exist // Disable old plugin name if exist
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
if (potentialPlugin != null) { if (potentialPlugin != null) {
Bukkit.getPluginManager().disablePlugin(potentialPlugin) Bukkit.getPluginManager().disablePlugin(potentialPlugin)
logger.warning("An old version of this plugin was detected") MsgWarning.LOAD_LEGACY_OLD_NAME.log()
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
} }
val isPaper = PlatformUtil.isPaper val isPaper = PlatformUtil.isPaper
if(!isPaper) { if(!isPaper) {
logger.warning("It seems you are using spigot") MsgWarning.LOAD_LEGACY_SPIGOT.log()
logger.warning("Please take notice that spigot is less supported than paper and derivatives") if(MinecraftVersionUtil.isTooNewForSpigot)
if(MinecraftVersionUtil.isTooNewForSpigot) { MsgWarning.LOAD_LEGACY_SPIGOT_OLD.log()
logger.warning("If replace too expensive is not working this is likely because of spigot")
logger.warning("As native nms is not supported for spigot starting 26.1")
}
} }
val loader = if(isPaper) "paper" else "spigot" val loader = if(isPaper) "paper" else "spigot"
@ -230,13 +237,13 @@ open class CustomAnvil : JavaPlugin() {
UpdateUtils.currentMinecraftVersion().toString()) UpdateUtils.currentMinecraftVersion().toString())
.setFeatured(featured) .setFeatured(featured)
.setOnError { .setOnError {
logger.log(Level.WARNING, "error trying to fetch latest update", it) MsgError.LOAD_UPDATE_CHECK_FAIL.log(it, level = Level.WARNING, track = false)
} }
.checkVersion { latestVer: String? -> .checkVersion { latestVer: String? ->
CustomAnvil.latestVer = latestVer CustomAnvil.latestVer = latestVer
if(latestVer == null || version.contains(latestVer)) return@checkVersion if(latestVer == null || version.contains(latestVer)) return@checkVersion
logger.warning("An update may be available: $latestVer") MsgWarning.LOAD_UPDATE_AVAILABLE.log(latestVer)
} }
} }
@ -251,6 +258,15 @@ open class CustomAnvil : JavaPlugin() {
server.pluginManager.registerEvents(AnvilCloseListener(DependencyManager.packetManager), this) server.pluginManager.registerEvents(AnvilCloseListener(DependencyManager.packetManager), this)
} }
private fun loadEnchantmentSystemDirty() {
try {
loadEnchantmentSystem()
} catch (e: Exception) {
MsgError.LOAD_ENCHANT_SYSTEM.log(e)
tryDirtyStart()
}
}
private fun loadEnchantmentSystem(){ private fun loadEnchantmentSystem(){
// Register enchantments // Register enchantments
CAEnchantmentRegistry.getInstance().registerBukkit() CAEnchantmentRegistry.getInstance().registerBukkit()
@ -261,7 +277,7 @@ open class CustomAnvil : JavaPlugin() {
// Load config // Load config
if (!ConfigHolder.loadNonDefaultConfig()) { if (!ConfigHolder.loadNonDefaultConfig()) {
logger.log(Level.SEVERE,"Plugin has an issue while trying to load non default config... exiting...") MsgError.LOAD_NON_DEFAULT_CONFIG.log()
server.pluginManager.disablePlugin(this) server.pluginManager.disablePlugin(this)
return return
} }
@ -315,16 +331,15 @@ open class CustomAnvil : JavaPlugin() {
try { try {
val configReader = FileReader(resourceFile) val configReader = FileReader(resourceFile)
yamlConfig.load(configReader) yamlConfig.load(configReader)
} catch (test: Exception) { } catch (e: Exception) {
MsgError.RELOAD_FAIL.log(e, resourceFile.path)
if (hardFailSafe) { if (hardFailSafe) {
// This is important and may impact gameplay if it does not load. // This is important and may impact gameplay if it does not load.
// Failsafe is to stop the plugin // Failsafe is to stop the plugin
logger.severe("Resource ${resourceFile.path} Could not be load or reload.") MsgError.RELOAD_HARD_FAIL.log()
logger.severe("Disabling plugin.")
Bukkit.getPluginManager().disablePlugin(this) Bukkit.getPluginManager().disablePlugin(this)
} else {
logger.warning("Resource ${resourceFile.path} Could not be load or reload.")
} }
return null return null
} }
return yamlConfig return yamlConfig

View file

@ -22,9 +22,9 @@ import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.CasedStringUtil import xyz.alexcrea.cuanvil.util.CasedStringUtil
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
@ -151,7 +151,7 @@ object AnvilMergeLogic {
) )
if (component != null) { if (component != null) {
renameText = MiniMessageUtil.legacy_mm.serialize(component) renameText = component.serializeLegacy()
sumCost += ConfigOptions.useOfColorCost sumCost += ConfigOptions.useOfColorCost
useColor = true useColor = true

View file

@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.command
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.lang.Message
interface CASubCommand { interface CASubCommand {
@ -21,7 +22,7 @@ interface CASubCommand {
list: MutableList<String> list: MutableList<String>
) )
fun description(): String fun description(): Message
fun allEnchantmentsByName(): Collection<String> { fun allEnchantmentsByName(): Collection<String> {
val names = mutableSetOf<String>() val names = mutableSetOf<String>()

View file

@ -6,7 +6,7 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter import org.bukkit.command.TabCompleter
import xyz.alexcrea.cuanvil.util.MetricsUtil import xyz.alexcrea.cuanvil.lang.MsgCommand
class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
@ -57,15 +57,15 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
} }
if (subcmd == null || !subcmd.allowed(sender)) { if (subcmd == null || !subcmd.allowed(sender)) {
sender.sendMessage("Invalid subcommand. run `$cmdstr help` to see available commands") MsgCommand.ROOT_UNKNOWN_SUBCOMMAND.send(sender, cmdstr)
return true return true
} }
try { try {
return subcmd.executeCommand(sender, cmd, subcmdStr, newargs) return subcmd.executeCommand(sender, cmd, subcmdStr, newargs)
} catch (e: Throwable) { } catch (e: Throwable) {
MetricsUtil.trackError(e) CustomAnvil.logError("Error running /$cmdstr ${args.joinToString(" ")}", e)
sender.sendMessage("§cError running this command") MsgCommand.ROOT_ERROR_SUBCOMMAND.send(sender)
return false return false
} }
} }

View file

@ -6,16 +6,22 @@ import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent import net.md_5.bungee.api.chat.TextComponent
import net.md_5.bungee.api.chat.hover.content.Text import net.md_5.bungee.api.chat.hover.content.Text
import org.bukkit.ChatColor
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.command.DiagnosticExecutor.Companion.NO_DIAG_PERM import xyz.alexcrea.cuanvil.lang.Lang
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.lang.MsgError
import xyz.alexcrea.cuanvil.lang.MsgUI
import xyz.alexcrea.cuanvil.lang.MsgWarning
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import java.util.Locale
class DebugToggleExecutor : CASubCommand { class DebugToggleExecutor: CASubCommand {
override fun description(): String { override fun description(): Message {
return "Used to toggle debug logs and retrieve it" return MsgCommand.DEBUG_DESCRIPTION
} }
override fun allowed(sender: CommandSender): Boolean { override fun allowed(sender: CommandSender): Boolean {
@ -26,18 +32,18 @@ class DebugToggleExecutor : CASubCommand {
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>,
): Boolean { ): Boolean {
if (!allowed(sender)) { if(!allowed(sender)) {
sender.sendMessage(NO_DIAG_PERM) MsgCommand.SHARED_NO_DIAG_PERM.send(sender)
return false return false
} }
if (args.isEmpty()) { if(args.isEmpty()) {
sender.sendMessage("Need to specify a subcommand: \"toggle\" or \"get\"") MsgCommand.SHARED_MISSING_SUBCOMMAND.send(sender, "\"toggle\"", "\"get\"")
return true return true
} }
when (args[0].lowercase()) { when(args[0].lowercase()) {
"toggle" -> executeToggle(sender, args) "toggle" -> executeToggle(sender, args)
"get" -> executeGet(sender) "get" -> executeGet(sender)
"get-and-clear" -> { "get-and-clear" -> {
@ -47,67 +53,216 @@ class DebugToggleExecutor : CASubCommand {
"clear" -> { "clear" -> {
CustomAnvil.debugStorageQueue.clear() CustomAnvil.debugStorageQueue.clear()
sender.sendMessage("Log Cleared") MsgCommand.DEBUG_LOG_CLEARED.send(sender)
} }
else -> return false "lang" -> {
executeLanguageDebug(sender, args)
}
else -> {
MsgCommand.SHARED_UNKNOWN_SUB_COMMAND.send(sender)
return false
}
} }
return true return true
} }
private fun executeToggle(sender: CommandSender, args: Array<out String>) { private fun executeToggle(sender: CommandSender, args: Array<out String>) {
if (args.size < 2) { if(args.size < 2) {
sender.sendMessage("Need to specify which type of debug to toggle: \"default\" or \"verbose\"") MsgCommand.DEBUG_WARNING_UNSPECIFIED_TYPE.send(sender)
return return
} }
when (args[1].lowercase()) { when(args[1].lowercase()) {
"default" -> { "default" -> {
ConfigOptions.OVERRIDE_DEBUG_LOG = !ConfigOptions.debugLog ConfigOptions.OVERRIDE_DEBUG_LOG = !ConfigOptions.debugLog
sender.sendMessage("Debug toggle to: ${ConfigOptions.debugLog}") MsgCommand.DEBUG_TOGGLED.send(sender, ConfigOptions.debugLog)
} }
"verbose" -> { "verbose" -> {
ConfigOptions.OVERRIDE_VERBOSE_DEBUG_LOG = !ConfigOptions.verboseDebugLog ConfigOptions.OVERRIDE_VERBOSE_DEBUG_LOG = !ConfigOptions.verboseDebugLog
sender.sendMessage("Debug toggle to: ${ConfigOptions.verboseDebugLog}") MsgCommand.DEBUG_TOGGLED.send(sender, ConfigOptions.debugLog)
} }
else -> sender.sendMessage("Invalid debug type: ${args[1]}") else -> MsgCommand.DEBUG_WARNING_INVALID_TYPE.send(sender, ConfigOptions.debugLog)
} }
} }
private fun executeGet(sender: CommandSender) { private fun executeGet(sender: CommandSender) {
val stb = StringBuilder("Debug Log data:") if(CustomAnvil.debugStorageQueue.isEmpty()) {
if (CustomAnvil.debugStorageQueue.isEmpty()) { MsgCommand.DEBUG_WARNING_NO_LOG.send(sender, "/ca debug toggle")
sender.sendMessage("No log to show ? make sure you tried with debug log toggled (/ca debug toggle)")
return return
} }
stb.append("\nFound ${CustomAnvil.debugStorageQueue.size} lines\n") val stb = StringBuilder(MsgCommand.DEBUG_DATA_HEADER.unformatted()).append(' ')
for (log in CustomAnvil.debugStorageQueue) { stb.append(MsgCommand.DEBUG_DATA_LINE_COUNT.unformatted(CustomAnvil.debugStorageQueue.size))
stb.append('\n').append(log) for(log in CustomAnvil.debugStorageQueue) {
stb.append('\n').append(log.serializePlain())
} }
if (sender is Player) { if(sender is Player) {
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy log data") val message = TextComponent(MsgCommand.DEBUG_COPY.legacy())
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy")) message.hoverEvent = HoverEvent(
HoverEvent.Action.SHOW_TEXT,
Text(MsgCommand.SHARED_HOVER_COPY.legacy())
)
sender.spigot().sendMessage(message); sender.spigot().sendMessage(message)
} else { } else {
sender.sendMessage(stb.toString()) sender.sendMessage(stb.toString())
} }
} }
private fun executeLanguageDebug(sender: CommandSender, args: Array<out String>) {
if(args.size > 1 && "details".contentEquals(args[1], ignoreCase = true))
detailedLangDebug(sender)
else
simpleLangDebug(sender)
}
private fun simpleLangDebug(sender: CommandSender) {
var validCount = 0
// load key from all provider class
MsgCommand.DEBUG_DATA_HEADER
MsgUI.SHARED_CONFIG_NO_EDIT_PERM
MsgError.LOAD_LISTENERS
MsgWarning.ANVIL_GENERIC_EXCEPTION
val registeredKeys = Message.getValues()
for(message in registeredKeys)
if(Lang.has(message.key)) validCount++
val valid = (100.0 * validCount) / registeredKeys.size
sender.sendMessage(
"Translated (${Lang.currentLang()}): ${
"%.1f".format(
Locale.ROOT,
valid
)
}% ($validCount/${registeredKeys.size})"
)
}
private fun detailedLangDebug(sender: CommandSender) {
simpleLangDebug(sender)
val stb = StringBuilder("Report of potential issue for language ${Lang.currentLang()}:\n")
var hadAny = false
val keySet = mutableSetOf<String>()
val registeredKeys = Message.getValues()
for(message in registeredKeys) {
val key = message.key
if(!Lang.has(key)) {
stb.append("Missing key inside translation file: $key\n")
hadAny = true
} else if(hashParamIssue(message, stb))
hadAny = true
if(keySet.contains(key)) {
stb.append("Duplicate registered key: $key\n")
hadAny = true
} else keySet.add(key)
}
for(key in Lang.getKeys()) {
if(!keySet.contains(key)) {
stb.append("Found unregistered key: $key\n")
hadAny = true
}
}
if(hadAny) {
val message = TextComponent(MsgCommand.DEBUG_LANG_COPY.legacy())
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
message.hoverEvent = HoverEvent(
HoverEvent.Action.SHOW_TEXT,
Text(MsgCommand.SHARED_HOVER_COPY.legacy())
)
sender.spigot().sendMessage(message)
} else {
sender.sendMessage("No additional issue found")
}
}
private fun hashParamIssue(message: Message, stb: StringBuilder): Boolean {
val section = Lang.getSection(message.key)
val texts = if(section == null)
listOf(Lang.getTranslated(message.key))
else
section.getValues(false).map {it.value.toString()}
val textParams = ArrayList<String>()
for(text in texts) {
var index = 0
while(true) {
index = text.indexOf('%', index)
if(index > 0 && text[index - 1] == '\\') {
index++
continue
}
if(index++ < 0) break
var end = text.indexOf(' ', index)
if(end == -1) end = text.length
val param = text.substring(index, end)
if(!textParams.contains(param)) textParams.add(param)
}
}
var hadIssue = false
// Check all parameter are valid
val usedParam = mutableSetOf<String>()
for(textParam in textParams) {
var found = false
for(param in message.params) {
if(param == null) continue
if(textParam.startsWith(param)) {
found = true
usedParam.add(param)
break
}
}
if(found) break
hadIssue = true
stb.append("Did not found param %$textParam in register list for ${message.key}\n")
}
for(param in message.params) {
if(param == null) continue
var found = false
for(used in usedParam) {
if(!used.startsWith(param)) continue
found = true
break
}
if(found) continue
hadIssue = true
stb.append("Param %$param is not used for key ${message.key}\n")
}
return hadIssue
}
override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) { override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) {
if (!allowed(sender)) return if(!allowed(sender)) return
list.addAll( list.addAll(
when (args.size) { when(args.size) {
1 -> listOf("toggle", "get", "get-and-clear", "clear") 1 -> listOf("toggle", "get", "get-and-clear", "clear", "lang")
2 -> when (args[0].lowercase()) { 2 -> when(args[0].lowercase()) {
"toggle" -> listOf("default", "verbose") "toggle" -> listOf("default", "verbose")
"lang" -> listOf("details")
else -> listOf() else -> listOf()
} }

View file

@ -6,7 +6,6 @@ import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent import net.md_5.bungee.api.chat.TextComponent
import net.md_5.bungee.api.chat.hover.content.Text import net.md_5.bungee.api.chat.hover.content.Text
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
@ -25,15 +24,17 @@ import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager
import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.MetricsUtil import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.util.* import java.util.*
import java.util.stream.Collectors import java.util.stream.Collectors
@Suppress("UnstableApiUsage")
class DiagnosticExecutor : CASubCommand { class DiagnosticExecutor : CASubCommand {
companion object { companion object {
const val NO_DIAG_PERM = "You do not have permission to diagnostic this server"
fun fetchNMSType(): String { fun fetchNMSType(): String {
val packetManager = DependencyManager.packetManager val packetManager = DependencyManager.packetManager
@ -101,7 +102,7 @@ class DiagnosticExecutor : CASubCommand {
args: Array<out String> args: Array<out String>
): Boolean { ): Boolean {
if (!allowed(sender)) { if (!allowed(sender)) {
sender.sendMessage(NO_DIAG_PERM) MsgCommand.SHARED_NO_DIAG_PERM.send(sender)
return false return false
} }
@ -122,12 +123,11 @@ class DiagnosticExecutor : CASubCommand {
if (sender is HumanEntity) { if (sender is HumanEntity) {
if (hasError) if (hasError)
sender.spigot() MsgCommand.DIAGNOSTIC_ERROR_GENERIC.send(sender)
.sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic")) val message = TextComponent(MsgCommand.DIAGNOSTIC_COPY.legacy())
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data")
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy")) message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text(MsgCommand.SHARED_HOVER_COPY.legacy()))
sender.spigot().sendMessage(message) sender.spigot().sendMessage(message)
} else { } else {
@ -214,13 +214,13 @@ class DiagnosticExecutor : CASubCommand {
return this.name + " v" + this.description.version return this.name + " v" + this.description.version
} }
override fun description(): String { override fun description(): Message {
return "Basic diagnostic of this plugin" return MsgCommand.DIAGNOSTIC_DESCRIPTION
} }
private fun pluginListDiag(sender: CommandSender, stb: StringBuilder) { private fun pluginListDiag(sender: CommandSender, stb: StringBuilder) {
val enabledPlugins: MutableList<Plugin?> = ArrayList<Plugin?>() val enabledPlugins: MutableList<Plugin?> = ArrayList()
val disabledPlugins: MutableList<Plugin?> = ArrayList<Plugin?>() val disabledPlugins: MutableList<Plugin?> = ArrayList()
for (plugin in Bukkit.getPluginManager().plugins) { for (plugin in Bukkit.getPluginManager().plugins) {
if (plugin.isEnabled) { if (plugin.isEnabled) {
enabledPlugins.add(plugin) enabledPlugins.add(plugin)

View file

@ -10,7 +10,9 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui
import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.lang.MsgUI
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
@ -20,42 +22,38 @@ class EditConfigExecutor : CASubCommand {
return sender.hasPermission(CustomAnvil.editConfigPermission) return sender.hasPermission(CustomAnvil.editConfigPermission)
} }
override fun description(): String { override fun description(): Message {
return "Gui to edit the plugin's config" return MsgCommand.CONFIG_DESCRIPTION
} }
override fun executeCommand( override fun executeCommand(
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>,
): Boolean { ): Boolean {
if (sender !is HumanEntity) return false if(sender !is HumanEntity) return false
if (!allowed(sender)) { if(!allowed(sender)) {
sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) MsgUI.SHARED_CONFIG_NO_EDIT_PERM.send(sender)
return false return false
} }
if (PlatformUtil.isFolia) { if(PlatformUtil.isFolia) {
sender.sendMessage("§cIt look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia.") MsgCommand.CONFIG_FOLIA_ISSUE.send(sender)
sender.sendMessage("§eIt is may come in a future version.")
sender.sendMessage("")
sender.sendMessage("§eCurrently you need to edit manually the config or copy from another server (spigot or better)")
sender.sendMessage("§eThen /ca reload after config file is edited")
return false return false
} }
if ("gui".equals(cmdstr, ignoreCase = true)) { if("gui".equals(cmdstr, ignoreCase = true)) {
sender.sendMessage("§c/ca gui has been moved to /ca config") MsgCommand.CONFIG_LEGACY_NAME_WARNING.send(sender)
} }
if (args.isEmpty()) if(args.isEmpty())
processOpen(sender) processOpen(sender)
else when (args[0].lowercase()) { else when(args[0].lowercase()) {
"open" -> processOpen(sender) "open" -> processOpen(sender)
"enchant" -> processEnchant(sender, args) "enchant" -> processEnchant(sender, args)
"item" -> processItem(sender) "item" -> processItem(sender)
else -> sender.sendMessage("Unknown subcommand \"${args[0]}\"") else -> MsgCommand.SHARED_UNKNOWN_SUB_COMMAND.send(sender)
} }
return true return true
@ -63,31 +61,30 @@ class EditConfigExecutor : CASubCommand {
private fun processEnchant(sender: HumanEntity, args: Array<out String>) { private fun processEnchant(sender: HumanEntity, args: Array<out String>) {
val enchantToFilter: Set<CAEnchantment> val enchantToFilter: Set<CAEnchantment>
if (args.size <= 1) { if(args.size <= 1) {
val item = sender.inventory.itemInMainHand val item = sender.inventory.itemInMainHand
enchantToFilter = EnchantmentApi.getEnchantments(item).keys enchantToFilter = EnchantmentApi.getEnchantments(item).keys
if (enchantToFilter.isEmpty()) { if(enchantToFilter.isEmpty()) {
sender.sendMessage("No enchantment found in the item you are holding") MsgCommand.CONFIG_ENCHANTMENT_NO_IN_HAND.send(sender)
return return
} }
} else { } else {
enchantToFilter = HashSet(EnchantmentApi.getByName(args[1].lowercase())) enchantToFilter = HashSet(EnchantmentApi.getByName(args[1].lowercase()))
if (enchantToFilter.isEmpty()) { if(enchantToFilter.isEmpty()) {
sender.sendMessage("No enchantment found with the name \"${args[1]}\"") MsgCommand.CONFIG_ENCHANTMENT_NO_NAME.send(sender, args[1])
return return
} }
} }
EnchantConfigGui(enchantToFilter).show(sender) EnchantConfigGui(enchantToFilter).show(sender)
} }
private fun processItem(sender: HumanEntity) { private fun processItem(sender: HumanEntity) {
val item = sender.inventory.itemInMainHand val item = sender.inventory.itemInMainHand
if (item.isAir) { if(item.isAir) {
sender.sendMessage("Cannot configure the item in hand") MsgCommand.CONFIG_CANNOT_CONFIGURE_WARNING.send(sender)
return return
} }
@ -104,10 +101,10 @@ class EditConfigExecutor : CASubCommand {
override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) { override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) {
list.addAll( list.addAll(
when (args.size) { when(args.size) {
1 -> listOf("item", "enchant", "open") 1 -> listOf("item", "enchant", "open")
2 -> { 2 -> {
when (args[0].lowercase()) { when(args[0].lowercase()) {
"enchant" -> allEnchantmentsByName() "enchant" -> allEnchantmentsByName()
else -> listOf() else -> listOf()
} }

View file

@ -10,6 +10,8 @@ import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
class EnchantExecutor : CASubCommand { class EnchantExecutor : CASubCommand {
@ -19,74 +21,74 @@ class EnchantExecutor : CASubCommand {
return sender.hasPermission(CustomAnvil.giveEnchantmentPermission) return sender.hasPermission(CustomAnvil.giveEnchantmentPermission)
} }
override fun description(): String { override fun description(): Message {
return "Allows to set enchantment to holden item" return MsgCommand.ENCHANT_DESCRIPTION
} }
override fun executeCommand( override fun executeCommand(
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>,
): Boolean { ): Boolean {
if (sender !is HumanEntity) return true if(sender !is HumanEntity) return true
if (!allowed(sender)) { if(!allowed(sender)) {
sender.sendMessage("No permission to execute this command") MsgCommand.SHARED_NO_PERMISSION.send(sender)
return true return true
} }
when (args.size) { when(args.size) {
0 -> { 0 -> {
sender.sendMessage("Missing enchantment parameter") MsgCommand.ENCHANT_MISSING_PARAMETER_WARNING.send(sender)
return true return true
} }
} }
val enchant = firstEnchantment(args[0]) val enchant = firstEnchantment(args[0])
if (enchant == null) { if(enchant == null) {
sender.sendMessage("Enchantment not found: ${args[0]}") MsgCommand.ENCHANT_NOT_FOUND_WARNING.send(sender, args[0])
return true return true
} }
val level = if (args.size > 1) val level = if(args.size > 1)
args[1].toIntOrNull()?.coerceIn(0, ConfigOptions.ENCHANT_LIMIT) args[1].toIntOrNull()?.coerceIn(0, ConfigOptions.ENCHANT_LIMIT)
else 1 else 1
if (level == null) { if(level == null) {
sender.sendMessage("Invalid number: ${args[1]}") MsgCommand.ENCHANT_MALFORMED_NUMBER_WARNING.send(sender, args[1])
return true return true
} }
val inHand = sender.inventory.itemInMainHand val inHand = sender.inventory.itemInMainHand
if (inHand.isAir) { if(inHand.isAir) {
sender.sendMessage("Cannot enchant this item") MsgCommand.ENCHANT_CANNOT_ENCHANT_WARNING.send(sender)
return true return true
} }
if (level == 0) { if(level == 0) {
enchant.removeFrom(inHand) enchant.removeFrom(inHand)
if (inHand.isEnchantedBook() && EnchantmentApi.getEnchantments(inHand).isEmpty()) if(inHand.isEnchantedBook() && EnchantmentApi.getEnchantments(inHand).isEmpty())
inHand.type = Material.BOOK inHand.type = Material.BOOK
sender.sendMessage("${enchant.prettyName} removed") MsgCommand.ENCHANT_REMOVE.send(sender, enchant.prettyName)
} else { } else {
if (Material.BOOK == inHand.type) if(Material.BOOK == inHand.type)
inHand.type = Material.ENCHANTED_BOOK inHand.type = Material.ENCHANTED_BOOK
enchant.addEnchantmentUnsafe(inHand, level) enchant.addEnchantmentUnsafe(inHand, level)
sender.sendMessage("${enchant.prettyName} set to level $level") MsgCommand.ENCHANT_SET.send(sender, enchant.prettyName, level)
} }
return true return true
} }
override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) { override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) {
if (sender !is HumanEntity) return if(sender !is HumanEntity) return
list.addAll( list.addAll(
when (args.size) { when(args.size) {
1 -> allEnchantmentsByName() 1 -> allEnchantmentsByName()
2 -> findEnchantmentLevels(sender, args[0]) 2 -> findEnchantmentLevels(sender, args[0])
@ -97,19 +99,19 @@ class EnchantExecutor : CASubCommand {
private fun findEnchantmentLevels( private fun findEnchantmentLevels(
sender: HumanEntity, sender: HumanEntity,
name: String name: String,
): Collection<String> { ): Collection<String> {
val enchant = firstEnchantment(name) ?: return listOf() val enchant = firstEnchantment(name) ?: return listOf()
val limit = ConfigOptions.enchantLimit(enchant) val limit = ConfigOptions.enchantLimit(enchant)
val result = mutableListOf<String>() val result = mutableListOf<String>()
for (i in 1 until limit + 1) { for(i in 1 until limit + 1) {
result.add(i.toString()) result.add(i.toString())
} }
val inHand = sender.inventory.itemInMainHand val inHand = sender.inventory.itemInMainHand
if (enchant.isEnchantmentPresent(inHand)) if(enchant.isEnchantmentPresent(inHand))
result.add("0") result.add("0")
return result return result
@ -117,7 +119,7 @@ class EnchantExecutor : CASubCommand {
private fun firstEnchantment(name: String): CAEnchantment? { private fun firstEnchantment(name: String): CAEnchantment? {
val enchants = EnchantmentApi.getByName(name.lowercase()) val enchants = EnchantmentApi.getByName(name.lowercase())
if (!enchants.isEmpty()) if(!enchants.isEmpty())
return enchants.iterator().next() return enchants.iterator().next()
return EnchantmentApi.getByKey(NamespacedKey.fromString(name)) return EnchantmentApi.getByKey(NamespacedKey.fromString(name))

View file

@ -1,29 +1,37 @@
package xyz.alexcrea.cuanvil.command package xyz.alexcrea.cuanvil.command
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import net.kyori.adventure.text.Component
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.ComponentUtil.send
class HelpExecutor : CASubCommand { class HelpExecutor : CASubCommand {
override fun description(): Message {
return MsgCommand.HELP_DESCRIPTION
}
lateinit var commands: ImmutableMap<String, CASubCommand> lateinit var commands: ImmutableMap<String, CASubCommand>
override fun executeCommand( override fun executeCommand(
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>,
): Boolean { ): Boolean {
var text = MsgCommand.HELP_HEADER.formatted().first()
for((key, cmd) in commands) {
if(!cmd.allowed(sender)) continue
val stb = StringBuilder("List of available commands:") text = text.appendNewline()
for ((key, cmd) in commands) { .append(Component.text("- $key: "))
if (!cmd.allowed(sender)) continue .append(cmd.description().formatted())
stb.append("\n- $key: ").append(cmd.description())
} }
sender.sendMessage(stb.toString()) text.send(sender)
return true return true
} }
@ -34,12 +42,8 @@ class HelpExecutor : CASubCommand {
override fun tabCompleter( override fun tabCompleter(
sender: CommandSender, sender: CommandSender,
args: Array<out String>, args: Array<out String>,
list: MutableList<String> list: MutableList<String>,
) { ) {
} }
override fun description(): String {
return "Help command"
}
} }

View file

@ -8,29 +8,36 @@ import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.gui.config.global.* import xyz.alexcrea.cuanvil.gui.config.global.*
import xyz.alexcrea.cuanvil.lang.Lang
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.update.UpdateHandler import xyz.alexcrea.cuanvil.update.UpdateHandler
class ReloadExecutor : CASubCommand { class ReloadExecutor : CASubCommand {
override fun description(): Message {
return MsgCommand.RELOAD_DESCRIPTION
}
override fun executeCommand( override fun executeCommand(
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>,
): Boolean { ): Boolean {
if (!allowed(sender)) { if(!allowed(sender)) {
sender.sendMessage("§cYou do not have permission to reload the config") MsgCommand.SHARED_NO_PERMISSION.send(sender)
return false return false
} }
sender.sendMessage("§eReloading config...") MsgCommand.RELOAD_START.send(sender)
val hardfail = args.isNotEmpty() && ("hard".equals(args[0], true)) val hardfail = args.isNotEmpty() && ("hard".equals(args[0], true))
val commandSuccess = commandBody(hardfail) val commandSuccess = commandBody(hardfail)
if (commandSuccess) { if(commandSuccess) {
sender.sendMessage("§aConfig reloaded !") MsgCommand.RELOAD_SUCCESS.send(sender)
} else { } else {
sender.sendMessage("§cConfig was not able to be reloaded...") MsgCommand.RELOAD_FAIL.send(sender)
if (hardfail) { if(hardfail) {
sender.sendMessage("§4Hard fail, plugin disabled") MsgCommand.RELOAD_HARD_FAIL.send(sender)
} }
} }
return commandSuccess return commandSuccess
@ -43,20 +50,19 @@ class ReloadExecutor : CASubCommand {
override fun tabCompleter( override fun tabCompleter(
sender: CommandSender, sender: CommandSender,
args: Array<out String>, args: Array<out String>,
list: MutableList<String> list: MutableList<String>,
) { ) {
} }
override fun description(): String {
return "Reload the configuration of this plugin"
}
/** /**
* Execute the command, return true if success or false otherwise * Execute the command, return true if success or false otherwise
*/ */
private fun commandBody(hardfail: Boolean): Boolean { private fun commandBody(hardfail: Boolean): Boolean {
try { try {
if (!ConfigHolder.reloadAllFromDisk(hardfail)) return false if(!ConfigHolder.reloadAllFromDisk(hardfail)) return false
// reload language config
if(!Lang.reload()) return false
// Then update all global gui containing value from config // Then update all global gui containing value from config
BasicConfigGui.getInstance()?.updateGuiValues() BasicConfigGui.getInstance()?.updateGuiValues()
@ -79,7 +85,7 @@ class ReloadExecutor : CASubCommand {
Bukkit.getServer().pluginManager.callEvent(configReadyEvent) Bukkit.getServer().pluginManager.callEvent(configReadyEvent)
return true return true
} catch (e: Exception) { } catch(e: Exception) {
e.printStackTrace() e.printStackTrace()
return false return false
} }

View file

@ -3,7 +3,6 @@ package xyz.alexcrea.cuanvil.dependency
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
@ -28,10 +27,10 @@ import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler
import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.lang.MsgWarning
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
import java.lang.IllegalStateException import java.lang.IllegalStateException
import java.util.logging.Level
@Suppress("UnstableApiUsage") @Suppress("UnstableApiUsage")
object DependencyManager { object DependencyManager {
@ -158,18 +157,14 @@ object DependencyManager {
} }
private fun logException(target: CommandSender, e: Exception) { private fun logException(target: CommandSender, e: Exception) {
CustomAnvil.instance.logger.log( CustomAnvil.logError(
Level.SEVERE,
"Error while trying to handle custom anvil supported plugin: ", "Error while trying to handle custom anvil supported plugin: ",
e e
) )
trackError(e) trackError(e)
// Finally, warn the player // Finally, warn the player
target.sendMessage( MsgWarning.ANVIL_GENERIC_EXCEPTION.send(target)
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
} }
private fun logExceptionAndClear(view: AnvilView, e: Exception) { private fun logExceptionAndClear(view: AnvilView, e: Exception) {

View file

@ -0,0 +1,83 @@
package xyz.alexcrea.cuanvil.lang
import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection
import xyz.alexcrea.cuanvil.config.ConfigHolder
import java.util.stream.Stream
object Lang {
private lateinit var default: Language
private lateinit var lang: Language
fun loadDefault() {
default = Language(DEFAULT_LANG, false)
lang = default
reload()
}
fun reload(): Boolean {
try {
unsafeReload()
return true
} catch(e: Exception) {
CustomAnvil.logError("Error loading language $langID", e, false)
return false
}
}
private fun unsafeReload() {
val langID = langID
if(lang.name == langID && lang != default)
lang.reload()
else
lang = Language(langID)
if(default != lang) default.reload()
}
fun getTranslated(key: String): String {
val value = lang.get(key)
if(value != null) return value
CustomAnvil.log("Missing language data for ${lang.name} using default")
return default.get(key) ?: key
}
fun getSection(key: String): ConfigurationSection? {
val value = lang.getSection(key)
if(value != null) return value
return default.getSection(key)
}
fun currentLang(): String {
return lang.name
}
fun has(key: String): Boolean {
return lang.has(key)
}
fun getKeys(): Collection<String> {
return lang.getFilteredKeys()
}
/*
* Config Options & get
*/
const val LANG_PATH = "language"
const val DEFAULT_LANG = "en"
/**
* Value of an item rename
*/
private val langID: String
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getString(LANG_PATH, DEFAULT_LANG)!!
}
}

View file

@ -0,0 +1,99 @@
package xyz.alexcrea.cuanvil.lang
import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.FileConfiguration
import org.bukkit.configuration.file.YamlConfiguration
import java.io.File
import java.io.InputStreamReader
import java.util.logging.Level
class Language(private val id: String, private val default: Boolean = false) {
private val resourcePath: String
private val file: File
private val conf: FileConfiguration
init {
conf = YamlConfiguration()
resourcePath = "lang/$id.yml"
file = File(CustomAnvil.instance.dataFolder, resourcePath)
reload()
}
fun reload() {
if(file.exists() && !default) try {
conf.load(file)
return
} catch(e: Exception) {
CustomAnvil.instance.logger.log(
Level.SEVERE,
"Could not load custom Anvil config file. using to internal resource",
e
)
}
loadInternalResource()
}
private fun loadInternalResource() {
val input = CustomAnvil.instance.getResource(resourcePath)
if(input != null)
conf.load(InputStreamReader(input))
else
CustomAnvil.instance.logger.log(Level.SEVERE, "Language $id not found")
}
fun get(key: String): String? {
return conf.getString(key)
}
fun getSection(key: String): ConfigurationSection? {
return conf.getConfigurationSection(key)
}
fun has(key: String): Boolean {
if(conf.isString(key)) return true
// we want at all child key as valid numbers and valid key if claimed to be multi line
val section = getSection(key) ?: return false
for(key in section.getKeys(false)) {
if(key.toUIntOrNull() == null) return false
if(!section.isString(key)) return false
}
return true
}
fun getFilteredKeys(): Collection<String> {
val result = ArrayList<String>()
// First pass we ignore key from root
for(root in conf.getKeys(false)) {
val section = conf.getConfigurationSection(root) ?: continue
exploreDeeper(section, root, result)
}
return result
}
private fun exploreDeeper(section: ConfigurationSection, root: String, result: ArrayList<String>) {
for(key in section.getKeys(false)) {
val newRoot = "$root.$key"
if(has(key)) {
result.add(newRoot)
continue
}
val newSection = section.getConfigurationSection(key) ?: continue
exploreDeeper(newSection, newRoot, result)
}
}
val name: String
get() = conf.getString("name", id)!!
}

View file

@ -0,0 +1,212 @@
package xyz.alexcrea.cuanvil.lang
import com.github.stefvanschie.inventoryframework.adventuresupport.ComponentHolder
import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder
import io.delilaheve.CustomAnvil
import net.kyori.adventure.text.Component
import org.bukkit.command.CommandSender
import org.bukkit.configuration.ConfigurationSection
import xyz.alexcrea.cuanvil.util.ComponentUtil.send
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import java.util.Collections
import java.util.logging.Level
import kotlin.math.max
import kotlin.math.min
open class Message(val key: String, vararg val params: String?, register: Boolean = true) {
companion object {
private val values = ArrayList<Message>()
fun getValues(): Collection<Message> {
return Collections.unmodifiableCollection(values)
}
}
init {
if(register) values.add(this)
}
protected fun replaceParameters(stb: StringBuilder, vararg values: Any?) {
// replace all placeholder thingy %key -> value
if(params.size != values.size) {
CustomAnvil.log("Wrong number of argument for parameter for key $key (${params.size}/${values.size})")
for(i in 0 until max(params.size, values.size)) {
val key = if(i >= params.size) "NOT KEY"
else params[i]
val value = if(i >= values.size) "NOT VALUE"
else values[i]
CustomAnvil.log("Parameter ${i + 1} is $key with value $value")
}
}
var foundBackslashPercent = false
for(i in 0 until min(params.size, values.size)) {
val key = params[i] ?: continue
val value = values[i]
if(value == null) {
CustomAnvil.log("Passed a null value for key ${this.key} for Parameter $key (${i + 1})")
continue
}
val replacement = value.toString()
if(replacement.isEmpty()) continue //May not be good but can be changed if cause an issue //TODO REPLACE WITH NULL
var current = 0
while(true) {
current = stb.indexOf('%', current)
if(current > 0 && stb[current - 1] == '\\') {
foundBackslashPercent = true
continue
}
if(++current <= 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ?
if(!stb.startsWith(key, current, false)) continue
stb.replace(current - 1, current + key.length, replacement)
current = current - 1 + replacement.length
}
}
if(foundBackslashPercent) {
// Remove the \% to \
var current = 0
while(true) {
current = stb.indexOf("\\%", current)
if(current < 0) break
stb.replace(current, current + 2, "%")
current++
}
}
}
private fun unformattedMonoline(vararg params: Any?): String {
val translated = Lang.getTranslated(key)
if(params.isEmpty() && this.params.isEmpty()) return translated
val stb = StringBuilder(translated)
replaceParameters(stb, *params)
return stb.toString()
}
private fun unformattedMultiline(section: ConfigurationSection, vararg params: Any?): String {
val stb = StringBuilder()
for(key in section.getKeys(false)) {
if(!section.isString(key)) continue
if(!stb.isEmpty()) stb.append('\n')
stb.append(section.getString(key))
}
replaceParameters(stb, *params)
return stb.toString()
}
fun unformatted(vararg params: Any?): String {
val section = Lang.getSection(key)
if(section != null) return unformattedMultiline(section, *params)
return unformattedMonoline(*params)
}
private fun formattedMultiline(section: ConfigurationSection, vararg params: Any?): MutableList<Component> {
val result = ArrayList<Component>()
for(key in section.getKeys(false)) {
if(!section.isString(key)) continue
val stb = StringBuilder(section.getString(key))
replaceParameters(stb, *params)
result.add(MiniMessageUtil.mm.deserialize(stb.toString()))
}
if(result.isEmpty()) return mutableListOf(Component.text(key))
return result
}
// return a list of AT LEAST 1 element. calling first is safe
fun formatted(vararg params: Any?): MutableList<Component> {
val section = Lang.getSection(key)
if(section != null) return formattedMultiline(section, *params)
val translated = unformattedMonoline(*params)
return mutableListOf(MiniMessageUtil.mm.deserialize(translated))
}
fun formattedConcatenated(vararg params: Any?): Component {
val formated = formatted(*params)
var result = formated.first()
for(i in 1 until formated.size) {
result = result.appendNewline().append(formated[i])
}
return result
}
fun textHolder(vararg params: Any?): TextHolder {
return ComponentHolder.of(formattedConcatenated(*params))
}
fun legacy(vararg params: Any?): String {
val formated = formatted(*params)
val stb = StringBuilder()
for(component in formated) {
if(!stb.isEmpty()) stb.append('\n')
stb.append(component.serializeLegacy())
}
return stb.toString()
}
open fun log(vararg params: Any?) {
val texts = formatted(*params)
for(component in texts) {
CustomAnvil.instance.logger.info(component.serializePlain())
}
}
open fun send(destination: CommandSender, vararg params: Any?) {
formatted(*params).send(destination)
}
}
class WarningMessage(key: String, vararg params: String): Message("warning.$key", *params) {
override fun log(vararg params: Any?) {
val texts = formatted(*params)
for(component in texts) {
CustomAnvil.instance.logger.warning(component.serializePlain())
}
}
}
class ErrorMessage(key: String, vararg params: String): Message("error.$key", *params) {
override fun log(vararg params: Any?) {
val texts = formatted(*params)
for(component in texts) {
CustomAnvil.logError(component.serializePlain())
}
}
fun log(e: Throwable, vararg params: Any?, level: Level = Level.SEVERE, track: Boolean = true) {
val texts = formatted(*params)
for(component in texts) {
CustomAnvil.logError(component.serializePlain(), e, track, level)
}
}
}
class CommandMessage(key: String, vararg params: String): Message("command.$key", *params)
class UIMessage(key: String, vararg params: String): Message("config-ui.$key", *params)

View file

@ -0,0 +1,69 @@
package xyz.alexcrea.cuanvil.lang
import xyz.alexcrea.cuanvil.lang.CommandMessage as Message
object MsgCommand {
// Root
val ROOT_UNKNOWN_SUBCOMMAND = Message("root.warning.unknown-sub", "command")
val ROOT_ERROR_SUBCOMMAND = Message("root.error.generic")
// Shared
val SHARED_NO_DIAG_PERM = Message("shared.no-diag-permission")
val SHARED_HOVER_COPY = Message("shared.hover-copy")
val SHARED_MISSING_SUBCOMMAND = Message("shared.warning.missing-subcmd", "example1", "example2")
val SHARED_UNKNOWN_SUB_COMMAND = Message("shared.unknown-subcmd", "command")
val SHARED_NO_PERMISSION = Message("shared.no-permission")
// Debug
val DEBUG_DESCRIPTION = Message("debug.description")
val DEBUG_LOG_CLEARED = Message("debug.log-cleared")
val DEBUG_TOGGLED = Message("debug.toggled", "type")
val DEBUG_COPY = Message("debug.copy")
val DEBUG_LANG_COPY = Message("debug.copy-lang")
val DEBUG_DATA_HEADER = Message("debug.data.header")
val DEBUG_DATA_LINE_COUNT = Message("debug.data.line-count", "count")
val DEBUG_WARNING_UNSPECIFIED_TYPE = Message("debug.warning.unspecified-type")
val DEBUG_WARNING_INVALID_TYPE = Message("debug.warning.invalid-type", "type")
val DEBUG_WARNING_NO_LOG = Message("debug.warning.no-log", "command")
// Diagnostic
val DIAGNOSTIC_DESCRIPTION = Message("diagnostic.description")
val DIAGNOSTIC_ERROR_GENERIC = Message("diagnostic.had-error")
val DIAGNOSTIC_COPY = Message("diagnostic.copy")
// Config
val CONFIG_DESCRIPTION = Message("config.description")
val CONFIG_LEGACY_NAME_WARNING = Message("config.warning.legacy-name")
val CONFIG_FOLIA_ISSUE = Message("config.folia-issue")
val CONFIG_ENCHANTMENT_NO_IN_HAND = Message("config.enchantment.no_hand")
val CONFIG_ENCHANTMENT_NO_NAME = Message("config.enchantment.no_name", "name")
val CONFIG_CANNOT_CONFIGURE_WARNING = Message("config.warning.cannot_configure")
// Enchant
val ENCHANT_DESCRIPTION = Message("enchant.description")
val ENCHANT_REMOVE = Message("enchant.removed", "name")
val ENCHANT_SET = Message("enchant.set", "name", "level")
val ENCHANT_MISSING_PARAMETER_WARNING = Message("enchant.warning.missing_parameter")
val ENCHANT_NOT_FOUND_WARNING = Message("enchant.warning.not_found", "path")
val ENCHANT_MALFORMED_NUMBER_WARNING = Message("enchant.warning.malformed_number", "num")
val ENCHANT_CANNOT_ENCHANT_WARNING = Message("enchant.warning.cannot_enchant")
// Help
val HELP_DESCRIPTION = Message("help.description")
val HELP_HEADER = Message("help.header")
// Reload
val RELOAD_DESCRIPTION = Message("reload.description")
val RELOAD_START = Message("reload.start")
val RELOAD_SUCCESS = Message("reload.success")
val RELOAD_FAIL = Message("reload.fail")
val RELOAD_HARD_FAIL = Message("reload.hard-fail")
}

View file

@ -0,0 +1,29 @@
package xyz.alexcrea.cuanvil.lang
object MsgError {
/*
* -----------------
* Load and reload
* -----------------
*/
val LOAD_UPDATE_CHECK_FAIL = ErrorMessage("load.update.check-fail")
val LOAD_LEGACY_FAILED = ErrorMessage("load.legacy.failed")
val LOAD_COMMAND_REGISTER = ErrorMessage("load.command-register")
val LOAD_COMPATIBILITY = ErrorMessage("load.compatibility")
val LOAD_LISTENERS = ErrorMessage("load.listeners")
val LOAD_ENCHANT_SYSTEM = ErrorMessage("load.enchant-system")
val LOAD_NON_DEFAULT_CONFIG = ErrorMessage("load.non-default-config")
val RELOAD_FAIL = ErrorMessage("reload.resource.fail", "path")
val RELOAD_HARD_FAIL = ErrorMessage("reload.resource.hard-fail")
/*
* ----
* UI
* ----
*/
val CONFIRM_ACTION_GENERIC = ErrorMessage("confirm-action.generic")
}

View file

@ -0,0 +1,166 @@
package xyz.alexcrea.cuanvil.lang
import xyz.alexcrea.cuanvil.lang.UIMessage as Message
object MsgUI {
val SHARED_CONFIG_NO_EDIT_PERM = Message("shared.no-permission")
val SHARED_TYPED_CONFIG_TITLE = Message("shared.typed-config-title", "type")
val SHARED_CLICK_TO_CHANGE = Message("shared.click-to-change")
val SHARED_GREEN_GET_ITEM = Message("shared.green-get-item", "name")
val SHARED_YELLOW_GET_ITEM = Message("shared.yellow-get-item", "name")
val GLOBAL_ITEM_ITEM_LORE_PREFIX = Message("global-item.item-lore-prefix", "value")
val GLOBAL_ITEM_ITEM_LORE_PREFIX_ALONE = Message("global-item.item-lore-prefix-alone", "value")
val CONFIRM_ACTION_FAILED = Message("confirm-action.fail")
val CONFIRM_ACTION_ARE_YOU_SURE = Message("confirm-action.is-user-sure")
val SELECT_ITEM_TYPE_PLACE_HERE = Message("select-item-type.place-here")
val ELEMENT_LIST_INSTRUCTION_NEW = Message("element-list.instruction-new", "type")
val ELEMENT_LIST_CANCELLED_NEW = Message("element-list.cancelled-new", "type")
val ELEMENT_LIST_DUPLICATED_NEW = Message("element-list.duplicated-new", "type")
val UNIT_REPAIR_TITLE = Message("unit-repair.title", null, "page", "max_page")
val UNIT_REPAIR_ITEM = Message("unit-repair.item", "name", "unit")
val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element.title", "type", "page", "max_page")
val UNIT_REPAIR_NEW_TITLE = Message("unit-repair.new.title", null)
val UNIT_REPAIR_NEW_DESCRIPTION = Message("unit-repair.new.description", null)
val UNIT_REPAIR_ELEMENT_VALUE_TITLE = Message("unit-repair.element.value.title", "name", null)
val UNIT_REPAIR_ELEMENT_VALUE_DESCRIPTION = Message("unit-repair.element.value.description", "name", "unit")
val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", null)
val UNIT_REPAIR_NEW_ELEMENT_DESCRIPTION = Message("unit-repair.element.new.description", "name")
val UNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR = Message("unit-repair.element.new.cannot-damage")
val UNIT_REPAIR_NEW_ELEMENT_SAME_TYPE = Message("unit-repair.element.new.same-type")
val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title", null, "page", "max_page")
val CUSTOM_RECIPE_ELEMENT_EXACT_COUNT_TITLE = Message("custom-recipe.element.exact-count")
val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_TITLE = Message("custom-recipe.element.linear-xp.title")
val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_NAME = Message("custom-recipe.element.linear-xp.name")
val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_LORE = Message("custom-recipe.element.linear-xp.lore")
val CUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP = Message("custom-recipe.element.recipe-cost.level")
val CUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP = Message("custom-recipe.element.recipe-cost.xp")
val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_TITLE = Message("custom-recipe.element.item.left.title")
val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION = Message("custom-recipe.element.item.left.description")
val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_TITLE = Message("custom-recipe.element.item.right.title")
val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION = Message("custom-recipe.element.item.right.description")
val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_TITLE = Message("custom-recipe.element.item.result.title")
val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION = Message("custom-recipe.element.item.result.description")
val CUSTOM_RECIPE_ELEMENT_DELETE_TITLE = Message("custom-recipe.element.delete.title", "type")
val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", null)
val CUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_NAME = Message("custom-recipe.element.delete.button.name")
val CUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_LORE = Message("custom-recipe.element.delete.button.lore")
val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title", null, "page", "max_page")
val ENCHANTMENT_LEVEL_COST_ELEMENT_TITLE = Message("enchant-level-cost.element.title", "name")
val ENCHANTMENT_LEVEL_COST_ELEMENT_DESCRIPTION = Message("enchant-level-cost.element.description", "name")
val ENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST = Message("enchant-level-cost.element.item-cost")
val ENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST = Message("enchant-level-cost.element.book-cost")
val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title", null, "page", "max_page")
val ENCHANTMENT_LEVEL_LIMIT_ELEMENT_TITLE = Message("enchant-level-limit.element.title", "name")
val ENCHANTMENT_LEVEL_LIMIT_ELEMENT_DESCRIPTION = Message("enchant-level-limit.element.description", "name")
val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title", null, "page", "max_page")
val ENCHANTMENT_MERGE_LIMIT_ELEMENT_TITLE = Message("enchant-merge-limit.element.title", "name")
val ENCHANTMENT_MERGE_LIMIT_ELEMENT_DESCRIPTION = Message("enchant-merge-limit.element.description", "name")
val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title", null, "page", "max_page")
val ENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS = Message("enchant-conflict.element.selected-enchantments", "group")
val ENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS = Message("enchant-conflict.element.selected-sub-groups", "group")
val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE = Message("enchant-conflict.element.delete.title", "type")
val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", null)
val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_NAME = Message("enchant-conflict.element.delete.button.name")
val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_LORE = Message("enchant-conflict.element.delete.button.lore")
val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE = Message("enchant-conflict.element.min-before-count.title")
val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION = Message("enchant-conflict.element.min-before-count.description")
val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_ITEM = Message("enchant-conflict.element.min-before-count.item")
val MATERIAL_GROUP_TITLE = Message("material-group.title", null, "page", "max_page")
val MATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS = Message("material-group.element.selected-materials", "group")
val MATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS = Message("material-group.element.selected-sub-groups", "group")
val MATERIAL_GROUP_ELEMENT_DELETE_TITLE = Message("material-group.element.delete.title", "type")
val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", null)
val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME = Message("material-group.element.delete.button.name")
val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE = Message("material-group.element.delete.button.lore")
val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.new.confirm.title", "name")
val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.new.confirm.description", "name")
/*
* ------------------
* Basic Config Gui
* ------------------
*/
val BASIC_TITLE = Message("basic-config.title")
val BASIC_CAP_ANVIL_COST_TITLE = Message("basic-config.cap-anvil-cost.title")
val BASIC_CAP_ANVIL_COST_DESCRIPTION = Message("basic-config.cap-anvil-cost.description")
val BASIC_CAP_ANVIL_COST_ITEM = Message("basic-config.cap-anvil-cost-cost.item")
val BASIC_CAP_ANVIL_COST_DISABLED_TITLE = Message("basic-config.cap-anvil-cost.disabled.title")
val BASIC_CAP_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.cap-anvil-cost.disabled.description")
val BASIC_MAX_ANVIL_COST_TITLE = Message("basic-config.max-anvil-cost.title")
val BASIC_MAX_ANVIL_COST_DESCRIPTION = Message("basic-config.max-anvil-cost.description")
val BASIC_MAX_ANVIL_COST_ITEM = Message("basic-config.max-anvil-cost.item")
val BASIC_MAX_ANVIL_COST_DISABLED_TITLE = Message("basic-config.max-anvil-cost.disabled.title")
val BASIC_MAX_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.max-anvil-cost.disabled.description")
val BASIC_REMOVE_COST_LIMIT_TITLE = Message("basic-config.remove-cost-limit.title")
val BASIC_REMOVE_COST_LIMIT_DESCRIPTION = Message("basic-config.remove-cost-limit.description")
val BASIC_REMOVE_COST_LIMIT_ITEM = Message("basic-config.remove-cost-limit.item")
val BASIC_REPLACE_TOO_EXPENSIVE_TITLE = Message("basic-config.remove-too-expensive.title")
val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION = Message("basic-config.remove-too-expensive.description")
val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION_NO_NMS = Message("basic-config.remove-too-expensive.description-no-nms")
val BASIC_ITEM_REPAIR_COST_TITLE = Message("basic-config.item-repair-cost.title")
val BASIC_ITEM_REPAIR_COST_DESCRIPTION = Message("basic-config.item-repair-cost.description")
val BASIC_ITEM_RENAME_COST_TITLE = Message("basic-config.item-rename-cost.title")
val BASIC_ITEM_RENAME_COST_DESCRIPTION = Message("basic-config.item-rename-cost.description")
val BASIC_UNIT_REPAIR_COST_TITLE = Message("basic-config.unit-repair-cost.title")
val BASIC_UNIT_REPAIR_COST_DESCRIPTION = Message("basic-config.unit-repair-cost.description")
val BASIC_SACRIFICE_ILLEGAL_COST_TITLE = Message("basic-config.sacrifice-illegal-cost.title")
val BASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION = Message("basic-config.sacrifice-illegal-cost.description")
val BASIC_COLOR_CODE_LIMIT_TITLE = Message("basic-config.color-code.title")
val BASIC_COLOR_CODE_LIMIT_DESCRIPTION = Message("basic-config.color-code.description")
val BASIC_COLOR_HEX_LIMIT_TITLE = Message("basic-config.color-hex.title")
val BASIC_COLOR_HEX_LIMIT_DESCRIPTION = Message("basic-config.color-hex.description")
val BASIC_COLOR_PERMISSION_TITLE = Message("basic-config.color-permission.title")
val BASIC_COLOR_PERMISSION_DESCRIPTION = Message("basic-config.color-permission.description")
val BASIC_COLOR_PERMISSION_DISABLED_TITLE = Message("basic-config.color-permission.disabled.title")
val BASIC_COLOR_PERMISSION_DISABLED_DESCRIPTION = Message("basic-config.color-permission.disabled.description")
val BASIC_COLOR_COST_TITLE = Message("basic-config.color-cost.title")
val BASIC_COLOR_COST_DESCRIPTION = Message("basic-config.color-cost.description")
val BASIC_COLOR_COST_ITEM = Message("basic-config.color-cost.item")
val BASIC_COLOR_COST_DISABLED_TITLE = Message("basic-config.color-cost.disabled.title")
val BASIC_COLOR_COST_DISABLED_DESCRIPTION = Message("basic-config.color-cost.disabled.description")
val BASIC_WORK_PENALTY_TITLE = Message("basic-config.work-penalty.title")
val BASIC_WORK_PENALTY_ITEM = Message("basic-config.work-penalty.item")
val BASIC_WORK_PENALTY_LORE = Message("basic-config.work-penalty.lore")
val BASIC_WORK_PENALTY_LORE_BREAK = Message("basic-config.work-penalty.lore-break")
val BASIC_WORK_PENALTY_EXPLAIN_INCREASING = Message("basic-config.work-penalty.explanation.increasing")
val BASIC_WORK_PENALTY_EXPLAIN_ADDITIVE = Message("basic-config.work-penalty.explanation.additive")
val BASIC_WORK_PENALTY_EXPLAIN_SHARED = Message("basic-config.work-penalty.explanation.shared")
val BASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE = Message("basic-config.work-penalty.explanation.exclusive")
}

View file

@ -0,0 +1,20 @@
package xyz.alexcrea.cuanvil.lang
import xyz.alexcrea.cuanvil.lang.WarningMessage as Message
object MsgWarning {
/*
* -----------------
* Load and reload
* -----------------
*/
val LOAD_UPDATE_AVAILABLE = Message("load.update.available", "version")
val LOAD_LEGACY_OLD_NAME = Message("load.legacy.old-name")
val LOAD_LEGACY_SPIGOT = Message("load.legacy.spigot")
val LOAD_LEGACY_SPIGOT_OLD = Message("load.legacy.spigot-old")
val ANVIL_GENERIC_EXCEPTION = Message("anvil.generic")
}

View file

@ -30,9 +30,9 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
@ -196,6 +196,9 @@ class AnvilResultListener : Listener {
result result
) )
) return ) return
else if(player.gameMode != GameMode.CREATIVE) {
return
}
// Finally, we add the item to the player // Finally, we add the item to the player
if (slotDestination.type == SlotType.CURSOR) { if (slotDestination.type == SlotType.CURSOR) {
@ -347,6 +350,8 @@ class AnvilResultListener : Listener {
view.setItem(ANVIL_OUTPUT_SLOT, null) view.setItem(ANVIL_OUTPUT_SLOT, null)
} else if(player.gameMode != GameMode.CREATIVE) {
return false
} }
// Finally, we add the item to the player // Finally, we add the item to the player
@ -536,7 +541,7 @@ class AnvilResultListener : Listener {
if (bookPage.isNotEmpty()) bookPage.append('\n') if (bookPage.isNotEmpty()) bookPage.append('\n')
if (it == null) return@forEach if (it == null) return@forEach
bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it)) bookPage.append(it.serializePlain())
} }
val resultPage = bookPage.toString() val resultPage = bookPage.toString()

View file

@ -0,0 +1,65 @@
package xyz.alexcrea.cuanvil.util
import net.kyori.adventure.text.Component
import org.bukkit.command.CommandSender
import org.bukkit.inventory.meta.ItemMeta
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setPaperLore
import xyz.alexcrea.cuanvil.lang.Message
object ComponentUtil {
fun Component.serializeMM(): String {
return MiniMessageUtil.mm.serialize(this)
}
fun Component.serializeMMColor(): String {
return MiniMessageUtil.color_only_mm.serialize(this)
}
fun Component.serializeLegacy(): String {
return MiniMessageUtil.legacy_mm.serialize(this)
}
fun Component.serializePlain(): String {
return MiniMessageUtil.plain_text_mm.serialize(this)
}
fun Component.send(destination: CommandSender) {
if(!destination.sendPaperMessage(this))
destination.sendMessage(this.serializeLegacy())
}
fun Collection<Component>.send(destination: CommandSender) {
for(component in this)
component.send(destination)
}
fun List<Component>.applyLore(meta: ItemMeta) {
if(!meta.setPaperLore(this))
meta.lore = this.map {obj -> obj.serializeLegacy()}
}
fun ItemMeta.setMessageName(message: Message, vararg params: Any?) {
this.setComponentDisplayName(message.formattedConcatenated(*params))
}
fun List<Message>.asComponents(vararg params: Any?): List<Component> {
val result = ArrayList<Component>()
for(message in this) {
result.addAll(message.formatted(*params))
}
return result
}
fun Array<Message>.asComponents(vararg params: Any?): List<Component> {
val result = ArrayList<Component>()
for(message in this) {
result.addAll(message.formatted(*params))
}
return result
}
}

View file

@ -74,8 +74,8 @@ object MetricsUtil {
lastError = e lastError = e
} }
fun trackError(message: String) { fun trackError(message: String, cause: Throwable? = null) {
ERROR_TRACKER?.trackError(message) trackError(RuntimeException(message, cause))
} }
} }

View file

@ -25,9 +25,4 @@ object MiniMessageUtil {
val legacy_mm = LegacyComponentSerializer.legacySection() val legacy_mm = LegacyComponentSerializer.legacySection()
val plain_text_mm = PlainTextComponentSerializer.plainText() val plain_text_mm = PlainTextComponentSerializer.plainText()
// Keeping track of this as most use of this can be replaced later on v2 with pure component alternative
fun fromLegacy(legacyText: String): TextComponent {
return legacy_mm.deserialize(legacyText)
}
} }

View file

@ -3,6 +3,9 @@ package xyz.alexcrea.cuanvil.util.anvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.permissions.Permissible import org.bukkit.permissions.Permissible
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeMM
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
@ -103,10 +106,10 @@ object AnvilColorUtil {
var result: Component = MiniMessageUtil.legacy_mm.deserialize(previousStr) var result: Component = MiniMessageUtil.legacy_mm.deserialize(previousStr)
if (permission.canUseMinimessage) { if (permission.canUseMinimessage) {
// we dance with formats here // we dance with formats here
val toMinimessage = MiniMessageUtil.mm.serialize(result) val toMinimessage = result.serializeMM()
val hackySolution = toMinimessage.replace("\\<", "<") val hackySolution = toMinimessage.replace("\\<", "<")
val fromMinimessage = MiniMessageUtil.mm.deserialize(hackySolution) val fromMinimessage = MiniMessageUtil.mm.deserialize(hackySolution)
val asPlain = MiniMessageUtil.plain_text_mm.serialize(fromMinimessage) val asPlain = fromMinimessage.serializePlain()
if (previousStr != asPlain) { if (previousStr != asPlain) {
useColor = true useColor = true
@ -145,8 +148,8 @@ object AnvilColorUtil {
): String? { ): String? {
if (!permission.allowed() || component == null) return null if (!permission.allowed() || component == null) return null
val transformed = MiniMessageUtil.mm.serialize(component) val transformed = component.serializeMM()
val plainTransform = MiniMessageUtil.plain_text_mm.serialize(component) val plainTransform = component.serializePlain()
if (transformed == plainTransform) return null if (transformed == plainTransform) return null
if (permission.onlyMinimessage()) { if (permission.onlyMinimessage()) {
return transformed return transformed
@ -154,7 +157,7 @@ object AnvilColorUtil {
// smol dance so we transform the component that may contain other tag into only decoration & color for legacy // smol dance so we transform the component that may contain other tag into only decoration & color for legacy
val coloredMessage = MiniMessageUtil.color_only_mm.deserialize(transformed) val coloredMessage = MiniMessageUtil.color_only_mm.deserialize(transformed)
val legacyMessage = StringBuilder(MiniMessageUtil.legacy_mm.serialize(coloredMessage)) val legacyMessage = StringBuilder(coloredMessage.serializeLegacy())
// Reverse hex pattern // Reverse hex pattern
if (permission.canUseHexColor) { if (permission.canUseHexColor) {

View file

@ -10,6 +10,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.config.LoreEditType
@ -320,7 +321,7 @@ object AnvilLoreEditUtil {
hasUndidColor = true hasUndidColor = true
result = clearedLine result = clearedLine
} else { } else {
result = MiniMessageUtil.plain_text_mm.serialize(line) result = line.serializePlain()
} }
lines[index] = MiniMessageUtil.plain_text_mm.deserialize(result) lines[index] = MiniMessageUtil.plain_text_mm.deserialize(result)
@ -354,7 +355,7 @@ object AnvilLoreEditUtil {
result = clearedLine result = clearedLine
} else { } else {
// Remove extra tags // Remove extra tags
result = MiniMessageUtil.plain_text_mm.serialize(coloredComponent) result = coloredComponent.serializePlain()
} }
line.set(MiniMessageUtil.plain_text_mm.deserialize(result)) line.set(MiniMessageUtil.plain_text_mm.deserialize(result))

View file

@ -16,6 +16,11 @@ metric_type: auto
# Accept true or false (true by default) # Accept true or false (true by default)
metric_collect_errors: true metric_collect_errors: true
# Which language should the plugin should be
# If you like to add language yourself see TODO link to guide
# Currently available languages: en
language: en
# All anvil cost will be capped to limit_repair_value if enabled. # All anvil cost will be capped to limit_repair_value if enabled.
# #
# In other words: # In other words:

View file

@ -0,0 +1,379 @@
name: English
last-updated: 2.1.0
warning.load:
legacy:
old-name:
1: "An old version of this plugin was detected"
2: "Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus"
spigot:
1: "It seems you are using spigot"
2: "Please take notice that spigot is less supported than paper and derivatives"
spigot-old:
1: "If replace too expensive is not working this is likely because of spigot"
2: "As native nms is not supported for spigot starting 26.1"
update.available: "An update may be available: %version"
warning.anvil:
generic: "<white>[<yellow>CustomAnvil<white>] <red>Error while handling the anvil."
error.load:
legacy.failed: "error trying to check for legacy system"
update.check-fail: "error trying to fetch latest update"
command-register: "error trying to register commands"
compatibility: "error loading dependency compatibility"
listeners: "error registering listeners"
enchant-system: "error initializing enchantment system"
non-default-config: "Plugin has an issue while trying to load non default config... exiting..."
error.reload:
resource:
fail: "Resource %path Could not be loaded or reloaded."
hard-fail: "Disabling plugin."
error.confirm-action:
generic: "Could not process confirmation supplier."
command.shared:
no-diag-permission: "<red>You do not have permission to diagnostic this server"
hover-copy: "<gray>Click to copy"
unknown-subcmd: "Unknown subcommand %command"
no-permission: "No permission to execute this command"
warning:
missing-subcmd: "Need to specify a subcommand. for example %example1 or %example2"
command.root:
warning:
unknown-sub: "<red>Invalid subcommand. run <yellow>`%command help` <red>to see available commands"
error:
generic: "<red>Error running this command"
command.debug:
description: "Used to toggle debug logs and retrieve them"
log-cleared: "Log Cleared"
toggled: "Debug toggled to %type"
copy: "<green>Click to copy log data"
copy-lang: "<green>Click to copy detailed lang issues"
data:
header: "Debug Log data:"
line-count: "Found %count lines"
warning:
unspecified-type: "Need to specify which type of debug to toggle: \"default\" or \"verbose\""
invalid-type: "Invalid debug type \"%type\""
no-log: "No log to show ? make sure you tried with debug log toggled (%command)"
command.diagnostic:
description: "Basic diagnostic of this plugin"
had-error: "<red>There was an error running the diagnostic"
copy: "<green>Click to copy diagnostic data"
command.config:
description: "Used to edit the configuration of the plugin"
folia-issue:
1: "<red>It look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia."
2: "<yellow>It is may come in a future version."
3: ""
4: "<yellow>Currently you need to edit manually the config or copy from another server (spigot or better)"
5: "<yellow>Then /ca reload after config file is edited"
enchantment:
no_hand: "No enchantment found in the item you are holding"
no_name: "No enchantment found with the name %name"
warning:
legacy-name: "<red>/ca gui has been moved to /ca config"
cannot_configure: "Cannot configure the item in hand"
command.enchant:
description: "Allows to set enchantment to holden item"
warning:
missing_parameter: "Missing enchantment parameter"
not_found: "Enchantment not found: %path"
malformed_number: "Invalid number: %num"
cannot_enchant: "Cannot enchant this item"
removed: "%name removed"
set: "%name set to level %level"
command.help:
description: "Help command"
header: "List of available commands:"
command.reload:
description: "Reload the configuration of this plugin"
start: "<yellow>Reloading config..."
success: "<green>Config reloaded !"
fail: "<red>Config was not able to be reloaded..."
hard-fail: "<red>Hard fail, plugin disabled"
config-ui.shared:
no-permission: "<red>You do not have permission to edit the config"
typed-config-title: "<yellow>%type <white>Config"
click-to-change: "<gray>Click Here to change the value"
green-get-item: "<green>%name"
yellow-get-item: "<yellow>%name"
config-ui.global-item:
item-lore-prefix: "<gray>value: %value"
item-lore-prefix-alone: "%value"
config-ui.confirm-action:
fail: "<red>Action could not be completed."
is-user-sure: "<yellow>Are you sure ?"
config-ui.select-item-type:
place-here: "<yellow>Place an item here"
config-ui.element-list:
instruction-new:
1: "<yellow>Write the %type name you want to create in the chat."
2: "<yellow>Or write <red>cancel <yellow>to go back to %type config menu"
cancelled-new: "%type creation cancelled..."
duplicated-new: "<red>Please enter a %type name that do not already exist..."
config-ui.unit-repair:
title: "Unit Repair Config <reset>(%page/%max_page)"
item: "<gray>\\%<green>%name <yellow>repaired by <green>%unit"
new:
title: "Select unit repair item."
description:
1: "<gray>Click here with an item to set the item"
2: "<gray>You like to be an unit repair item"
element:
title: "<yellow>%type <red>Unit repair <reset>(%page/%max_page)"
value:
title: "<black>\\%<dark_gray>%name Repair"
description:
1: "<gray>Click here to change how many <yellow>\\% <gray>of <green>%name"
2: "<gray>Should get repaired by <yellow>%unit"
new:
title: "Select item to be repaired."
description:
1: "<gray>Click here with an item to set the item"
2: "<gray>You like to be repaired by %name"
cannot-damage: "<red>This item can't be damaged, so it can't be repaired."
same-type: "<red>Item can't repair something of the same type."
config-ui.custom-recipe:
title: "Custom Recipe Config <reset>(%page/%max_page)"
element:
exact-count: "<dark_gray>Exact count ?"
linear-xp:
title: "<dark_gray>Remove exact linear xp ?"
name: "<red>Remove exact linear xp ?"
lore: "<gray>Not usable if linear cost is 0"
recipe-cost:
level: "<dark_gray>recipe Level Cost"
xp: "<dark_gray>Recipe Linear Xp Cost"
item:
left:
title: "<yellow>Recipe Left <dark_gray>Item"
description:
1: "<gray>Set the left item of the custom craft"
2: "<gray>■ + □ = □"
right:
title: "<yellow>Recipe Right <dark_gray>Item"
description:
1: "<gray>Set the right item of the custom craft"
2: "<gray>□ + ■ = □"
result:
title: "<green>Recipe Result <dark_gray>Item"
description:
1: "<gray>Set the result item of the custom craft"
2: "<gray>□ + □ = ■"
delete:
title: "<red>Delete <yellow>%type<red>?"
description: "<gray>Confirm that you want to delete this recipe."
button:
name: "<dark_red>DELETE RECIPE"
lore: "<red>Caution with this button !"
config-ui.enchant-level-cost:
title: "<dark_gray>Enchantment Level Limit <reset>(%page/%max_page)"
element:
title: "<green>%name Cost"
description:
1: "<gray>How many level should %name"
2: "<gray>cost when applied by book or by another item."
item-cost: "<gray>Item Cost: <yellow>%cost"
book-cost: "<gray>Book Cost: <yellow>%cost"
config-ui.enchant-level-limit:
title: "<dark_gray>Enchantment Level Limit <reset>(%page/%max_page)"
element:
title: "<green>%name Limit"
description:
1: "<gray>Maximum applied level of %name"
config-ui.enchant-merge-limit:
title: "<dark_gray>Enchantment Maximum Merge Level <reset>(%page/%max_page)"
element:
title: "<green>%name Merge Limit"
description:
1: "<gray>Maximum merge level for for %name"
2: ""
3: "<gray>For example, if set to <yellow>2<gray>, <green>lvl1 <gray>+ <green>lvl1 <gray>of will give a <green>lvl2"
4: "<gray>But <green>lvl2 <gray>+ <green>lvl2 <gray>will not give a <red>lv3<gray>."
5: "<gray>Will still not merge above max enchantment level"
6: "<yellow>-1 <gray>(default) will set the merge limit to enchantment's maximum level"
config-ui.enchant-conflict:
title: "Conflict Config <reset>(%page/%max_page)"
element:
selected-enchantments: "<yellow>%group<dark_purple>" # likely need page and max page
selected-sub-groups: "<yellow>%group <red>Groups"
delete:
title: "<red>Delete <yellow>%type<red>?"
description: "<gray>Confirm that you want to delete this conflict."
button:
name: "<dark_red>DELETE CONFLICT"
lore: "<red>Caution with this button !"
min-before-count:
item: "<green>Minimum Enchantment Count"
title: "<dark_gray>Minimum enchantment count"
description:
1: "<gray>Minimum enchantment count set to X mean only X enchantment can be put"
2: "<gray>on an item before the conflict is active."
config-ui.material-group:
title: "Group Config <reset>(%page/%max_page)"
element:
selected-materials: "<yellow>%group <red>Materials"
selected-sub-groups: "<yellow>%group <red>Groups"
delete:
title: "<red>Delete <yellow>%type<red>?"
description: "<gray>Confirm that you want to delete this group."
button:
name: "<dark_red>DELETE GROUP"
lore: "<red>Caution with this button !"
config-ui.material-select:
new:
confirm:
title: "Remove %name"
description: "<dark_gray>Confirm Remove %name from this list."
config-ui.basic-config:
title: "<dark_gray>Basic Config"
config-ui.basic-config.cap-anvil-cost:
item: "<yellow>Cap Anvil Cost"
title: "<dark_gray>Cap Anvil Cost ?"
description:
1: "<gray>All anvil cost will be capped to <green>Max Anvil Cost<gray> if enabled."
2: "<gray>In other words:"
3: "<gray>For any anvil cost greater than <green>Max Anvil Cost<gray>, Cost will be set to <green>Max Anvil Cost<gray>."
disabled:
title: "<red>Cap Anvil Cost ?"
description: "<gray>This config only work if <red>Limit Repair Cost<gray> is disabled."
config-ui.basic-config.max-anvil-cost:
item: "<green>Max Anvil Cost"
title: "<dark_gray>Max Anvil Cost"
description:
1: "<gray>Max cost the Anvil can get to."
2: "<gray>Valid values include <yellow>0 <gray>to <yellow>1000<gray>."
3: "<gray>Cost will be displayed as <red>Too Expensive<gray>:"
4: "<gray>- If Cost is above <yellow>39"
5: "<gray>- And <yellow>Replace Too Expensive<gray> is disabled"
disabled:
title: "<red>Max Anvil Cost"
description: "<gray>This config only work if <red>Limit Repair Cost<gray> is disabled."
config-ui.basic-config.remove-cost-limit:
item: "<yellow>Remove Anvil Cost Limit"
title: "<dark_gray>Remove Anvil Cost Limit ?"
description:
1: "<gray>Whether the anvil's cost limit should be removed entirely."
2: "<gray>The anvil will still visually display <red>Too Expensive<gray> if <yellow>Replace Too Expensive<gray> is disabled."
3: "<gray>However, the action will be completable if xp requirement is meet."
config-ui.basic-config.remove-too-expensive:
title: "<dark_gray>Replace Too Expensive ?"
description:
1: "<gray>Whenever anvil cost is above <yellow>39<gray> should display the true price and not <red>Too Expensive<gray>."
2: "<gray>However, when bypassing <red>Too Expensive<gray>, anvil price will be displayed as <green>Green<gray>."
3: "<gray>Even if cost is displayed as <green>Green<gray>:"
4: "<gray>If the player do not have the required xp level, the action will not be completable."
description-no-nms:
1: ""
2: "<dark_red>/!\\<red>Caution<dark_red>/!\\ <red>You need ProtocoLib installed and working, or a paper server."
3: "<red>Currently ProtocoLib is not detected."
config-ui.basic-config.item-repair-cost:
title: "<dark_gray>Item Repair Cost"
description:
1: "<gray>XP Level amount added to the anvil when the item"
2: "<gray>is repaired by another item of the same type."
config-ui.basic-config.item-rename-cost:
title: "<dark_gray>Rename Cost"
description:
1: "<gray>XP Level amount added to the anvil when the item is renamed."
config-ui.basic-config.unit-repair-cost:
title: "<dark_gray>Unit Repair Cost"
description:
1: "<gray>XP Level amount added to the anvil when the item is repaired by an <yello<>unit<gray>."
2: "<gray>For example: a Diamond on a Diamond Sword."
3: "<gray>What's considered unit for what can be edited on the unit repair configuration."
config-ui.basic-config.sacrifice-illegal-cost:
title: "<dark_gray>Sacrifice Illegal Enchant Cost"
description:
1: "<gray>XP Level amount added to the anvil when a sacrifice enchantment"
2: "<gray>conflict With one of the left item enchantment"
config-ui.basic-config.color-code:
title: "<dark_gray>Allow Use Of Color Code ?"
description:
1: "<gray>Whether players can use color code."
2: "<gray>Color code a formatted like <green>&a<gray> and is used in the rename field of the anvil."
3: "<gray>Player may need permission to use color code if <yellow>Player need permission to use color<gray> is enabled."
config-ui.basic-config.color-hex:
title: "<dark_gray>Allow Use Of Hexadecimal Color ?"
description:
1: "<gray>Whether players can use hexadecimal color."
2: "<gray>Color code a formatted like <gray>#012345 <gray>and is used in the rename field of the anvil."
3: "<gray>Player may need permission to use color code if <yellow>Permission Needed For Color<gray> is enabled."
config-ui.basic-config.color-permission:
title: "<dark_gray>Need Permission To Use Color ?"
description:
1: "<gray>Whether players should have permission to be able to use colors."
2: "<gray>Give player <yellow>ca.color.code <gray>Permission to allow use of color code."
3: "<gray>Give player <yellow>ca.color.hex <gray>Permission to allow use of hexadecimal color."
disabled:
title: "<red>Need Permission To Use Color ?"
description:
1: "<gray>This config can do something only if one of the following config is enabled:"
2: "<gray>- <green>Allow Use Of Color Code"
3: "<gray>- <green>Allow Use Of Hexadecimal Color"
config-ui.basic-config.color-cost:
item: "<green>Cost Of Using Color"
title: "<dark_gray>Cost Of Using Color"
description:
1: "<gray>XP level cost when using color code or hexadecimal color using the anvil."
2: "<gray>conflict With one of the left item enchantment"
disabled:
title: "<red>Cost Of Using Color"
description:
1: "<gray>This config can do something only if one of the following config is enabled:"
2: "<gray>- <green>Allow Use Of Color Code"
3: "<gray>- <green>Allow Use Of Hexadecimal Color"
config-ui.basic-config.work-penalty:
title: "<dark_gray>Work Penalty Type"
item: "<green>Work Penalty Type"
lore:
1: "<gray>Work penalty increase the price for every anvil use."
2: "<gray>This config allow you to choose the comportment of work penalty."
lore-break:
1: ""
2: "<gray>About shared/exclusive penalty:"
explanation:
increasing: "<yellow>Increasing<gray>: will penalty be increased (in item)"
additive: "<yellow>Additive<gray>: will penalty be added to the cost"
shared: "<yellow>Shared<gray>: Vanilla, shared penalty. it will be kept from before the plugin installation."
exclusive: "<yellow>Exclusive<gray>: Custom, per anvil use type penalty. it will be lost after plugin uninstallation"