From 55b4aedb3a74c057f1226e514f0a9b7295edb016 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 6 Mar 2025 21:26:27 +0100 Subject: [PATCH 01/37] Lore edit config values --- defaultconfigs/1.18/config.yml | 13 +++ defaultconfigs/1.21/config.yml | 13 +++ .../cuanvil/update/PluginSetDefault.java | 35 ++++---- .../io/delilaheve/util/ConfigOptions.kt | 80 +++++++++++++++++++ src/main/resources/config.yml | 13 +++ 5 files changed, 140 insertions(+), 14 deletions(-) diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index 10d6ef9..2ba97b9 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -270,6 +270,19 @@ disable-merge-over: # If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied #minecraft:unbreaking: 2 +# Settings for lore modification +lore_edit: + book_and_quil: + # permission is ca.lore.book_and_quil + use_permission: true + append: false + remove: false + paper: + append_line: false + remove_line: false + # what order should the lines should get added/removed (start/end, if invalid or not present will be end) + order: end + # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index 10d6ef9..2ba97b9 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -270,6 +270,19 @@ disable-merge-over: # If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied #minecraft:unbreaking: 2 +# Settings for lore modification +lore_edit: + book_and_quil: + # permission is ca.lore.book_and_quil + use_permission: true + append: false + remove: false + paper: + append_line: false + remove_line: false + # what order should the lines should get added/removed (start/end, if invalid or not present will be end) + order: end + # Whether to show debug logging debug_log: false diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index e890918..40ad6ec 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -1,11 +1,12 @@ package xyz.alexcrea.cuanvil.update; import io.delilaheve.CustomAnvil; -import io.delilaheve.util.ConfigOptions; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import static io.delilaheve.util.ConfigOptions.*; + public class PluginSetDefault { public static void reAddMissingDefault(){ @@ -13,19 +14,25 @@ public class PluginSetDefault { int nbSet = 0; - nbSet+= trySetDefault(config, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST); - nbSet+= trySetDefault(config, ConfigOptions.MAX_ANVIL_COST, ConfigOptions.DEFAULT_MAX_ANVIL_COST); - nbSet+= trySetDefault(config, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT); - nbSet+= trySetDefault(config, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE); - nbSet+= trySetDefault(config, ConfigOptions.ITEM_REPAIR_COST, ConfigOptions.DEFAULT_ITEM_REPAIR_COST); - nbSet+= trySetDefault(config, ConfigOptions.UNIT_REPAIR_COST, ConfigOptions.DEFAULT_UNIT_REPAIR_COST); - nbSet+= trySetDefault(config, ConfigOptions.ITEM_RENAME_COST, ConfigOptions.DEFAULT_ITEM_RENAME_COST); - nbSet+= trySetDefault(config, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST); - nbSet+= trySetDefault(config, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE); - nbSet+= trySetDefault(config, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR); - nbSet+= trySetDefault(config, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR); - nbSet+= trySetDefault(config, ConfigOptions.USE_OF_COLOR_COST, ConfigOptions.DEFAULT_USE_OF_COLOR_COST); - nbSet+= trySetDefault(config, ConfigOptions.DEFAULT_LIMIT_PATH, ConfigOptions.DEFAULT_ENCHANT_LIMIT); + nbSet+= trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST); + nbSet+= trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST); + nbSet+= trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT); + nbSet+= trySetDefault(config, REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE); + nbSet+= trySetDefault(config, ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST); + nbSet+= trySetDefault(config, UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST); + nbSet+= trySetDefault(config, ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST); + nbSet+= trySetDefault(config, SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST); + nbSet+= trySetDefault(config, ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE); + nbSet+= trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR); + nbSet+= trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR); + nbSet+= trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST); + nbSet+= trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT); + + nbSet+= trySetDefault(config, APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL); + nbSet+= trySetDefault(config, APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER); + nbSet+= trySetDefault(config, REMOVE_LORE_BOOK_AND_QUIL, DEFAULT_REMOVE_LORE_BOOK_AND_QUIL); + nbSet+= trySetDefault(config, REMOVE_LORE_LINE_PAPER, DEFAULT_REMOVE_LORE_LINE_PAPER); + nbSet+= trySetDefault(config, LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER); if(nbSet > 0){ CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 50bbc25..0cbb2ec 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -37,6 +37,7 @@ object ConfigOptions { const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color" const val USE_OF_COLOR_COST = "use_of_color_cost" + // Work penalty config const val WORK_PENALTY_ROOT = "work_penalty" const val WORK_PENALTY_INCREASE = "shared_increase" const val WORK_PENALTY_ADDITIVE = "shared_additive" @@ -50,6 +51,13 @@ object ConfigOptions { const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over" + // Lore edit configs + const val APPEND_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.append" + const val REMOVE_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.remove" + const val APPEND_LORE_LINE_PAPER = "lore_edit.paper.append_line" + const val REMOVE_LORE_LINE_PAPER = "lore_edit.paper.remove_line" + const val LORE_LINE_WITH_PAPER_ORDER = "lore_edit.paper.order" + // Keys for specific enchantment values private const val KEY_BOOK = "book" private const val KEY_ITEM = "item" @@ -83,6 +91,13 @@ object ConfigOptions { const val DEFAULT_ENCHANT_LIMIT = 5 + // lore edit config + const val DEFAULT_APPEND_LORE_BOOK_AND_QUIL = false + const val DEFAULT_REMOVE_LORE_BOOK_AND_QUIL = false + const val DEFAULT_APPEND_LORE_LINE_PAPER = false + const val DEFAULT_REMOVE_LORE_LINE_PAPER = false + const val DEFAULT_LORE_LINE_WITH_PAPER_ORDER = "end" + // Debug flag private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_VERBOSE_DEBUG_LOG = false @@ -467,4 +482,69 @@ object ConfigOptions { .takeIf { it in ENCHANT_LIMIT_RANGE } } + // ---------- + // Lore edits + // ---------- + + /* + + const val DEFAULT_APPEND_LORE_WITH_BOOK_AND_QUIL = false + const val DEFAULT_REMOVE_LORE_WITH_BOOK_AND_QUIL = false + const val DEFAULT_APPEND_LORE_LINE_WITH_PAPER = false + const val DEFAULT_REMOVE_LORE_LINE_WITH_PAPER = false + const val DEFAULT_LORE_LINE_WITH_PAPER_ORDER = "end" + */ + + /** + * If we should allow appending lore via book and quil + */ + val appendLoreBookAndQuil: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL) + } + + /** + * If we should allow appending lore line via paper + */ + val appendLoreLinePaper: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER) + } + + /** + * If we should allow removing lore via book and quil + */ + val removeLoreBookAndQuil: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL) + } + + /** + * If we should allow removing lore line via paper + */ + val removeLoreLinePaper: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER) + } + + /** + * Get if we should append/remove at the end or at the start of the lore list + * This may change to an "OrderType" enum or equivalent later + */ + val paperLoreOrderIsEnd: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getString(LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER) + .equals(DEFAULT_LORE_LINE_WITH_PAPER_ORDER, ignoreCase = true) + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 10d6ef9..2ba97b9 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -270,6 +270,19 @@ disable-merge-over: # If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied #minecraft:unbreaking: 2 +# Settings for lore modification +lore_edit: + book_and_quil: + # permission is ca.lore.book_and_quil + use_permission: true + append: false + remove: false + paper: + append_line: false + remove_line: false + # what order should the lines should get added/removed (start/end, if invalid or not present will be end) + order: end + # Whether to show debug logging debug_log: false From 8d558a62f0d8d6913a3fb36ae4cb0d1be5ea194d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 6 Mar 2025 21:51:28 +0100 Subject: [PATCH 02/37] Forgot about lore edit permission --- README.md | 13 +++++-- defaultconfigs/1.18/config.yml | 6 ++- defaultconfigs/1.21/config.yml | 6 ++- .../cuanvil/update/PluginSetDefault.java | 4 ++ .../io/delilaheve/util/ConfigOptions.kt | 37 ++++++++++++++----- src/main/resources/config.yml | 6 ++- src/main/resources/plugin.yml | 14 +++++-- 7 files changed, 64 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ee386c8..0af6b69 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,16 @@ ca.bypass.fuse: Allow player to combine every enchantments to every item (no cus ca.bypass.level: Allow player to bypass every level limit (no custom limit) ca.command.reload: Allow administrator to reload the plugin's configs ca.config.edit: Allow administrator to edit the plugin's config in game -# Related to use of color (usage of permission for color is toggleable in basic config gui or config.yml) -ca.color.code: Allow player to use color code if permission is required (toggleable) -ca.color.hex: Allow player to use hexadecimal color if permission is required (toggleable) +# Bellow permissions also require some config change to allow usage of features +# usage of these permission is toggleable in basic config gui or config.yml + +# Permissions related to use of color +ca.color.code: Allow player to use color code if enabled (toggleable) +ca.color.hex: Allow player to use hexadecimal color if enabled (toggleable) + +# Permissions related to edition of the lore +ca.lore_edit.book: Allow player to edit lore via book and quil if enabled (toggleable) +ca.lore_edit.paper: Allow player to edit lore via paper if enabled (toggleable) ``` ### Commands diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index 2ba97b9..b6b49e1 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -273,15 +273,17 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: - # permission is ca.lore.book_and_quil use_permission: true + # permission is ca.lore_edit.book append: false remove: false paper: + use_permission: true + # permission is ca.lore_edit.paper append_line: false remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) - order: end + order: "end" # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index 2ba97b9..b6b49e1 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -273,15 +273,17 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: - # permission is ca.lore.book_and_quil use_permission: true + # permission is ca.lore_edit.book append: false remove: false paper: + use_permission: true + # permission is ca.lore_edit.paper append_line: false remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) - order: end + order: "end" # Whether to show debug logging debug_log: false diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 40ad6ec..d79ffba 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -30,10 +30,14 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL); nbSet+= trySetDefault(config, APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER); + nbSet+= trySetDefault(config, REMOVE_LORE_BOOK_AND_QUIL, DEFAULT_REMOVE_LORE_BOOK_AND_QUIL); nbSet+= trySetDefault(config, REMOVE_LORE_LINE_PAPER, DEFAULT_REMOVE_LORE_LINE_PAPER); nbSet+= trySetDefault(config, LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER); + nbSet+= trySetDefault(config, EDIT_LORE_WITH_BOOK_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION); + nbSet+= trySetDefault(config, EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION); + if(nbSet > 0){ CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 0cbb2ec..9295c88 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -54,10 +54,14 @@ object ConfigOptions { // Lore edit configs const val APPEND_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.append" const val REMOVE_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.remove" + const val APPEND_LORE_LINE_PAPER = "lore_edit.paper.append_line" const val REMOVE_LORE_LINE_PAPER = "lore_edit.paper.remove_line" const val LORE_LINE_WITH_PAPER_ORDER = "lore_edit.paper.order" + const val EDIT_LORE_WITH_BOOK_NEED_PERMISSION = "lore_edit.book_and_quil.use_permission" + const val EDIT_LORE_WITH_PAPER_NEED_PERMISSION = "lore_edit.paper.use_permission" + // Keys for specific enchantment values private const val KEY_BOOK = "book" private const val KEY_ITEM = "item" @@ -94,10 +98,14 @@ object ConfigOptions { // lore edit config const val DEFAULT_APPEND_LORE_BOOK_AND_QUIL = false const val DEFAULT_REMOVE_LORE_BOOK_AND_QUIL = false + const val DEFAULT_APPEND_LORE_LINE_PAPER = false const val DEFAULT_REMOVE_LORE_LINE_PAPER = false const val DEFAULT_LORE_LINE_WITH_PAPER_ORDER = "end" + const val DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION = true + const val DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION = true + // Debug flag private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_VERBOSE_DEBUG_LOG = false @@ -486,15 +494,6 @@ object ConfigOptions { // Lore edits // ---------- - /* - - const val DEFAULT_APPEND_LORE_WITH_BOOK_AND_QUIL = false - const val DEFAULT_REMOVE_LORE_WITH_BOOK_AND_QUIL = false - const val DEFAULT_APPEND_LORE_LINE_WITH_PAPER = false - const val DEFAULT_REMOVE_LORE_LINE_WITH_PAPER = false - const val DEFAULT_LORE_LINE_WITH_PAPER_ORDER = "end" - */ - /** * If we should allow appending lore via book and quil */ @@ -547,4 +546,24 @@ object ConfigOptions { .equals(DEFAULT_LORE_LINE_WITH_PAPER_ORDER, ignoreCase = true) } + /** + * If lore edit via book need permission + */ + val BookLoreEditNeedPermission: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(EDIT_LORE_WITH_BOOK_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION) + } + + /** + * If lore edit via paper need permission + */ + val PaperLoreEditNeedPermission: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION) + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2ba97b9..b6b49e1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -273,15 +273,17 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: - # permission is ca.lore.book_and_quil use_permission: true + # permission is ca.lore_edit.book append: false remove: false paper: + use_permission: true + # permission is ca.lore_edit.paper append_line: false remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) - order: end + order: "end" # Whether to show debug logging debug_log: false diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 570e258..0e58169 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -42,13 +42,19 @@ permissions: # color permissions ca.color.code: default: op - description: Allow player to use color code if permission is required (toggleable) + description: Allow player to use color code if enabled (toggleable) ca.color.hex: default: op - description: Allow player to use hexadecimal color if permission is required (toggleable) + description: Allow player to use hexadecimal color if enabled (toggleable) + # lore edit permissions + ca.lore_edit.book: + default: op + description: Allow player to edit lore via book and quil if enabled (toggleable) + ca.lore_edit.paper: + default: op + description: Allow player to edit lore via paper if enabled (toggleable) - -# soft depend on old name (UnsafeEnchantsPlus), so I can disable it if it is on the same server (old name for this plugin) +# soft depend on old name of this plugin (UnsafeEnchantsPlus), so I can disable it if it is on the same server # Also depend to other plugin for compatibility softdepend: - UnsafeEnchantsPlus From 20f9de084db84756a9ad885c947b634d1e9457c0 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 7 Mar 2025 13:28:53 +0100 Subject: [PATCH 03/37] book lore edit start --- .../cuanvil/listener/PrepareAnvilListener.kt | 35 +++++++- .../cuanvil/util/AnvilLoreEditUtil.kt | 90 +++++++++++++++++++ 2 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index e938922..39f415f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -11,6 +11,7 @@ import io.delilaheve.util.ItemUtil.repairFrom import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor +import org.bukkit.Material import org.bukkit.entity.HumanEntity import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -18,11 +19,9 @@ import org.bukkit.event.Listener import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.BookMeta import xyz.alexcrea.cuanvil.dependency.DependencyManager -import xyz.alexcrea.cuanvil.util.AnvilColorUtil -import xyz.alexcrea.cuanvil.util.AnvilUseType -import xyz.alexcrea.cuanvil.util.AnvilXpUtil -import xyz.alexcrea.cuanvil.util.CustomRecipeUtil +import xyz.alexcrea.cuanvil.util.* import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair /** * Listener for anvil events @@ -72,6 +71,9 @@ class PrepareAnvilListener : Listener { // Test for unit repair if(testUnitRepair(event, inventory, player, first, second)) return + // Test for lore edit + if(testLoreEdit(event, inventory, player, first, second)) return + CustomAnvil.log("no anvil fuse type found") event.result = null @@ -222,4 +224,29 @@ class PrepareAnvilListener : Listener { return true } + private fun testLoreEdit(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, + first: ItemStack, second: ItemStack): Boolean { + val type = second.type + var result: ItemStack? = null + + if(Material.WRITABLE_BOOK == type) { + result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second) + } + else if(Material.PAPER == type) { + + } + + if(result == null || first == result) { + CustomAnvil.log("lore edit, But input is same as output") + event.result = null + return false + } + + event.result = result + + // TODO forgot about xp config & logic + // AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) + + return true + } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt new file mode 100644 index 0000000..342ba74 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -0,0 +1,90 @@ +package xyz.alexcrea.cuanvil.util + +import io.delilaheve.util.ConfigOptions +import org.bukkit.entity.HumanEntity +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.BookMeta +import org.bukkit.permissions.Permissible + +object AnvilLoreEditUtil { + + private const val LORE_BY_BOOK: String = "ca.lore_edit.book" + private const val LORE_BY_PAPER: String = "ca.lore_edit.paper" + + private fun hasLoreEditByBookPermission(player: Permissible): Boolean { + return ConfigOptions.BookLoreEditNeedPermission && player.hasPermission(LORE_BY_BOOK) + } + + private fun hasLoreEditByPaperPermission(player: Permissible): Boolean { + return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) + } + + private fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? { + if(!hasLoreEditByBookPermission(player)) return null + + val result = first.clone() + val meta = result.itemMeta + meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled + result.itemMeta = meta + + return result + } + + private fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? { + if(!hasLoreEditByBookPermission(player)) return null + + val meta = first.itemMeta + if(meta == null || !meta.hasLore()) return null + + val bookPage = StringBuilder() + meta.lore!!.forEach { + if(bookPage.isNotEmpty()) bookPage.append('\n') + bookPage.append(it) + } + + val resultPage = bookPage.toString() + //TODO maybe check page size ? bc it may be too big ??? + + val result = second.clone() + book.setPages(resultPage) + result.itemMeta = book + + return result + } + + fun bookLoreEditType(second: ItemStack) : Boolean? { + // Test if the book & quil contain content + val meta = second.itemMeta as BookMeta + + var hasContent = false + if(meta.hasPages() && meta.pageCount >= 1){ + // Test if the pages is ok + for (page in meta.pages) { + if(page.isNotEmpty()) { + hasContent = true + break + } + } + } + + // We don't want to "add" the first page is there is content and the first page is empty + if(hasContent){ + if(meta.pages[0].isEmpty()) return null + if(ConfigOptions.appendLoreBookAndQuil) + return true + } + else if(ConfigOptions.removeLoreBookAndQuil) { + return false + } + return null + } + + fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { + val bookType = bookLoreEditType(second) ?: return null + + val meta = second.itemMeta as BookMeta + return if(bookType) handleLoreAppendByBook(player, first, meta) + else handleLoreRemoveByBook(player, first, second, meta) + } + +} \ No newline at end of file From b25e3961c231e2d2830608e244b20746d8264343 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 8 Mar 2025 11:16:55 +0100 Subject: [PATCH 04/37] book edit kind of working --- .../cuanvil/listener/AnvilResultListener.kt | 219 +++++++++++++----- .../cuanvil/listener/PrepareAnvilListener.kt | 2 +- .../cuanvil/util/AnvilLoreEditUtil.kt | 41 ++-- 3 files changed, 180 insertions(+), 82 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 5190c8c..9025de8 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -15,18 +15,21 @@ import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.InventoryView import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.BookMeta import xyz.alexcrea.cuanvil.dependency.DependencyManager 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_OUTPUT_SLOT import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe +import xyz.alexcrea.cuanvil.util.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.AnvilUseType import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.* import kotlin.math.min -class AnvilResultListener: Listener { +class AnvilResultListener : Listener { companion object { // static slot container @@ -48,67 +51,80 @@ class AnvilResultListener: Listener { } // Test if the event should bypass custom anvil. - if(DependencyManager.tryClickAnvilResultBypass(event, inventory)) return + if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT) - if(GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) { + if (GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) { event.result = Event.Result.DENY return } // Test custom recipe val recipe = CustomRecipeUtil.getCustomRecipe(leftItem, rightItem) - if(recipe != null){ + if (recipe != null) { event.result = Event.Result.ALLOW onCustomCraft( event, recipe, player, - leftItem, rightItem, output, inventory) + leftItem, rightItem, output, inventory + ) return } - val canMerge = leftItem.canMergeWith(rightItem) - val unitRepairResult = leftItem.getRepair(rightItem) - val allowed = (rightItem == null) - || (canMerge) - || (unitRepairResult != null) - - // True if there was no change or not allowed - if ((output == inventory.getItem(ANVIL_INPUT_LEFT)) - || !allowed - ) { + // Do not continue if there was no change + if ((output == inventory.getItem(ANVIL_INPUT_LEFT))) { event.result = Event.Result.DENY return } + + // Rename if (rightItem == null) { event.result = Event.Result.ALLOW return } + + // Merge + val canMerge = leftItem.canMergeWith(rightItem) if (canMerge) { event.result = Event.Result.ALLOW - } else if (unitRepairResult != null) { + return + } + + // Unit repair + val unitRepairResult = leftItem.getRepair(rightItem) + if (unitRepairResult != null) { onUnitRepairExtract( leftItem, rightItem, output, unitRepairResult, event, player, inventory ) - return } + + // For lore edit + if (handleBookLoreEdit(event, inventory, player, leftItem, rightItem, output)) { + return + } else if (Material.PAPER == rightItem.type) { + //TODO + } + + // Else there was no working situation somehow so we deny + event.result = Event.Result.DENY } - private fun onCustomCraft(event: InventoryClickEvent, - recipe: AnvilCustomRecipe, - player: Player, - leftItem: ItemStack, - rightItem: ItemStack?, - output: ItemStack, - inventory: AnvilInventory + private fun onCustomCraft( + event: InventoryClickEvent, + recipe: AnvilCustomRecipe, + player: Player, + leftItem: ItemStack, + rightItem: ItemStack?, + output: ItemStack, + inventory: AnvilInventory ) { event.result = Event.Result.DENY - if(recipe.leftItem == null) return // in case it changed + if (recipe.leftItem == null) return // in case it changed val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, leftItem, rightItem) val xpCost = amount * recipe.xpCostPerCraft @@ -123,7 +139,8 @@ class AnvilResultListener: Listener { // Handle not creative middle click... if (event.click != ClickType.MIDDLE && - !handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost)) return + !handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost) + ) return // Finally, we add the item to the player if (slotDestination.type == SlotType.CURSOR) { @@ -133,13 +150,15 @@ class AnvilResultListener: Listener { } } - private fun handleCustomCraftClick(event: InventoryClickEvent, recipe: AnvilCustomRecipe, - inventory: AnvilInventory, player: Player, - leftItem: ItemStack, rightItem: ItemStack?, - amount: Int, xpCost: Int): Boolean { + private fun handleCustomCraftClick( + event: InventoryClickEvent, recipe: AnvilCustomRecipe, + inventory: AnvilInventory, player: Player, + leftItem: ItemStack, rightItem: ItemStack?, + amount: Int, xpCost: Int + ): Boolean { // We remove what should be removed - if(rightItem != null){ - if(recipe.rightItem == null) return false// in case it changed + if (rightItem != null) { + if (recipe.rightItem == null) return false// in case it changed rightItem.amount -= amount * recipe.rightItem!!.amount inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) @@ -148,7 +167,7 @@ class AnvilResultListener: Listener { leftItem.amount -= amount * recipe.leftItem!!.amount inventory.setItem(ANVIL_INPUT_LEFT, leftItem) - if(player.gameMode != GameMode.CREATIVE){ + if (player.gameMode != GameMode.CREATIVE) { player.level -= xpCost } @@ -156,9 +175,9 @@ class AnvilResultListener: Listener { val newAmount = CustomRecipeUtil.getCustomRecipeAmount(recipe, leftItem, rightItem) CustomAnvil.verboseLog("new amount is $newAmount") - if(newAmount <= 0 || recipe.exactCount){ + if (newAmount <= 0 || recipe.exactCount) { inventory.setItem(ANVIL_OUTPUT_SLOT, null) - }else{ + } else { val resultItem: ItemStack = recipe.resultItem!!.clone() resultItem.amount *= newAmount @@ -174,6 +193,48 @@ class AnvilResultListener: Listener { return true } + private fun extractAnvilResult( + event: InventoryClickEvent, + player: Player, + inventory: AnvilInventory, + leftItem: ItemStack, + leftRemoveCount: Int, + rightItem: ItemStack, + rightRemoveCount: Int, + output: ItemStack, + repairCost: Int, + ): Boolean { + // Assumed if player do not have enough xp then it returned MIN_VALUE + if (repairCost == Int.MIN_VALUE) return false + + // Where should we get the item + val slotDestination = getActionSlot(event, player) + if (slotDestination.type == SlotType.NO_SLOT) return false + + // If not creative middle click... + if (event.click != ClickType.MIDDLE) { + // We remove what should be removed + leftItem.amount -= leftRemoveCount + inventory.setItem(ANVIL_INPUT_LEFT, leftItem) + + rightItem.amount -= rightRemoveCount + inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) + + inventory.setItem(ANVIL_OUTPUT_SLOT, null) + player.level -= repairCost + } + + // Finally, we add the item to the player + if (SlotType.CURSOR == slotDestination.type) { + player.setItemOnCursor(output) + } else {// We assume SlotType == SlotType.INVENTORY + player.inventory.setItem(slotDestination.slot, output) + } + + // TODO probably anvil damage & sound here ?? + return true + } + private fun onUnitRepairExtract( leftItem: ItemStack, rightItem: ItemStack, @@ -191,36 +252,24 @@ class AnvilResultListener: Listener { // To avoid vanilla, we cancel the event for unit repair event.result = Event.Result.DENY event.isCancelled = true - // And we give the item manually - // But first we check if we should give the item - val slotDestination = getActionSlot(event, player) - if (slotDestination.type == SlotType.NO_SLOT) return - // Test repair cost + // Get repair cost val repairCost = getUnitRepairCost(inventory, player, leftItem, output, resultCopy, resultAmount) - if(repairCost == Int.MIN_VALUE) return - // If not creative middle click... - if (event.click != ClickType.MIDDLE) { - // We remove what should be removed - inventory.setItem(ANVIL_INPUT_LEFT, null) - rightItem.amount -= resultAmount - inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) - inventory.setItem(ANVIL_OUTPUT_SLOT, null) - player.level -= repairCost - } - - // Finally, we add the item to the player - if (slotDestination.type == SlotType.CURSOR) { - player.setItemOnCursor(output) - } else {// We assume SlotType == SlotType.INVENTORY - player.inventory.setItem(slotDestination.slot, output) - } + // And then we give the item manually + extractAnvilResult( + event, player, inventory, + leftItem, 1, + rightItem, resultAmount, + output, repairCost + ) } - private fun getUnitRepairCost(inventory: AnvilInventory, player: Player, - leftItem: ItemStack, output: ItemStack, - resultCopy: ItemStack, resultAmount: Int): Int { + private fun getUnitRepairCost( + inventory: AnvilInventory, player: Player, + leftItem: ItemStack, output: ItemStack, + resultCopy: ItemStack, resultAmount: Int + ): Int { if (player.gameMode == GameMode.CREATIVE) return 0 var repairCost = 0 @@ -233,7 +282,7 @@ class AnvilResultListener: Listener { repairCost += ConfigOptions.itemRenameCost // Color cost - if(it.displayName.contains('§')){ + if (it.displayName.contains('§')) { repairCost += ConfigOptions.useOfColorCost } } @@ -257,6 +306,51 @@ class AnvilResultListener: Listener { return repairCost } + private fun handleBookLoreEdit( + event: InventoryClickEvent, + inventory: AnvilInventory, + player: Player, + leftItem: ItemStack, + rightItem: ItemStack, + output: ItemStack, + ): Boolean { + if (Material.WRITABLE_BOOK != rightItem.type) return false + val bookMeta = rightItem.itemMeta as BookMeta + + val editType = AnvilLoreEditUtil.bookLoreEditTypeAppend(leftItem, rightItem) ?: return false + + if (editType) { + if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta)) return false + + // Remove pages to + val bookCopy = rightItem.clone() + bookMeta.pages = Collections.emptyList() + bookCopy.itemMeta = bookMeta + + return extractAnvilResult( + event, player, inventory, + leftItem, 1, + bookCopy, 0, + output, 0 + ) //TODO DO REPAIR COST + } else { + if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, rightItem, bookMeta)) return false + + // remove lore + val leftCopy = leftItem.clone() + val leftMeta = leftCopy.itemMeta + leftMeta!!.lore = null + leftCopy.itemMeta = leftMeta + + return extractAnvilResult( + event, player, inventory, + leftCopy, 0, + rightItem, 1, + output, 0 + ) //TODO DO REPAIR COST + } + } + /** * Get the destination slot or "NO_SLOT" slot container if there is no slot available */ @@ -283,8 +377,7 @@ class AnvilResultListener: Listener { return NO_SLOT } return SlotContainer(SlotType.INVENTORY, slotIndex) - } - else if (player.itemOnCursor.type != Material.AIR) return NO_SLOT + } else if (player.itemOnCursor.type != Material.AIR) return NO_SLOT return CURSOR_SLOT } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 39f415f..95a6159 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -245,7 +245,7 @@ class PrepareAnvilListener : Listener { event.result = result // TODO forgot about xp config & logic - // AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost) + AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, 1) return true } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 342ba74..e3927c4 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -19,26 +19,27 @@ object AnvilLoreEditUtil { return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) } - private fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? { - if(!hasLoreEditByBookPermission(player)) return null + fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? { + if (!hasLoreEditByBookPermission(player)) return null val result = first.clone() val meta = result.itemMeta + //TODO take into account previous lore meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled result.itemMeta = meta return result } - private fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? { - if(!hasLoreEditByBookPermission(player)) return null + fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? { + if (!hasLoreEditByBookPermission(player)) return null val meta = first.itemMeta - if(meta == null || !meta.hasLore()) return null + if (meta == null || !meta.hasLore()) return null val bookPage = StringBuilder() meta.lore!!.forEach { - if(bookPage.isNotEmpty()) bookPage.append('\n') + if (bookPage.isNotEmpty()) bookPage.append('\n') bookPage.append(it) } @@ -52,15 +53,16 @@ object AnvilLoreEditUtil { return result } - fun bookLoreEditType(second: ItemStack) : Boolean? { + // Return true if append, false if remove, null if neither + fun bookLoreEditTypeAppend(first: ItemStack, second: ItemStack): Boolean? { // Test if the book & quil contain content val meta = second.itemMeta as BookMeta var hasContent = false - if(meta.hasPages() && meta.pageCount >= 1){ + if (meta.hasPages() && meta.pageCount >= 1) { // Test if the pages is ok for (page in meta.pages) { - if(page.isNotEmpty()) { + if (page.isNotEmpty()) { hasContent = true break } @@ -68,23 +70,26 @@ object AnvilLoreEditUtil { } // We don't want to "add" the first page is there is content and the first page is empty - if(hasContent){ - if(meta.pages[0].isEmpty()) return null - if(ConfigOptions.appendLoreBookAndQuil) + if (hasContent) { + if (meta.pages[0].isEmpty()) return null + if (ConfigOptions.appendLoreBookAndQuil) return true - } - else if(ConfigOptions.removeLoreBookAndQuil) { - return false + } else if (ConfigOptions.removeLoreBookAndQuil) { + if (!first.hasItemMeta()) return null + + val leftMeta = first.itemMeta!! + return if (leftMeta.hasLore()) false + else null } return null } fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { - val bookType = bookLoreEditType(second) ?: return null + val bookType = bookLoreEditTypeAppend(first, second) ?: return null val meta = second.itemMeta as BookMeta - return if(bookType) handleLoreAppendByBook(player, first, meta) - else handleLoreRemoveByBook(player, first, second, meta) + return if (bookType) handleLoreAppendByBook(player, first, meta) + else handleLoreRemoveByBook(player, first, second, meta) } } \ No newline at end of file From 3217a9e4cc850c8c674ca55e38b78f6a5160238f Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 8 Mar 2025 12:52:25 +0100 Subject: [PATCH 05/37] paper lore edit partially works --- .../cuanvil/listener/AnvilResultListener.kt | 68 +++++++++++-- .../cuanvil/listener/PrepareAnvilListener.kt | 3 +- .../cuanvil/util/AnvilLoreEditUtil.kt | 95 +++++++++++++++++-- 3 files changed, 152 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 9025de8..d8c4a0c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -27,6 +27,7 @@ import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import java.util.* +import kotlin.collections.ArrayList import kotlin.math.min class AnvilResultListener : Listener { @@ -105,8 +106,8 @@ class AnvilResultListener : Listener { // For lore edit if (handleBookLoreEdit(event, inventory, player, leftItem, rightItem, output)) { return - } else if (Material.PAPER == rightItem.type) { - //TODO + } else if (handlePaperLoreEdit(event, inventory, player, leftItem, rightItem, output)) { + return } // Else there was no working situation somehow so we deny @@ -315,14 +316,14 @@ class AnvilResultListener : Listener { output: ItemStack, ): Boolean { if (Material.WRITABLE_BOOK != rightItem.type) return false - val bookMeta = rightItem.itemMeta as BookMeta + val bookMeta = rightItem.itemMeta as BookMeta? ?: return false - val editType = AnvilLoreEditUtil.bookLoreEditTypeAppend(leftItem, rightItem) ?: return false + val editType = AnvilLoreEditUtil.bookLoreEditIsAppend(leftItem, rightItem) ?: return false if (editType) { if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta)) return false - // Remove pages to + // Remove pages to book val bookCopy = rightItem.clone() bookMeta.pages = Collections.emptyList() bookCopy.itemMeta = bookMeta @@ -338,8 +339,8 @@ class AnvilResultListener : Listener { // remove lore val leftCopy = leftItem.clone() - val leftMeta = leftCopy.itemMeta - leftMeta!!.lore = null + val leftMeta = leftCopy.itemMeta!! + leftMeta.lore = null leftCopy.itemMeta = leftMeta return extractAnvilResult( @@ -351,6 +352,59 @@ class AnvilResultListener : Listener { } } + private fun handlePaperLoreEdit( + event: InventoryClickEvent, + inventory: AnvilInventory, + player: Player, + leftItem: ItemStack, + rightItem: ItemStack, + output: ItemStack, + ): Boolean { + if (Material.PAPER != rightItem.type) return false + val paperMeta = rightItem.itemMeta ?: return false + + val editType = AnvilLoreEditUtil.paperLoreEditIsAppend(leftItem, rightItem) ?: return false + + if (editType) { + if (output != AnvilLoreEditUtil.handleLoreAppendByPaper(player, leftItem, rightItem)) return false + + // Remove custom name to paper + val paperCopy = rightItem.clone() + paperMeta.setDisplayName(null) + paperCopy.itemMeta = paperMeta + + return extractAnvilResult( + event, player, inventory, + leftItem, 1, + paperCopy, 0, + output, 0 + ) //TODO DO REPAIR COST + } else { + if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem, rightItem)) return false + + // remove lore line + val leftCopy = leftItem.clone() + val leftMeta = leftCopy.itemMeta!! + + val removeEnd = ConfigOptions.paperLoreOrderIsEnd + val lore: ArrayList = ArrayList(leftMeta.lore!!) + + if(removeEnd) lore.removeAt(lore.size - 1) + else lore.removeAt(0) + + leftMeta.lore = if(lore.isEmpty()) null else lore + leftCopy.itemMeta = leftMeta + + return extractAnvilResult( + event, player, inventory, + leftCopy, 0, + rightItem, 1, + output, 0 + ) //TODO DO REPAIR COST + } + + } + /** * Get the destination slot or "NO_SLOT" slot container if there is no slot available */ diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 95a6159..6eb1b6e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -12,6 +12,7 @@ import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor import org.bukkit.Material +import org.bukkit.entity.AbstractVillager import org.bukkit.entity.HumanEntity import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -233,7 +234,7 @@ class PrepareAnvilListener : Listener { result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second) } else if(Material.PAPER == type) { - + result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second) } if(result == null || first == result) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index e3927c4..9bcf963 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -24,8 +24,14 @@ object AnvilLoreEditUtil { val result = first.clone() val meta = result.itemMeta - //TODO take into account previous lore - meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled + val lore = if (meta?.hasLore() == true) { + ArrayList(meta.lore!!) + } else ArrayList() + + //TODO check color if color if enabled + lore.addAll(book.pages[0].split("\n")) + + meta?.lore = lore result.itemMeta = meta return result @@ -36,10 +42,13 @@ object AnvilLoreEditUtil { val meta = first.itemMeta if (meta == null || !meta.hasLore()) return null + val lore = meta.lore!! + if(lore.isEmpty()) return null val bookPage = StringBuilder() - meta.lore!!.forEach { + lore.forEach { if (bookPage.isNotEmpty()) bookPage.append('\n') + //TODO check & do color bookPage.append(it) } @@ -54,9 +63,9 @@ object AnvilLoreEditUtil { } // Return true if append, false if remove, null if neither - fun bookLoreEditTypeAppend(first: ItemStack, second: ItemStack): Boolean? { + fun bookLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? { // Test if the book & quil contain content - val meta = second.itemMeta as BookMeta + val meta = second.itemMeta as BookMeta? ?: return false var hasContent = false if (meta.hasPages() && meta.pageCount >= 1) { @@ -85,11 +94,85 @@ object AnvilLoreEditUtil { } fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { - val bookType = bookLoreEditTypeAppend(first, second) ?: return null + val bookType = bookLoreEditIsAppend(first, second) ?: return null val meta = second.itemMeta as BookMeta return if (bookType) handleLoreAppendByBook(player, first, meta) else handleLoreRemoveByBook(player, first, second, meta) } + // Return true if append, false if remove, null if neither + fun paperLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? { + // Test if the paper contain a display name + val meta = second.itemMeta ?: return false + + val hasContent = meta.hasDisplayName() + if (hasContent) { + if (ConfigOptions.appendLoreBookAndQuil) + return true + } else if (ConfigOptions.removeLoreBookAndQuil) { + if (!first.hasItemMeta()) return null + + val leftMeta = first.itemMeta!! + return if (leftMeta.hasLore() && leftMeta.lore!!.isNotEmpty()) false + else null + } + return null + } + + fun handleLoreAppendByPaper(player: Permissible, first: ItemStack, second: ItemStack): ItemStack? { + if (!hasLoreEditByPaperPermission(player)) return null + + val result = first.clone() + val meta = result.itemMeta + val lore = if (meta?.hasLore() == true) { + ArrayList(meta.lore!!) + } else ArrayList() + + val appendEnd = ConfigOptions.paperLoreOrderIsEnd + + //TODO check color if color if enabled + val line = second.itemMeta!!.displayName + if(appendEnd) + lore.add(line) + else + lore.add(0, line) + + meta?.lore = lore + result.itemMeta = meta + + return result + } + + fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, second: ItemStack): ItemStack? { + if (!hasLoreEditByPaperPermission(player)) return null + + val meta = first.itemMeta + if (meta == null || !meta.hasLore()) return null + val lore = meta.lore!! + if(lore.isEmpty()) return null + + val removeEnd = ConfigOptions.paperLoreOrderIsEnd + //TODO check & do color + val line = if(removeEnd) lore[lore.size-1] + else lore[0] + + // Create result item + val result = second.clone() + result.amount = 1 + + val resultMeta = result.itemMeta ?: return null + resultMeta.setDisplayName(line) + result.itemMeta = resultMeta + + return result + } + + fun tryLoreEditByPaper(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { + val bookType = paperLoreEditIsAppend(first, second) ?: return null + + return if (bookType) handleLoreAppendByPaper(player, first, second) + else handleLoreRemoveByPaper(player, first, second) + } + } \ No newline at end of file From 78e4ffd0c6cee9e1e8f4733685a43b662bf1470b Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 8 Mar 2025 16:58:50 +0100 Subject: [PATCH 06/37] always display changed left item to user --- .../cuanvil/listener/AnvilResultListener.kt | 106 ++++++++++++------ .../cuanvil/util/AnvilLoreEditUtil.kt | 52 +++------ 2 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index d8c4a0c..15e420f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -27,7 +27,6 @@ import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import java.util.* -import kotlin.collections.ArrayList import kotlin.math.min class AnvilResultListener : Listener { @@ -198,9 +197,9 @@ class AnvilResultListener : Listener { event: InventoryClickEvent, player: Player, inventory: AnvilInventory, - leftItem: ItemStack, + leftItem: ItemStack?, leftRemoveCount: Int, - rightItem: ItemStack, + rightItem: ItemStack?, rightRemoveCount: Int, output: ItemStack, repairCost: Int, @@ -215,10 +214,10 @@ class AnvilResultListener : Listener { // If not creative middle click... if (event.click != ClickType.MIDDLE) { // We remove what should be removed - leftItem.amount -= leftRemoveCount + if (leftItem != null) leftItem.amount -= leftRemoveCount inventory.setItem(ANVIL_INPUT_LEFT, leftItem) - rightItem.amount -= rightRemoveCount + if (rightItem != null) rightItem.amount -= rightRemoveCount inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) inventory.setItem(ANVIL_OUTPUT_SLOT, null) @@ -335,18 +334,32 @@ class AnvilResultListener : Listener { output, 0 ) //TODO DO REPAIR COST } else { - if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, rightItem, bookMeta)) return false + if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem)) return false - // remove lore - val leftCopy = leftItem.clone() - val leftMeta = leftCopy.itemMeta!! - leftMeta.lore = null - leftCopy.itemMeta = leftMeta + // fill book meta + val meta = leftItem.itemMeta + if (meta == null || !meta.hasLore()) return false + val lore = meta.lore!! + if (lore.isEmpty()) return false + + val bookPage = StringBuilder() + lore.forEach { + if (bookPage.isNotEmpty()) bookPage.append('\n') + //TODO check & do color + bookPage.append(it) + } + + val resultPage = bookPage.toString() + //TODO maybe check page size ? bc it may be too big ??? + + val rightCopy = rightItem.clone() + bookMeta.setPages(resultPage) + rightCopy.itemMeta = bookMeta return extractAnvilResult( event, player, inventory, - leftCopy, 0, - rightItem, 1, + leftItem, 1, + rightCopy, 0, output, 0 ) //TODO DO REPAIR COST } @@ -370,37 +383,62 @@ class AnvilResultListener : Listener { // Remove custom name to paper val paperCopy = rightItem.clone() + paperCopy.amount = 1 paperMeta.setDisplayName(null) paperCopy.itemMeta = paperMeta - return extractAnvilResult( - event, player, inventory, - leftItem, 1, - paperCopy, 0, - output, 0 - ) //TODO DO REPAIR COST + // TODO CONSUME PAPER CONFIG + return if (rightItem.amount > 1) { + extractAnvilResult( + event, player, inventory, + paperCopy, 0, + rightItem, 1, + output, 0 + ) //TODO DO REPAIR COST + } else { + extractAnvilResult( + event, player, inventory, + null, 0, + paperCopy, 0, + output, 0 + ) //TODO DO REPAIR COST + } } else { - if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem, rightItem)) return false + if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem)) return false - // remove lore line - val leftCopy = leftItem.clone() - val leftMeta = leftCopy.itemMeta!! + val leftMeta = leftItem.itemMeta + if (leftMeta == null || !leftMeta.hasLore()) return false + val lore = leftMeta.lore!! + if (lore.isEmpty()) return false val removeEnd = ConfigOptions.paperLoreOrderIsEnd - val lore: ArrayList = ArrayList(leftMeta.lore!!) + //TODO check & do color + val line = if (removeEnd) lore[lore.size - 1] + else lore[0] - if(removeEnd) lore.removeAt(lore.size - 1) - else lore.removeAt(0) + // Create result item + val rightClone = rightItem.clone() + rightClone.amount = 1 - leftMeta.lore = if(lore.isEmpty()) null else lore - leftCopy.itemMeta = leftMeta + val resultMeta = rightClone.itemMeta ?: return false + resultMeta.setDisplayName(line) + rightClone.itemMeta = resultMeta - return extractAnvilResult( - event, player, inventory, - leftCopy, 0, - rightItem, 1, - output, 0 - ) //TODO DO REPAIR COST + return if (rightItem.amount > 1) { + extractAnvilResult( + event, player, inventory, + rightClone, 0, + rightItem, 1, + output, 0 + ) //TODO DO REPAIR COST + } else { + extractAnvilResult( + event, player, inventory, + null, 0, + rightClone, 0, + output, 0 + ) //TODO DO REPAIR COST + } } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 9bcf963..539c90b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -37,27 +37,14 @@ object AnvilLoreEditUtil { return result } - fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? { + fun handleLoreRemoveByBook(player: Permissible, first: ItemStack): ItemStack? { if (!hasLoreEditByBookPermission(player)) return null - val meta = first.itemMeta - if (meta == null || !meta.hasLore()) return null - val lore = meta.lore!! - if(lore.isEmpty()) return null - - val bookPage = StringBuilder() - lore.forEach { - if (bookPage.isNotEmpty()) bookPage.append('\n') - //TODO check & do color - bookPage.append(it) - } - - val resultPage = bookPage.toString() - //TODO maybe check page size ? bc it may be too big ??? - - val result = second.clone() - book.setPages(resultPage) - result.itemMeta = book + // remove lore + val result = first.clone() + val leftMeta = result.itemMeta!! + leftMeta.lore = null + result.itemMeta = leftMeta return result } @@ -98,7 +85,7 @@ object AnvilLoreEditUtil { val meta = second.itemMeta as BookMeta return if (bookType) handleLoreAppendByBook(player, first, meta) - else handleLoreRemoveByBook(player, first, second, meta) + else handleLoreRemoveByBook(player, first) } // Return true if append, false if remove, null if neither @@ -144,26 +131,21 @@ object AnvilLoreEditUtil { return result } - fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, second: ItemStack): ItemStack? { + fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack): ItemStack? { if (!hasLoreEditByPaperPermission(player)) return null - val meta = first.itemMeta - if (meta == null || !meta.hasLore()) return null - val lore = meta.lore!! - if(lore.isEmpty()) return null + // remove lore line + val result = first.clone() + val meta = result.itemMeta!! val removeEnd = ConfigOptions.paperLoreOrderIsEnd - //TODO check & do color - val line = if(removeEnd) lore[lore.size-1] - else lore[0] + val lore: ArrayList = ArrayList(meta.lore!!) - // Create result item - val result = second.clone() - result.amount = 1 + if(removeEnd) lore.removeAt(lore.size - 1) + else lore.removeAt(0) - val resultMeta = result.itemMeta ?: return null - resultMeta.setDisplayName(line) - result.itemMeta = resultMeta + meta.lore = if(lore.isEmpty()) null else lore + result.itemMeta = meta return result } @@ -172,7 +154,7 @@ object AnvilLoreEditUtil { val bookType = paperLoreEditIsAppend(first, second) ?: return null return if (bookType) handleLoreAppendByPaper(player, first, second) - else handleLoreRemoveByPaper(player, first, second) + else handleLoreRemoveByPaper(player, first) } } \ No newline at end of file From 3f15143c2b758426e58a854b55e7ecc6996cd823 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 10 Mar 2025 13:54:37 +0100 Subject: [PATCH 07/37] Moved some and added more config --- defaultconfigs/1.18/config.yml | 72 ++++++- defaultconfigs/1.21/config.yml | 72 ++++++- .../cuanvil/update/PluginSetDefault.java | 6 +- .../io/delilaheve/util/ConfigOptions.kt | 163 ++++------------ .../cuanvil/listener/AnvilResultListener.kt | 3 +- .../cuanvil/util/AnvilLoreEditUtil.kt | 21 ++- .../cuanvil/util/config/LoreEditConfigUtil.kt | 177 ++++++++++++++++++ .../cuanvil/util/config/LoreEditType.kt | 87 +++++++++ src/main/resources/config.yml | 74 +++++++- 9 files changed, 519 insertions(+), 156 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index b6b49e1..f460923 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -273,18 +273,78 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: + # Permission is ca.lore_edit.book use_permission: true - # permission is ca.lore_edit.book - append: false - remove: false + append: + # If adding lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line added + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore consume the book & quil + do_consume: false + + remove: + # If removing lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line removed + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: false + allow_hexadecimal_color: false + paper: + # Permission is ca.lore_edit.paper use_permission: true - # permission is ca.lore_edit.paper - append_line: false - remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) order: "end" + append_line: + # If adding lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore line consume the paper + do_consume: false + + remove_line: + # If removing lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: false + allow_hexadecimal_color: false + # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index b6b49e1..f460923 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -273,18 +273,78 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: + # Permission is ca.lore_edit.book use_permission: true - # permission is ca.lore_edit.book - append: false - remove: false + append: + # If adding lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line added + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore consume the book & quil + do_consume: false + + remove: + # If removing lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line removed + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: false + allow_hexadecimal_color: false + paper: + # Permission is ca.lore_edit.paper use_permission: true - # permission is ca.lore_edit.paper - append_line: false - remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) order: "end" + append_line: + # If adding lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore line consume the paper + do_consume: false + + remove_line: + # If removing lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: false + allow_hexadecimal_color: false + # Whether to show debug logging debug_log: false diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index d79ffba..2299f93 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; import static io.delilaheve.util.ConfigOptions.*; +import static xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.*; public class PluginSetDefault { @@ -28,7 +29,8 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST); nbSet+= trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT); - nbSet+= trySetDefault(config, APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL); + // TODO rework lore edit defaults + /*nbSet+= trySetDefault(config, APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL); nbSet+= trySetDefault(config, APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER); nbSet+= trySetDefault(config, REMOVE_LORE_BOOK_AND_QUIL, DEFAULT_REMOVE_LORE_BOOK_AND_QUIL); @@ -36,7 +38,7 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER); nbSet+= trySetDefault(config, EDIT_LORE_WITH_BOOK_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION); - nbSet+= trySetDefault(config, EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION); + nbSet+= trySetDefault(config, EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION);*/ if(nbSet > 0){ CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 9295c88..be017af 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -7,7 +7,7 @@ import xyz.alexcrea.cuanvil.config.WorkPenaltyType import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.util.AnvilUseType -import java.util.EnumMap +import java.util.* /** * Config option accessors @@ -51,17 +51,6 @@ object ConfigOptions { const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over" - // Lore edit configs - const val APPEND_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.append" - const val REMOVE_LORE_BOOK_AND_QUIL = "lore_edit.book_and_quil.remove" - - const val APPEND_LORE_LINE_PAPER = "lore_edit.paper.append_line" - const val REMOVE_LORE_LINE_PAPER = "lore_edit.paper.remove_line" - const val LORE_LINE_WITH_PAPER_ORDER = "lore_edit.paper.order" - - const val EDIT_LORE_WITH_BOOK_NEED_PERMISSION = "lore_edit.book_and_quil.use_permission" - const val EDIT_LORE_WITH_PAPER_NEED_PERMISSION = "lore_edit.paper.use_permission" - // Keys for specific enchantment values private const val KEY_BOOK = "book" private const val KEY_ITEM = "item" @@ -95,17 +84,6 @@ object ConfigOptions { const val DEFAULT_ENCHANT_LIMIT = 5 - // lore edit config - const val DEFAULT_APPEND_LORE_BOOK_AND_QUIL = false - const val DEFAULT_REMOVE_LORE_BOOK_AND_QUIL = false - - const val DEFAULT_APPEND_LORE_LINE_PAPER = false - const val DEFAULT_REMOVE_LORE_LINE_PAPER = false - const val DEFAULT_LORE_LINE_WITH_PAPER_ORDER = "end" - - const val DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION = true - const val DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION = true - // Debug flag private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_VERBOSE_DEBUG_LOG = false @@ -138,6 +116,9 @@ object ConfigOptions { @JvmField val ENCHANT_LIMIT_RANGE = 1..255 + // -------------- + // Other defaults + // -------------- // Default value for an enchantment multiplier private const val DEFAULT_ENCHANT_VALUE = 0 @@ -262,7 +243,10 @@ object ConfigOptions { /** * If one of the color component is enabled */ - val renameColorPossible: Boolean get() { return allowColorCode || allowHexadecimalColor } + val renameColorPossible: Boolean + get() { + return allowColorCode || allowHexadecimalColor + } /** * If players need a permission to use color @@ -313,8 +297,10 @@ object ConfigOptions { val penaltyIncrease = section.getBoolean(WORK_PENALTY_INCREASE, defaultPenalty.penaltyIncrease) val penaltyAdditive = section.getBoolean(WORK_PENALTY_ADDITIVE, defaultPenalty.penaltyAdditive) - val exclusivePenaltyIncrease = section.getBoolean(EXCLUSIVE_WORK_PENALTY_INCREASE, defaultPenalty.exclusivePenaltyIncrease) - val exclusivePenaltyAdditive = section.getBoolean(EXCLUSIVE_WORK_PENALTY_ADDITIVE, defaultPenalty.exclusivePenaltyAdditive) + val exclusivePenaltyIncrease = + section.getBoolean(EXCLUSIVE_WORK_PENALTY_INCREASE, defaultPenalty.exclusivePenaltyIncrease) + val exclusivePenaltyAdditive = + section.getBoolean(EXCLUSIVE_WORK_PENALTY_ADDITIVE, defaultPenalty.exclusivePenaltyAdditive) return WorkPenaltyPart(penaltyIncrease, penaltyAdditive, exclusivePenaltyIncrease, exclusivePenaltyAdditive) } @@ -355,11 +341,11 @@ object ConfigOptions { fun enchantLimit(enchantment: CAEnchantment): Int { // Test namespace var limit = enchantLimit(enchantment.key.toString()) - if(limit != null) return limit + if (limit != null) return limit // Test legacy (name only) limit = enchantLimit(enchantment.enchantmentName) - if(limit != null) return limit + if (limit != null) return limit // get default (and test old legacy if present) return getDefaultLevel(enchantment.enchantmentName) @@ -373,18 +359,19 @@ object ConfigOptions { val path = "${ENCHANT_LIMIT_ROOT}.$enchantmentName" return CustomAnvil.instance .config - .getInt(path, ENCHANT_LIMIT_RANGE.first-1) + .getInt(path, ENCHANT_LIMIT_RANGE.first - 1) .takeIf { it in ENCHANT_LIMIT_RANGE } } /** * Get default value if enchantment do not exist on config */ - private fun getDefaultLevel(enchantmentName: String, // compatibility with 1.20.5. TODO better update system - ) : Int { - if(enchantmentName == "sweeping_edge"){ - val limit = enchantLimit("sweeping") - if(limit != null) return limit + private fun getDefaultLevel( + enchantmentName: String, // compatibility with 1.20.5. TODO better update system + ): Int { + if (enchantmentName == "sweeping_edge") { + val limit = enchantLimit("sweeping") + if (limit != null) return limit } return defaultEnchantLimit @@ -400,11 +387,11 @@ object ConfigOptions { ): Int { // Test namespace var limit = enchantmentValue(enchantment.key.toString(), isFromBook) - if(limit != null) return limit + if (limit != null) return limit // Test legacy (name only) limit = enchantmentValue(enchantment.enchantmentName, isFromBook) - if(limit != null) return limit + if (limit != null) return limit // get default (and test old legacy if present) return getDefaultValue(enchantment, isFromBook) @@ -430,21 +417,23 @@ object ConfigOptions { /** * Get default value if enchantment do not exist on config */ - private fun getDefaultValue(enchantment: CAEnchantment, // compatibility with 1.20.5. TODO better update system - isFromBook: Boolean) : Int { + private fun getDefaultValue( + enchantment: CAEnchantment, // compatibility with 1.20.5. TODO better update system + isFromBook: Boolean + ): Int { val enchantmentName = enchantment.key.toString() - if(enchantmentName == "minecraft:sweeping_edge"){ + if (enchantmentName == "minecraft:sweeping_edge") { var limit = enchantmentValue("minecraft:sweeping", isFromBook) - if(limit != null) return limit - + if (limit != null) return limit + // legacy name limit = enchantmentValue("sweeping", isFromBook) - if(limit != null) return limit + if (limit != null) return limit } val rarity = enchantment.defaultRarity() - return if(isFromBook) + return if (isFromBook) rarity.bookValue else rarity.itemValue @@ -457,20 +446,20 @@ object ConfigOptions { fun maxBeforeMergeDisabled(enchantment: CAEnchantment): Int { val key = enchantment.key.toString() var value = maxBeforeMergeDisabled(key) - if(value != null) return value + if (value != null) return value // Legacy name val legacy = enchantment.enchantmentName value = maxBeforeMergeDisabled(legacy) - if(value != null) return value + if (value != null) return value - if(key == "minecraft:sweeping_edge"){ + if (key == "minecraft:sweeping_edge") { value = maxBeforeMergeDisabled("minecraft:sweeping") - if(value != null) return value + if (value != null) return value // legacy name of legacy enchantment name value = maxBeforeMergeDisabled("sweeping") - if(value != null) return value + if (value != null) return value } return DEFAULT_MAX_BEFORE_MERGE_DISABLED @@ -480,7 +469,7 @@ object ConfigOptions { * Get the given [enchantmentName]'s level before merge is disabled * a negative value would mean never disabled */ - private fun maxBeforeMergeDisabled(enchantmentName: String) : Int? { + private fun maxBeforeMergeDisabled(enchantmentName: String): Int? { // find if set val path = "${DISABLE_MERGE_OVER_ROOT}.$enchantmentName" @@ -490,80 +479,4 @@ object ConfigOptions { .takeIf { it in ENCHANT_LIMIT_RANGE } } - // ---------- - // Lore edits - // ---------- - - /** - * If we should allow appending lore via book and quil - */ - val appendLoreBookAndQuil: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL) - } - - /** - * If we should allow appending lore line via paper - */ - val appendLoreLinePaper: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER) - } - - /** - * If we should allow removing lore via book and quil - */ - val removeLoreBookAndQuil: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL) - } - - /** - * If we should allow removing lore line via paper - */ - val removeLoreLinePaper: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER) - } - - /** - * Get if we should append/remove at the end or at the start of the lore list - * This may change to an "OrderType" enum or equivalent later - */ - val paperLoreOrderIsEnd: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getString(LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER) - .equals(DEFAULT_LORE_LINE_WITH_PAPER_ORDER, ignoreCase = true) - } - - /** - * If lore edit via book need permission - */ - val BookLoreEditNeedPermission: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(EDIT_LORE_WITH_BOOK_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION) - } - - /** - * If lore edit via paper need permission - */ - val PaperLoreEditNeedPermission: Boolean - get() { - return ConfigHolder.DEFAULT_CONFIG - .config - .getBoolean(EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION) - } - } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 15e420f..1afc17a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -26,6 +26,7 @@ import xyz.alexcrea.cuanvil.util.AnvilUseType import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import java.util.* import kotlin.math.min @@ -411,7 +412,7 @@ class AnvilResultListener : Listener { val lore = leftMeta.lore!! if (lore.isEmpty()) return false - val removeEnd = ConfigOptions.paperLoreOrderIsEnd + val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd //TODO check & do color val line = if (removeEnd) lore[lore.size - 1] else lore[0] diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 539c90b..a6a7b40 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -1,10 +1,11 @@ package xyz.alexcrea.cuanvil.util -import io.delilaheve.util.ConfigOptions import org.bukkit.entity.HumanEntity import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.BookMeta import org.bukkit.permissions.Permissible +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil +import xyz.alexcrea.cuanvil.util.config.LoreEditType object AnvilLoreEditUtil { @@ -12,11 +13,11 @@ object AnvilLoreEditUtil { private const val LORE_BY_PAPER: String = "ca.lore_edit.paper" private fun hasLoreEditByBookPermission(player: Permissible): Boolean { - return ConfigOptions.BookLoreEditNeedPermission && player.hasPermission(LORE_BY_BOOK) + return LoreEditConfigUtil.bookLoreEditNeedPermission && player.hasPermission(LORE_BY_BOOK) } private fun hasLoreEditByPaperPermission(player: Permissible): Boolean { - return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) + return LoreEditConfigUtil.paperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) } fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? { @@ -58,7 +59,7 @@ object AnvilLoreEditUtil { if (meta.hasPages() && meta.pageCount >= 1) { // Test if the pages is ok for (page in meta.pages) { - if (page.isNotEmpty()) { + if (page.isNotBlank()) { hasContent = true break } @@ -68,9 +69,9 @@ object AnvilLoreEditUtil { // We don't want to "add" the first page is there is content and the first page is empty if (hasContent) { if (meta.pages[0].isEmpty()) return null - if (ConfigOptions.appendLoreBookAndQuil) + if (LoreEditType.APPEND_BOOK.enabled) return true - } else if (ConfigOptions.removeLoreBookAndQuil) { + } else if (LoreEditType.REMOVE_BOOK.enabled) { if (!first.hasItemMeta()) return null val leftMeta = first.itemMeta!! @@ -95,9 +96,9 @@ object AnvilLoreEditUtil { val hasContent = meta.hasDisplayName() if (hasContent) { - if (ConfigOptions.appendLoreBookAndQuil) + if (LoreEditType.APPEND_PAPER.enabled) return true - } else if (ConfigOptions.removeLoreBookAndQuil) { + } else if (LoreEditType.REMOVE_PAPER.enabled) { if (!first.hasItemMeta()) return null val leftMeta = first.itemMeta!! @@ -116,7 +117,7 @@ object AnvilLoreEditUtil { ArrayList(meta.lore!!) } else ArrayList() - val appendEnd = ConfigOptions.paperLoreOrderIsEnd + val appendEnd = LoreEditConfigUtil.paperLoreOrderIsEnd //TODO check color if color if enabled val line = second.itemMeta!!.displayName @@ -138,7 +139,7 @@ object AnvilLoreEditUtil { val result = first.clone() val meta = result.itemMeta!! - val removeEnd = ConfigOptions.paperLoreOrderIsEnd + val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd val lore: ArrayList = ArrayList(meta.lore!!) if(removeEnd) lore.removeAt(lore.size - 1) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt new file mode 100644 index 0000000..eebb047 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt @@ -0,0 +1,177 @@ +package xyz.alexcrea.cuanvil.util.config + +import xyz.alexcrea.cuanvil.config.ConfigHolder.DEFAULT_CONFIG as CONFIG + +object LoreEditConfigUtil { + + // Per edit type configs Path + const val IS_ENABLED = "enabled" + const val FIXED_COST = "fixed_cost" + const val PER_LINE_COST = "per_line_cost" + const val USE_COST_PENALTY = "use_cost_penalty" + const val INCREASE_COST_PENALTY = "increase_cost_penalty" + const val DO_CONSUME = "do_consume" + + // Permission configs path + const val BOOK_PERMISSION_NEEDED = "lore_edit.book_and_quil.use_permission" + const val PAPER_PERMISSION_NEEDED = "lore_edit.paper.use_permission" + + // Color configs path + const val COLOR_BOOK_COLOR_CODE = "lore_edit.book_and_quil.color.allow_color_code" + const val COLOR_BOOK_HEX = "lore_edit.book_and_quil.color.allow_hexadecimal_color" + const val COLOR_BOOK_COST = "lore_edit.book_and_quil.color.use_cost" + + const val COLOR_PAPER_COLOR_CODE = "lore_edit.paper.color.allow_color_code" + const val COLOR_PAPER_HEX = "lore_edit.paper.color.allow_hexadecimal_color" + const val COLOR_PAPER_COST = "lore_edit.paper.color.use_cost" + + // Lore order config path + const val PAPER_EDIT_ORDER = "lore_edit.paper.order" + + // -------------- + // Default Values + // -------------- + + // Per edit type configs defaults + const val DEFAULT_IS_ENABLED = true + const val DEFAULT_FIXED_COST = 1 + const val DEFAULT_PER_LINE_COST = 0 + const val DEFAULT_USE_COST_PENALTY = false + const val DEFAULT_INCREASE_COST_PENALTY = false + const val DEFAULT_DO_CONSUME = false + + // Permission configs defaults + const val DEFAULT_BOOK_PERMISSION_NEEDED = true + const val DEFAULT_PAPER_PERMISSION_NEEDED = true + + // Color configs defaults + const val DEFAULT_COLOR_BOOK_COLOR_CODE = true + const val DEFAULT_COLOR_BOOK_HEX = true + const val DEFAULT_COLOR_BOOK_COST = 0 + + const val DEFAULT_COLOR_PAPER_COLOR_CODE = true + const val DEFAULT_COLOR_PAPER_HEX = true + const val DEFAULT_COLOR_PAPER_COST = 0 + + // Lore order config default + const val DEFAULT_PAPER_EDIT_ORDER = "end" + + // ------------- + // Config Ranges + // ------------- + + val FIXED_COST_RANGE = 0..1000 + val PER_LINE_COST_RANGE = 0..1000 + + val COLOR_BOOK_COST_RANGE = 0..1000 + val COLOR_PAPER_COST_RANGE = 0..1000 + + // ------------------- + // Generic Get methods + // ------------------- + + /** + * Get if we should append/remove at the end or at the start of the lore list + * This may change to an "OrderType" enum or equivalent later + */ + val paperLoreOrderIsEnd: Boolean + get() { + return CONFIG + .config + .getString(PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER) + .equals(DEFAULT_PAPER_EDIT_ORDER, ignoreCase = true) + } + + /** + * If lore edit via book need permission + */ + val bookLoreEditNeedPermission: Boolean + get() { + return CONFIG + .config + .getBoolean(BOOK_PERMISSION_NEEDED, DEFAULT_BOOK_PERMISSION_NEEDED) + } + + /** + * If lore edit via paper need permission + */ + val paperLoreEditNeedPermission: Boolean + get() { + return CONFIG + .config + .getBoolean(PAPER_PERMISSION_NEEDED, DEFAULT_PAPER_PERMISSION_NEEDED) + } + + // ----------------- + // Color Get methods + // ----------------- + + // book edit functions + /** + * Allow usage of color code on book lore edit + */ + val bookAllowColorCode: Boolean + get() { + return CONFIG + .config + .getBoolean(COLOR_BOOK_COLOR_CODE, DEFAULT_COLOR_BOOK_COLOR_CODE) + } + + /** + * Allow usage of hexadecimal color on book lore edit + */ + val bookAllowHexColor: Boolean + get() { + return CONFIG + .config + .getBoolean(COLOR_BOOK_HEX, DEFAULT_COLOR_BOOK_HEX) + } + + /** + * Cost when using either color code and hex color on book edit + */ + val bookUseColorCost: Int + get() { + return CONFIG + .config + .getInt(COLOR_BOOK_COST, DEFAULT_COLOR_BOOK_COST) + .takeIf { it in COLOR_BOOK_COST_RANGE } + ?: DEFAULT_COLOR_BOOK_COST + + } + + // paper edit functions + /** + * Allow usage of color code on paper lore edit + */ + val paperAllowColorCode: Boolean + get() { + return CONFIG + .config + .getBoolean(COLOR_PAPER_COLOR_CODE, DEFAULT_COLOR_PAPER_COLOR_CODE) + } + + /** + * Allow usage of hexadecimal color on paper lore edit + */ + val paperAllowHexColor: Boolean + get() { + return CONFIG + .config + .getBoolean(COLOR_PAPER_HEX, DEFAULT_COLOR_PAPER_HEX) + } + + /** + * Cost when using either color code and hex color on paper edit + */ + val paperUseColorCost: Int + get() { + return CONFIG + .config + .getInt(COLOR_PAPER_COST, DEFAULT_COLOR_PAPER_COST) + .takeIf { it in COLOR_PAPER_COST_RANGE } + ?: DEFAULT_COLOR_PAPER_COST + + } + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt new file mode 100644 index 0000000..c7be618 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -0,0 +1,87 @@ +package xyz.alexcrea.cuanvil.util.config + +import xyz.alexcrea.cuanvil.config.ConfigHolder.DEFAULT_CONFIG as CONFIG + +enum class LoreEditType( + val rootPath: String, + val isAppend: Boolean, +) { + APPEND_BOOK("lore_edit.book_and_quil.append", true), + REMOVE_BOOK("lore_edit.book_and_quil.remove", false), + APPEND_PAPER("lore_edit.paper.append", true), + REMOVE_PAPER("lore_edit.paper.remove", false), + ; + + /** + * If this edit type is enabled + */ + val enabled: Boolean + get() { + return CONFIG + .config + .getBoolean("${rootPath}.${LoreEditConfigUtil.IS_ENABLED}", LoreEditConfigUtil.DEFAULT_IS_ENABLED) + } + + /** + * Fixed cost added to this edit + */ + val fixedCost: Int + get() { + return CONFIG + .config + .getInt("${rootPath}.${LoreEditConfigUtil.FIXED_COST}", LoreEditConfigUtil.DEFAULT_FIXED_COST) + .takeIf { it in LoreEditConfigUtil.FIXED_COST_RANGE } + ?: LoreEditConfigUtil.DEFAULT_FIXED_COST + } + + /** + * Cost added per line added + */ + val perLineCost: Int + get() { + return CONFIG + .config + .getInt("${rootPath}.${LoreEditConfigUtil.PER_LINE_COST}", LoreEditConfigUtil.DEFAULT_PER_LINE_COST) + .takeIf { it in LoreEditConfigUtil.PER_LINE_COST_RANGE } + ?: LoreEditConfigUtil.DEFAULT_PER_LINE_COST + } + + /** + * If the edit should use the item's cost penalty + */ + val useCostPenalty: Boolean + get() { + return CONFIG + .config + .getBoolean( + "${rootPath}.${LoreEditConfigUtil.USE_COST_PENALTY}", + LoreEditConfigUtil.DEFAULT_USE_COST_PENALTY + ) + } + + /** + * If the edit should increase the items cost penalty + */ + val increaseCostPenalty: Boolean + get() { + + return CONFIG + .config + .getBoolean( + "${rootPath}.${LoreEditConfigUtil.INCREASE_COST_PENALTY}", + LoreEditConfigUtil.DEFAULT_INCREASE_COST_PENALTY + ) + } + + /** + * If the edit should consume the provided material + */ + val doConsume: Boolean + get() { + if (!isAppend) throw IllegalStateException("Lore edit Consume test should not happen on append") + return CONFIG + .config + .getBoolean("${rootPath}.${LoreEditConfigUtil.DO_CONSUME}", LoreEditConfigUtil.DEFAULT_DO_CONSUME) + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b6b49e1..b8ec795 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -273,18 +273,80 @@ disable-merge-over: # Settings for lore modification lore_edit: book_and_quil: + # Permission is ca.lore_edit.book use_permission: true - # permission is ca.lore_edit.book - append: false - remove: false + append: + # If adding lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line added + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore consume the book & quil + do_consume: false + + remove: + # If removing lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line removed + per_line_cost: 0 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 + paper: + # Permission is ca.lore_edit.paper use_permission: true - # permission is ca.lore_edit.paper - append_line: false - remove_line: false # what order should the lines should get added/removed (start/end, if invalid or not present will be end) order: "end" + append_line: + # If adding lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + # If adding the lore line consume the paper + do_consume: false + + remove_line: + # If removing lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item cost penalty if any + use_cost_penalty: false + # Increase left item cost penalty + increase_cost_penalty: false + + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + color: + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 + # Whether to show debug logging debug_log: false From bd917b84b48091843adc26ea1293664d4a381e26 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:31:46 +0100 Subject: [PATCH 08/37] Set lore edit defaults if absent Also fix lore edit being enabled by default --- .../cuanvil/update/PluginSetDefault.java | 33 ++++++++++++++----- .../cuanvil/util/config/LoreEditConfigUtil.kt | 2 +- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 2299f93..29b1f63 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.util.config.LoreEditType; import static io.delilaheve.util.ConfigOptions.*; import static xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.*; @@ -29,16 +30,32 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST); nbSet+= trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT); - // TODO rework lore edit defaults - /*nbSet+= trySetDefault(config, APPEND_LORE_BOOK_AND_QUIL, DEFAULT_APPEND_LORE_BOOK_AND_QUIL); - nbSet+= trySetDefault(config, APPEND_LORE_LINE_PAPER, DEFAULT_APPEND_LORE_LINE_PAPER); + // Lore Edit defaults + for (@NotNull LoreEditType value : LoreEditType.values()) { + String path = value.getRootPath() + "."; - nbSet+= trySetDefault(config, REMOVE_LORE_BOOK_AND_QUIL, DEFAULT_REMOVE_LORE_BOOK_AND_QUIL); - nbSet+= trySetDefault(config, REMOVE_LORE_LINE_PAPER, DEFAULT_REMOVE_LORE_LINE_PAPER); - nbSet+= trySetDefault(config, LORE_LINE_WITH_PAPER_ORDER, DEFAULT_LORE_LINE_WITH_PAPER_ORDER); + nbSet+= trySetDefault(config, path + IS_ENABLED, DEFAULT_IS_ENABLED); + nbSet+= trySetDefault(config, path + FIXED_COST, DEFAULT_FIXED_COST); + nbSet+= trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); + nbSet+= trySetDefault(config, path + USE_COST_PENALTY, DEFAULT_USE_COST_PENALTY); + nbSet+= trySetDefault(config, path + INCREASE_COST_PENALTY, DEFAULT_INCREASE_COST_PENALTY); + if(value.isAppend()){ + nbSet+= trySetDefault(config, path + DO_CONSUME, DEFAULT_DO_CONSUME); + } + } - nbSet+= trySetDefault(config, EDIT_LORE_WITH_BOOK_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_BOOK_NEED_PERMISSION); - nbSet+= trySetDefault(config, EDIT_LORE_WITH_PAPER_NEED_PERMISSION, DEFAULT_EDIT_LORE_WITH_PAPER_NEED_PERMISSION);*/ + nbSet+= trySetDefault(config, BOOK_PERMISSION_NEEDED, DEFAULT_BOOK_PERMISSION_NEEDED); + nbSet+= trySetDefault(config, PAPER_PERMISSION_NEEDED, DEFAULT_PAPER_PERMISSION_NEEDED); + + nbSet+= trySetDefault(config, COLOR_BOOK_COLOR_CODE, DEFAULT_COLOR_BOOK_COLOR_CODE); + nbSet+= trySetDefault(config, COLOR_BOOK_HEX, DEFAULT_COLOR_BOOK_HEX); + nbSet+= trySetDefault(config, COLOR_BOOK_COST, DEFAULT_COLOR_BOOK_COST); + + nbSet+= trySetDefault(config, COLOR_PAPER_COLOR_CODE, DEFAULT_COLOR_PAPER_COLOR_CODE); + nbSet+= trySetDefault(config, COLOR_PAPER_HEX, DEFAULT_COLOR_PAPER_HEX); + nbSet+= trySetDefault(config, COLOR_PAPER_COST, DEFAULT_COLOR_PAPER_COST); + + nbSet+= trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER); if(nbSet > 0){ CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt index eebb047..e1debbe 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt @@ -33,7 +33,7 @@ object LoreEditConfigUtil { // -------------- // Per edit type configs defaults - const val DEFAULT_IS_ENABLED = true + const val DEFAULT_IS_ENABLED = false const val DEFAULT_FIXED_COST = 1 const val DEFAULT_PER_LINE_COST = 0 const val DEFAULT_USE_COST_PENALTY = false From d2fdaace80759c09b81b6326ff8ee3c6366136ef Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:41:36 +0100 Subject: [PATCH 09/37] made edit type consume --- .../cuanvil/listener/AnvilResultListener.kt | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 1afc17a..d943ce6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -27,6 +27,7 @@ import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil +import xyz.alexcrea.cuanvil.util.config.LoreEditType import java.util.* import kotlin.math.min @@ -324,9 +325,14 @@ class AnvilResultListener : Listener { if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta)) return false // Remove pages to book - val bookCopy = rightItem.clone() - bookMeta.pages = Collections.emptyList() - bookCopy.itemMeta = bookMeta + val bookCopy: ItemStack? + if (LoreEditType.APPEND_BOOK.doConsume) { + bookCopy = rightItem.clone() + bookMeta.pages = Collections.emptyList() + bookCopy.itemMeta = bookMeta + } else { + bookCopy = null + } return extractAnvilResult( event, player, inventory, @@ -382,13 +388,17 @@ class AnvilResultListener : Listener { if (editType) { if (output != AnvilLoreEditUtil.handleLoreAppendByPaper(player, leftItem, rightItem)) return false - // Remove custom name to paper - val paperCopy = rightItem.clone() - paperCopy.amount = 1 - paperMeta.setDisplayName(null) - paperCopy.itemMeta = paperMeta + val paperCopy: ItemStack? + if (LoreEditType.APPEND_PAPER.doConsume) { + paperCopy = null + } else { + // Remove custom name to paper + paperCopy = rightItem.clone() + paperCopy.amount = 1 + paperMeta.setDisplayName(null) + paperCopy.itemMeta = paperMeta + } - // TODO CONSUME PAPER CONFIG return if (rightItem.amount > 1) { extractAnvilResult( event, player, inventory, From 2f30e19573b0ae0395b518bb01244251ccb18439 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:34:35 +0100 Subject: [PATCH 10/37] base xp cost + work penalty --- defaultconfigs/1.18/config.yml | 42 ++++++------ defaultconfigs/1.21/config.yml | 42 ++++++------ .../settings/WorkPenaltyTypeSettingGui.java | 23 +++++-- .../cuanvil/update/PluginSetDefault.java | 2 - .../io/delilaheve/util/ConfigOptions.kt | 3 +- .../cuanvil/listener/AnvilResultListener.kt | 35 +++++----- .../cuanvil/listener/PrepareAnvilListener.kt | 14 ++-- .../cuanvil/util/AnvilLoreEditUtil.kt | 65 +++++++++++++++---- .../xyz/alexcrea/cuanvil/util/AnvilUseType.kt | 62 +++++++++++++++--- .../xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt | 17 ++--- .../cuanvil/util/config/LoreEditConfigUtil.kt | 2 - .../cuanvil/util/config/LoreEditType.kt | 37 ++--------- src/main/resources/config.yml | 32 ++++----- 13 files changed, 222 insertions(+), 154 deletions(-) diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index f460923..2f7dc0e 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -282,10 +282,10 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line added per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore consume the book & quil do_consume: false @@ -296,18 +296,19 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line removed per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # # Color code are prefixed by "&" and hexadecimal color by "#" # Color code will not be applied if it colors nothing. "&&" can be used to write "&" color: - allow_color_code: false - allow_hexadecimal_color: false + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 paper: # Permission is ca.lore_edit.paper @@ -320,10 +321,10 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore line consume the paper do_consume: false @@ -332,18 +333,19 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # # Color code are prefixed by "&" and hexadecimal color by "#" # Color code will not be applied if it colors nothing. "&&" can be used to write "&" color: - allow_color_code: false - allow_hexadecimal_color: false + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index f460923..2f7dc0e 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -282,10 +282,10 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line added per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore consume the book & quil do_consume: false @@ -296,18 +296,19 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line removed per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # # Color code are prefixed by "&" and hexadecimal color by "#" # Color code will not be applied if it colors nothing. "&&" can be used to write "&" color: - allow_color_code: false - allow_hexadecimal_color: false + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 paper: # Permission is ca.lore_edit.paper @@ -320,10 +321,10 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore line consume the paper do_consume: false @@ -332,18 +333,19 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # # Color code are prefixed by "&" and hexadecimal color by "#" # Color code will not be applied if it colors nothing. "&&" can be used to write "&" color: - allow_color_code: false - allow_hexadecimal_color: false + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 # Whether to show debug logging debug_log: false diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java index 2df9a58..89af20e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java @@ -39,7 +39,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { this.currentType = ConfigOptions.INSTANCE.getWorkPenaltyType(); this.items = new EnumMap<>(this.currentType.getPartMap()); - for (AnvilUseType type : AnvilUseType.getEntries()) { + for (AnvilUseType type : useTypes.keySet()) { updateGuiForType(type); } } @@ -80,6 +80,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { }, CustomAnvil.instance); } + private static final Map useTypes = + Map.of( + AnvilUseType.RENAME_ONLY, "a1z9Z", + AnvilUseType.MERGE, "b2y8Y", + AnvilUseType.UNIT_REPAIR, "c3x7X", + AnvilUseType.CUSTOM_CRAFT, "d4w6W" + ); + @Override protected Pattern getGuiPattern() { return new Pattern( // Yeah that a mess @@ -92,13 +100,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { public void updateGuiForType(AnvilUseType type) { PatternPane pane = getPane(); - int ordinal = type.ordinal(); - int display = 'z' - ordinal; - int increment = 'a' + ordinal; - int additive = '1' + ordinal; - int exclusiveIncrement = 'Z' - ordinal; - int exclusiveAdditive = '9' - ordinal; + String typeVals = useTypes.get(type); + + char increment = typeVals.charAt(0); + char additive = typeVals.charAt(1); + char display = typeVals.charAt(2); + char exclusiveIncrement = typeVals.charAt(3); + char exclusiveAdditive = typeVals.charAt(4); WorkPenaltyType.WorkPenaltyPart part = items.get(type); String increasingStr = (part.penaltyIncrease() ? "§a" : "§c") + "Increasing"; diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 29b1f63..96d6502 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -37,8 +37,6 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, path + IS_ENABLED, DEFAULT_IS_ENABLED); nbSet+= trySetDefault(config, path + FIXED_COST, DEFAULT_FIXED_COST); nbSet+= trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); - nbSet+= trySetDefault(config, path + USE_COST_PENALTY, DEFAULT_USE_COST_PENALTY); - nbSet+= trySetDefault(config, path + INCREASE_COST_PENALTY, DEFAULT_INCREASE_COST_PENALTY); if(value.isAppend()){ nbSet+= trySetDefault(config, path + DO_CONSUME, DEFAULT_DO_CONSUME); } diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index be017af..d9d1f87 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -289,11 +289,10 @@ object ConfigOptions { */ fun workPenaltyPart(type: AnvilUseType): WorkPenaltyPart { val config = ConfigHolder.DEFAULT_CONFIG.config - val path = WORK_PENALTY_ROOT + "." + type.typeName // Find values val defaultPenalty = type.defaultPenalty - val section = config.getConfigurationSection(path) ?: return defaultPenalty + val section = config.getConfigurationSection(type.path) ?: return defaultPenalty val penaltyIncrease = section.getBoolean(WORK_PENALTY_INCREASE, defaultPenalty.penaltyIncrease) val penaltyAdditive = section.getBoolean(WORK_PENALTY_ADDITIVE, defaultPenalty.penaltyAdditive) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index d943ce6..2c19183 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -29,6 +29,7 @@ import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType import java.util.* +import java.util.concurrent.atomic.AtomicInteger import kotlin.math.min class AnvilResultListener : Listener { @@ -321,8 +322,9 @@ class AnvilResultListener : Listener { val editType = AnvilLoreEditUtil.bookLoreEditIsAppend(leftItem, rightItem) ?: return false + val xpCost = AtomicInteger() if (editType) { - if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta)) return false + if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta, xpCost)) return false // Remove pages to book val bookCopy: ItemStack? @@ -338,10 +340,10 @@ class AnvilResultListener : Listener { event, player, inventory, leftItem, 1, bookCopy, 0, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } else { - if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem)) return false + if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, xpCost)) return false // fill book meta val meta = leftItem.itemMeta @@ -367,8 +369,8 @@ class AnvilResultListener : Listener { event, player, inventory, leftItem, 1, rightCopy, 0, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } } @@ -385,8 +387,9 @@ class AnvilResultListener : Listener { val editType = AnvilLoreEditUtil.paperLoreEditIsAppend(leftItem, rightItem) ?: return false + val xpCost = AtomicInteger() if (editType) { - if (output != AnvilLoreEditUtil.handleLoreAppendByPaper(player, leftItem, rightItem)) return false + if (output != AnvilLoreEditUtil.handleLoreAppendByPaper(player, leftItem, rightItem, xpCost)) return false val paperCopy: ItemStack? if (LoreEditType.APPEND_PAPER.doConsume) { @@ -404,18 +407,18 @@ class AnvilResultListener : Listener { event, player, inventory, paperCopy, 0, rightItem, 1, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } else { extractAnvilResult( event, player, inventory, null, 0, paperCopy, 0, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } } else { - if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem)) return false + if (output != AnvilLoreEditUtil.handleLoreRemoveByPaper(player, leftItem, xpCost)) return false val leftMeta = leftItem.itemMeta if (leftMeta == null || !leftMeta.hasLore()) return false @@ -440,15 +443,15 @@ class AnvilResultListener : Listener { event, player, inventory, rightClone, 0, rightItem, 1, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } else { extractAnvilResult( event, player, inventory, null, 0, rightClone, 0, - output, 0 - ) //TODO DO REPAIR COST + output, xpCost.get() + ) } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 6eb1b6e..d2ad027 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -12,7 +12,6 @@ import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor import org.bukkit.Material -import org.bukkit.entity.AbstractVillager import org.bukkit.entity.HumanEntity import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -20,10 +19,11 @@ import org.bukkit.event.Listener import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.BookMeta import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.util.* import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.concurrent.atomic.AtomicInteger + /** * Listener for anvil events */ @@ -230,11 +230,12 @@ class PrepareAnvilListener : Listener { val type = second.type var result: ItemStack? = null + val xpCost = AtomicInteger() if(Material.WRITABLE_BOOK == type) { - result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second) + result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, xpCost) } else if(Material.PAPER == type) { - result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second) + result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, xpCost) } if(result == null || first == result) { @@ -244,10 +245,7 @@ class PrepareAnvilListener : Listener { } event.result = result - - // TODO forgot about xp config & logic - AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, 1) - + AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, xpCost.get()) return true } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index a6a7b40..49732cf 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -6,6 +6,7 @@ import org.bukkit.inventory.meta.BookMeta import org.bukkit.permissions.Permissible import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType +import java.util.concurrent.atomic.AtomicInteger object AnvilLoreEditUtil { @@ -20,7 +21,12 @@ object AnvilLoreEditUtil { return LoreEditConfigUtil.paperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) } - fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? { + fun handleLoreAppendByBook( + player: Permissible, + first: ItemStack, + book: BookMeta, + xpCost: AtomicInteger + ): ItemStack? { if (!hasLoreEditByBookPermission(player)) return null val result = first.clone() @@ -35,10 +41,13 @@ object AnvilLoreEditUtil { meta?.lore = lore result.itemMeta = meta + // Handle other xp + xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK)) + return result } - fun handleLoreRemoveByBook(player: Permissible, first: ItemStack): ItemStack? { + fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, xpCost: AtomicInteger): ItemStack? { if (!hasLoreEditByBookPermission(player)) return null // remove lore @@ -47,6 +56,9 @@ object AnvilLoreEditUtil { leftMeta.lore = null result.itemMeta = leftMeta + // Handle other xp + xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_BOOK)) + return result } @@ -81,12 +93,12 @@ object AnvilLoreEditUtil { return null } - fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { + fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack, xpCost: AtomicInteger): ItemStack? { val bookType = bookLoreEditIsAppend(first, second) ?: return null val meta = second.itemMeta as BookMeta - return if (bookType) handleLoreAppendByBook(player, first, meta) - else handleLoreRemoveByBook(player, first) + return if (bookType) handleLoreAppendByBook(player, first, meta, xpCost) + else handleLoreRemoveByBook(player, first, xpCost) } // Return true if append, false if remove, null if neither @@ -108,7 +120,12 @@ object AnvilLoreEditUtil { return null } - fun handleLoreAppendByPaper(player: Permissible, first: ItemStack, second: ItemStack): ItemStack? { + fun handleLoreAppendByPaper( + player: Permissible, + first: ItemStack, + second: ItemStack, + xpCost: AtomicInteger + ): ItemStack? { if (!hasLoreEditByPaperPermission(player)) return null val result = first.clone() @@ -121,7 +138,7 @@ object AnvilLoreEditUtil { //TODO check color if color if enabled val line = second.itemMeta!!.displayName - if(appendEnd) + if (appendEnd) lore.add(line) else lore.add(0, line) @@ -129,10 +146,13 @@ object AnvilLoreEditUtil { meta?.lore = lore result.itemMeta = meta + // Handle other xp + xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_PAPER)) + return result } - fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack): ItemStack? { + fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, xpCost: AtomicInteger): ItemStack? { if (!hasLoreEditByPaperPermission(player)) return null // remove lore line @@ -142,20 +162,39 @@ object AnvilLoreEditUtil { val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd val lore: ArrayList = ArrayList(meta.lore!!) - if(removeEnd) lore.removeAt(lore.size - 1) + if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) - meta.lore = if(lore.isEmpty()) null else lore + meta.lore = if (lore.isEmpty()) null else lore result.itemMeta = meta + // Handle other xp + xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_PAPER)) + return result } - fun tryLoreEditByPaper(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? { + fun tryLoreEditByPaper( + player: HumanEntity, + first: ItemStack, + second: ItemStack, + xpCost: AtomicInteger + ): ItemStack? { val bookType = paperLoreEditIsAppend(first, second) ?: return null - return if (bookType) handleLoreAppendByPaper(player, first, second) - else handleLoreRemoveByPaper(player, first) + return if (bookType) handleLoreAppendByPaper(player, first, second, xpCost) + else handleLoreRemoveByPaper(player, first, xpCost) + } + + private fun baseEditLoreXpCost( + first: ItemStack, + result: ItemStack, + editType: LoreEditType + ): Int { + var xpCost = editType.fixedCost + + xpCost += AnvilXpUtil.calculatePenalty(first, null, result, editType.useType) + return xpCost } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt index c0048de..d765fa3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt @@ -1,29 +1,73 @@ package xyz.alexcrea.cuanvil.util +import io.delilaheve.util.ConfigOptions import org.bukkit.Material import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart -enum class AnvilUseType(val typeName: String, - val defaultPenalty: WorkPenaltyPart, - val displayName: String, val displayMat: Material - ) { +enum class AnvilUseType( + val typeName: String, val path: String, + val defaultPenalty: WorkPenaltyPart, + val displayName: String, val displayMat: Material +) { - RENAME_ONLY("rename_only", + RENAME_ONLY( + "rename_only", WorkPenaltyPart(false, true), "Rename Only", Material.NAME_TAG - ), - MERGE("merge", + ), + MERGE( + "merge", WorkPenaltyPart(true, true), "Merge", Material.ANVIL ), - UNIT_REPAIR("unit_repair", + UNIT_REPAIR( + "unit_repair", WorkPenaltyPart(true, true), "Unit Repair", Material.DIAMOND ), - CUSTOM_CRAFT("custom_craft", + CUSTOM_CRAFT( + "custom_craft", WorkPenaltyPart(false, false), "Custom Craft", Material.CRAFTING_TABLE ), + LORE_EDIT_BOOK_APPEND( + "lore_edit_book_append", "lore_edit.book_and_quil.append", + WorkPenaltyPart(false, false), + "Book Add", Material.WRITABLE_BOOK + ), + LORE_EDIT_BOOK_REMOVE( + "lore_edit_book_remove", "lore_edit.book_and_quil.remove", + WorkPenaltyPart(false, false), + "Book Remove", Material.WRITABLE_BOOK + ), + LORE_EDIT_PAPER_APPEND( + "lore_edit_paper_append", "lore_edit.paper.append", + WorkPenaltyPart(false, false), + "Paper Add", Material.WRITABLE_BOOK + ), + LORE_EDIT_PAPER_REMOVE( + "lore_edit_paper_remove", "lore_edit.paper.remove", + WorkPenaltyPart(false, false), + "Paper Remove", Material.WRITABLE_BOOK + ), ; + companion object { + private fun defaultPath(typeName: String): String { + return "${ConfigOptions.WORK_PENALTY_ROOT}.$typeName" + } + + } + + constructor( + typeName: String, + defaultPenalty: WorkPenaltyPart, + displayName: String, displayMat: Material + ) : + this( + typeName, defaultPath(typeName), + defaultPenalty, + displayName, displayMat + ) + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt index 3893724..9220ee3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt @@ -11,7 +11,6 @@ import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.InventoryView -import org.bukkit.inventory.InventoryView.Property.REPAIR_COST import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.Repairable import org.bukkit.persistence.PersistentDataType @@ -129,13 +128,16 @@ object AnvilXpUtil { return resultSum } + private fun exclusivePenaltyKey(useType: AnvilUseType): NamespacedKey { + return NamespacedKey(CustomAnvil.instance, "${EXCLUSIVE_PENALTY_PREFIX}_${useType.typeName}") + } + private fun setExclusivePenalty( result: ItemStack, resultPenalty: Int, useType: AnvilUseType ) { - val tagPath = EXCLUSIVE_PENALTY_PREFIX + "_" + useType.typeName - val key = NamespacedKey(CustomAnvil.instance, tagPath) + val key = exclusivePenaltyKey(useType) val meta = result.itemMeta!! meta.persistentDataContainer.set(key, PersistentDataType.INTEGER, resultPenalty) @@ -143,14 +145,13 @@ object AnvilXpUtil { } private fun findExclusivePenalty( - left: ItemStack?, + item: ItemStack?, useType: AnvilUseType ): Int { - if (left == null) return 0 - val tagPath = EXCLUSIVE_PENALTY_PREFIX + "_" + useType.typeName - val key = NamespacedKey(CustomAnvil.instance, tagPath) + if (item == null || !item.hasItemMeta()) return 0 + val key = exclusivePenaltyKey(useType) - val meta = left.itemMeta!! + val meta = item.itemMeta!! return meta.persistentDataContainer.get(key, PersistentDataType.INTEGER) ?: return 0 } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt index e1debbe..680bb57 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt @@ -36,8 +36,6 @@ object LoreEditConfigUtil { const val DEFAULT_IS_ENABLED = false const val DEFAULT_FIXED_COST = 1 const val DEFAULT_PER_LINE_COST = 0 - const val DEFAULT_USE_COST_PENALTY = false - const val DEFAULT_INCREASE_COST_PENALTY = false const val DEFAULT_DO_CONSUME = false // Permission configs defaults diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt index c7be618..d7ca042 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -1,15 +1,17 @@ package xyz.alexcrea.cuanvil.util.config +import xyz.alexcrea.cuanvil.util.AnvilUseType import xyz.alexcrea.cuanvil.config.ConfigHolder.DEFAULT_CONFIG as CONFIG enum class LoreEditType( val rootPath: String, + val useType: AnvilUseType, val isAppend: Boolean, ) { - APPEND_BOOK("lore_edit.book_and_quil.append", true), - REMOVE_BOOK("lore_edit.book_and_quil.remove", false), - APPEND_PAPER("lore_edit.paper.append", true), - REMOVE_PAPER("lore_edit.paper.remove", false), + APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true), + REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE,false), + APPEND_PAPER("lore_edit.paper.append", AnvilUseType.LORE_EDIT_PAPER_APPEND,true), + REMOVE_PAPER("lore_edit.paper.remove", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false), ; /** @@ -46,33 +48,6 @@ enum class LoreEditType( ?: LoreEditConfigUtil.DEFAULT_PER_LINE_COST } - /** - * If the edit should use the item's cost penalty - */ - val useCostPenalty: Boolean - get() { - return CONFIG - .config - .getBoolean( - "${rootPath}.${LoreEditConfigUtil.USE_COST_PENALTY}", - LoreEditConfigUtil.DEFAULT_USE_COST_PENALTY - ) - } - - /** - * If the edit should increase the items cost penalty - */ - val increaseCostPenalty: Boolean - get() { - - return CONFIG - .config - .getBoolean( - "${rootPath}.${LoreEditConfigUtil.INCREASE_COST_PENALTY}", - LoreEditConfigUtil.DEFAULT_INCREASE_COST_PENALTY - ) - } - /** * If the edit should consume the provided material */ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b8ec795..2f7dc0e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -282,10 +282,10 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line added per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore consume the book & quil do_consume: false @@ -296,10 +296,10 @@ lore_edit: fixed_cost: 1 # Cost used for every lore line removed per_line_cost: 0 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # @@ -321,10 +321,10 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # If adding the lore line consume the paper do_consume: false @@ -333,10 +333,10 @@ lore_edit: enabled: false # Cost used every time fixed_cost: 1 - # Use left item cost penalty if any - use_cost_penalty: false - # Increase left item cost penalty - increase_cost_penalty: false + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false # Allow using color code and hexadecimal color when editing lore via book & quil # From 20d8fb6eda7dc0188d3238d6d7f9ebbbac04b740 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:53:48 +0100 Subject: [PATCH 11/37] remove per line cost on single line use type --- .../xyz/alexcrea/cuanvil/update/PluginSetDefault.java | 4 +++- .../xyz/alexcrea/cuanvil/util/config/LoreEditType.kt | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 96d6502..0530140 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -36,7 +36,9 @@ public class PluginSetDefault { nbSet+= trySetDefault(config, path + IS_ENABLED, DEFAULT_IS_ENABLED); nbSet+= trySetDefault(config, path + FIXED_COST, DEFAULT_FIXED_COST); - nbSet+= trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); + if(value.isMultiLine()){ + nbSet+= trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); + } if(value.isAppend()){ nbSet+= trySetDefault(config, path + DO_CONSUME, DEFAULT_DO_CONSUME); } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt index d7ca042..76a1bb8 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -7,11 +7,12 @@ enum class LoreEditType( val rootPath: String, val useType: AnvilUseType, val isAppend: Boolean, + val isMultiLine: Boolean, ) { - APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true), - REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE,false), - APPEND_PAPER("lore_edit.paper.append", AnvilUseType.LORE_EDIT_PAPER_APPEND,true), - REMOVE_PAPER("lore_edit.paper.remove", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false), + APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true), + REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE,false, true), + APPEND_PAPER("lore_edit.paper.append", AnvilUseType.LORE_EDIT_PAPER_APPEND,true, false), + REMOVE_PAPER("lore_edit.paper.remove", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false, false), ; /** @@ -41,6 +42,7 @@ enum class LoreEditType( */ val perLineCost: Int get() { + if (!isMultiLine) throw IllegalStateException("Per line cost get on single line edit type") return CONFIG .config .getInt("${rootPath}.${LoreEditConfigUtil.PER_LINE_COST}", LoreEditConfigUtil.DEFAULT_PER_LINE_COST) From 2c9b2ef9fa0894a06b2a676a8721924b913431ad Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:00:31 +0100 Subject: [PATCH 12/37] multi line per line xp cost added --- .../alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 49732cf..cbe0594 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -30,18 +30,20 @@ object AnvilLoreEditUtil { if (!hasLoreEditByBookPermission(player)) return null val result = first.clone() - val meta = result.itemMeta - val lore = if (meta?.hasLore() == true) { + val meta = result.itemMeta?: return null + val lore = if (meta.hasLore()) { ArrayList(meta.lore!!) } else ArrayList() //TODO check color if color if enabled - lore.addAll(book.pages[0].split("\n")) + val lines = book.pages[0].split("\n") + lore.addAll(lines) - meta?.lore = lore + meta.lore = lore result.itemMeta = meta // Handle other xp + xpCost.addAndGet(lines.size * LoreEditType.APPEND_BOOK.perLineCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK)) return result @@ -52,11 +54,14 @@ object AnvilLoreEditUtil { // remove lore val result = first.clone() - val leftMeta = result.itemMeta!! + val leftMeta = result.itemMeta?: return null + val currentLore = leftMeta.lore?: return null + leftMeta.lore = null result.itemMeta = leftMeta // Handle other xp + xpCost.addAndGet(currentLore.size * LoreEditType.REMOVE_BOOK.perLineCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_BOOK)) return result From 762e7d4e0b4dd482d06bdc98707f43281e736931 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:07:44 +0100 Subject: [PATCH 13/37] lore edit color should work --- .../cuanvil/listener/AnvilResultListener.kt | 16 +- .../cuanvil/listener/PrepareAnvilListener.kt | 7 +- .../alexcrea/cuanvil/util/AnvilColorUtil.kt | 132 +++++++++++++--- .../cuanvil/util/AnvilLoreEditUtil.kt | 143 +++++++++++++++--- .../cuanvil/util/config/LoreEditConfigUtil.kt | 6 +- 5 files changed, 259 insertions(+), 45 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 2c19183..ce0f3af 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -30,6 +30,7 @@ import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType import java.util.* import java.util.concurrent.atomic.AtomicInteger +import kotlin.collections.ArrayList import kotlin.math.min class AnvilResultListener : Listener { @@ -348,13 +349,15 @@ class AnvilResultListener : Listener { // fill book meta val meta = leftItem.itemMeta if (meta == null || !meta.hasLore()) return false - val lore = meta.lore!! + val lore = ArrayList(meta.lore!!) if (lore.isEmpty()) return false + // Uncolor the page + AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK) + val bookPage = StringBuilder() lore.forEach { if (bookPage.isNotEmpty()) bookPage.append('\n') - //TODO check & do color bookPage.append(it) } @@ -426,10 +429,15 @@ class AnvilResultListener : Listener { if (lore.isEmpty()) return false val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd - //TODO check & do color - val line = if (removeEnd) lore[lore.size - 1] + var line = if (removeEnd) lore[lore.size - 1] else lore[0] + // Overkill but uncolor the line + val tempList = ArrayList(1) + tempList.add(line) + AnvilLoreEditUtil.uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) + line = tempList[0] + // Create result item val rightClone = rightItem.clone() rightClone.amount = 1 diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index d2ad027..5708126 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -80,7 +80,7 @@ class PrepareAnvilListener : Listener { } - // return true if a custom recipe exist with these ingredient + // return true if a custom recipe exist with these ingredients private fun testCustomRecipe(event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity, first: ItemStack, second: ItemStack?): Boolean { @@ -134,7 +134,10 @@ class PrepareAnvilListener : Listener { if(ConfigOptions.renameColorPossible && inventoryName != null){ val resultString = StringBuilder(inventoryName) - useColor = AnvilColorUtil.handleRenamingColor(resultString, player) + useColor = AnvilColorUtil.handleColor(resultString, player, + ConfigOptions.permissionNeededForColor, + ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, + AnvilColorUtil.ColorUseType.RENAME) if(useColor) { inventoryName = resultString.toString() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt index 0e216e8..0bb1fe9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt @@ -1,38 +1,99 @@ package xyz.alexcrea.cuanvil.util -import io.delilaheve.util.ConfigOptions -import org.bukkit.entity.HumanEntity +import org.bukkit.permissions.Permissible import java.util.regex.Matcher import java.util.regex.Pattern object AnvilColorUtil { private val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string + private val TRANSFORMED_HEX_PATTERN = Pattern.compile("§x(§[0-9a-fA-F]){6}") // pattern to find minecraft hex string - fun handleRenamingColor(textToColor: StringBuilder, player: HumanEntity): Boolean { - val usePermission = ConfigOptions.permissionNeededForColor - val canUseColorCode = ConfigOptions.allowColorCode && (!usePermission || player.hasPermission("ca.color.code")) - val canUseHexColor = ConfigOptions.allowHexadecimalColor && (!usePermission || player.hasPermission("ca.color.hex")) + /** + * Color a stringbuilder object depending on allowed color type and player permissions on color use type + * @return if the stringbuilder was changed and color applied + */ + fun handleColor( + textToColor: StringBuilder, + player: Permissible, + usePermission: Boolean, + allowColorCode: Boolean, + allowHexadecimalColor: Boolean, + useType: ColorUseType + ): Boolean { + if (!allowColorCode && !allowHexadecimalColor) return false - if((!canUseColorCode) && (!canUseHexColor)) return false + val canUseColorCode = + allowColorCode && (!usePermission || useType.colorCodePerm == null || player.hasPermission( + useType.colorCodePerm + )) + val canUseHexColor = + allowHexadecimalColor && (!usePermission || useType.hexColorPerm == null || player.hasPermission( + useType.hexColorPerm + )) + + if ((!canUseColorCode) && (!canUseHexColor)) return false var useColor = false // Handle color code - if(canUseColorCode){ + if (canUseColorCode) { var nbReplacement = replaceAll(textToColor, "&", "§", 2) nbReplacement -= 2 * replaceAll(textToColor, "§§", "&", 2) - if(nbReplacement > 0) useColor = true + if (nbReplacement > 0) useColor = true } - if(canUseHexColor){ + if (canUseHexColor) { val nbReplacement = replaceHexToColor(textToColor, 7) - if(nbReplacement > 0) useColor = true + if (nbReplacement > 0) useColor = true } return useColor } + /** + * Revert a stringbuilder to a state where applying handleColor with the same options would give the same result + * @return if the stringbuilder was changed and color unapplied + */ + fun revertColor( + colorToText: StringBuilder, + player: Permissible, + usePermission: Boolean, + allowColorCode: Boolean, + allowHexadecimalColor: Boolean, + useType: ColorUseType + ): Boolean { + if (!allowColorCode && !allowHexadecimalColor) return false + + val canUseColorCode = + allowColorCode && (!usePermission || useType.colorCodePerm == null || player.hasPermission( + useType.colorCodePerm + )) + val canUseHexColor = + allowHexadecimalColor && (!usePermission || useType.hexColorPerm == null || player.hasPermission( + useType.hexColorPerm + )) + + if ((!canUseColorCode) && (!canUseHexColor)) return false + var hasReversed = false + + // Reverse hex pattern + if (canUseHexColor) { + val nbReplacement = replaceHexToColor(colorToText, 14) + + if (nbReplacement > 0) hasReversed = true + } + + if (canUseColorCode) { + replaceAll(colorToText, "&", "&&", 1) + val nbReplacement = replaceAll(colorToText, "§", "&", 2) + + if (nbReplacement > 0) hasReversed = true + } + + return hasReversed + } + /** * Replace every instance of "from" to "to". * @param builder The builder to replace the string from. @@ -50,7 +111,7 @@ object AnvilColorUtil { index += to.length index = builder.indexOf(from, index) - numberOfChanges+=1 + numberOfChanges += 1 } return numberOfChanges @@ -68,21 +129,58 @@ object AnvilColorUtil { var numberOfChanges = 0 var startIndex = 0 - while(matcher.find(startIndex)){ + while (matcher.find(startIndex)) { startIndex = matcher.start() - if(startIndex >= builder.length - endOffset) break + if (startIndex >= builder.length - endOffset) break //HOW AND WHERE WOULD THIS HAPPEN ????? builder.replace(startIndex, startIndex + 1, "§x") - startIndex+=2 + startIndex += 2 for (i in 0..5) { builder.insert(startIndex, '§') - startIndex+=2 + startIndex += 2 } - numberOfChanges+=1 + numberOfChanges += 1 } return numberOfChanges } + /** + * Replace every hex color from the minecraft format to a format like #000000 + * @param builder The builder to replace the minecraft hex color from. + * @param endOffset Amount of character that should be ignored at the end. + * @return The number of replacement was that was done. + */ + private fun replaceColorToHex(builder: StringBuilder, endOffset: Int): Int { + val matcher: Matcher = TRANSFORMED_HEX_PATTERN.matcher(builder) + + var numberOfChanges = 0 + var startIndex = 0 + + while (matcher.find(startIndex)) { + startIndex = matcher.start() + if (startIndex >= builder.length - endOffset) break //HOW AND WHERE WOULD THIS HAPPEN ????? + + builder.replace(startIndex, startIndex + 2, "#") + startIndex += 1 + for (i in 0..5) { + builder.deleteCharAt(startIndex) + startIndex += 1 + } + + numberOfChanges += 1 + } + + return numberOfChanges + } + + enum class ColorUseType( + val colorCodePerm: String?, + val hexColorPerm: String? + ) { + RENAME("ca.color.code", "ca.color.hex"), + LORE_EDIT(null, null) + } + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index cbe0594..05f5831 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -30,21 +30,26 @@ object AnvilLoreEditUtil { if (!hasLoreEditByBookPermission(player)) return null val result = first.clone() - val meta = result.itemMeta?: return null + val meta = result.itemMeta ?: return null val lore = if (meta.hasLore()) { ArrayList(meta.lore!!) } else ArrayList() - //TODO check color if color if enabled - val lines = book.pages[0].split("\n") + val page = book.pages[0] + val lines = ArrayList(page.split("\n")) + val colorCost = colorLines(player, lines, LoreEditType.APPEND_BOOK) + lore.addAll(lines) meta.lore = lore result.itemMeta = meta - // Handle other xp - xpCost.addAndGet(lines.size * LoreEditType.APPEND_BOOK.perLineCost) - xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK)) + if (result == first) return null + + // Handle xp + xpCost.addAndGet(colorCost) // Cost of using color + xpCost.addAndGet(lines.size * LoreEditType.APPEND_BOOK.perLineCost) // per line cost + xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_BOOK)) // Fixed cost and work penalty return result } @@ -54,20 +59,25 @@ object AnvilLoreEditUtil { // remove lore val result = first.clone() - val leftMeta = result.itemMeta?: return null - val currentLore = leftMeta.lore?: return null + val leftMeta = result.itemMeta ?: return null + val currentLore = ArrayList(leftMeta.lore ?: return null) + + val uncolorCost = uncolorLines(player, currentLore, LoreEditType.REMOVE_BOOK) leftMeta.lore = null result.itemMeta = leftMeta - // Handle other xp + if (result == first) return null + + // Handle xp + xpCost.addAndGet(uncolorCost) xpCost.addAndGet(currentLore.size * LoreEditType.REMOVE_BOOK.perLineCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_BOOK)) return result } - // Return true if append, false if remove, null if neither + // Return true if appended, false if removed, null if neither fun bookLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? { // Test if the book & quil contain content val meta = second.itemMeta as BookMeta? ?: return false @@ -106,7 +116,7 @@ object AnvilLoreEditUtil { else handleLoreRemoveByBook(player, first, xpCost) } - // Return true if append, false if remove, null if neither + // Return true if appended, false if removed, null if neither fun paperLoreEditIsAppend(first: ItemStack, second: ItemStack): Boolean? { // Test if the paper contain a display name val meta = second.itemMeta ?: return false @@ -134,24 +144,31 @@ object AnvilLoreEditUtil { if (!hasLoreEditByPaperPermission(player)) return null val result = first.clone() - val meta = result.itemMeta - val lore = if (meta?.hasLore() == true) { + val meta = result.itemMeta?: return null + val lore = if (meta.hasLore()) { ArrayList(meta.lore!!) } else ArrayList() val appendEnd = LoreEditConfigUtil.paperLoreOrderIsEnd - //TODO check color if color if enabled - val line = second.itemMeta!!.displayName + // A bit overdone to color 1 line but hey + val tempList = ArrayList(1) + tempList.add(second.itemMeta!!.displayName) + val colorCost = colorLines(player, tempList, LoreEditType.APPEND_PAPER) + + val line = tempList[0] if (appendEnd) lore.add(line) else lore.add(0, line) - meta?.lore = lore + meta.lore = lore result.itemMeta = meta - // Handle other xp + if (result == first) return null + + // Handle xp + xpCost.addAndGet(colorCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.APPEND_PAPER)) return result @@ -167,13 +184,21 @@ object AnvilLoreEditUtil { val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd val lore: ArrayList = ArrayList(meta.lore!!) - if (removeEnd) lore.removeAt(lore.size - 1) + val line = if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) meta.lore = if (lore.isEmpty()) null else lore result.itemMeta = meta + // Get color cost to uncolor this line + val tempList = ArrayList(1) + tempList.add(line) + val uncolorCost = uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) + + if (result == first) return null + // Handle other xp + xpCost.addAndGet(uncolorCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_PAPER)) return result @@ -202,4 +227,86 @@ object AnvilLoreEditUtil { return xpCost } + private fun colorLines(player: Permissible, lines: ArrayList, useType: LoreEditType): Int { + val canUseHex: Boolean + val canUseColorCode: Boolean + val colorCost: Int + // If is book + if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) { + canUseHex = LoreEditConfigUtil.bookAllowHexColor + canUseColorCode = LoreEditConfigUtil.bookAllowColorCode + colorCost = LoreEditConfigUtil.bookUseColorCost + } // Else if is paper + else { + canUseHex = LoreEditConfigUtil.paperAllowHexColor + canUseColorCode = LoreEditConfigUtil.paperAllowColorCode + colorCost = LoreEditConfigUtil.paperUseColorCost + } + + // Now handle color of each lines + var hasUsedColor = false + for ((index, line) in lines.withIndex()) { + val coloredLine = StringBuilder(line) + + val lineUsedColor = AnvilColorUtil.handleColor( + coloredLine, + player, + false, canUseColorCode, canUseHex, + AnvilColorUtil.ColorUseType.LORE_EDIT + ) + + if (lineUsedColor) { + hasUsedColor = true + lines[index] = coloredLine.toString() + } + } + + return if (hasUsedColor) { + colorCost + } else { + 0 + } + } + + fun uncolorLines(player: Permissible, lines: ArrayList, useType: LoreEditType): Int { + val canUseHex: Boolean + val canUseColorCode: Boolean + val colorCost: Int + // If is book + if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) { + canUseHex = LoreEditConfigUtil.bookAllowHexColor + canUseColorCode = LoreEditConfigUtil.bookAllowColorCode + colorCost = LoreEditConfigUtil.bookUseColorCost + } // Else if is paper + else { + canUseHex = LoreEditConfigUtil.paperAllowHexColor + canUseColorCode = LoreEditConfigUtil.paperAllowColorCode + colorCost = LoreEditConfigUtil.paperUseColorCost + } + + // Now handle color of each lines + var hasUndidColor = false + for ((index, line) in lines.withIndex()) { + val uncoloredLine = StringBuilder(line) + + val lineUndidColor = AnvilColorUtil.revertColor( + uncoloredLine, + player, + false, canUseColorCode, canUseHex, + AnvilColorUtil.ColorUseType.LORE_EDIT + ) + + if (lineUndidColor) { + hasUndidColor = true + lines[index] = uncoloredLine.toString() + } + } + + return if (hasUndidColor) { + colorCost + } else { + 0 + } + } + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt index 680bb57..e393279 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt @@ -8,8 +8,6 @@ object LoreEditConfigUtil { const val IS_ENABLED = "enabled" const val FIXED_COST = "fixed_cost" const val PER_LINE_COST = "per_line_cost" - const val USE_COST_PENALTY = "use_cost_penalty" - const val INCREASE_COST_PENALTY = "increase_cost_penalty" const val DO_CONSUME = "do_consume" // Permission configs path @@ -61,8 +59,8 @@ object LoreEditConfigUtil { val FIXED_COST_RANGE = 0..1000 val PER_LINE_COST_RANGE = 0..1000 - val COLOR_BOOK_COST_RANGE = 0..1000 - val COLOR_PAPER_COST_RANGE = 0..1000 + private val COLOR_BOOK_COST_RANGE = 0..1000 + private val COLOR_PAPER_COST_RANGE = 0..1000 // ------------------- // Generic Get methods From 21a36637230a6ed79bbc1723a88cc34fc9aa8205 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:39:14 +0100 Subject: [PATCH 14/37] fix stupid init bug --- .../xyz/alexcrea/cuanvil/util/AnvilUseType.kt | 11 ++------ .../alexcrea/cuanvil/util/AnvilUseTypeUtil.kt | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseTypeUtil.kt diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt index d765fa3..00f272f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt @@ -1,6 +1,5 @@ package xyz.alexcrea.cuanvil.util -import io.delilaheve.util.ConfigOptions import org.bukkit.Material import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart @@ -52,20 +51,14 @@ enum class AnvilUseType( ), ; - companion object { - private fun defaultPath(typeName: String): String { - return "${ConfigOptions.WORK_PENALTY_ROOT}.$typeName" - } - - } - constructor( typeName: String, defaultPenalty: WorkPenaltyPart, displayName: String, displayMat: Material ) : this( - typeName, defaultPath(typeName), + typeName, + AnvilUseTypeUtil.defaultPath(typeName), // stupid util class defaultPenalty, displayName, displayMat ) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseTypeUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseTypeUtil.kt new file mode 100644 index 0000000..c72a35a --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseTypeUtil.kt @@ -0,0 +1,26 @@ +package xyz.alexcrea.cuanvil.util + +import io.delilaheve.util.ConfigOptions + +object AnvilUseTypeUtil { + + /* + By stupidity of kotlin not allowing static function outside of companion object I need to do another util class only for 1 function: + Companion object on enum class seems to get initialized AFTER the enum itself + that mean. if you want to call a static function on the enum class itself YOU CAN'T. you need to do this stupid thing + or you can make a stupid top level function OR object that even worse because of global scope pollution + (btw was gpt ""solution"". fortunately I do not "vibe code" so I do what I know instead of stupid AI solution & code) + I mean, this is still global scope pollution bc of a USELESS class that SHOULD not exist but as a class is better than a random *ss function + + sorry for the rent but this made me frustrated + + Note: I still like a lot of part of kotlin compared to java but this part is one that I hate + */ + /** + * Get config path for normal anvil use + */ + fun defaultPath(typeName: String): String { + return "${ConfigOptions.WORK_PENALTY_ROOT}.$typeName" + } + +} \ No newline at end of file From 91346209ddfef665809eef17b92a00a9cc5d4c9a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:22:34 +0100 Subject: [PATCH 15/37] fixed item sometimes dupe --- .../cuanvil/listener/AnvilResultListener.kt | 26 +++++++++---------- .../cuanvil/util/config/LoreEditType.kt | 4 +-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index ce0f3af..c684af6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -208,6 +208,10 @@ class AnvilResultListener : Listener { output: ItemStack, repairCost: Int, ): Boolean { + // To avoid vanilla, we cancel the event + event.result = Event.Result.DENY + event.isCancelled = true + // Assumed if player do not have enough xp then it returned MIN_VALUE if (repairCost == Int.MIN_VALUE) return false @@ -253,19 +257,15 @@ class AnvilResultListener : Listener { rightItem.amount, unitRepairResult ) - // To avoid vanilla, we cancel the event for unit repair - event.result = Event.Result.DENY - event.isCancelled = true - // Get repair cost val repairCost = getUnitRepairCost(inventory, player, leftItem, output, resultCopy, resultAmount) // And then we give the item manually extractAnvilResult( event, player, inventory, - leftItem, 1, + null, 0, rightItem, resultAmount, - output, repairCost + resultCopy, repairCost ) } @@ -328,19 +328,19 @@ class AnvilResultListener : Listener { if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta, xpCost)) return false // Remove pages to book - val bookCopy: ItemStack? + val clearedBook: ItemStack? if (LoreEditType.APPEND_BOOK.doConsume) { - bookCopy = rightItem.clone() + clearedBook = rightItem.clone() bookMeta.pages = Collections.emptyList() - bookCopy.itemMeta = bookMeta + clearedBook.itemMeta = bookMeta } else { - bookCopy = null + clearedBook = null } return extractAnvilResult( event, player, inventory, - leftItem, 1, - bookCopy, 0, + null, 0, + clearedBook, 0, output, xpCost.get() ) } else { @@ -370,7 +370,7 @@ class AnvilResultListener : Listener { return extractAnvilResult( event, player, inventory, - leftItem, 1, + null, 0, rightCopy, 0, output, xpCost.get() ) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt index 76a1bb8..edc8cc1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -11,8 +11,8 @@ enum class LoreEditType( ) { APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true), REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE,false, true), - APPEND_PAPER("lore_edit.paper.append", AnvilUseType.LORE_EDIT_PAPER_APPEND,true, false), - REMOVE_PAPER("lore_edit.paper.remove", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false, false), + APPEND_PAPER("lore_edit.paper.append_line", AnvilUseType.LORE_EDIT_PAPER_APPEND,true, false), + REMOVE_PAPER("lore_edit.paper.remove_line", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false, false), ; /** From 23ff1eb5d35387a9f37943f8f06cbd8cb6827fd4 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:25:33 +0100 Subject: [PATCH 16/37] fix do consume being inverted for book edit --- .../xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index c684af6..9a2f896 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -330,11 +330,11 @@ class AnvilResultListener : Listener { // Remove pages to book val clearedBook: ItemStack? if (LoreEditType.APPEND_BOOK.doConsume) { + clearedBook = null + } else { clearedBook = rightItem.clone() bookMeta.pages = Collections.emptyList() clearedBook.itemMeta = bookMeta - } else { - clearedBook = null } return extractAnvilResult( From 4cbfb6eab0cf3b47beb2ee5b6a9315453374947b Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:49:37 +0100 Subject: [PATCH 17/37] 2 minor fix fix work penalty type setting gui not saving on the right path fix anvil use type not using correct path for paper --- .../gui/config/settings/WorkPenaltyTypeSettingGui.java | 3 +-- .../kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java index 89af20e..888aa25 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java @@ -219,12 +219,11 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { } public static boolean saveWorkPenalty(Map partEnum) { - String path = ConfigOptions.WORK_PENALTY_ROOT; ConfigHolder configHolder = ConfigHolder.DEFAULT_CONFIG; FileConfiguration config = configHolder.getConfig(); partEnum.forEach((key, value) -> { - String partPath = path + "." + key.getTypeName(); + String partPath = key.getPath(); if (key.getDefaultPenalty().equals(value)) { config.set(partPath, null); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt index 00f272f..2072d56 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.util import org.bukkit.Material import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart +import xyz.alexcrea.cuanvil.util.config.LoreEditType enum class AnvilUseType( val typeName: String, val path: String, @@ -30,22 +31,22 @@ enum class AnvilUseType( "Custom Craft", Material.CRAFTING_TABLE ), LORE_EDIT_BOOK_APPEND( - "lore_edit_book_append", "lore_edit.book_and_quil.append", + "lore_edit_book_append", LoreEditType.APPEND_BOOK.rootPath, WorkPenaltyPart(false, false), "Book Add", Material.WRITABLE_BOOK ), LORE_EDIT_BOOK_REMOVE( - "lore_edit_book_remove", "lore_edit.book_and_quil.remove", + "lore_edit_book_remove", LoreEditType.REMOVE_BOOK.rootPath, WorkPenaltyPart(false, false), "Book Remove", Material.WRITABLE_BOOK ), LORE_EDIT_PAPER_APPEND( - "lore_edit_paper_append", "lore_edit.paper.append", + "lore_edit_paper_append", LoreEditType.APPEND_PAPER.rootPath, WorkPenaltyPart(false, false), "Paper Add", Material.WRITABLE_BOOK ), LORE_EDIT_PAPER_REMOVE( - "lore_edit_paper_remove", "lore_edit.paper.remove", + "lore_edit_paper_remove", LoreEditType.REMOVE_PAPER.rootPath, WorkPenaltyPart(false, false), "Paper Remove", Material.WRITABLE_BOOK ), From 51dbbccc1ca4853390ce491a39365739a625900d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Mon, 17 Mar 2025 17:20:29 +0100 Subject: [PATCH 18/37] change color configs & add do consume to lore removal --- .../cuanvil/update/PluginSetDefault.java | 77 +++++++-------- .../cuanvil/listener/AnvilResultListener.kt | 66 +++++++------ .../cuanvil/util/AnvilLoreEditUtil.kt | 40 ++------ .../cuanvil/util/config/LoreEditConfigUtil.kt | 94 +++---------------- .../cuanvil/util/config/LoreEditType.kt | 80 +++++++++++++++- src/main/resources/config.yml | 44 +++++---- 6 files changed, 199 insertions(+), 202 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 0530140..363bd6a 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -1,9 +1,11 @@ package xyz.alexcrea.cuanvil.update; import io.delilaheve.CustomAnvil; +import io.delilaheve.util.ConfigOptions; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil; import xyz.alexcrea.cuanvil.util.config.LoreEditType; import static io.delilaheve.util.ConfigOptions.*; @@ -11,75 +13,74 @@ import static xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.*; public class PluginSetDefault { - public static void reAddMissingDefault(){ + public static void reAddMissingDefault() { FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); int nbSet = 0; - nbSet+= trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST); - nbSet+= trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST); - nbSet+= trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT); - nbSet+= trySetDefault(config, REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE); - nbSet+= trySetDefault(config, ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST); - nbSet+= trySetDefault(config, UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST); - nbSet+= trySetDefault(config, ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST); - nbSet+= trySetDefault(config, SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST); - nbSet+= trySetDefault(config, ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE); - nbSet+= trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR); - nbSet+= trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR); - nbSet+= trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST); - nbSet+= trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT); + nbSet += trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST); + nbSet += trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST); + nbSet += trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT); + nbSet += trySetDefault(config, REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE); + nbSet += trySetDefault(config, ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST); + nbSet += trySetDefault(config, UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST); + nbSet += trySetDefault(config, ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST); + nbSet += trySetDefault(config, SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST); + nbSet += trySetDefault(config, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE); + nbSet += trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR); + nbSet += trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR); + nbSet += trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST); + nbSet += trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT); // Lore Edit defaults for (@NotNull LoreEditType value : LoreEditType.values()) { String path = value.getRootPath() + "."; - nbSet+= trySetDefault(config, path + IS_ENABLED, DEFAULT_IS_ENABLED); - nbSet+= trySetDefault(config, path + FIXED_COST, DEFAULT_FIXED_COST); - if(value.isMultiLine()){ - nbSet+= trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); + nbSet += trySetDefault(config, path + IS_ENABLED, DEFAULT_IS_ENABLED); + nbSet += trySetDefault(config, path + FIXED_COST, DEFAULT_FIXED_COST); + + nbSet += trySetDefault(config, path + DO_CONSUME, DEFAULT_DO_CONSUME); + if (value.isMultiLine()) { + nbSet += trySetDefault(config, path + PER_LINE_COST, DEFAULT_PER_LINE_COST); } - if(value.isAppend()){ - nbSet+= trySetDefault(config, path + DO_CONSUME, DEFAULT_DO_CONSUME); + if (value.isAppend()) { + nbSet += trySetDefault(config, path + LoreEditConfigUtil.ALLOW_COLOR_CODE, LoreEditConfigUtil.DEFAULT_ALLOW_COLOR_CODE); + nbSet += trySetDefault(config, path + ALLOW_HEX_COLOR, DEFAULT_ALLOW_HEX_COLOR); + nbSet += trySetDefault(config, path + USE_COLOR_COST, DEFAULT_USE_COLOR_COST); + } else { + nbSet += trySetDefault(config, path + REMOVE_COLOR_ON_LORE_REMOVE, DEFAULT_REMOVE_COLOR_ON_LORE_REMOVE); + nbSet += trySetDefault(config, path + REMOVE_COLOR_COST, DEFAULT_REMOVE_COLOR_COST); } } - nbSet+= trySetDefault(config, BOOK_PERMISSION_NEEDED, DEFAULT_BOOK_PERMISSION_NEEDED); - nbSet+= trySetDefault(config, PAPER_PERMISSION_NEEDED, DEFAULT_PAPER_PERMISSION_NEEDED); + nbSet += trySetDefault(config, BOOK_PERMISSION_NEEDED, DEFAULT_BOOK_PERMISSION_NEEDED); + nbSet += trySetDefault(config, PAPER_PERMISSION_NEEDED, DEFAULT_PAPER_PERMISSION_NEEDED); - nbSet+= trySetDefault(config, COLOR_BOOK_COLOR_CODE, DEFAULT_COLOR_BOOK_COLOR_CODE); - nbSet+= trySetDefault(config, COLOR_BOOK_HEX, DEFAULT_COLOR_BOOK_HEX); - nbSet+= trySetDefault(config, COLOR_BOOK_COST, DEFAULT_COLOR_BOOK_COST); + nbSet += trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER); - nbSet+= trySetDefault(config, COLOR_PAPER_COLOR_CODE, DEFAULT_COLOR_PAPER_COLOR_CODE); - nbSet+= trySetDefault(config, COLOR_PAPER_HEX, DEFAULT_COLOR_PAPER_HEX); - nbSet+= trySetDefault(config, COLOR_PAPER_COST, DEFAULT_COLOR_PAPER_COST); - - nbSet+= trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER); - - if(nbSet > 0){ + if (nbSet > 0) { CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); } } - private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, @NotNull String value){ - if(config.isSet(path)) return 0; + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, @NotNull String value) { + if (config.isSet(path)) return 0; config.set(path, value); return 1; } - private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, int value){ - if(config.isSet(path)) return 0; + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, int value) { + if (config.isSet(path)) return 0; config.set(path, value); return 1; } - private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, boolean value){ - if(config.isSet(path)) return 0; + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, boolean value) { + if (config.isSet(path)) return 0; config.set(path, value); return 1; diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 9a2f896..f4a1cff 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -352,22 +352,27 @@ class AnvilResultListener : Listener { val lore = ArrayList(meta.lore!!) if (lore.isEmpty()) return false - // Uncolor the page - AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK) + val rightCopy : ItemStack? + if (LoreEditType.APPEND_PAPER.doConsume) { + rightCopy = null + } else { + // Uncolor the page + AnvilLoreEditUtil.uncolorLines(player, lore, LoreEditType.REMOVE_BOOK) - val bookPage = StringBuilder() - lore.forEach { - if (bookPage.isNotEmpty()) bookPage.append('\n') - bookPage.append(it) + val bookPage = StringBuilder() + lore.forEach { + if (bookPage.isNotEmpty()) bookPage.append('\n') + bookPage.append(it) + } + + val resultPage = bookPage.toString() + //TODO maybe check page size ? bc it may be too big ??? + + rightCopy = rightItem.clone() + bookMeta.setPages(resultPage) + rightCopy.itemMeta = bookMeta } - val resultPage = bookPage.toString() - //TODO maybe check page size ? bc it may be too big ??? - - val rightCopy = rightItem.clone() - bookMeta.setPages(resultPage) - rightCopy.itemMeta = bookMeta - return extractAnvilResult( event, player, inventory, null, 0, @@ -428,23 +433,28 @@ class AnvilResultListener : Listener { val lore = leftMeta.lore!! if (lore.isEmpty()) return false - val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd - var line = if (removeEnd) lore[lore.size - 1] - else lore[0] - - // Overkill but uncolor the line - val tempList = ArrayList(1) - tempList.add(line) - AnvilLoreEditUtil.uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) - line = tempList[0] - // Create result item - val rightClone = rightItem.clone() - rightClone.amount = 1 + val rightClone: ItemStack? + if(LoreEditType.REMOVE_PAPER.doConsume){ + rightClone = null + }else{ + val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd + var line = if (removeEnd) lore[lore.size - 1] + else lore[0] - val resultMeta = rightClone.itemMeta ?: return false - resultMeta.setDisplayName(line) - rightClone.itemMeta = resultMeta + // Overkill but uncolor the line + val tempList = ArrayList(1) + tempList.add(line) + AnvilLoreEditUtil.uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) + line = tempList[0] + + rightClone = rightItem.clone() + rightClone.amount = 1 + + val resultMeta = rightClone.itemMeta ?: return false + resultMeta.setDisplayName(line) + rightClone.itemMeta = resultMeta + } return if (rightItem.amount > 1) { extractAnvilResult( diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 05f5831..e33a43d 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -227,21 +227,10 @@ object AnvilLoreEditUtil { return xpCost } - private fun colorLines(player: Permissible, lines: ArrayList, useType: LoreEditType): Int { - val canUseHex: Boolean - val canUseColorCode: Boolean - val colorCost: Int - // If is book - if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) { - canUseHex = LoreEditConfigUtil.bookAllowHexColor - canUseColorCode = LoreEditConfigUtil.bookAllowColorCode - colorCost = LoreEditConfigUtil.bookUseColorCost - } // Else if is paper - else { - canUseHex = LoreEditConfigUtil.paperAllowHexColor - canUseColorCode = LoreEditConfigUtil.paperAllowColorCode - colorCost = LoreEditConfigUtil.paperUseColorCost - } + private fun colorLines(player: Permissible, lines: ArrayList, editType: LoreEditType): Int { + val canUseHex = editType.allowHexColor + val canUseColorCode = editType.allowColorCode + val colorCost = editType.useColorCost // Now handle color of each lines var hasUsedColor = false @@ -268,21 +257,8 @@ object AnvilLoreEditUtil { } } - fun uncolorLines(player: Permissible, lines: ArrayList, useType: LoreEditType): Int { - val canUseHex: Boolean - val canUseColorCode: Boolean - val colorCost: Int - // If is book - if (useType == LoreEditType.REMOVE_BOOK || useType == LoreEditType.APPEND_BOOK) { - canUseHex = LoreEditConfigUtil.bookAllowHexColor - canUseColorCode = LoreEditConfigUtil.bookAllowColorCode - colorCost = LoreEditConfigUtil.bookUseColorCost - } // Else if is paper - else { - canUseHex = LoreEditConfigUtil.paperAllowHexColor - canUseColorCode = LoreEditConfigUtil.paperAllowColorCode - colorCost = LoreEditConfigUtil.paperUseColorCost - } + fun uncolorLines(player: Permissible, lines: ArrayList, editType: LoreEditType): Int { + if(!editType.shouldRemoveColorOnLoreRemoval) return 0 // Now handle color of each lines var hasUndidColor = false @@ -292,7 +268,7 @@ object AnvilLoreEditUtil { val lineUndidColor = AnvilColorUtil.revertColor( uncoloredLine, player, - false, canUseColorCode, canUseHex, + false, true, true, AnvilColorUtil.ColorUseType.LORE_EDIT ) @@ -303,7 +279,7 @@ object AnvilLoreEditUtil { } return if (hasUndidColor) { - colorCost + editType.removeColorCost } else { 0 } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt index e393279..f5758dc 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditConfigUtil.kt @@ -15,13 +15,12 @@ object LoreEditConfigUtil { const val PAPER_PERMISSION_NEEDED = "lore_edit.paper.use_permission" // Color configs path - const val COLOR_BOOK_COLOR_CODE = "lore_edit.book_and_quil.color.allow_color_code" - const val COLOR_BOOK_HEX = "lore_edit.book_and_quil.color.allow_hexadecimal_color" - const val COLOR_BOOK_COST = "lore_edit.book_and_quil.color.use_cost" + const val ALLOW_COLOR_CODE = "allow_color_code" + const val ALLOW_HEX_COLOR = "allow_hexadecimal_color" + const val USE_COLOR_COST = "use_cost" - const val COLOR_PAPER_COLOR_CODE = "lore_edit.paper.color.allow_color_code" - const val COLOR_PAPER_HEX = "lore_edit.paper.color.allow_hexadecimal_color" - const val COLOR_PAPER_COST = "lore_edit.paper.color.use_cost" + const val REMOVE_COLOR_ON_LORE_REMOVE = "remove_color_on_remove" + const val REMOVE_COLOR_COST = "remove_color_cost" // Lore order config path const val PAPER_EDIT_ORDER = "lore_edit.paper.order" @@ -41,13 +40,12 @@ object LoreEditConfigUtil { const val DEFAULT_PAPER_PERMISSION_NEEDED = true // Color configs defaults - const val DEFAULT_COLOR_BOOK_COLOR_CODE = true - const val DEFAULT_COLOR_BOOK_HEX = true - const val DEFAULT_COLOR_BOOK_COST = 0 + const val DEFAULT_ALLOW_COLOR_CODE = true + const val DEFAULT_ALLOW_HEX_COLOR = true + const val DEFAULT_USE_COLOR_COST = 0 - const val DEFAULT_COLOR_PAPER_COLOR_CODE = true - const val DEFAULT_COLOR_PAPER_HEX = true - const val DEFAULT_COLOR_PAPER_COST = 0 + const val DEFAULT_REMOVE_COLOR_ON_LORE_REMOVE = false + const val DEFAULT_REMOVE_COLOR_COST = 0 // Lore order config default const val DEFAULT_PAPER_EDIT_ORDER = "end" @@ -59,8 +57,8 @@ object LoreEditConfigUtil { val FIXED_COST_RANGE = 0..1000 val PER_LINE_COST_RANGE = 0..1000 - private val COLOR_BOOK_COST_RANGE = 0..1000 - private val COLOR_PAPER_COST_RANGE = 0..1000 + val USE_COLOR_COST_RANGE = 0..1000 + val REMOVE_COLOR_COST_RANGE = 0..1000 // ------------------- // Generic Get methods @@ -102,72 +100,4 @@ object LoreEditConfigUtil { // Color Get methods // ----------------- - // book edit functions - /** - * Allow usage of color code on book lore edit - */ - val bookAllowColorCode: Boolean - get() { - return CONFIG - .config - .getBoolean(COLOR_BOOK_COLOR_CODE, DEFAULT_COLOR_BOOK_COLOR_CODE) - } - - /** - * Allow usage of hexadecimal color on book lore edit - */ - val bookAllowHexColor: Boolean - get() { - return CONFIG - .config - .getBoolean(COLOR_BOOK_HEX, DEFAULT_COLOR_BOOK_HEX) - } - - /** - * Cost when using either color code and hex color on book edit - */ - val bookUseColorCost: Int - get() { - return CONFIG - .config - .getInt(COLOR_BOOK_COST, DEFAULT_COLOR_BOOK_COST) - .takeIf { it in COLOR_BOOK_COST_RANGE } - ?: DEFAULT_COLOR_BOOK_COST - - } - - // paper edit functions - /** - * Allow usage of color code on paper lore edit - */ - val paperAllowColorCode: Boolean - get() { - return CONFIG - .config - .getBoolean(COLOR_PAPER_COLOR_CODE, DEFAULT_COLOR_PAPER_COLOR_CODE) - } - - /** - * Allow usage of hexadecimal color on paper lore edit - */ - val paperAllowHexColor: Boolean - get() { - return CONFIG - .config - .getBoolean(COLOR_PAPER_HEX, DEFAULT_COLOR_PAPER_HEX) - } - - /** - * Cost when using either color code and hex color on paper edit - */ - val paperUseColorCost: Int - get() { - return CONFIG - .config - .getInt(COLOR_PAPER_COST, DEFAULT_COLOR_PAPER_COST) - .takeIf { it in COLOR_PAPER_COST_RANGE } - ?: DEFAULT_COLOR_PAPER_COST - - } - } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt index edc8cc1..6079bbe 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -1,6 +1,18 @@ package xyz.alexcrea.cuanvil.util.config import xyz.alexcrea.cuanvil.util.AnvilUseType +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_COLOR_CODE +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_HEX_COLOR +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.DEFAULT_ALLOW_COLOR_CODE +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.DEFAULT_ALLOW_HEX_COLOR +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.DEFAULT_REMOVE_COLOR_COST +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.DEFAULT_REMOVE_COLOR_ON_LORE_REMOVE +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.DEFAULT_USE_COLOR_COST +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.REMOVE_COLOR_COST +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.REMOVE_COLOR_COST_RANGE +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.USE_COLOR_COST +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.USE_COLOR_COST_RANGE import xyz.alexcrea.cuanvil.config.ConfigHolder.DEFAULT_CONFIG as CONFIG enum class LoreEditType( @@ -10,9 +22,9 @@ enum class LoreEditType( val isMultiLine: Boolean, ) { APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true), - REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE,false, true), - APPEND_PAPER("lore_edit.paper.append_line", AnvilUseType.LORE_EDIT_PAPER_APPEND,true, false), - REMOVE_PAPER("lore_edit.paper.remove_line", AnvilUseType.LORE_EDIT_PAPER_REMOVE,false, false), + REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE, false, true), + APPEND_PAPER("lore_edit.paper.append_line", AnvilUseType.LORE_EDIT_PAPER_APPEND, true, false), + REMOVE_PAPER("lore_edit.paper.remove_line", AnvilUseType.LORE_EDIT_PAPER_REMOVE, false, false), ; /** @@ -55,10 +67,70 @@ enum class LoreEditType( */ val doConsume: Boolean get() { - if (!isAppend) throw IllegalStateException("Lore edit Consume test should not happen on append") return CONFIG .config .getBoolean("${rootPath}.${LoreEditConfigUtil.DO_CONSUME}", LoreEditConfigUtil.DEFAULT_DO_CONSUME) } + /** + * Allow usage of color code on lore add + */ + val allowColorCode: Boolean + get() { + if (!isAppend) throw IllegalStateException("Can only call with an append edit type") + return CONFIG + .config + .getBoolean("$rootPath.$ALLOW_COLOR_CODE", DEFAULT_ALLOW_COLOR_CODE) + } + + /** + * Allow usage of hexadecimal color on lore add + */ + val allowHexColor: Boolean + get() { + if (!isAppend) throw IllegalStateException("Can only call with an append edit type") + return CONFIG + .config + .getBoolean("${rootPath}.$ALLOW_HEX_COLOR", DEFAULT_ALLOW_HEX_COLOR) + } + + /** + * Cost when using either color code and hex color on lore add + */ + val useColorCost: Int + get() { + if (!isAppend) throw IllegalStateException("Can only call with an append edit type") + return CONFIG + .config + .getInt("${rootPath}.$USE_COLOR_COST", DEFAULT_USE_COLOR_COST) + .takeIf { it in USE_COLOR_COST_RANGE } + ?: DEFAULT_USE_COLOR_COST + + } + + /** + * Should the color code & hex color should get removed on lore remove + */ + val shouldRemoveColorOnLoreRemoval: Boolean + get() { + if (isAppend) throw IllegalStateException("Can only call with a remove edit type") + return CONFIG + .config + .getBoolean("${rootPath}.$REMOVE_COLOR_ON_LORE_REMOVE", DEFAULT_REMOVE_COLOR_ON_LORE_REMOVE) + } + + /** + * Cost when using either color code and hex color on lore remove + */ + val removeColorCost: Int + get() { + if (isAppend) throw IllegalStateException("Can only call with a remove edit type") + return CONFIG + .config + .getInt("${rootPath}.$REMOVE_COLOR_COST", DEFAULT_REMOVE_COLOR_COST) + .takeIf { it in REMOVE_COLOR_COST_RANGE } + ?: DEFAULT_REMOVE_COLOR_COST + + } + } \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2f7dc0e..9c1ad67 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -288,6 +288,13 @@ lore_edit: shared_additive: false # If adding the lore consume the book & quil do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 remove: # If removing lore using book & quil is enabled @@ -300,15 +307,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore consume the book & quil + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 paper: # Permission is ca.lore_edit.paper @@ -327,6 +331,13 @@ lore_edit: shared_additive: false # If adding the lore line consume the paper do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + color_use_cost: 0 remove_line: # If removing lore line using paper is enabled @@ -337,15 +348,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore line consume the paper + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 # Whether to show debug logging debug_log: false From c4ad5ae28eb0dff98162b546556027ff88276ca7 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:38:19 +0100 Subject: [PATCH 19/37] fix circular dependency WHY is there no warning when it happens --- .../xyz/alexcrea/cuanvil/util/AnvilUseType.kt | 8 ++++---- .../alexcrea/cuanvil/util/config/LoreEditType.kt | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt index 2072d56..d17e908 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilUseType.kt @@ -31,22 +31,22 @@ enum class AnvilUseType( "Custom Craft", Material.CRAFTING_TABLE ), LORE_EDIT_BOOK_APPEND( - "lore_edit_book_append", LoreEditType.APPEND_BOOK.rootPath, + "lore_edit_book_append", "lore_edit.book_and_quil.append", WorkPenaltyPart(false, false), "Book Add", Material.WRITABLE_BOOK ), LORE_EDIT_BOOK_REMOVE( - "lore_edit_book_remove", LoreEditType.REMOVE_BOOK.rootPath, + "lore_edit_book_remove", "lore_edit.book_and_quil.remove", WorkPenaltyPart(false, false), "Book Remove", Material.WRITABLE_BOOK ), LORE_EDIT_PAPER_APPEND( - "lore_edit_paper_append", LoreEditType.APPEND_PAPER.rootPath, + "lore_edit_paper_append", "lore_edit.paper.append_line", WorkPenaltyPart(false, false), "Paper Add", Material.WRITABLE_BOOK ), LORE_EDIT_PAPER_REMOVE( - "lore_edit_paper_remove", LoreEditType.REMOVE_PAPER.rootPath, + "lore_edit_paper_remove", "lore_edit.paper.remove_line", WorkPenaltyPart(false, false), "Paper Remove", Material.WRITABLE_BOOK ), diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt index 6079bbe..ed5ef1b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/config/LoreEditType.kt @@ -21,12 +21,18 @@ enum class LoreEditType( val isAppend: Boolean, val isMultiLine: Boolean, ) { - APPEND_BOOK("lore_edit.book_and_quil.append", AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true), - REMOVE_BOOK("lore_edit.book_and_quil.remove", AnvilUseType.LORE_EDIT_BOOK_REMOVE, false, true), - APPEND_PAPER("lore_edit.paper.append_line", AnvilUseType.LORE_EDIT_PAPER_APPEND, true, false), - REMOVE_PAPER("lore_edit.paper.remove_line", AnvilUseType.LORE_EDIT_PAPER_REMOVE, false, false), + APPEND_BOOK(AnvilUseType.LORE_EDIT_BOOK_APPEND, true, true), + REMOVE_BOOK(AnvilUseType.LORE_EDIT_BOOK_REMOVE, false, true), + APPEND_PAPER(AnvilUseType.LORE_EDIT_PAPER_APPEND, true, false), + REMOVE_PAPER(AnvilUseType.LORE_EDIT_PAPER_REMOVE, false, false), ; + constructor( + useType: AnvilUseType, + isAppend: Boolean, + isMultiLine: Boolean, + ) : this(useType.path, useType, isAppend, isMultiLine) + /** * If this edit type is enabled */ From 90db843417211dabe657c42ff812a8603224bdb7 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:05:47 +0100 Subject: [PATCH 20/37] fix "revert color" not using the right function --- src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt index 0bb1fe9..277a8d1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt @@ -79,7 +79,7 @@ object AnvilColorUtil { // Reverse hex pattern if (canUseHexColor) { - val nbReplacement = replaceHexToColor(colorToText, 14) + val nbReplacement = replaceColorToHex(colorToText, 14) if (nbReplacement > 0) hasReversed = true } From 62d32fcd7e0f2810c7e1325c2faa29eca893795b Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:07:31 +0100 Subject: [PATCH 21/37] update default configs --- defaultconfigs/1.18/config.yml | 44 ++++++++++++++++++++-------------- defaultconfigs/1.21/config.yml | 44 ++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 36 deletions(-) diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index 2f7dc0e..9c1ad67 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -288,6 +288,13 @@ lore_edit: shared_additive: false # If adding the lore consume the book & quil do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 remove: # If removing lore using book & quil is enabled @@ -300,15 +307,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore consume the book & quil + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 paper: # Permission is ca.lore_edit.paper @@ -327,6 +331,13 @@ lore_edit: shared_additive: false # If adding the lore line consume the paper do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + color_use_cost: 0 remove_line: # If removing lore line using paper is enabled @@ -337,15 +348,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore line consume the paper + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index 2f7dc0e..9c1ad67 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -288,6 +288,13 @@ lore_edit: shared_additive: false # If adding the lore consume the book & quil do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + use_cost: 0 remove: # If removing lore using book & quil is enabled @@ -300,15 +307,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore consume the book & quil + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 paper: # Permission is ca.lore_edit.paper @@ -327,6 +331,13 @@ lore_edit: shared_additive: false # If adding the lore line consume the paper do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + allow_color_code: true + allow_hexadecimal_color: true + color_use_cost: 0 remove_line: # If removing lore line using paper is enabled @@ -337,15 +348,12 @@ lore_edit: shared_increase: false # Increase shared left item cost penalty shared_additive: false - - # Allow using color code and hexadecimal color when editing lore via book & quil - # - # Color code are prefixed by "&" and hexadecimal color by "#" - # Color code will not be applied if it colors nothing. "&&" can be used to write "&" - color: - allow_color_code: true - allow_hexadecimal_color: true - use_cost: 0 + # If removing the lore line consume the paper + do_consume: false + # If the color should get back to color code or hex format + remove_color_on_remove: true + # Cost of replacing colors + remove_color_cost: 0 # Whether to show debug logging debug_log: false From 7bde5bcb04fca77fbe286028d721464f82ab84ff Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:57:45 +0100 Subject: [PATCH 22/37] fix disabled permission not working --- .../kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index e33a43d..e3b6d41 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -14,11 +14,11 @@ object AnvilLoreEditUtil { private const val LORE_BY_PAPER: String = "ca.lore_edit.paper" private fun hasLoreEditByBookPermission(player: Permissible): Boolean { - return LoreEditConfigUtil.bookLoreEditNeedPermission && player.hasPermission(LORE_BY_BOOK) + return !LoreEditConfigUtil.bookLoreEditNeedPermission || player.hasPermission(LORE_BY_BOOK) } private fun hasLoreEditByPaperPermission(player: Permissible): Boolean { - return LoreEditConfigUtil.paperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER) + return !LoreEditConfigUtil.paperLoreEditNeedPermission || player.hasPermission(LORE_BY_PAPER) } fun handleLoreAppendByBook( From 1b462e8af6bc4d85463d1856cdfd4dcaff979fc1 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 18:38:47 +0100 Subject: [PATCH 23/37] Add cursor click test --- .../cuanvil/util/AnvilClickTestData.java | 50 ++++++++++++ .../cuanvil/util/AnvilFuseTestUtil.java | 79 ++++++++++++++++--- 2 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java new file mode 100644 index 0000000..7192303 --- /dev/null +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java @@ -0,0 +1,50 @@ +package xyz.alexcrea.cuanvil.util; + +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +public record AnvilClickTestData( + @Nullable ItemStack leftItem, + @Nullable ItemStack rightItem, + @Nullable ItemStack resultSlotItem, + @Nullable ItemStack expectedCursor, + int levelCost, + @Nullable Event.Result expectedResult, + boolean testNoLevelNoChange, + @Nullable Event.Result npChangeResult +) { + + public AnvilClickTestData(@Nullable ItemStack leftItem, + @Nullable ItemStack rightItem, + @Nullable ItemStack resultSlotItem, + @Nullable ItemStack expectedCursor, + int levelCost, + @Nullable Event.Result expectedResult) { + this(leftItem, rightItem, resultSlotItem, + expectedCursor, levelCost, expectedResult, + false, null); + } + + public AnvilClickTestData(@Nullable ItemStack leftItem, + @Nullable ItemStack rightItem, + @Nullable ItemStack resultSlotItem, + @Nullable ItemStack expectedCursor, + int levelCost) { + this(leftItem, rightItem, resultSlotItem, + expectedCursor, levelCost, null); + } + + public AnvilClickTestData(@Nullable ItemStack expectedCursor, + int levelCost, + @Nullable Event.Result expectedResult) { + this(null, null, null, + expectedCursor, levelCost, expectedResult, + false, null); + } + + public AnvilClickTestData(@Nullable ItemStack expectedCursor, + int levelCost) { + this(expectedCursor, levelCost, null); + } +} diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java index 2bb5bc2..1fb534e 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java @@ -3,7 +3,9 @@ package xyz.alexcrea.cuanvil.util; import io.delilaheve.util.ItemUtil; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.inventory.*; import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -12,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Assertions; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.listener.AnvilResultListener; import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener; import xyz.alexcrea.cuanvil.mock.AnvilViewMock; @@ -21,6 +24,9 @@ import java.util.List; public class AnvilFuseTestUtil { + private static PrepareAnvilListener PREPARE_LISTENER = new PrepareAnvilListener(); + private static AnvilResultListener RESULT_LISTENER = new AnvilResultListener(); + public static ItemStack prepareItem(@NotNull Material material, @NotNull List enchantments, @NotNull List level){ @@ -86,7 +92,7 @@ public class AnvilFuseTestUtil { PrepareAnvilEvent event = new PrepareAnvilEvent(view, anvil.getItem(2)); // Not ideal but possible and the easiest so why not - new PrepareAnvilListener().anvilCombineCheck(event); + PREPARE_LISTENER.anvilCombineCheck(event); anvil.setResult(event.getResult()); } catch (Exception e){ Assertions.fail(e); @@ -117,9 +123,62 @@ public class AnvilFuseTestUtil { testPlacingItem(anvil, player, 0, data.expectedPriceAfterBothPlaced(), data.leftItem(), data.expectedResult()); + } - // Sadly, can't currently test player click + public static void executeAnvilClick( + @NotNull AnvilInventory anvil, + @NotNull Player player, + @NotNull AnvilClickTestData data + ) { + if(data.testNoLevelNoChange()){ + ItemStack left = anvil.getFirstItem(); + ItemStack right = anvil.getSecondItem(); + ItemStack result = anvil.getResult(); + player.setLevel(0); + player.setItemOnCursor(null); + + // Do a test with not enough level + simulateClick(anvil, player, data.npChangeResult()); + + // Nothing should have changed + assertEqual(left, anvil.getFirstItem()); + assertEqual(right, anvil.getSecondItem()); + assertEqual(result, anvil.getResult()); + assertEqual(null, player.getItemOnCursor()); + } + player.setLevel(data.levelCost()); + player.setItemOnCursor(null); + + simulateClick(anvil, player, data.expectedResult()); + + // Nothing should have changed + assertEqual(data.leftItem(), anvil.getFirstItem()); + assertEqual(data.rightItem(), anvil.getSecondItem()); + assertEqual(data.resultSlotItem(), anvil.getResult()); + assertEqual(data.expectedCursor(), data.expectedCursor()); + } + + private static void simulateClick( + @NotNull AnvilInventory anvil, + @NotNull Player player, + @Nullable Event.Result expectedResult + ){ + AnvilViewMock view = new AnvilViewMock(player, anvil); + try { + InventoryClickEvent event = new InventoryClickEvent(view, + InventoryType.SlotType.RESULT, + PrepareAnvilListener.ANVIL_OUTPUT_SLOT, + ClickType.LEFT, + InventoryAction.PICKUP_ALL); + + RESULT_LISTENER.anvilExtractionCheck(event); + if(expectedResult != null){ + Assertions.assertEquals(expectedResult, event.getResult()); + } + } catch (Exception e){ + Assertions.fail(e); + } } @SuppressWarnings({"removal"}) @@ -140,15 +199,15 @@ public class AnvilFuseTestUtil { assertPriceEqual(expectedPrice, anvil.getRepairCost()); } - public static void assertEqual(@Nullable ItemStack item1, @Nullable ItemStack item2) { - boolean secondIsAir = isAir(item2); - if(isAir(item1)) Assertions.assertTrue(secondIsAir,"Item "+item2+" was not AIR but was expected to be air"); + public static void assertEqual(@Nullable ItemStack expected, @Nullable ItemStack other) { + boolean secondIsAir = isAir(other); + if(isAir(expected)) Assertions.assertTrue(secondIsAir,"Item "+other+" was not AIR but was expected to be air"); else { - Assertions.assertFalse(secondIsAir,"Item "+item2+" was expected not to be air"); + Assertions.assertFalse(secondIsAir,"Item "+other+" was expected not to be air"); - item1.setDurability(item1.getDurability()); - item2.setDurability(item2.getDurability()); - Assertions.assertEquals(item1, item2); + expected.setDurability(expected.getDurability()); + other.setDurability(other.getDurability()); + Assertions.assertEquals(expected, other); } } From b7691bf3ffb8db19052b60240ed094c5bd70b7af Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 18:56:30 +0100 Subject: [PATCH 24/37] update mockbukkit --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index cd131bd..579eb6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ dependencies { implementation(kotlin("stdlib")) // Test dependency - testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.21.0") + testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.37.0") testRuntimeOnly("commons-lang:commons-lang:2.6") } From 74788b69afacf368a639c7667a90ba002daee0e3 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 19:35:33 +0100 Subject: [PATCH 25/37] fix lore edit price issue --- .../cuanvil/listener/AnvilResultListener.kt | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index f4a1cff..49876c1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -6,6 +6,7 @@ import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.GameMode import org.bukkit.Material +import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler @@ -310,6 +311,20 @@ class AnvilResultListener : Listener { return repairCost } + private fun getFromLoreEditXpCost( + xpCost: AtomicInteger, + player: Player, + inventory: AnvilInventory, + ): Int { + if(GameMode.CREATIVE == player.gameMode) return 0 + + val repairCost = xpCost.get() + return if ((inventory.maximumRepairCost <= repairCost) + || (player.level < repairCost)) Int.MIN_VALUE + + else repairCost + } + private fun handleBookLoreEdit( event: InventoryClickEvent, inventory: AnvilInventory, @@ -341,7 +356,7 @@ class AnvilResultListener : Listener { event, player, inventory, null, 0, clearedBook, 0, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } else { if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, xpCost)) return false @@ -377,7 +392,7 @@ class AnvilResultListener : Listener { event, player, inventory, null, 0, rightCopy, 0, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } } @@ -415,14 +430,14 @@ class AnvilResultListener : Listener { event, player, inventory, paperCopy, 0, rightItem, 1, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } else { extractAnvilResult( event, player, inventory, null, 0, paperCopy, 0, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } } else { @@ -461,14 +476,14 @@ class AnvilResultListener : Listener { event, player, inventory, rightClone, 0, rightItem, 1, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } else { extractAnvilResult( event, player, inventory, null, 0, rightClone, 0, - output, xpCost.get() + output, getFromLoreEditXpCost(xpCost, player, inventory) ) } } From 4ae53df238cc6e8da6535313e47c90c5abc0606d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 22:00:27 +0100 Subject: [PATCH 26/37] Fixed Book remove do consume using paper append do consume --- .../kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 49876c1..ae089cb 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -368,7 +368,7 @@ class AnvilResultListener : Listener { if (lore.isEmpty()) return false val rightCopy : ItemStack? - if (LoreEditType.APPEND_PAPER.doConsume) { + if (LoreEditType.REMOVE_BOOK.doConsume) { rightCopy = null } else { // Uncolor the page From dba48d6c10ddb6b537b4f8d02f512b79493d3254 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Tue, 18 Mar 2025 22:03:12 +0100 Subject: [PATCH 27/37] Added most of the lore edit unit tests --- .../delilaheve/util/EnchantmentUtilTests.java | 24 +- .../cuanvil/anvil/AnvilFuseTests.java | 11 +- .../alexcrea/cuanvil/anvil/LoreEditTests.java | 511 ++++++++++++++++++ .../cuanvil/api/ConflictApiTests.java | 10 +- .../api/CustomAnvilRecipeApiTests.java | 18 +- .../cuanvil/api/UnitRepairApiTests.java | 10 +- .../{util => data}/AnvilClickTestData.java | 2 +- .../{util => data}/AnvilFuseTestData.java | 2 +- .../cuanvil/data/TestDataContainer.java | 250 +++++++++ .../cuanvil/util/AnvilFuseTestUtil.java | 45 +- src/test/resources/plugin.yml | 11 +- 11 files changed, 834 insertions(+), 60 deletions(-) create mode 100644 src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java rename src/test/java/xyz/alexcrea/cuanvil/{util => data}/AnvilClickTestData.java (98%) rename src/test/java/xyz/alexcrea/cuanvil/{util => data}/AnvilFuseTestData.java (97%) create mode 100644 src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java diff --git a/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java b/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java index 0be9f08..48efc6b 100644 --- a/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java +++ b/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java @@ -14,7 +14,7 @@ import org.mockbukkit.mockbukkit.entity.PlayerMock; import org.mockbukkit.mockbukkit.inventory.ItemStackMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import java.util.List; @@ -88,16 +88,16 @@ public class EnchantmentUtilTests extends ConfigResetCustomAnvilTest { ); // Test with no permission - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData2); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData2); // Add permission PermissionAttachment attachment = player.addAttachment(plugin); attachment.setPermission(permission, true); // Test with new permission - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); } @Test @@ -161,24 +161,24 @@ public class EnchantmentUtilTests extends ConfigResetCustomAnvilTest { ); // Test failing result first - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData2); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData3); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData2); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData3); // Test working sharpness 2 - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); // Set merge limit to 2 & test ConfigHolder.DEFAULT_CONFIG.getConfig().set("disable-merge-over.minecraft:sharpness", 1); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); // Add permission PermissionAttachment attachment = player.addAttachment(plugin); attachment.setPermission(permission, true); // Test working sharpness 2 - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData3); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData3); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java index d1a3fcd..60df37e 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java @@ -9,7 +9,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.Repairable; -import org.eclipse.aether.util.ConfigUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -17,7 +16,7 @@ import org.junit.jupiter.api.Test; import org.mockbukkit.mockbukkit.entity.PlayerMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.tests.SharedCustomAnvilTest; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import xyz.alexcrea.cuanvil.util.CommonItemUtil; @@ -68,7 +67,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { 5 ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); } @Test @@ -88,7 +87,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { 5 ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); } @Test @@ -102,7 +101,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { null ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); } // Note: currently anvil can only have null name. maybe handle differently later @@ -121,7 +120,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { 1, 1, null ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, data); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java new file mode 100644 index 0000000..9d0fd38 --- /dev/null +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java @@ -0,0 +1,511 @@ +package xyz.alexcrea.cuanvil.anvil; + +import io.delilaheve.util.ConfigOptions; +import org.bukkit.Material; +import org.bukkit.event.Event; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.AnvilInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockbukkit.mockbukkit.entity.PlayerMock; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.data.AnvilClickTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.TestDataContainer; +import xyz.alexcrea.cuanvil.tests.SharedCustomAnvilTest; +import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil; +import xyz.alexcrea.cuanvil.util.config.LoreEditType; + +import java.util.ArrayList; +import java.util.Map; + +public class LoreEditTests extends SharedCustomAnvilTest { + + private static AnvilInventory anvil; + private static PlayerMock player; + + private static final String COLORED_LORE_LINE = "§x§1§2§3§4§5§6TEST §atest"; + private static final String UNCOLORED_LORE_LINE = "#123456TEST &atest"; + + private static final int COLOR_USE_COST = 1; + private static final int COLOR_REMOVE_COST = 2; + private static final int NON_ONE_TEST_FIXED_COST = 10; + private static final int NON_ZERO_TEST_LINE_COST = 2; + + private static ItemStack emptyItem; + private static ItemStack oneColoredLoreItem; + private static ItemStack twoColoredLoreItem; + private static ItemStack oneUncoloredLoreItem; + private static ItemStack twoUncoloredLoreItem; + + private static ItemStack emptyPaperStack; + private static ItemStack emptyPaper63Item; + private static ItemStack emptyPaperOne; + private static ItemStack coloredPaperStack; + private static ItemStack coloredPaper63Item; + private static ItemStack coloredPaperOne; + private static ItemStack uncoloredPaperStack; + private static ItemStack uncoloredPaper63Item; + private static ItemStack uncoloredPaperOne; + + private static ItemStack emptyBook; + private static ItemStack coloredBook1Line; + private static ItemStack coloredBook2Line; + private static ItemStack uncoloredBook1Line; + private static ItemStack uncoloredBook2Line; + + private static TestDataContainer defBookAppend; + private static TestDataContainer defBookRemove; + + private static TestDataContainer defPaperAppend; + private static TestDataContainer defPaperRemove; + + private static TestDataContainer defMultilineBookAppend; + private static TestDataContainer defMultilineBookRemove; + + private static TestDataContainer defMultilinePaperAppend; + private static TestDataContainer defMultilinePaperRemove; + + private static Map singleLineTypeToTest; + private static Map multiLineTypeToTest; + + @BeforeAll + public static void setUp() { + // Mock used player & open anvil + player = server.addPlayer(); + + Inventory anvil = server.createInventory(player, InventoryType.ANVIL); + + LoreEditTests.anvil = (AnvilInventory) anvil; + player.openInventory(anvil); + + ConfigHolder.DEFAULT_CONFIG.getConfig().set(ConfigOptions.DEBUG_LOGGING, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(ConfigOptions.VERBOSE_DEBUG_LOGGING, true); + + // Applied item + ItemStack item = new ItemStack(Material.STICK, 33); + ItemMeta meta = item.getItemMeta(); + ArrayList lore = new ArrayList<>(); + + emptyItem = item.clone(); + + lore.add(COLORED_LORE_LINE); + meta.setLore(lore); + item.setItemMeta(meta); + oneColoredLoreItem = item.clone(); + + lore.add(COLORED_LORE_LINE); + meta.setLore(lore); + item.setItemMeta(meta); + twoColoredLoreItem = item.clone(); + + lore.clear(); + lore.add(UNCOLORED_LORE_LINE); + meta.setLore(lore); + item.setItemMeta(meta); + oneUncoloredLoreItem = item.clone(); + + lore.add(UNCOLORED_LORE_LINE); + meta.setLore(lore); + item.setItemMeta(meta); + twoUncoloredLoreItem = item.clone(); + lore.clear(); + + // Paper items + item = new ItemStack(Material.PAPER, 64); + meta = item.getItemMeta(); + emptyPaperStack = item.clone(); + item.setAmount(63); + emptyPaper63Item = item.clone(); + item.setAmount(1); + emptyPaperOne = item.clone(); + + item.setAmount(64); + meta.setDisplayName(COLORED_LORE_LINE); + item.setItemMeta(meta); + coloredPaperStack = item.clone(); + item.setAmount(63); + coloredPaper63Item = item.clone(); + item.setAmount(1); + coloredPaperOne = item.clone(); + + item.setAmount(64); + meta.setDisplayName(UNCOLORED_LORE_LINE); + item.setItemMeta(meta); + uncoloredPaperStack = item.clone(); + item.setAmount(63); + uncoloredPaper63Item = item.clone(); + item.setAmount(1); + uncoloredPaperOne = item.clone(); + + // Book items + item = new ItemStack(Material.WRITABLE_BOOK); + BookMeta bookmeta = (BookMeta) item.getItemMeta(); + emptyBook = item.clone(); + + bookmeta.setPages(COLORED_LORE_LINE); + item.setItemMeta(bookmeta); + coloredBook1Line = item.clone(); + + bookmeta.setPages(COLORED_LORE_LINE + "\n" + COLORED_LORE_LINE); + item.setItemMeta(bookmeta); + coloredBook2Line = item.clone(); + + bookmeta.setPages(UNCOLORED_LORE_LINE); + item.setItemMeta(bookmeta); + uncoloredBook1Line = item.clone(); + + bookmeta.setPages(UNCOLORED_LORE_LINE + "\n" + UNCOLORED_LORE_LINE); + item.setItemMeta(bookmeta); + uncoloredBook2Line = item.clone(); + + // Default working test data + defBookAppend = new TestDataContainer( + new AnvilFuseTestData( + emptyItem, uncoloredBook1Line, + oneColoredLoreItem, + 1 + ), new AnvilClickTestData( + null, emptyBook, null, oneColoredLoreItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defBookRemove = new TestDataContainer( + new AnvilFuseTestData( + oneColoredLoreItem, emptyBook, + emptyItem, + 1 + ), new AnvilClickTestData( + null, coloredBook1Line, null, emptyItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defPaperAppend = new TestDataContainer( + new AnvilFuseTestData( + emptyItem, uncoloredPaperStack, + oneColoredLoreItem, + 1 + ), new AnvilClickTestData( + emptyPaperOne, uncoloredPaper63Item, null, oneColoredLoreItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defPaperRemove = new TestDataContainer( + new AnvilFuseTestData( + oneColoredLoreItem, emptyPaperStack, + emptyItem, + 1 + ), new AnvilClickTestData( + coloredPaperOne, emptyPaper63Item, null, emptyItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + defMultilineBookAppend = new TestDataContainer( + new AnvilFuseTestData( + emptyItem, uncoloredBook2Line, + twoColoredLoreItem, + 1 + ), new AnvilClickTestData( + null, emptyBook, null, twoColoredLoreItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defMultilineBookRemove = new TestDataContainer( + new AnvilFuseTestData( + twoColoredLoreItem, emptyBook, + emptyItem, + 1 + ), new AnvilClickTestData( + null, coloredBook2Line, null, emptyItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defMultilinePaperAppend = new TestDataContainer( + new AnvilFuseTestData( + oneColoredLoreItem, uncoloredPaperStack, + twoColoredLoreItem, + 1 + ), new AnvilClickTestData( + emptyPaperOne, uncoloredPaper63Item, null, twoColoredLoreItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + defMultilinePaperRemove = new TestDataContainer( + new AnvilFuseTestData( + twoColoredLoreItem, emptyPaperStack, + oneColoredLoreItem, + 1 + ), new AnvilClickTestData( + coloredPaperOne, emptyPaper63Item, null, oneColoredLoreItem, + 1, Event.Result.DENY, + true, Event.Result.DENY + )); + + singleLineTypeToTest = Map.of( + LoreEditType.APPEND_BOOK, defBookAppend, + LoreEditType.REMOVE_BOOK, defBookRemove, + LoreEditType.APPEND_PAPER, defPaperAppend, + LoreEditType.REMOVE_PAPER, defPaperRemove + ); + + multiLineTypeToTest = Map.of( + LoreEditType.APPEND_BOOK, defMultilineBookAppend, + LoreEditType.REMOVE_BOOK, defMultilineBookRemove, + LoreEditType.APPEND_PAPER, defMultilinePaperAppend, + LoreEditType.REMOVE_PAPER, defMultilinePaperRemove + ); + } + + public @Nullable ItemStack uncoloredEquivalent(@Nullable ItemStack colored){ + // null check + if(null == colored) return null; + + if(oneColoredLoreItem == colored) return oneUncoloredLoreItem; + if(twoColoredLoreItem == colored) return twoUncoloredLoreItem; + + if(coloredPaperStack == colored) return uncoloredPaperStack; + if(coloredPaper63Item == colored) return uncoloredPaper63Item; + if(coloredPaperOne == colored) return uncoloredPaperOne; + + if(coloredBook1Line == colored) return uncoloredBook1Line; + if(coloredBook2Line == colored) return uncoloredBook2Line; + + // They already are uncolored + if(oneUncoloredLoreItem == colored) return oneUncoloredLoreItem; + if(twoUncoloredLoreItem == colored) return twoUncoloredLoreItem; + + if(uncoloredPaperStack == colored) return uncoloredPaperStack; + if(uncoloredPaper63Item == colored) return uncoloredPaper63Item; + if(uncoloredPaperOne == colored) return uncoloredPaperOne; + + if(uncoloredBook1Line == colored) return uncoloredBook1Line; + if(uncoloredBook2Line == colored) return uncoloredBook2Line; + + // No lore items return themself + if(emptyItem == colored) return emptyItem; + if(emptyBook == colored) return emptyBook; + if(emptyPaperStack == colored) return emptyPaperStack; + if(emptyPaper63Item == colored) return emptyPaper63Item; + if(emptyPaperOne == colored) return emptyPaperOne; + + Assertions.fail("Could not find uncolored version of " + colored); + return null; + } + + @BeforeEach + public void prepareAnvil() { + anvil.clear(); + + // Make sure we reset value in case it got modified + for (@NotNull LoreEditType type : LoreEditType.values()) { + // Make sure it is enabled for the tests (unless its is enabled test) + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.IS_ENABLED, true); + + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.FIXED_COST, 1); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.PER_LINE_COST, 0); + + + // Make sur color is enabled by default + if (type.isAppend()) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_HEX_COLOR, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_COLOR_CODE, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, 0); + } else { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_COST, 0); + } + + } + + // Disable them by default and test them on specific tests + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.BOOK_PERMISSION_NEEDED, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_PERMISSION_NEEDED, false); + } + + @AfterAll + public static void tearDown() { + player = null; + anvil = null; + } + + @Test + public void simpleTest() { + // Test all defaults to make sure they works + for (LoreEditType type : LoreEditType.values()) { + singleLineTypeToTest.get(type).executeTest(anvil, player); + multiLineTypeToTest.get(type).executeTest(anvil, player); + } + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testPermissionNeeded_DEOP(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.BOOK_PERMISSION_NEEDED, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_PERMISSION_NEEDED, true); + player.setOp(false); + + singleLineTypeToTest.get(type).nullifyResult().executeTest(anvil, player); + multiLineTypeToTest.get(type).nullifyResult().executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testPermissionNeeded_OP(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.BOOK_PERMISSION_NEEDED, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_PERMISSION_NEEDED, true); + player.setOp(true); + + singleLineTypeToTest.get(type).executeTest(anvil, player); + multiLineTypeToTest.get(type).executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testLoreTypeDisabled(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.IS_ENABLED, false); + + singleLineTypeToTest.get(type).nullifyResult().executeTest(anvil, player); + multiLineTypeToTest.get(type).nullifyResult().executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testFixedCost_Default(LoreEditType type) { + singleLineTypeToTest.get(type).setCost(1).executeTest(anvil, player); + multiLineTypeToTest.get(type).setCost(1).executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testFixedCost_Modified(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.FIXED_COST, NON_ONE_TEST_FIXED_COST); + + singleLineTypeToTest.get(type).setCost(NON_ONE_TEST_FIXED_COST).executeTest(anvil, player); + multiLineTypeToTest.get(type).setCost(NON_ONE_TEST_FIXED_COST).executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testLineCost_Modified(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.PER_LINE_COST, NON_ZERO_TEST_LINE_COST); + + if (type.isMultiLine()) { + singleLineTypeToTest.get(type).setCost(NON_ZERO_TEST_LINE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST).executeTest(anvil, player); + multiLineTypeToTest.get(type).setCost(2 * NON_ZERO_TEST_LINE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST).executeTest(anvil, player); + } else { + singleLineTypeToTest.get(type).executeTest(anvil, player); + multiLineTypeToTest.get(type).executeTest(anvil, player); + } + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testColorCost(LoreEditType type) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, COLOR_USE_COST); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_COST, COLOR_REMOVE_COST); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, true); + + TestDataContainer singleLData = singleLineTypeToTest.get(type); + TestDataContainer multiLData = multiLineTypeToTest.get(type); + + if (type.isAppend()) { + singleLData.setCost(COLOR_USE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST).executeTest(anvil, player); + multiLData.setCost(COLOR_USE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST).executeTest(anvil, player); + } else { + singleLData + .setCost(COLOR_REMOVE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST) + .setClickRight(uncoloredEquivalent(singleLData.getRightClick())) + .setClickLeft(uncoloredEquivalent(singleLData.getLeftClick())) + .executeTest(anvil, player); + + multiLData.setCost(COLOR_REMOVE_COST + LoreEditConfigUtil.DEFAULT_FIXED_COST) + .setClickRight(uncoloredEquivalent(multiLData.getRightClick())) + .setClickLeft(uncoloredEquivalent(multiLData.getLeftClick())) + .executeTest(anvil, player); + } + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testColorDisabled(LoreEditType type) { + if(!type.isAppend()) return; + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, COLOR_USE_COST); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_HEX_COLOR, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_COLOR_CODE, false); + + TestDataContainer singleLData = singleLineTypeToTest.get(type); + TestDataContainer multiLData = multiLineTypeToTest.get(type); + + singleLData + .setExpectedResult(uncoloredEquivalent(singleLData.getExpectedFuse())) + .executeTest(anvil, player); + multiLData + .setFuseLeft(uncoloredEquivalent(multiLData.getLeftFuse())) + .setExpectedResult(uncoloredEquivalent(multiLData.getExpectedFuse())) + .executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testColorRemoveEnabled(LoreEditType type) { + if(type.isAppend()) return; + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, true); + + TestDataContainer singleLData = singleLineTypeToTest.get(type); + TestDataContainer multiLData = multiLineTypeToTest.get(type); + + singleLData + .setClickRight(uncoloredEquivalent(singleLData.getRightClick())) + .setClickLeft(uncoloredEquivalent(singleLData.getLeftClick())) + .executeTest(anvil, player); + multiLData + .setClickRight(uncoloredEquivalent(multiLData.getRightClick())) + .setClickLeft(uncoloredEquivalent(multiLData.getLeftClick())) + .executeTest(anvil, player); + } + + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void testDoConsume(LoreEditType type) { + if(type.isAppend()) return; + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, true); + + TestDataContainer singleLData = singleLineTypeToTest.get(type); + TestDataContainer multiLData = multiLineTypeToTest.get(type); + + // NOTE: we set to null right item only on multi line bc the default data has more than one paper and would go to the left instead + singleLData = singleLData + .setClickRight(type.isMultiLine() ? null : singleLData.getRightClick()) + .setClickLeft(null); + singleLData.executeTest(anvil, player); + multiLData = multiLData + .setClickRight(type.isMultiLine() ? null : singleLData.getRightClick()) + .setClickLeft(null); + multiLData.executeTest(anvil, player); + + if(!type.isMultiLine()){ + singleLData.setFuseRight(emptyPaperOne).setClickRight(null).executeTest(anvil, player); + multiLData.setFuseRight(emptyPaperOne).setClickRight(null).executeTest(anvil, player); + } + } + + //TODO single paper test + + //TODO remove order test + //TODO work penalty test + +} diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java index 095554b..b1d7564 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java @@ -16,7 +16,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import xyz.alexcrea.cuanvil.util.CommonItemUtil; @@ -71,7 +71,7 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { Assertions.assertNotNull(sharpness); // Testing default conflict (illegal item should not be produced) - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); // Try to find & remove conflict EnchantConflictGroup conflict = findGroup("sword_enchant_conflict"); @@ -79,7 +79,7 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { // Test what happen when we remove the conflict (illegal item should be allowed) ConflictAPI.removeConflict(conflict); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); // We create and add a new conflict ConflictBuilder builder = new ConflictBuilder("sword_enchant_conflict"); @@ -88,11 +88,11 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { // Nothing should change as it is not new: it was previously deleted Assertions.assertFalse(builder.registerIfNew()); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); // Now the conflict should be registered and conflict should exist Assertions.assertTrue(builder.registerIfAbsent()); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); } @Test diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java index 680f396..3ebdd7c 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java @@ -13,7 +13,7 @@ import org.mockbukkit.mockbukkit.inventory.ItemStackMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import static org.junit.jupiter.api.Assertions.*; @@ -57,14 +57,14 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { ); // Testing default conflict (no recipe exist) - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); // Add and test recipe AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); builder.setExactCount(true).setLeftItem(stick).setResultItem(stick).setXpCostPerCraft(2); assertTrue(builder.registerIfAbsent()); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); AnvilCustomRecipe recipe = getByName(recipeName); assertNotNull(recipe); @@ -72,21 +72,21 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { // Remove recipe assertTrue(CustomAnvilRecipeApi.removeRecipe(recipe)); assertFalse(CustomAnvilRecipeApi.removeRecipe(recipe)); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); recipe = getByName(recipeName); assertNull(recipe); // Try to add deleted recipe with no override (should not add) assertFalse(CustomAnvilRecipeApi.addRecipe(builder, false)); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); recipe = getByName(recipeName); assertNull(recipe); // Try to add deleted recipe with override (should add) assertTrue(CustomAnvilRecipeApi.addRecipe(builder, true)); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); recipe = getByName(recipeName); assertNotNull(recipe); @@ -119,7 +119,7 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { null, null ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); builder.setExactCount(false) @@ -130,8 +130,8 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { assertTrue(builder.registerIfAbsent()); // Now working test - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData1); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData2); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData1); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); } @Nullable diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java index 0696690..8166797 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java @@ -13,7 +13,7 @@ import org.mockbukkit.mockbukkit.entity.PlayerMock; import org.mockbukkit.mockbukkit.inventory.ItemStackMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import static org.junit.jupiter.api.Assertions.*; @@ -58,7 +58,7 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { 2 ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); } @Test @@ -76,7 +76,7 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { // Remove unit repair assertTrue(UnitRepairApi.removeUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE)); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); // see override assertFalse(UnitRepairApi.addUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE, 0.25)); @@ -107,12 +107,12 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { 2 ); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, nullResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); // Add unit repair assertTrue(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE)); assertFalse(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE)); - AnvilFuseTestUtil.executeAnvilTest(anvil, player, legalResultData); + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java similarity index 98% rename from src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java rename to src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java index 7192303..65d7ddb 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilClickTestData.java +++ b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java @@ -1,4 +1,4 @@ -package xyz.alexcrea.cuanvil.util; +package xyz.alexcrea.cuanvil.data; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java similarity index 97% rename from src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java rename to src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java index cc042f2..a01d0ab 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestData.java +++ b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java @@ -1,4 +1,4 @@ -package xyz.alexcrea.cuanvil.util; +package xyz.alexcrea.cuanvil.data; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; diff --git a/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java b/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java new file mode 100644 index 0000000..2c8ff93 --- /dev/null +++ b/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java @@ -0,0 +1,250 @@ +package xyz.alexcrea.cuanvil.data; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.AnvilInventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; + +@SuppressWarnings("unused") +public record TestDataContainer( + @NotNull AnvilFuseTestData fuseData, + @Nullable AnvilClickTestData clickData +) { + + public void executeTest(AnvilInventory anvil, Player player) { + executeFuseTest(anvil, player); + if (clickData != null) executeClickTest(anvil, player); + } + + public void executeFuseTest(AnvilInventory anvil, HumanEntity player) { + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, fuseData); + } + + public void executeClickTest(AnvilInventory anvil, Player player) { + Assertions.assertNotNull(clickData); + AnvilFuseTestUtil.executeAnvilClickTest(anvil, player, clickData); + } + + public @NotNull TestDataContainer nullifyResult() { + return new TestDataContainer( + new AnvilFuseTestData( + fuseData.leftItem(), fuseData.rightItem(), + null + ), null); + } + + public @NotNull TestDataContainer setCost( + @Nullable Integer priceAfterLeft, + @Nullable Integer priceAfterRight, + int priceAfterBoth + ) { + AnvilFuseTestData data = new AnvilFuseTestData( + fuseData.leftItem(), fuseData.rightItem(), fuseData.expectedResult(), + fuseData.expectedAfterLeftPlaced(), + fuseData.expectedAfterRightPlaced(), + priceAfterLeft, + priceAfterRight, + priceAfterBoth + ); + + AnvilClickTestData CData; + if (clickData == null) { + CData = null; + } else { + CData = new AnvilClickTestData( + clickData.leftItem(), clickData.rightItem(), clickData.resultSlotItem(), + clickData.expectedCursor(), priceAfterBoth, + clickData.expectedResult(), + clickData.testNoLevelNoChange(), clickData.npChangeResult() + ); + } + return new TestDataContainer(data, CData); + } + + public @NotNull TestDataContainer setCost( + int priceAfterBoth + ) { + return setCost(null, null, priceAfterBoth); + } + + // Set fuse items + public @NotNull TestDataContainer setFuseItems(@Nullable ItemStack left, @Nullable ItemStack right, @Nullable ItemStack expected) { + AnvilFuseTestData data = new AnvilFuseTestData( + left, right, expected, + fuseData.expectedAfterLeftPlaced(), + fuseData.expectedAfterRightPlaced(), + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseItems( + @Nullable ItemStack left, @Nullable ItemStack right, @Nullable ItemStack expected, + @Nullable ItemStack leftExpected, @Nullable ItemStack rightExpected) { + AnvilFuseTestData data = new AnvilFuseTestData( + left, right, expected, + leftExpected, + rightExpected, + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseLeft(@Nullable ItemStack left) { + AnvilFuseTestData data = new AnvilFuseTestData( + left, fuseData.rightItem(), fuseData.expectedResult(), + fuseData.expectedAfterLeftPlaced(), + fuseData.expectedAfterRightPlaced(), + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseRight(@Nullable ItemStack right) { + AnvilFuseTestData data = new AnvilFuseTestData( + fuseData.leftItem(), right, fuseData.expectedResult(), + fuseData.expectedAfterLeftPlaced(), + fuseData.expectedAfterRightPlaced(), + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseExpected(@Nullable ItemStack expected) { + AnvilFuseTestData data = new AnvilFuseTestData( + fuseData.leftItem(), fuseData.rightItem(), expected, + fuseData.expectedAfterLeftPlaced(), + fuseData.expectedAfterRightPlaced(), + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseExpectedLeft(@Nullable ItemStack expected) { + AnvilFuseTestData data = new AnvilFuseTestData( + fuseData.leftItem(), fuseData.rightItem(), fuseData.expectedResult(), + expected, + fuseData.expectedAfterRightPlaced(), + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + public @NotNull TestDataContainer setFuseExpectedRight(@Nullable ItemStack expected) { + AnvilFuseTestData data = new AnvilFuseTestData( + fuseData.leftItem(), fuseData.rightItem(), fuseData.expectedResult(), + fuseData.expectedAfterLeftPlaced(), + expected, + fuseData.expectedPriceAfterLeftPlaced(), + fuseData.expectedPriceAfterRightPlaced(), + fuseData.expectedPriceAfterBothPlaced() + ); + return new TestDataContainer(data, clickData); + } + + // Set click items + public @NotNull TestDataContainer setClickLeft(@Nullable ItemStack left) { + if (clickData == null) return this; + AnvilClickTestData data = new AnvilClickTestData( + left, clickData.rightItem(), clickData.resultSlotItem(), clickData.expectedCursor(), + clickData.levelCost(), clickData.expectedResult(), + clickData.testNoLevelNoChange(), clickData.npChangeResult() + ); + + return new TestDataContainer(fuseData, data); + } + + public @NotNull TestDataContainer setClickRight(@Nullable ItemStack right) { + if (clickData == null) return this; + AnvilClickTestData data = new AnvilClickTestData( + clickData.leftItem(), right, clickData.resultSlotItem(), clickData.expectedCursor(), + clickData.levelCost(), clickData.expectedResult(), + clickData.testNoLevelNoChange(), clickData.npChangeResult() + ); + + return new TestDataContainer(fuseData, data); + } + + public @NotNull TestDataContainer setClickOutput(@Nullable ItemStack output) { + if (clickData == null) return this; + AnvilClickTestData data = new AnvilClickTestData( + clickData.leftItem(), clickData.rightItem(), output, clickData.expectedCursor(), + clickData.levelCost(), clickData.expectedResult(), + clickData.testNoLevelNoChange(), clickData.npChangeResult() + ); + + return new TestDataContainer(fuseData, data); + } + + public @NotNull TestDataContainer setClickCursor(@Nullable ItemStack cursor) { + if (clickData == null) return this; + AnvilClickTestData data = new AnvilClickTestData( + clickData.leftItem(), clickData.rightItem(), clickData.resultSlotItem(), cursor, + clickData.levelCost(), clickData.expectedResult(), + clickData.testNoLevelNoChange(), clickData.npChangeResult() + ); + + return new TestDataContainer(fuseData, data); + } + + // Both item + public @NotNull TestDataContainer setExpectedResult(@Nullable ItemStack result) { + return setFuseExpected(result).setClickCursor(result); + } + + // Get fuse item + public @Nullable ItemStack getLeftFuse() { + return fuseData.leftItem(); + } + + public @Nullable ItemStack getRightFuse() { + return fuseData.rightItem(); + } + + public @Nullable ItemStack getExpectedFuse() { + return fuseData.expectedResult(); + } + + public @Nullable ItemStack getLeftExpectedFuse() { + return fuseData.expectedAfterLeftPlaced(); + } + + public @Nullable ItemStack getRightExpectedFuse() { + return fuseData.expectedAfterRightPlaced(); + } + + // Get click item + public @Nullable ItemStack getLeftClick() { + return clickData == null ? null : clickData.leftItem(); + } + + public @Nullable ItemStack getRightClick() { + return clickData == null ? null : clickData.rightItem(); + } + + public @Nullable ItemStack getOutputClick() { + return clickData == null ? null : clickData.resultSlotItem(); + } + + public @Nullable ItemStack getCursorClick() { + return clickData == null ? null : clickData.expectedCursor(); + } + + +} diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java index 1fb534e..b73b884 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java @@ -13,6 +13,8 @@ import org.bukkit.inventory.meta.Repairable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Assertions; +import xyz.alexcrea.cuanvil.data.AnvilClickTestData; +import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.listener.AnvilResultListener; import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener; @@ -29,14 +31,14 @@ public class AnvilFuseTestUtil { public static ItemStack prepareItem(@NotNull Material material, @NotNull List enchantments, - @NotNull List level){ + @NotNull List level) { return prepareItem(material, 0, enchantments, level); } public static ItemStack prepareItem(@NotNull Material material, int repairCost, @NotNull List enchantments, - @NotNull List level){ + @NotNull List level) { Assertions.assertEquals(enchantments.size(), level.size()); HashMap enchantmentMap = new HashMap<>(); @@ -57,13 +59,14 @@ public class AnvilFuseTestUtil { public static ItemStack prepareItem(@NotNull Material material, @NotNull List enchantmentNames, - Integer... levels){ + Integer... levels) { return prepareItem(material, 0, enchantmentNames, levels); } + public static ItemStack prepareItem(@NotNull Material material, int repairCost, @NotNull List enchantmentNames, - Integer... levels){ + Integer... levels) { List enchantments = new ArrayList<>(); for (String enchantmentName : enchantmentNames) { @@ -94,16 +97,16 @@ public class AnvilFuseTestUtil { // Not ideal but possible and the easiest so why not PREPARE_LISTENER.anvilCombineCheck(event); anvil.setResult(event.getResult()); - } catch (Exception e){ + } catch (Exception e) { Assertions.fail(e); } } - public static void executeAnvilTest( + public static void executeAnvilFuseTest( @NotNull AnvilInventory anvil, @NotNull HumanEntity player, @NotNull AnvilFuseTestData data - ){ + ) { Assertions.assertEquals(player.getOpenInventory().getTopInventory(), anvil, "Openned inventory is not anvil"); @@ -125,12 +128,12 @@ public class AnvilFuseTestUtil { data.leftItem(), data.expectedResult()); } - public static void executeAnvilClick( + public static void executeAnvilClickTest( @NotNull AnvilInventory anvil, @NotNull Player player, @NotNull AnvilClickTestData data ) { - if(data.testNoLevelNoChange()){ + if (data.testNoLevelNoChange()) { ItemStack left = anvil.getFirstItem(); ItemStack right = anvil.getSecondItem(); ItemStack result = anvil.getResult(); @@ -152,18 +155,21 @@ public class AnvilFuseTestUtil { simulateClick(anvil, player, data.expectedResult()); - // Nothing should have changed + // Should have similated the click assertEqual(data.leftItem(), anvil.getFirstItem()); assertEqual(data.rightItem(), anvil.getSecondItem()); assertEqual(data.resultSlotItem(), anvil.getResult()); assertEqual(data.expectedCursor(), data.expectedCursor()); + + // Test if the player has no more xp + Assertions.assertEquals(0, player.getLevel(), "Player has more level than expected"); } private static void simulateClick( @NotNull AnvilInventory anvil, @NotNull Player player, @Nullable Event.Result expectedResult - ){ + ) { AnvilViewMock view = new AnvilViewMock(player, anvil); try { InventoryClickEvent event = new InventoryClickEvent(view, @@ -173,10 +179,10 @@ public class AnvilFuseTestUtil { InventoryAction.PICKUP_ALL); RESULT_LISTENER.anvilExtractionCheck(event); - if(expectedResult != null){ + if (expectedResult != null) { Assertions.assertEquals(expectedResult, event.getResult()); } - } catch (Exception e){ + } catch (Exception e) { Assertions.fail(e); } } @@ -188,7 +194,7 @@ public class AnvilFuseTestUtil { int slot, Integer expectedPrice, @Nullable ItemStack toPlace, - @Nullable ItemStack expectedResult){ + @Nullable ItemStack expectedResult) { anvil.setItem(slot, toPlace); anvil.setItem(2, null); AnvilFuseTestUtil.imitateAnvilUpdate(player, anvil); @@ -201,9 +207,10 @@ public class AnvilFuseTestUtil { public static void assertEqual(@Nullable ItemStack expected, @Nullable ItemStack other) { boolean secondIsAir = isAir(other); - if(isAir(expected)) Assertions.assertTrue(secondIsAir,"Item "+other+" was not AIR but was expected to be air"); + if (isAir(expected)) + Assertions.assertTrue(secondIsAir, "Item " + other + " was not air but was expected to be"); else { - Assertions.assertFalse(secondIsAir,"Item "+other+" was expected not to be air"); + Assertions.assertFalse(secondIsAir, "Item " + other + " is air but was expected to be " + expected); expected.setDurability(expected.getDurability()); other.setDurability(other.getDurability()); @@ -212,12 +219,12 @@ public class AnvilFuseTestUtil { } - public static boolean isAir(@Nullable ItemStack item){ + public static boolean isAir(@Nullable ItemStack item) { return item == null || item.isEmpty(); } - public static void assertPriceEqual(Integer expectedPrice, int price){ - if(expectedPrice == null) return; + public static void assertPriceEqual(Integer expectedPrice, int price) { + if (expectedPrice == null) return; Assertions.assertEquals(expectedPrice, price); } diff --git a/src/test/resources/plugin.yml b/src/test/resources/plugin.yml index a1f6983..c116cce 100644 --- a/src/test/resources/plugin.yml +++ b/src/test/resources/plugin.yml @@ -43,10 +43,17 @@ permissions: # color permissions ca.color.code: default: op - description: Allow player to use color code if permission is required (toggleable) + description: Allow player to use color code if enabled (toggleable) ca.color.hex: default: op - description: Allow player to use hexadecimal color if permission is required (toggleable) + description: Allow player to use hexadecimal color if enabled (toggleable) + # lore edit permissions + ca.lore_edit.book: + default: op + description: Allow player to edit lore via book and quil if enabled (toggleable) + ca.lore_edit.paper: + default: op + description: Allow player to edit lore via paper if enabled (toggleable) # soft depend on old name (UnsafeEnchantsPlus), so I can disable it if it is on the same server (old name for this plugin) From dc5009aff50ca184f8c295d3fa77cada939861b3 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Wed, 19 Mar 2025 00:08:00 +0100 Subject: [PATCH 28/37] Add single paper tests --- .../alexcrea/cuanvil/anvil/LoreEditTests.java | 101 +++++++++++++----- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java index 9d0fd38..b0e38b1 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import org.mockbukkit.mockbukkit.entity.PlayerMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.data.AnvilClickTestData; @@ -24,6 +25,7 @@ import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil; import xyz.alexcrea.cuanvil.util.config.LoreEditType; import java.util.ArrayList; +import java.util.List; import java.util.Map; public class LoreEditTests extends SharedCustomAnvilTest { @@ -269,37 +271,37 @@ public class LoreEditTests extends SharedCustomAnvilTest { ); } - public @Nullable ItemStack uncoloredEquivalent(@Nullable ItemStack colored){ + public @Nullable ItemStack uncoloredEquivalent(@Nullable ItemStack colored) { // null check - if(null == colored) return null; + if (null == colored) return null; - if(oneColoredLoreItem == colored) return oneUncoloredLoreItem; - if(twoColoredLoreItem == colored) return twoUncoloredLoreItem; + if (oneColoredLoreItem == colored) return oneUncoloredLoreItem; + if (twoColoredLoreItem == colored) return twoUncoloredLoreItem; - if(coloredPaperStack == colored) return uncoloredPaperStack; - if(coloredPaper63Item == colored) return uncoloredPaper63Item; - if(coloredPaperOne == colored) return uncoloredPaperOne; + if (coloredPaperStack == colored) return uncoloredPaperStack; + if (coloredPaper63Item == colored) return uncoloredPaper63Item; + if (coloredPaperOne == colored) return uncoloredPaperOne; - if(coloredBook1Line == colored) return uncoloredBook1Line; - if(coloredBook2Line == colored) return uncoloredBook2Line; + if (coloredBook1Line == colored) return uncoloredBook1Line; + if (coloredBook2Line == colored) return uncoloredBook2Line; // They already are uncolored - if(oneUncoloredLoreItem == colored) return oneUncoloredLoreItem; - if(twoUncoloredLoreItem == colored) return twoUncoloredLoreItem; + if (oneUncoloredLoreItem == colored) return oneUncoloredLoreItem; + if (twoUncoloredLoreItem == colored) return twoUncoloredLoreItem; - if(uncoloredPaperStack == colored) return uncoloredPaperStack; - if(uncoloredPaper63Item == colored) return uncoloredPaper63Item; - if(uncoloredPaperOne == colored) return uncoloredPaperOne; + if (uncoloredPaperStack == colored) return uncoloredPaperStack; + if (uncoloredPaper63Item == colored) return uncoloredPaper63Item; + if (uncoloredPaperOne == colored) return uncoloredPaperOne; - if(uncoloredBook1Line == colored) return uncoloredBook1Line; - if(uncoloredBook2Line == colored) return uncoloredBook2Line; + if (uncoloredBook1Line == colored) return uncoloredBook1Line; + if (uncoloredBook2Line == colored) return uncoloredBook2Line; // No lore items return themself - if(emptyItem == colored) return emptyItem; - if(emptyBook == colored) return emptyBook; - if(emptyPaperStack == colored) return emptyPaperStack; - if(emptyPaper63Item == colored) return emptyPaper63Item; - if(emptyPaperOne == colored) return emptyPaperOne; + if (emptyItem == colored) return emptyItem; + if (emptyBook == colored) return emptyBook; + if (emptyPaperStack == colored) return emptyPaperStack; + if (emptyPaper63Item == colored) return emptyPaper63Item; + if (emptyPaperOne == colored) return emptyPaperOne; Assertions.fail("Could not find uncolored version of " + colored); return null; @@ -342,6 +344,22 @@ public class LoreEditTests extends SharedCustomAnvilTest { anvil = null; } + public static List onlyAppendTypes() { + ArrayList typeList = new ArrayList<>(); + for (@NotNull LoreEditType type : LoreEditType.values()) { + if (type.isAppend()) typeList.add(type); + } + return typeList; + } + + public static List onlyRemoveTypes() { + ArrayList typeList = new ArrayList<>(); + for (@NotNull LoreEditType type : LoreEditType.values()) { + if (!type.isAppend()) typeList.add(type); + } + return typeList; + } + @Test public void simpleTest() { // Test all defaults to make sure they works @@ -440,9 +458,8 @@ public class LoreEditTests extends SharedCustomAnvilTest { } @ParameterizedTest - @EnumSource(LoreEditType.class) + @MethodSource("onlyAppendTypes") public void testColorDisabled(LoreEditType type) { - if(!type.isAppend()) return; ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, COLOR_USE_COST); ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_HEX_COLOR, false); ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_COLOR_CODE, false); @@ -460,9 +477,8 @@ public class LoreEditTests extends SharedCustomAnvilTest { } @ParameterizedTest - @EnumSource(LoreEditType.class) + @MethodSource("onlyRemoveTypes") public void testColorRemoveEnabled(LoreEditType type) { - if(type.isAppend()) return; ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, true); TestDataContainer singleLData = singleLineTypeToTest.get(type); @@ -479,9 +495,8 @@ public class LoreEditTests extends SharedCustomAnvilTest { } @ParameterizedTest - @EnumSource(LoreEditType.class) + @MethodSource("onlyRemoveTypes") public void testDoConsume(LoreEditType type) { - if(type.isAppend()) return; ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, true); TestDataContainer singleLData = singleLineTypeToTest.get(type); @@ -497,13 +512,41 @@ public class LoreEditTests extends SharedCustomAnvilTest { .setClickLeft(null); multiLData.executeTest(anvil, player); - if(!type.isMultiLine()){ + // Single paper consumed + if (!type.isMultiLine()) { singleLData.setFuseRight(emptyPaperOne).setClickRight(null).executeTest(anvil, player); multiLData.setFuseRight(emptyPaperOne).setClickRight(null).executeTest(anvil, player); } } - //TODO single paper test + private void SinglePaperTestPart(LoreEditType type, TestDataContainer data, ItemStack expectedFuse, ItemStack postFuse) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, false); + data = data.setFuseRight(expectedFuse).setClickLeft(null).setClickRight(postFuse); + data.executeTest(anvil, player); + + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, true); + data.setClickRight(null).executeTest(anvil, player); + } + + @Test + public void testSinglePaper_Append() { + SinglePaperTestPart(LoreEditType.APPEND_PAPER, + singleLineTypeToTest.get(LoreEditType.APPEND_PAPER), + uncoloredPaperOne, emptyPaperOne); + SinglePaperTestPart(LoreEditType.APPEND_PAPER, + multiLineTypeToTest.get(LoreEditType.APPEND_PAPER), + uncoloredPaperOne, emptyPaperOne); + } + + @Test + public void testSinglePaper_Remove() { + SinglePaperTestPart(LoreEditType.REMOVE_PAPER, + singleLineTypeToTest.get(LoreEditType.REMOVE_PAPER), + emptyPaperOne, coloredPaperOne); + SinglePaperTestPart(LoreEditType.REMOVE_PAPER, + multiLineTypeToTest.get(LoreEditType.REMOVE_PAPER), + emptyPaperOne, coloredPaperOne); + } //TODO remove order test //TODO work penalty test From f8555175c124c0f2c7dc397ec16503bf511ffef2 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:23:35 +0100 Subject: [PATCH 29/37] add paper order test --- .../alexcrea/cuanvil/anvil/LoreEditTests.java | 145 +++++++++++++----- 1 file changed, 107 insertions(+), 38 deletions(-) diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java index b0e38b1..4465be4 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java @@ -15,6 +15,7 @@ import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import org.mockbukkit.mockbukkit.entity.PlayerMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.data.AnvilClickTestData; @@ -271,6 +272,44 @@ public class LoreEditTests extends SharedCustomAnvilTest { ); } + @BeforeEach + public void prepareAnvil() { + anvil.clear(); + + // Make sure we reset value in case it got modified + for (@NotNull LoreEditType type : LoreEditType.values()) { + // Make sure it is enabled for the tests (unless its is enabled test) + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.IS_ENABLED, true); + + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.FIXED_COST, 1); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.PER_LINE_COST, 0); + + // Make sur color is enabled by default + if (type.isAppend()) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_HEX_COLOR, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_COLOR_CODE, true); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, 0); + } else { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_COST, 0); + } + + } + + // Disable them by default and test them on specific tests + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.BOOK_PERMISSION_NEEDED, false); + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_PERMISSION_NEEDED, false); + + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_EDIT_ORDER, LoreEditConfigUtil.DEFAULT_PAPER_EDIT_ORDER); + } + + @AfterAll + public static void tearDown() { + player = null; + anvil = null; + } + public @Nullable ItemStack uncoloredEquivalent(@Nullable ItemStack colored) { // null check if (null == colored) return null; @@ -307,43 +346,6 @@ public class LoreEditTests extends SharedCustomAnvilTest { return null; } - @BeforeEach - public void prepareAnvil() { - anvil.clear(); - - // Make sure we reset value in case it got modified - for (@NotNull LoreEditType type : LoreEditType.values()) { - // Make sure it is enabled for the tests (unless its is enabled test) - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.IS_ENABLED, true); - - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.DO_CONSUME, false); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.FIXED_COST, 1); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.PER_LINE_COST, 0); - - - // Make sur color is enabled by default - if (type.isAppend()) { - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_HEX_COLOR, true); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.ALLOW_COLOR_CODE, true); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.USE_COLOR_COST, 0); - } else { - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_ON_LORE_REMOVE, false); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(type.getRootPath() + "." + LoreEditConfigUtil.REMOVE_COLOR_COST, 0); - } - - } - - // Disable them by default and test them on specific tests - ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.BOOK_PERMISSION_NEEDED, false); - ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_PERMISSION_NEEDED, false); - } - - @AfterAll - public static void tearDown() { - player = null; - anvil = null; - } - public static List onlyAppendTypes() { ArrayList typeList = new ArrayList<>(); for (@NotNull LoreEditType type : LoreEditType.values()) { @@ -548,7 +550,74 @@ public class LoreEditTests extends SharedCustomAnvilTest { emptyPaperOne, coloredPaperOne); } - //TODO remove order test + @NotNull + private static ItemStack insertToLore(@NotNull ItemStack item, int index, @NotNull String toAppend) { + item = item.clone(); + ItemMeta meta = item.getItemMeta(); + Assertions.assertNotNull(meta); + Assertions.assertTrue(meta.hasLore()); + + ArrayList lore = new ArrayList<>(meta.getLore()); + lore.add(index, toAppend); + + meta.setLore(lore); + item.setItemMeta(meta); + return item; + } + + @NotNull + private static ItemStack setDisplayedName(@NotNull ItemStack item, @NotNull String name) { + item = item.clone(); + ItemMeta meta = item.getItemMeta(); + Assertions.assertNotNull(meta); + + meta.setDisplayName(name); + item.setItemMeta(meta); + return item; + } + + private static final String TESTED_LORE = "tested_lore"; + + @ParameterizedTest + @ValueSource(strings = {"sTaRt", "eNd"}) + public void testPaperOrder_Append(String order) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_EDIT_ORDER, order); + + ItemStack result = insertToLore(oneColoredLoreItem, "start".equalsIgnoreCase(order) ? 0 : 1, TESTED_LORE); + ItemStack paper = setDisplayedName(emptyPaperOne, TESTED_LORE); + + new TestDataContainer( + new AnvilFuseTestData( + oneColoredLoreItem, paper, result, 1 + ), + new AnvilClickTestData( + null, emptyPaperOne, null, result, + 1, + Event.Result.DENY, true, Event.Result.DENY + ) + ).executeTest(anvil, player); + } + + @ParameterizedTest + @ValueSource(strings = {"sTaRt", "eNd"}) + public void testPaperOrder_Remove(String order) { + ConfigHolder.DEFAULT_CONFIG.getConfig().set(LoreEditConfigUtil.PAPER_EDIT_ORDER, order); + + ItemStack from = insertToLore(oneColoredLoreItem, "start".equalsIgnoreCase(order) ? 0 : 1, TESTED_LORE); + ItemStack paper = setDisplayedName(emptyPaperOne, TESTED_LORE); + + new TestDataContainer( + new AnvilFuseTestData( + from, emptyPaperOne, oneColoredLoreItem, 1 + ), + new AnvilClickTestData( + null, paper, null, oneColoredLoreItem, + 1, + Event.Result.DENY, true, Event.Result.DENY + ) + ).executeTest(anvil, player); + } + //TODO work penalty test } From fd7e7684d9680580e4b009c38f64c2fbc2c4c857 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 21 Mar 2025 17:04:50 +0100 Subject: [PATCH 30/37] made lore edit compatible with enchantment squared --- .../cuanvil/dependency/DependencyManager.kt | 41 +++++++++++++++---- .../EnchantmentSquaredDependency.kt | 8 ++++ .../cuanvil/util/AnvilLoreEditUtil.kt | 8 +++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 437f3d5..212dc6d 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -105,8 +105,12 @@ object DependencyManager { fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { try { return unsafeTryEventPreAnvilBypass(event, player) - } catch (e: Exception){ - CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + } catch (e: Exception) { + CustomAnvil.instance.logger.log( + Level.SEVERE, + "Error while trying to handle custom anvil supported plugin: ", + e + ) // Just in case to avoid illegal items event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) @@ -141,8 +145,12 @@ object DependencyManager { try { unsafeTryTreatAnvilResult(event, result) return false - } catch (e: Exception){ - CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + } catch (e: Exception) { + CustomAnvil.instance.logger.log( + Level.SEVERE, + "Error while trying to handle custom anvil supported plugin: ", + e + ) // Just in case to avoid illegal items event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) @@ -160,9 +168,13 @@ object DependencyManager { // Return true if should bypass (either by a dependency or error) fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { try { - return unsafeTryClickAnvilResultBypass(event, inventory) - } catch (e: Exception){ - CustomAnvil.instance.logger.log(Level.SEVERE, "Error while trying to handle custom anvil supported plugin: ", e) + return unsafeTryClickAnvilResultBypass(event, inventory) + } catch (e: Exception) { + CustomAnvil.instance.logger.log( + Level.SEVERE, + "Error while trying to handle custom anvil supported plugin: ", + e + ) // Just in case to avoid illegal items event.inventory.setItem(ANVIL_OUTPUT_SLOT, null) @@ -191,6 +203,21 @@ object DependencyManager { return bypass } + fun stripLore(item: ItemStack): ArrayList { + val lore = ArrayList() + val dummy = item.clone() + + enchantmentSquaredCompatibility?.stripLore(dummy) + + val itemLore = item.itemMeta!!.lore + if (itemLore != null) lore.addAll(itemLore) + + return lore + } + + fun updateLore(item: ItemStack) { + enchantmentSquaredCompatibility?.updateLore(item) + } private fun testIsFolia(): Boolean { try { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt index 1b16c43..e630e8c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/EnchantmentSquaredDependency.kt @@ -203,4 +203,12 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) } } + fun stripLore(item: ItemStack) { + CustomEnchantManager.getInstance().removeAllEnchants(item) + } + + fun updateLore(item: ItemStack) { + CustomEnchantManager.getInstance().updateLore(item) + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index e3b6d41..5d93a05 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -1,9 +1,11 @@ package xyz.alexcrea.cuanvil.util +import com.willfp.eco.util.toNiceString import org.bukkit.entity.HumanEntity import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.BookMeta import org.bukkit.permissions.Permissible +import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType import java.util.concurrent.atomic.AtomicInteger @@ -60,13 +62,14 @@ object AnvilLoreEditUtil { // remove lore val result = first.clone() val leftMeta = result.itemMeta ?: return null - val currentLore = ArrayList(leftMeta.lore ?: return null) + val currentLore: ArrayList = DependencyManager.stripLore(result) val uncolorCost = uncolorLines(player, currentLore, LoreEditType.REMOVE_BOOK) leftMeta.lore = null result.itemMeta = leftMeta + DependencyManager.updateLore(result) if (result == first) return null // Handle xp @@ -182,7 +185,7 @@ object AnvilLoreEditUtil { val meta = result.itemMeta!! val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd - val lore: ArrayList = ArrayList(meta.lore!!) + val lore: ArrayList = DependencyManager.stripLore(result) val line = if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) @@ -195,6 +198,7 @@ object AnvilLoreEditUtil { tempList.add(line) val uncolorCost = uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) + DependencyManager.updateLore(result) if (result == first) return null // Handle other xp From 7f15e0eb55f404b55e8385f4d5d403aa40f4be9b Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 22 Mar 2025 13:42:40 +0100 Subject: [PATCH 31/37] fix enchantment squared once again --- .../cuanvil/listener/AnvilResultListener.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index ae089cb..e43ff62 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -6,7 +6,6 @@ import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.GameMode import org.bukkit.Material -import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler @@ -31,7 +30,6 @@ import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType import java.util.* import java.util.concurrent.atomic.AtomicInteger -import kotlin.collections.ArrayList import kotlin.math.min class AnvilResultListener : Listener { @@ -316,12 +314,12 @@ class AnvilResultListener : Listener { player: Player, inventory: AnvilInventory, ): Int { - if(GameMode.CREATIVE == player.gameMode) return 0 + if (GameMode.CREATIVE == player.gameMode) return 0 val repairCost = xpCost.get() return if ((inventory.maximumRepairCost <= repairCost) - || (player.level < repairCost)) Int.MIN_VALUE - + || (player.level < repairCost) + ) Int.MIN_VALUE else repairCost } @@ -364,10 +362,10 @@ class AnvilResultListener : Listener { // fill book meta val meta = leftItem.itemMeta if (meta == null || !meta.hasLore()) return false - val lore = ArrayList(meta.lore!!) + val lore = DependencyManager.stripLore(leftItem) if (lore.isEmpty()) return false - val rightCopy : ItemStack? + val rightCopy: ItemStack? if (LoreEditType.REMOVE_BOOK.doConsume) { rightCopy = null } else { @@ -445,14 +443,14 @@ class AnvilResultListener : Listener { val leftMeta = leftItem.itemMeta if (leftMeta == null || !leftMeta.hasLore()) return false - val lore = leftMeta.lore!! + val lore = DependencyManager.stripLore(leftItem) if (lore.isEmpty()) return false // Create result item val rightClone: ItemStack? - if(LoreEditType.REMOVE_PAPER.doConsume){ + if (LoreEditType.REMOVE_PAPER.doConsume) { rightClone = null - }else{ + } else { val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd var line = if (removeEnd) lore[lore.size - 1] else lore[0] From f02ac69928c9bd3f94d75b2d9917c2c4c28502f1 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 22 Mar 2025 18:54:44 +0100 Subject: [PATCH 32/37] fix me being stupid --- .../kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt | 2 +- src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 212dc6d..b962b03 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -209,7 +209,7 @@ object DependencyManager { enchantmentSquaredCompatibility?.stripLore(dummy) - val itemLore = item.itemMeta!!.lore + val itemLore = dummy.itemMeta!!.lore if (itemLore != null) lore.addAll(itemLore) return lore diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 5d93a05..e3b052a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -63,6 +63,7 @@ object AnvilLoreEditUtil { val result = first.clone() val leftMeta = result.itemMeta ?: return null val currentLore: ArrayList = DependencyManager.stripLore(result) + if(currentLore.isEmpty()) return null val uncolorCost = uncolorLines(player, currentLore, LoreEditType.REMOVE_BOOK) @@ -186,6 +187,7 @@ object AnvilLoreEditUtil { val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd val lore: ArrayList = DependencyManager.stripLore(result) + if(lore.isEmpty()) return null val line = if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) From a08fb3ac75b7afbb7e326d2163c382a4efeb14f6 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 22 Mar 2025 19:24:40 +0100 Subject: [PATCH 33/37] better order for paper remove lore --- .../alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index e3b052a..25256a1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -192,17 +192,24 @@ object AnvilLoreEditUtil { val line = if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) - meta.lore = if (lore.isEmpty()) null else lore + meta.lore = null result.itemMeta = meta + // Update lore but make sure custom lore is put last + DependencyManager.updateLore(result) + + val finalLore = ArrayList() + finalLore.addAll(meta.lore!!) + finalLore.addAll(lore) + + meta.lore = lore + if (result == first) return null + // Get color cost to uncolor this line val tempList = ArrayList(1) tempList.add(line) val uncolorCost = uncolorLines(player, tempList, LoreEditType.REMOVE_PAPER) - DependencyManager.updateLore(result) - if (result == first) return null - // Handle other xp xpCost.addAndGet(uncolorCost) xpCost.addAndGet(baseEditLoreXpCost(first, result, LoreEditType.REMOVE_PAPER)) From 8dbfeec2fa4334eb6ddd611061d9d589a87b3c75 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 21:20:49 +0200 Subject: [PATCH 34/37] update mockbukkit --- build.gradle.kts | 7 ++++--- .../java/xyz/alexcrea/cuanvil/mock/AnvilViewMock.java | 9 +++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 579eb6e..fc9fc09 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { signing id("cn.lalaki.central").version("1.2.5") // Paper - id("io.papermc.paperweight.userdev") version "2.0.0-beta.14" apply false + id("io.papermc.paperweight.userdev") version "2.0.0-beta.16" apply false } group = "xyz.alexcrea" @@ -72,7 +72,7 @@ dependencies { implementation(kotlin("stdlib")) // Test dependency - testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.37.0") + testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.45.1") testRuntimeOnly("commons-lang:commons-lang:2.6") } @@ -94,8 +94,9 @@ allprojects { compileOnly(kotlin("stdlib")) // Test dependency - testImplementation(platform("org.junit:junit-bom:5.11.3")) + testImplementation(platform("org.junit:junit-bom:5.12.2")) testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } tasks.getByName("test") { diff --git a/src/test/java/xyz/alexcrea/cuanvil/mock/AnvilViewMock.java b/src/test/java/xyz/alexcrea/cuanvil/mock/AnvilViewMock.java index cdb4c44..afcbb26 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/mock/AnvilViewMock.java +++ b/src/test/java/xyz/alexcrea/cuanvil/mock/AnvilViewMock.java @@ -60,12 +60,12 @@ public class AnvilViewMock extends PlayerInventoryViewMock implements AnvilView @Override public boolean bypassesEnchantmentLevelRestriction() { - throw new UnsupportedOperationException("Custom anvil was not think with this existing"); + throw new UnsupportedOperationException("This is currently is not used in CustomAnvil"); } @Override public void bypassEnchantmentLevelRestriction(boolean bypassEnchantmentLevelRestriction) { - throw new UnsupportedOperationException("Custom anvil was not think with this existing"); + throw new UnsupportedOperationException("This is currently is not used in CustomAnvil"); } @Override @@ -73,4 +73,9 @@ public class AnvilViewMock extends PlayerInventoryViewMock implements AnvilView return top; } + @Override + public void open() { + throw new UnsupportedOperationException("This is currently is not used in CustomAnvil"); + } + } From d145eb1122d7d5ad2daf1a0451a42e2ddf51ae2a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 23:29:02 +0200 Subject: [PATCH 35/37] fix null lore issue --- .../xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 25256a1..8f5b180 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -1,6 +1,5 @@ package xyz.alexcrea.cuanvil.util -import com.willfp.eco.util.toNiceString import org.bukkit.entity.HumanEntity import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.BookMeta @@ -63,7 +62,7 @@ object AnvilLoreEditUtil { val result = first.clone() val leftMeta = result.itemMeta ?: return null val currentLore: ArrayList = DependencyManager.stripLore(result) - if(currentLore.isEmpty()) return null + if (currentLore.isEmpty()) return null val uncolorCost = uncolorLines(player, currentLore, LoreEditType.REMOVE_BOOK) @@ -148,7 +147,7 @@ object AnvilLoreEditUtil { if (!hasLoreEditByPaperPermission(player)) return null val result = first.clone() - val meta = result.itemMeta?: return null + val meta = result.itemMeta ?: return null val lore = if (meta.hasLore()) { ArrayList(meta.lore!!) } else ArrayList() @@ -187,7 +186,7 @@ object AnvilLoreEditUtil { val removeEnd = LoreEditConfigUtil.paperLoreOrderIsEnd val lore: ArrayList = DependencyManager.stripLore(result) - if(lore.isEmpty()) return null + if (lore.isEmpty()) return null val line = if (removeEnd) lore.removeAt(lore.size - 1) else lore.removeAt(0) @@ -199,7 +198,7 @@ object AnvilLoreEditUtil { DependencyManager.updateLore(result) val finalLore = ArrayList() - finalLore.addAll(meta.lore!!) + finalLore.addAll(meta.lore ?: emptyList()) finalLore.addAll(lore) meta.lore = lore @@ -271,7 +270,7 @@ object AnvilLoreEditUtil { } fun uncolorLines(player: Permissible, lines: ArrayList, editType: LoreEditType): Int { - if(!editType.shouldRemoveColorOnLoreRemoval) return 0 + if (!editType.shouldRemoveColorOnLoreRemoval) return 0 // Now handle color of each lines var hasUndidColor = false From 5d427074a993fba04870b1284e0a355e2f18da8d Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 23:41:23 +0200 Subject: [PATCH 36/37] fix lore meta issue on paper remove --- .../xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt | 3 ++- .../xyz/alexcrea/cuanvil/anvil/LoreEditTests.java | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt index 8f5b180..dd0da1e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilLoreEditUtil.kt @@ -201,7 +201,8 @@ object AnvilLoreEditUtil { finalLore.addAll(meta.lore ?: emptyList()) finalLore.addAll(lore) - meta.lore = lore + meta.lore = finalLore + result.itemMeta = meta if (result == first) return null // Get color cost to uncolor this line diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java index 4465be4..ebfb84f 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/LoreEditTests.java @@ -362,13 +362,13 @@ public class LoreEditTests extends SharedCustomAnvilTest { return typeList; } - @Test - public void simpleTest() { + @ParameterizedTest + @EnumSource(LoreEditType.class) + public void simpleTest(LoreEditType type) { // Test all defaults to make sure they works - for (LoreEditType type : LoreEditType.values()) { - singleLineTypeToTest.get(type).executeTest(anvil, player); - multiLineTypeToTest.get(type).executeTest(anvil, player); - } + singleLineTypeToTest.get(type).executeTest(anvil, player); + multiLineTypeToTest.get(type).executeTest(anvil, player); + } @ParameterizedTest From 02dea53a69567964f18c82f1d16fc41cfdb0f330 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 27 Apr 2025 23:49:05 +0200 Subject: [PATCH 37/37] do not mock every time --- .../cuanvil/tests/DefaultCustomAnvilTest.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/test/java/xyz/alexcrea/cuanvil/tests/DefaultCustomAnvilTest.java b/src/test/java/xyz/alexcrea/cuanvil/tests/DefaultCustomAnvilTest.java index 3a1c399..bdb280c 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/tests/DefaultCustomAnvilTest.java +++ b/src/test/java/xyz/alexcrea/cuanvil/tests/DefaultCustomAnvilTest.java @@ -1,7 +1,9 @@ package xyz.alexcrea.cuanvil.tests; import io.delilaheve.CustomAnvil; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.mockbukkit.mockbukkit.MockBukkit; import org.mockbukkit.mockbukkit.ServerMock; @@ -13,13 +15,16 @@ import java.util.List; public abstract class DefaultCustomAnvilTest { - protected ServerMock server; + protected static ServerMock server; protected CustomAnvil plugin; + @BeforeAll + public static void setupMock() { + server = MockBukkit.mock(); + } + @BeforeEach public void setUp() { - // Start the mock server - server = MockBukkit.mock(); // Load your plugin plugin = MockBukkit.load(CustomAnvil.class); // Continue initialization of the plugin @@ -28,9 +33,6 @@ public abstract class DefaultCustomAnvilTest { @AfterEach public void tearDown() { - // Stop the mock server - MockBukkit.unmock(); - // Unregister enchantments List toUnregister = new ArrayList<>( CAEnchantmentRegistry.getInstance().values() @@ -40,6 +42,13 @@ public abstract class DefaultCustomAnvilTest { CAEnchantmentRegistry.getInstance().unregister(caEnchantment); } + server.getPluginManager().disablePlugin(plugin); + } + + @AfterAll + public static void tearDownMock() { + // Stop the mock server + MockBukkit.unmock(); } }