diff --git a/build.gradle.kts b/build.gradle.kts index db82f1c..71945d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.16.3" +version = "1.17.0" val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true" diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index 872ea2e..12322e9 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -99,6 +99,24 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Dialogue rename menu make use of dialog menu to allow bigger rename +# You can also change the maximum size and set it to -1 or less for maximum +# +# This feature only work on paper 1.21.7 or later +# +# At the moment only english is available for this menu... sorry ! +# +# CustomAnvil use "ca.rename.dialog" when permission +enable_dialog_rename: false +dialog_rename_max_size: 256 +permission_needed_for_dialog_rename: false + +# This allows custom anvil to not "guess" the text used for rename but store it in the item +# It will make item stackable only and only if it had used the same rename text +# +# For practical reason. this only work when dialog rename is enabled +dialog_rename_keep_user_text: true + # Override limits for specific enchants # # Enchantments not listed here will use the value of default_limit diff --git a/defaultconfigs/1.21.11/config.yml b/defaultconfigs/1.21.11/config.yml index bbfcb88..39c8504 100644 --- a/defaultconfigs/1.21.11/config.yml +++ b/defaultconfigs/1.21.11/config.yml @@ -101,6 +101,24 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Dialogue rename menu make use of dialog menu to allow bigger rename +# You can also change the maximum size and set it to -1 or less for maximum +# +# This feature only work on paper 1.21.7 or later +# +# At the moment only english is available for this menu... sorry ! +# +# CustomAnvil use "ca.rename.dialog" when permission +enable_dialog_rename: false +dialog_rename_max_size: 256 +permission_needed_for_dialog_rename: false + +# This allows custom anvil to not "guess" the text used for rename but store it in the item +# It will make item stackable only and only if it had used the same rename text +# +# For practical reason. this only work when dialog rename is enabled +dialog_rename_keep_user_text: true + # Override limits for specific enchants # # Enchantments not listed here will use the value of default_limit diff --git a/defaultconfigs/1.21.9/config.yml b/defaultconfigs/1.21.9/config.yml index 0d4f810..84eccba 100644 --- a/defaultconfigs/1.21.9/config.yml +++ b/defaultconfigs/1.21.9/config.yml @@ -99,6 +99,24 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Dialogue rename menu make use of dialog menu to allow bigger rename +# You can also change the maximum size and set it to -1 or less for maximum +# +# This feature only work on paper 1.21.7 or later +# +# At the moment only english is available for this menu... sorry ! +# +# CustomAnvil use "ca.rename.dialog" when permission +enable_dialog_rename: false +dialog_rename_max_size: 256 +permission_needed_for_dialog_rename: false + +# This allows custom anvil to not "guess" the text used for rename but store it in the item +# It will make item stackable only and only if it had used the same rename text +# +# For practical reason. this only work when dialog rename is enabled +dialog_rename_keep_user_text: true + # Override limits for specific enchants # # Enchantments not listed here will use the value of default_limit diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index 24df643..df62e6a 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -99,6 +99,24 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Dialogue rename menu make use of dialog menu to allow bigger rename +# You can also change the maximum size and set it to -1 or less for maximum +# +# This feature only work on paper 1.21.7 or later +# +# At the moment only english is available for this menu... sorry ! +# +# CustomAnvil use "ca.rename.dialog" when permission +enable_dialog_rename: false +dialog_rename_max_size: 256 +permission_needed_for_dialog_rename: false + +# This allows custom anvil to not "guess" the text used for rename but store it in the item +# It will make item stackable only and only if it had used the same rename text +# +# For practical reason. this only work when dialog rename is enabled +dialog_rename_keep_user_text: true + # Override limits for specific enchants # # Enchantments not listed here will use the value of default_limit diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialog.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialog.kt new file mode 100644 index 0000000..62e1cf0 --- /dev/null +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialog.kt @@ -0,0 +1,21 @@ +package xyz.alexcrea.cuanvil.dialog + +import org.bukkit.NamespacedKey +import org.bukkit.entity.HumanEntity +import org.bukkit.event.inventory.PrepareAnvilEvent + +interface AnvilRenameDialog { + + companion object { + val PCD_KEEP_RENAME_TEXT_KEY = NamespacedKey.fromString("customanvil:last_rename_text")!! + } + + fun canSendDialog(): Boolean + + fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent) + + fun closeInventory(player: HumanEntity) + + fun currentText(player: HumanEntity): String? + +} \ No newline at end of file diff --git a/nms/nms-paper/build.gradle.kts b/nms/nms-paper/build.gradle.kts index ea23f5c..d0e12a7 100644 --- a/nms/nms-paper/build.gradle.kts +++ b/nms/nms-paper/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { implementation(project(":nms:nms-common")) // Used for nms - paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") + paperweight.paperDevBundle("1.21.7-R0.1-SNAPSHOT") } repositories { diff --git a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialogImpl.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialogImpl.kt new file mode 100644 index 0000000..603a215 --- /dev/null +++ b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dialog/AnvilRenameDialogImpl.kt @@ -0,0 +1,196 @@ +package xyz.alexcrea.cuanvil.dialog + +import io.papermc.paper.dialog.Dialog +import io.papermc.paper.registry.data.dialog.ActionButton +import io.papermc.paper.registry.data.dialog.DialogBase +import io.papermc.paper.registry.data.dialog.action.DialogAction +import io.papermc.paper.registry.data.dialog.body.DialogBody +import io.papermc.paper.registry.data.dialog.input.DialogInput +import io.papermc.paper.registry.data.dialog.type.DialogType +import io.papermc.paper.threadedregions.scheduler.ScheduledTask +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.event.ClickCallback +import net.kyori.adventure.text.format.TextColor +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer +import net.minecraft.world.inventory.AnvilMenu +import org.bukkit.craftbukkit.event.CraftEventFactory +import org.bukkit.craftbukkit.inventory.CraftInventoryView +import org.bukkit.craftbukkit.inventory.view.CraftAnvilView +import org.bukkit.entity.HumanEntity +import org.bukkit.event.inventory.PrepareAnvilEvent +import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataType +import org.bukkit.plugin.Plugin +import java.util.* +import java.util.function.BiFunction +import java.util.function.Consumer +import java.util.function.Supplier + +@Suppress("UnstableApiUsage") +class AnvilRenameDialogImpl( + val fromFormated: BiFunction, + val keepUserPreviousDialog: Supplier, + val maxLength: Supplier, + val plugin: Plugin, +): AnvilRenameDialog { + + companion object { + private const val RENAME_TEXT_KEY = "rename" + + private const val MAX_WIDTH = 512 + + private val PLAIN_TEXT_SERIALIZER = PlainTextComponentSerializer.plainText() + + // Need to be able to translate it later ! + private val USER_FACING_RENAME_TITLE = Component.text("Rename Your Item") + private val USER_FACING_WARNING = Component.text("Note that the repair text will appear blank after Confirm\n" + + "But the name will be correctly applied") + private val USER_FACING_CONFIRM = Component.text("Confirm").color(TextColor.fromHexString("#40FF40")) + private val USER_FACING_CANCEL = Component.text("Cancel").color(TextColor.fromHexString("#FF4040")) + } + + private val lastNames = HashMap() + private val lastLeftItem = HashMap() + private val runTaskMap = HashMap() + + private val containerField = CraftInventoryView::class.java.getDeclaredField("container") + + init { + containerField.setAccessible(true) + } + + override fun canSendDialog(): Boolean { + return true + } + + fun makeDialog(initial: String?, callback: Consumer): Dialog { + val maxLength = this.maxLength.get() + val initialFinal = initial?.take(maxLength) + + val baseBuilder = DialogBase.builder(USER_FACING_RENAME_TITLE) + .canCloseWithEscape(true) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .inputs(listOf( + DialogInput.text(RENAME_TEXT_KEY, Component.text("Rename text")) + .maxLength(maxLength) + .initial(initialFinal ?: "") + .labelVisible(false) + .width(MAX_WIDTH) + .build(), + ), + ) + baseBuilder.body(listOf( + DialogBody.plainMessage(USER_FACING_WARNING, MAX_WIDTH) + )) + + return Dialog.create { builder -> builder.empty() + .base(baseBuilder.build()) + .type(DialogType.confirmation( + ActionButton.builder(USER_FACING_CONFIRM) + .action(DialogAction.customClick({ response, _ -> + val text = response.getText(RENAME_TEXT_KEY)!! + callback.accept(text) + }, ClickCallback.Options.builder().build())) + .build(), + ActionButton.builder(USER_FACING_CANCEL) + .build(), + )) + } + } + + private fun setResult(player: HumanEntity, view: CraftAnvilView, result: String?) { + val defaultName = PLAIN_TEXT_SERIALIZER.serializeOrNull(view.getItem(0)?.effectiveName()) + if(defaultName == result) { + setName(player, view, "") + if(defaultName != null) lastNames[player.uniqueId] = defaultName + } + else setName(player, view, result) + } + + private fun setName(player: HumanEntity, view: CraftAnvilView, name: String?) { + val menu = (containerField.get(view) as AnvilMenu) + menu.itemName = name + + if(name == null) + lastNames.remove(player.uniqueId) + else + lastNames[player.uniqueId] = name + CraftEventFactory.callPrepareResultEvent(menu, 2); + } + + private fun nameFromItem(player: HumanEntity, item: ItemStack?): String? { + // Already has text + if(item?.hasItemMeta() != true || !item.itemMeta.hasCustomName()) + return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName()) + + if(keepUserPreviousDialog.get() && item.hasItemMeta()) { + val lastName = item.itemMeta.persistentDataContainer.get( + AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY, + PersistentDataType.STRING) + + if(lastName != null) return lastName + } + + return fromFormated.apply(player, item.effectiveName()) + } + + private fun tryShowDialogScheduled(player: HumanEntity, event: PrepareAnvilEvent) { + val view = event.view + if(view !is CraftAnvilView) return + + val renameText = view.renameText + val leftItem = view.getItem(0) + val leftItemStr = leftItem?.toString() + val lastName = lastNames.getOrDefault(player.uniqueId, null) + + if(lastLeftItem.getOrDefault(player.uniqueId, null) != leftItemStr) { + if(leftItemStr == null) + lastLeftItem.remove(player.uniqueId) + else lastLeftItem[player.uniqueId] = leftItemStr + + setName(player, view, nameFromItem(player, leftItem)) + return + } + + if(lastName == renameText) + return + + if(renameText?.isBlank() == true) { + setName(player, view, lastNames[player.uniqueId]) + return + } + + val dialog = makeDialog(lastName) + { result -> setResult(player, view, result) } + player.showDialog(dialog) + } + + // We need to wait for a short time as changing item will change the name BEFORE the item change + // no guaranty both of them came in the same tick too so let's wait 2 tick.... + override fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent) { + runTaskMap.remove(player.uniqueId)?.cancel() + + val task = player.scheduler.runDelayed( + plugin, + { _ -> + run { tryShowDialogScheduled(player, event) } + }, + {}, + 2 + ) + if(task == null) return + + runTaskMap[player.uniqueId] = task + } + + override fun closeInventory(player: HumanEntity) { + lastNames.remove(player.uniqueId) + lastLeftItem.remove(player.uniqueId) + runTaskMap.remove(player.uniqueId)?.cancel() + } + + override fun currentText(player: HumanEntity): String? { + return lastNames[player.uniqueId] + } + +} \ No newline at end of file diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java index 774c5da..707a218 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/PluginSetDefault.java @@ -5,6 +5,7 @@ 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.MetricType; import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil; import xyz.alexcrea.cuanvil.util.config.LoreEditType; @@ -18,6 +19,9 @@ public class PluginSetDefault { int nbSet = 0; + nbSet += trySetDefault(config, METRIC_TYPE, MetricType.AUTO.getValue()); + nbSet += trySetDefault(config, METRIC_COLLECT_ERROR, true); + 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); @@ -30,6 +34,7 @@ public class PluginSetDefault { 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, PER_COLOR_CODE_PERMISSION, DEFAULT_PER_COLOR_CODE_PERMISSION); // Lore Edit defaults for (@NotNull LoreEditType value : LoreEditType.values()) { @@ -56,6 +61,11 @@ public class PluginSetDefault { nbSet += trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER); + nbSet += trySetDefault(config, DIALOG_RENAME_ENABLED, DEFAULT_DIALOG_RENAME_ENABLED); + nbSet += trySetDefault(config, DIALOG_MAX_SIZE, DEFAULT_DIALOG_MAX_SIZE); + nbSet += trySetDefault(config, DIALOG_RENAME_USE_PERMISSION, DEFAULT_DIALOG_RENAME_USE_PERMISSION); + nbSet += trySetDefault(config, DIALOG_KEEP_USER_TEXT, DEFAULT_DIALOG_KEEP_USER_TEXT); + 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 b6aa3d7..46f79bc 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -61,6 +61,13 @@ object ConfigOptions { const val ENCHANT_LIMIT_ROOT = "enchant_limits" const val ENCHANT_VALUES_ROOT = "enchant_values" + // Dialog menu rename + const val DIALOG_RENAME_ENABLED = "enable_dialog_rename" + const val DIALOG_MAX_SIZE = "dialog_rename_max_size" + const val DIALOG_RENAME_USE_PERMISSION = "permission_needed_for_dialog_rename" + const val DIALOG_KEEP_USER_TEXT = "dialog_rename_keep_user_text" + + // Others const val DISABLE_MERGE_OVER_ROOT = "disable-merge-over" const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments" @@ -107,6 +114,12 @@ object ConfigOptions { private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_VERBOSE_DEBUG_LOG = false + // Dialog menu rename + const val DEFAULT_DIALOG_RENAME_ENABLED = false + const val DEFAULT_DIALOG_MAX_SIZE = 256 + const val DEFAULT_DIALOG_RENAME_USE_PERMISSION = false + const val DEFAULT_DIALOG_KEEP_USER_TEXT = true + // ------------- // Config Ranges // ------------- @@ -131,6 +144,9 @@ object ConfigOptions { @JvmField val USE_OF_COLOR_COST_RANGE = 0..1000 + @JvmField + val DIALOG_MAX_SIZE_RANGE = 0..Int.MAX_VALUE + // Valid range for an enchantment limit const val ENCHANT_LIMIT = 255 @@ -416,6 +432,48 @@ object ConfigOptions { .getBoolean(VERBOSE_DEBUG_LOGGING, DEFAULT_VERBOSE_DEBUG_LOG) } + /** + * Is the dialog menu for rename enabled + */ + val doRenameDialog: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(DIALOG_RENAME_ENABLED, DEFAULT_DIALOG_RENAME_ENABLED) + } + + /** + * Do the dialog menu require permission + */ + val doRenameDialogUsePermission: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(DIALOG_RENAME_USE_PERMISSION, DEFAULT_DIALOG_RENAME_USE_PERMISSION) + } + + /** + * Do the dialog menu require permission + */ + val renameDialogMaxSize: Int + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getInt(DIALOG_MAX_SIZE, DEFAULT_DIALOG_MAX_SIZE) + .takeIf { it in DIALOG_MAX_SIZE_RANGE } + ?: Int.MAX_VALUE + } + + /** + * Should the text used for rename should be kept in the item's pdc + */ + val shouldKeepRenameText: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(DIALOG_KEEP_USER_TEXT, DEFAULT_DIALOG_KEEP_USER_TEXT) + } + /** * Get the given [enchantment]'s limit */ diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilCloseListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilCloseListener.kt index 60a0339..d707b56 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilCloseListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilCloseListener.kt @@ -7,6 +7,7 @@ import org.bukkit.event.Listener import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.inventory.AnvilInventory import xyz.alexcrea.cuanvil.dependency.packet.PacketManager +import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil class AnvilCloseListener(private val packetManager: PacketManager) : Listener { @@ -18,6 +19,7 @@ class AnvilCloseListener(private val packetManager: PacketManager) : Listener { packetManager.setInstantBuild(player, false) } + AnvilRenameDialogUtil.anvilRenameDialog.closeInventory(player) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 03865f0..0525a85 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -21,11 +21,14 @@ import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.EnchantmentStorageMeta import org.bukkit.inventory.meta.ItemMeta +import org.bukkit.persistence.PersistentDataType import xyz.alexcrea.cuanvil.dependency.DependencyManager +import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.util.* import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import java.util.concurrent.atomic.AtomicInteger /** @@ -41,6 +44,8 @@ class PrepareAnvilListener : Listener { const val ANVIL_OUTPUT_SLOT = 2 var IS_EMPTY_TEST = false + + private const val RENAME_DIALOG_PERMISSION = "ca.rename.dialog" } /** @@ -80,6 +85,8 @@ class PrepareAnvilListener : Listener { return } + tryRenameDialog(player, event) + // Test if the event should bypass custom anvil. if (DependencyManager.tryEventPreAnvilBypass(event, player)) { // even if we got bypassed we still want to set price @@ -117,6 +124,36 @@ class PrepareAnvilListener : Listener { } + private fun tryRenameDialog( + player: HumanEntity, + event: PrepareAnvilEvent + ) { + if(!canUseRenameDialog(player)) return + + AnvilRenameDialogUtil.anvilRenameDialog.tryShowDialog(player, event) + } + + private fun canUseRenameDialog(player: HumanEntity): Boolean { + if(!ConfigOptions.doRenameDialog || !AnvilRenameDialogUtil.anvilRenameDialog.canSendDialog()) return false + if(ConfigOptions.doRenameDialogUsePermission && !player.hasPermission(RENAME_DIALOG_PERMISSION)) return false + + return true + } + + private fun processDialogPCD(it: ItemMeta, player: HumanEntity) { + val keepDialog = canUseRenameDialog(player) && ConfigOptions.shouldKeepRenameText + + val pdc = it.persistentDataContainer + if(!keepDialog) + pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY) + else { + val text = AnvilRenameDialogUtil.anvilRenameDialog.currentText(player) + if(text == null || text.isBlank()) + pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY) + else pdc.set(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY, PersistentDataType.STRING, text) + } + } + private fun isImmutable(item: ItemStack?): Boolean { if (item.isAir) return false @@ -208,11 +245,8 @@ class PrepareAnvilListener : Listener { var useColor = false if (ConfigOptions.renameColorPossible && renameText != null) { val component = AnvilColorUtil.handleColor( - renameText, player, - ConfigOptions.permissionNeededForColor, - ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, ConfigOptions.allowMinimessage, - AnvilColorUtil.ColorUseType.RENAME - ) + renameText, + AnvilColorUtil.renamePermission(player)) if (component != null) { renameText = MiniMessageUtil.legacy_mm.serialize(component) @@ -230,8 +264,13 @@ class PrepareAnvilListener : Listener { else ChatColor.stripColor(it.displayName) - if (!displayName.contentEquals(renameText) && !(displayName == null && renameText == "")) { + if (!displayName.contentEquals(renameText) && !(displayName == null && + renameText == "" || + //TODO on recent paper check effective name instead + renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase()) + )) { it.setDisplayName(renameText) + processDialogPCD(it, player) resultItem.itemMeta = it sumCost += ConfigOptions.itemRenameCost diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt index 25c4268..0492d32 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilColorUtil.kt @@ -60,25 +60,11 @@ object AnvilColorUtil { return ColorPermissions(canUseColorCode, canUseHexColor, canUseMinimessage, player) } - /** - * Color a string depending on allowed color type, color use type and player permissions - * @return colored component or null if nothing has been colored - */ - fun handleColor( - textToColorText: String, - player: Permissible, - usePermission: Boolean, - allowColorCode: Boolean, - allowHexadecimalColor: Boolean, - allowMinimessage: Boolean, - useType: ColorUseType - ): Component? { - val permission = calculatePermissions( - player, usePermission, - allowColorCode, allowHexadecimalColor, allowMinimessage, - useType - ) - return handleColor(textToColorText, permission) + fun renamePermission(player: Permissible): ColorPermissions { + return calculatePermissions(player, + ConfigOptions.permissionNeededForColor, + ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, ConfigOptions.allowMinimessage, + ColorUseType.RENAME) } /** diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/dialog/AnvilRenameDialogUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/dialog/AnvilRenameDialogUtil.kt new file mode 100644 index 0000000..dbff77b --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/dialog/AnvilRenameDialogUtil.kt @@ -0,0 +1,51 @@ +package xyz.alexcrea.cuanvil.util.dialog + +import io.delilaheve.CustomAnvil +import io.delilaheve.util.ConfigOptions +import org.bukkit.entity.HumanEntity +import org.bukkit.event.inventory.PrepareAnvilEvent +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil +import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog +import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialogImpl +import xyz.alexcrea.cuanvil.update.UpdateUtils +import xyz.alexcrea.cuanvil.util.AnvilColorUtil + +object AnvilRenameDialogUtil { + + val anvilRenameDialog: AnvilRenameDialog; + + init { + val version = UpdateUtils.currentMinecraftVersion() + anvilRenameDialog = (if(!PlatformUtil.isPaper || + (version.major <= 1 && version.minor <= 21 && version.patch <= 6)) { + NoImplAnvilRenameDialog() + } else { + AnvilRenameDialogImpl({ player, component -> AnvilColorUtil.revertColorSmallest( + component, AnvilColorUtil.renamePermission(player) + ) }, + { ConfigOptions.shouldKeepRenameText }, + { ConfigOptions.renameDialogMaxSize }, + CustomAnvil.instance, + ) + }) + } + + class NoImplAnvilRenameDialog: AnvilRenameDialog { + + override fun canSendDialog(): Boolean { + return false + } + + override fun tryShowDialog( + player: HumanEntity, + event: PrepareAnvilEvent + ) {} + + override fun closeInventory(player: HumanEntity) {} + + override fun currentText(player: HumanEntity): String? { + return null + } + + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 3fe75c2..49b5e5a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -101,6 +101,24 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Dialogue rename menu make use of dialog menu to allow bigger rename +# You can also change the maximum size and set it to -1 or less for maximum +# +# This feature only work on paper 1.21.7 or later +# +# At the moment only english is available for this menu... sorry ! +# +# CustomAnvil use "ca.rename.dialog" when permission +enable_dialog_rename: false +dialog_rename_max_size: 256 +permission_needed_for_dialog_rename: false + +# This allows custom anvil to not "guess" the text used for rename but store it in the item +# It will make item stackable only and only if it had used the same rename text +# +# For practical reason. this only work when dialog rename is enabled +dialog_rename_keep_user_text: true + # Override limits for specific enchants # # Enchantments not listed here will use the value of default_limit diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c0f548f..dab9997 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -63,6 +63,11 @@ permissions: ca.lore_edit.paper: default: op description: Allow player to edit lore via paper if enabled (toggleable) + # dialog menu permission + ca.rename.dialog: + default: op + description: Allow player to use the dialog rename menu (toggleable) + # 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