From 7a19632150a7e2270dc1832c1ed0e4b8d6fe21ae Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 04:24:44 +0200 Subject: [PATCH 01/12] Add permission and config option in the config file. --- .../io/delilaheve/util/ConfigOptions.kt | 114 ++++++++++++------ src/main/resources/config.yml | 18 ++- src/main/resources/plugin.yml | 8 ++ 3 files changed, 103 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 03eedcf..3715e52 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -10,87 +10,74 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment */ object ConfigOptions { - // Path for limiting anvil cost + // ---------------------- + // Path for config values + // ---------------------- + const val CAP_ANVIL_COST = "limit_repair_cost" - - // Path for max anvil cost value const val MAX_ANVIL_COST = "limit_repair_value" - - // Path for removing anvil cost limits const val REMOVE_ANVIL_COST_LIMIT = "remove_repair_limit" - // Path for removing too expensive when unused const val REPLACE_TOO_EXPENSIVE = "replace_too_expensive" - // Path for level cost on item repair const val ITEM_REPAIR_COST = "item_repair_cost" - - // Path for level cost on unit repair const val UNIT_REPAIR_COST = "unit_repair_cost" - // Path for level cost on item renaming const val ITEM_RENAME_COST = "item_rename_cost" - // Path for level cost on illegal enchantment on sacrifice const val SACRIFICE_ILLEGAL_COST = "sacrifice_illegal_enchant_cost" - // Path for default enchantment limits + // Color related config + const val ALLOW_COLOR_CODE = "allow_color_code" + const val ALLOW_HEXADECIMAL_COLOR = "allow_hexadecimal_color" + const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color" + const val USE_OF_COLOR_COST = "use_of_color_cost" + private const val DEFAULT_LIMIT_PATH = "default_limit" - - // Root path for enchantment limits const val ENCHANT_LIMIT_ROOT = "enchant_limits" - - - // Root path for enchantment values const val ENCHANT_VALUES_ROOT = "enchant_values" // Keys for specific enchantment values private const val KEY_BOOK = "book" private const val KEY_ITEM = "item" - - // Debug logging toggle path + // Debug flag private const val DEBUG_LOGGING = "debug_log" - - // Debug verbose logging toggle path private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose" + // ---------------------- + // Default config values + // ---------------------- - // Default value for limiting repair cost const val DEFAULT_CAP_ANVIL_COST = false - - // Default value for repair cost limit const val DEFAULT_MAX_ANVIL_COST = 39 - - // Default for removing repair cost limits const val DEFAULT_REMOVE_ANVIL_COST_LIMIT = false - // Default for removing repair cost limits const val DEFAULT_REPLACE_TOO_EXPENSIVE = false - // Default value for level cost on item repair const val DEFAULT_ITEM_REPAIR_COST = 2 - - // Default value for level cost per unit repair const val DEFAULT_UNIT_REPAIR_COST = 1 - // Default value for level cost on item renaming const val DEFAULT_ITEM_RENAME_COST = 1 - // Default value for level cost on illegal enchantment on sacrifice const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1 + // Color related config + const val DEFAULT_ALLOW_COLOR_CODE = false + const val DEFAULT_ALLOW_HEXADECIMAL_COLOR = false + const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true + const val DEFAULT_USE_OF_COLOR_COST = 0 - // Default value for enchantment limits private const val DEFAULT_ENCHANT_LIMIT = 5 - // Default value for debug logging + // Debug flag private const val DEFAULT_DEBUG_LOG = false - - // Default value for debug logging private const val DEFAULT_VERBOSE_DEBUG_LOG = false + // ------------- + // Config Ranges + // ------------- // Valid range for repair cost limit @JvmField @@ -108,6 +95,10 @@ object ConfigOptions { @JvmField val SACRIFICE_ILLEGAL_COST_RANGE = 0..1000 + // Valid range for color use cost + @JvmField + val USE_OF_COLOR_COST_RANGE = 0..1000 + // Valid range for an enchantment limit @JvmField val ENCHANT_LIMIT_RANGE = 1..255 @@ -116,6 +107,10 @@ object ConfigOptions { // Default value for an enchantment multiplier private const val DEFAULT_ENCHANT_VALUE = 0 + // ------------- + // Get methods + // ------------- + /** * Whether to cap anvil costs */ @@ -206,6 +201,53 @@ object ConfigOptions { ?: DEFAULT_SACRIFICE_ILLEGAL_COST } + /** + * Allow usage of color code + */ + val allowColorCode: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE) + } + + /** + * Allow usage of hexadecimal color + */ + val allowHexadecimalColor: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR) + } + + /** + * If one of the color component is enabled + */ + val renameColorPossible: Boolean get() { return allowColorCode || allowHexadecimalColor } + + /** + * If players need a permission to use color + */ + val permissionNeededForColor: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR) + } + + /** + * How many xp should use of color should cost + */ + private val useOfColorCost: Int + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getInt(USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST) + .takeIf { it in USE_OF_COLOR_COST_RANGE } + ?: DEFAULT_USE_OF_COLOR_COST + } + /** * Default enchantment limit */ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5cc0929..2cbd83e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -55,7 +55,23 @@ unit_repair_cost: 1 # Valid values include 0 to 1000 sacrifice_illegal_enchant_cost: 1 -# Default limit to apply to any enchants missing from override_limits +# Allow using color code and hexadecimal color. +# +# Color code are prefixed by "&" and hexadecimal color by "#". +allow_color_code: false +allow_hexadecimal_color: false + +# Toggle if color should only be applicable if the player a certain permission. +# +# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color. +permission_needed_for_color: true + +# Xp cost if the player use color in the items name on rename. +# +# Valid values include 0 to 1000. +use_of_color_cost: 0 + +# Default limit to apply to any enchants missing from enchant_limits # # Valid values include 1 to 1000 default_limit: 5 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c5ff2e5..f28e52d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -39,6 +39,14 @@ permissions: ca.config.edit: default: op description: Allow administrator to edit the plugin's config in game + # color permissions + ca.color.code: + default: op + description: Allow player to use color code if permission is required (toggleable) + ca.color.hex: + default: op + description: Allow player to use hexadecimal color if permission is required (toggleable) + # soft depend on old name, so I can disable it if it is on the same server # as it is the old name for this plugin From 9744817c043e340b75d60ec7ee143102cac1daab Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:25:12 +0200 Subject: [PATCH 02/12] Fast build for color code support. --- build.gradle.kts | 2 +- src/main/kotlin/io/delilaheve/AnvilEventListener.kt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 31aad8f..7de0b7a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.5.3" +version = "1.5.4-beta-1" java { disableAutoTargetJvm() diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 5837e98..1dadb9d 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -164,9 +164,15 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { resultItem.itemMeta?.let { val displayName = ChatColor.stripColor(it.displayName) val inventoryName = ChatColor.stripColor(inventory.renameText) + // Change color name + if(inventoryName != null){ + inventoryName.replace("&", "§") + } + if (!displayName.contentEquals(inventoryName)) { it.setDisplayName(inventory.renameText) resultItem.itemMeta = it + return ConfigOptions.itemRenameCost } } From b6853a6889db29a4ae8a0b0f01d6b9b252e02a49 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:29:07 +0200 Subject: [PATCH 03/12] Fix mistake caused by string being imutable. --- src/main/kotlin/io/delilaheve/AnvilEventListener.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 1dadb9d..32b0e49 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -163,10 +163,10 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { // Rename item and add renaming cost resultItem.itemMeta?.let { val displayName = ChatColor.stripColor(it.displayName) - val inventoryName = ChatColor.stripColor(inventory.renameText) + var inventoryName = ChatColor.stripColor(inventory.renameText) // Change color name if(inventoryName != null){ - inventoryName.replace("&", "§") + inventoryName = inventoryName.replace("&", "§") } if (!displayName.contentEquals(inventoryName)) { From 90344e635ae12c07e26fad8b9c65351527766f07 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:33:15 +0200 Subject: [PATCH 04/12] Fix not using the modified string. --- build.gradle.kts | 2 +- src/main/kotlin/io/delilaheve/AnvilEventListener.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7de0b7a..1c816c7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.5.4-beta-1" +version = "1.5.4-beta.1" java { disableAutoTargetJvm() diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 32b0e49..ebd03af 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -170,7 +170,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { } if (!displayName.contentEquals(inventoryName)) { - it.setDisplayName(inventory.renameText) + it.setDisplayName(inventoryName) resultItem.itemMeta = it return ConfigOptions.itemRenameCost From 94941d1559d3e092348b03e4b55f086dc4cdd36e Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:25:31 +0200 Subject: [PATCH 05/12] Correct logic for coloring using color code. --- .../io/delilaheve/AnvilEventListener.kt | 62 ++++++++++++++++--- src/main/resources/config.yml | 1 + 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index ebd03af..11d1ed2 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -12,6 +12,7 @@ import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor 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 @@ -79,7 +80,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { // Test rename lonely item if (second == null) { val resultItem = first.clone() - var anvilCost = handleRename(resultItem, inventory) + var anvilCost = handleRename(resultItem, inventory, player) // Test/stop if nothing changed. if (first == resultItem) { @@ -121,7 +122,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { // As calculatePenalty edit result, we need to calculate penalty after checking equality anvilCost += calculatePenalty(first, second, resultItem) // Calculate rename cost - anvilCost += handleRename(resultItem, inventory) + anvilCost += handleRename(resultItem, inventory, player) // Finally, we set result event.result = resultItem @@ -134,7 +135,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { val unitRepairAmount = first.getRepair(second) if (unitRepairAmount != null) { val resultItem = first.clone() - var anvilCost = handleRename(resultItem, inventory) + var anvilCost = handleRename(resultItem, inventory, player) val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount) if (repairAmount > 0) { @@ -159,17 +160,22 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { } - private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int { + private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { // Rename item and add renaming cost resultItem.itemMeta?.let { val displayName = ChatColor.stripColor(it.displayName) var inventoryName = ChatColor.stripColor(inventory.renameText) - // Change color name - if(inventoryName != null){ - inventoryName = inventoryName.replace("&", "§") + + var useColor = false + if(ConfigOptions.renameColorPossible){ + val resultString = StringBuilder(inventoryName) + + useColor = handleRenamingColor(resultString, player) + + if(useColor) inventoryName = resultString.toString() } - if (!displayName.contentEquals(inventoryName)) { + if ((!useColor && !displayName.contentEquals(inventoryName)) || (useColor && !(it.displayName).contentEquals(inventoryName))) { it.setDisplayName(inventoryName) resultItem.itemMeta = it @@ -179,6 +185,46 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { return 0 } + private 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")) + + if((!canUseColorCode) && (!canUseHexColor)) return false + + var useColor = false + // Handle color code + if(canUseColorCode){ + useColor = replaceAll(textToColor, "&", "§", 2) + replaceAll(textToColor, "§§", "&", 2) + } + + //TODO handle hexadecimal color + + return useColor + } + + /** + * Replace every instance of "from" to "to". + * @param builder The builder to replace the string from. + * @param from The source that should be replaced. + * @param to The string that should replace. + * @param endOffset Amount of character that should be ignored at the end. + */ + private fun replaceAll(builder: java.lang.StringBuilder, from: String, to: String, endOffset: Int): Boolean { + var index = builder.indexOf(from) + if(index == -1 || index >= builder.length - endOffset) return false + + while (index != -1 && index < builder.length - endOffset) { + CustomAnvil.log("$index ; ${builder.length - endOffset} ") + builder.replace(index, index + from.length, to) + index += to.length + index = builder.indexOf(from, index) + } + + return true + } + /** * Event handler logic for when a player is trying to pull an item out of the anvil */ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2cbd83e..10da46c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -58,6 +58,7 @@ sacrifice_illegal_enchant_cost: 1 # Allow using color code and hexadecimal color. # # 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: false allow_hexadecimal_color: false From 761f8ed4e829928ae0cdb2551140d48522459d95 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:30:34 +0200 Subject: [PATCH 06/12] Fix && being considered using color. --- .../kotlin/io/delilaheve/AnvilEventListener.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 11d1ed2..78725b2 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -195,8 +195,10 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { var useColor = false // Handle color code if(canUseColorCode){ - useColor = replaceAll(textToColor, "&", "§", 2) - replaceAll(textToColor, "§§", "&", 2) + var nbReplacement = replaceAll(textToColor, "&", "§", 2) + nbReplacement -= 2 * replaceAll(textToColor, "§§", "&", 2) + + if(nbReplacement > 0) useColor = true } //TODO handle hexadecimal color @@ -210,19 +212,20 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { * @param from The source that should be replaced. * @param to The string that should replace. * @param endOffset Amount of character that should be ignored at the end. + * @return The number of replacement was that was done. */ - private fun replaceAll(builder: java.lang.StringBuilder, from: String, to: String, endOffset: Int): Boolean { + private fun replaceAll(builder: java.lang.StringBuilder, from: String, to: String, endOffset: Int): Int { var index = builder.indexOf(from) - if(index == -1 || index >= builder.length - endOffset) return false + var numberOfChanges = 0 while (index != -1 && index < builder.length - endOffset) { - CustomAnvil.log("$index ; ${builder.length - endOffset} ") builder.replace(index, index + from.length, to) index += to.length index = builder.indexOf(from, index) + numberOfChanges+=1 } - return true + return numberOfChanges } /** From 794a440d33bb967d6f7b3eeffeb430be0234e712 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:06:39 +0200 Subject: [PATCH 07/12] Add hexadecimal color support. --- .../io/delilaheve/AnvilEventListener.kt | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 78725b2..c574153 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -31,8 +31,11 @@ import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.regex.Matcher +import java.util.regex.Pattern import kotlin.math.min + /** * Listener for anvil events */ @@ -201,7 +204,11 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { if(nbReplacement > 0) useColor = true } - //TODO handle hexadecimal color + if(canUseHexColor){ + val nbReplacement = replaceHexToColor(textToColor, 7) + + if(nbReplacement > 0) useColor = true + } return useColor } @@ -222,6 +229,37 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { builder.replace(index, index + from.length, to) index += to.length index = builder.indexOf(from, index) + + numberOfChanges+=1 + } + + return numberOfChanges + } + + val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string + /** + * Replace every hex color formatted like #000000 to the minecraft format + * @param builder The builder to replace the 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 replaceHexToColor(builder: StringBuilder, endOffset: Int): Int { + val matcher: Matcher = HEX_PATTERN.matcher(builder) + + var numberOfChanges = 0 + var startIndex = 0 + CustomAnvil.log("${matcher.find(startIndex)} $builder") + while(matcher.find(startIndex)){ + startIndex = matcher.start() + if(startIndex >= builder.length - endOffset) break + + builder.replace(startIndex, startIndex + 1, "§x") + startIndex+=2 + for (i in 0..5) { + builder.insert(startIndex, '§') + startIndex+=2 + } + numberOfChanges+=1 } From f72d3622ca7305b748fc71ac9991e1016941ee0e Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 18:28:06 +0200 Subject: [PATCH 08/12] Add use of color cost. --- .../io/delilaheve/AnvilEventListener.kt | 20 ++++++++++++++++--- .../io/delilaheve/util/ConfigOptions.kt | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index c574153..5abb6fc 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -169,21 +169,29 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { val displayName = ChatColor.stripColor(it.displayName) var inventoryName = ChatColor.stripColor(inventory.renameText) + var sumCost = 0 + var useColor = false if(ConfigOptions.renameColorPossible){ val resultString = StringBuilder(inventoryName) useColor = handleRenamingColor(resultString, player) - if(useColor) inventoryName = resultString.toString() + if(useColor) { + inventoryName = resultString.toString() + + sumCost+= ConfigOptions.useOfColorCost + } } - if ((!useColor && !displayName.contentEquals(inventoryName)) || (useColor && !(it.displayName).contentEquals(inventoryName))) { + if ((!useColor && (!displayName.contentEquals(inventoryName))) || (useColor && !(it.displayName).contentEquals(inventoryName))) { it.setDisplayName(inventoryName) resultItem.itemMeta = it - return ConfigOptions.itemRenameCost + sumCost+= ConfigOptions.itemRenameCost } + + return sumCost } return 0 } @@ -415,8 +423,14 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { leftItem.itemMeta?.let { leftMeta -> val leftName = leftMeta.displayName output.itemMeta?.let { + // Rename cost if (!leftName.contentEquals(it.displayName)) { repairCost += ConfigOptions.itemRenameCost + + // Color cost + if(it.displayName.contains('§')){ + repairCost += ConfigOptions.useOfColorCost + } } } } diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 3715e52..80dea06 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -239,7 +239,7 @@ object ConfigOptions { /** * How many xp should use of color should cost */ - private val useOfColorCost: Int + val useOfColorCost: Int get() { return ConfigHolder.DEFAULT_CONFIG .config From 904e7a769a3e4a7b1739ff6aa1f65242e80789e6 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Jul 2024 20:12:58 +0200 Subject: [PATCH 09/12] Fix anvil repair cost being increased for renaming. --- .../kotlin/io/delilaheve/AnvilEventListener.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 5abb6fc..7c6ca2a 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -256,7 +256,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { var numberOfChanges = 0 var startIndex = 0 - CustomAnvil.log("${matcher.find(startIndex)} $builder") + while(matcher.find(startIndex)){ startIndex = matcher.start() if(startIndex >= builder.length - endOffset) break @@ -503,7 +503,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { /** * Function to calculate work penalty of anvil work - * Also change result work penalty + * Also change result work penalty if right item is not null */ private fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack): Int { // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation @@ -516,10 +516,13 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { (right.itemMeta as? Repairable)?.repairCost ?: 0 } - // Try to set work penalty for the result item - result.itemMeta?.let { - (it as? Repairable)?.repairCost = leftPenalty * 2 + 1 - result.itemMeta = it + // Try to set work penalty for the result item only if right item not null + if(right != null){ + result.itemMeta?.let { + (it as? Repairable)?.repairCost = leftPenalty * 2 + 1 + result.itemMeta = it + + } } CustomAnvil.log( From 3444c717633e506fcfd724ea0732dab721846d2a Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:21:13 +0200 Subject: [PATCH 10/12] Add color config to basic gui. --- .../gui/config/global/BasicConfigGui.java | 82 ++++++++++++++++--- 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java index 4d900dc..1943b48 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java @@ -59,8 +59,8 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { private void init() { Pattern pattern = new Pattern( GuiSharedConstant.EMPTY_GUI_FULL_LINE, - "0L0T0I0S0", - "0C0R0U0r0", + "LT0I0S0cp", + "CR0U0r0hP", "B00000000" ); pane = new PatternPane(0, 0, 9, 4, pattern); @@ -73,9 +73,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { updateGuiValues(); } - private BoolSettingsGui.BoolSettingFactory capAnvilCostFactory; // L character + private BoolSettingsGui.BoolSettingFactory capAnvilCost; // L character private GuiItem noCapRepairItem; - private IntSettingsGui.IntSettingFactory maxAnvilCostFactory; // C character + private IntSettingsGui.IntSettingFactory maxAnvilCost; // C character private GuiItem noMaxCostItem; private BoolSettingsGui.BoolSettingFactory removeAnvilCostLimit; // R character @@ -86,12 +86,18 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { private IntSettingsGui.IntSettingFactory itemRenameCost; // r character private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost; // S character + private BoolSettingsGui.BoolSettingFactory allowColorCode; // c character + private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character + + private BoolSettingsGui.BoolSettingFactory permissionNeededForColor; // p character + private IntSettingsGui.IntSettingFactory useOfColorCost; // P character + /** * Prepare basic gui displayed items factory and static items.. */ protected void prepareValues() { // cap anvil cost - this.capAnvilCostFactory = BoolSettingsGui.boolFactory("\u00A78Cap Anvil Cost ?", this, + this.capAnvilCost = BoolSettingsGui.boolFactory("\u00A78Cap Anvil Cost ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, "\u00A77All anvil cost will be capped to \u00A7aMax Anvil Cost\u00A77 if enabled.", @@ -110,7 +116,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // repair cost item IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; - this.maxAnvilCostFactory = IntSettingsGui.intFactory("\u00A78Max Anvil Cost", this, + this.maxAnvilCost = IntSettingsGui.intFactory("\u00A78Max Anvil Cost", this, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "\u00A77Max cost the Anvil can get to.", @@ -147,6 +153,10 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, getReplaceToExpensiveLore()); + // ------------ + // Cost config + // ------------ + // item repair cost range = ConfigOptions.REPAIR_COST_RANGE; this.itemRepairCost = IntSettingsGui.intFactory("\u00A78Item Repair Cost", this, @@ -194,6 +204,42 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, 1, 5, 10, 50, 100); + // ------------- + // Color config + // ------------- + + this.allowColorCode = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Color Code ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, + "\u00A77Whether players can use color code.", + "\u00A77Color code a formatted like \u00A7a&a\u00A77 and is used in the rename field of the anvil.", + "\u00A77Player may need permission to use color code if \u00A7ePlayer need permission to use color\u00A77 is enabled."); + + this.allowHexColor = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Hexadecimal Color ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, + "\u00A77Whether players can use hexadecimal color.", + "\u00A77Color code a formatted like \u00A7e#012345\u00A77 and is used in the rename field of the anvil.", + "\u00A77Player may need permission to use color code if \u00A7ePermission Needed For Color\u00A77 is enabled."); + + this.permissionNeededForColor = BoolSettingsGui.boolFactory("\u00A78Need Permission To Use Color ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, + "\u00A77Whether players should have permission to be able to use colors.", + "\u00A77Give player \u00A7eca.color.code\u00A77 Permission to allow use of color code.", + "\u00A77Give player \u00A7eca.color.hex\u00A77 Permission to allow use of hexadecimal color."); + + range = ConfigOptions.USE_OF_COLOR_COST_RANGE; + this.useOfColorCost = IntSettingsGui.intFactory("\u00A78Cost Of Using Color", this, + ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP level cost when using color code or hexadecimal color using the anvil.", + "\u00A77conflict With one of the left item enchantment" + ), + range.getFirst(), range.getLast(), + ConfigOptions.DEFAULT_USE_OF_COLOR_COST, + 1, 5, 10, 50, 100); + } @NotNull @@ -219,8 +265,8 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { GuiItem capAnvilCostItem; GuiItem maxAnvilCostItem; if (!this.removeAnvilCostLimit.getConfiguredValue()) { - capAnvilCostItem = this.capAnvilCostFactory.getItem("Cap Anvil Cost"); - maxAnvilCostItem = this.maxAnvilCostFactory.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); + capAnvilCostItem = this.capAnvilCost.getItem("Cap Anvil Cost"); + maxAnvilCostItem = this.maxAnvilCost.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); } else { capAnvilCostItem = this.noCapRepairItem; maxAnvilCostItem = this.noMaxCostItem; @@ -247,13 +293,29 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { pane.bindItem('U', unitRepairCostItem); // item rename cost - GuiItem itemRenameCost = this.itemRenameCost.getItem(Material.NAME_TAG); - pane.bindItem('r', itemRenameCost); + GuiItem itemRenameCostItem = this.itemRenameCost.getItem(Material.NAME_TAG); + pane.bindItem('r', itemRenameCostItem); // sacrifice illegal enchant cost GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK); pane.bindItem('S', illegalCostItem); + // allow color code + GuiItem allowColorCodeItem = this.allowColorCode.getItem(); + pane.bindItem('c', allowColorCodeItem); + + // allow hex color + GuiItem allowHexColorItem = this.allowHexColor.getItem(); + pane.bindItem('h', allowHexColorItem); + + // use permission for color + GuiItem permissionNeededItem = this.permissionNeededForColor.getItem(); + pane.bindItem('p', permissionNeededItem); + + // using color cost + GuiItem useColorCostItem = this.useOfColorCost.getItem(Material.EXPERIENCE_BOTTLE, "Use color"); + pane.bindItem('P', useColorCostItem); + update(); } From 1cc3143a0ec911e20481c36455e8f0efaeb86c23 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:36:59 +0200 Subject: [PATCH 11/12] Add item to disable configuration button that would change nothing. --- .../gui/config/global/BasicConfigGui.java | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java index 1943b48..8729232 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java @@ -90,7 +90,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character private BoolSettingsGui.BoolSettingFactory permissionNeededForColor; // p character + private GuiItem noPermissionNeededItem; private IntSettingsGui.IntSettingFactory useOfColorCost; // P character + private GuiItem noColorCostItem; /** * Prepare basic gui displayed items factory and static items.. @@ -208,6 +210,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // Color config // ------------- + // Allow us of color code this.allowColorCode = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Color Code ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, @@ -215,13 +218,15 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { "\u00A77Color code a formatted like \u00A7a&a\u00A77 and is used in the rename field of the anvil.", "\u00A77Player may need permission to use color code if \u00A7ePlayer need permission to use color\u00A77 is enabled."); + // Allow us of hexadecimal color this.allowHexColor = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Hexadecimal Color ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, "\u00A77Whether players can use hexadecimal color.", - "\u00A77Color code a formatted like \u00A7e#012345\u00A77 and is used in the rename field of the anvil.", + "\u00A77Color code a formatted like \u00A72#012345 \u00A77and is used in the rename field of the anvil.", "\u00A77Player may need permission to use color code if \u00A7ePermission Needed For Color\u00A77 is enabled."); + // Permission needed for color this.permissionNeededForColor = BoolSettingsGui.boolFactory("\u00A78Need Permission To Use Color ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, @@ -229,6 +234,19 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { "\u00A77Give player \u00A7eca.color.code\u00A77 Permission to allow use of color code.", "\u00A77Give player \u00A7eca.color.hex\u00A77 Permission to allow use of hexadecimal color."); + // Permission needed for color not necessary + item = new ItemStack(Material.BARRIER); + meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7cNeed Permission To Use Color ?"); + meta.setLore(Arrays.asList("\u00A77This config can do something only if one of the following config is enabled:", + "\u00A77- \u00A7aAllow Use Of Color Code", + "\u00A77- \u00A7aAllow Use Of Hexadecimal Color")); + item.setItemMeta(meta); + this.noPermissionNeededItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + + // Cost of using color range = ConfigOptions.USE_OF_COLOR_COST_RANGE; this.useOfColorCost = IntSettingsGui.intFactory("\u00A78Cost Of Using Color", this, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, @@ -240,6 +258,18 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.DEFAULT_USE_OF_COLOR_COST, 1, 5, 10, 50, 100); + // Permission needed for color not necessary + item = new ItemStack(Material.BARRIER); + meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7cCost Of Using Color"); + meta.setLore(Arrays.asList("\u00A77This config can do something only if one of the following config is enabled:", + "\u00A77- \u00A7aAllow Use Of Color Code", + "\u00A77- \u00A7aAllow Use Of Hexadecimal Color")); + item.setItemMeta(meta); + this.noColorCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + } @NotNull @@ -308,13 +338,20 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { GuiItem allowHexColorItem = this.allowHexColor.getItem(); pane.bindItem('h', allowHexColorItem); - // use permission for color - GuiItem permissionNeededItem = this.permissionNeededForColor.getItem(); - pane.bindItem('p', permissionNeededItem); + // True if player could place color + if(ConfigOptions.INSTANCE.getRenameColorPossible()){ + // use permission for color + GuiItem permissionNeededItem = this.permissionNeededForColor.getItem(); + pane.bindItem('p', permissionNeededItem); + + // using color cost + GuiItem useColorCostItem = this.useOfColorCost.getItem(Material.EXPERIENCE_BOTTLE, "Use color"); + pane.bindItem('P', useColorCostItem); + }else{ + pane.bindItem('p', this.noPermissionNeededItem); + pane.bindItem('P', this.noColorCostItem); + } - // using color cost - GuiItem useColorCostItem = this.useOfColorCost.getItem(Material.EXPERIENCE_BOTTLE, "Use color"); - pane.bindItem('P', useColorCostItem); update(); } From 06ea5e72d5b6e342e992bd122b6fa9e190517b57 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:45:38 +0200 Subject: [PATCH 12/12] Add Permission and feature to README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5cde745..77c6618 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ or [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest) - Display xp cost instead of "to expensive" when above lv 40. (need ProtocoLib) - Can handle some custom enchantment plugins (see bellow for more information) - Gui to configure the plugin in game. +- Support of color code and hexadecimal color --- ### Permissions: ```yml @@ -34,6 +35,9 @@ 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) ``` /!\ version under 1.3.1 use other permission. from 1.2.0 to 1.3.1-A1 use ua.unsafe instead of ca.affected under 1.2.0 replace ca prefix by ue and use ue.unsafe. some permission/features may not exist before the last version.