mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 08:14:00 +02:00
Rename Dialog (#113)
Add a rename dialog for longer possible rename text Also has a rename fix
This commit is contained in:
commit
f0d53a6ffa
16 changed files with 485 additions and 27 deletions
|
|
@ -22,7 +22,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "xyz.alexcrea"
|
group = "xyz.alexcrea"
|
||||||
version = "1.16.3"
|
version = "1.17.0"
|
||||||
|
|
||||||
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
|
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
|
||||||
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
|
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,24 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
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
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
# Enchantments not listed here will use the value of default_limit
|
# Enchantments not listed here will use the value of default_limit
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,24 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
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
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
# Enchantments not listed here will use the value of default_limit
|
# Enchantments not listed here will use the value of default_limit
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,24 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
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
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
# Enchantments not listed here will use the value of default_limit
|
# Enchantments not listed here will use the value of default_limit
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,24 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
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
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
# Enchantments not listed here will use the value of default_limit
|
# Enchantments not listed here will use the value of default_limit
|
||||||
|
|
|
||||||
|
|
@ -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?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ dependencies {
|
||||||
implementation(project(":nms:nms-common"))
|
implementation(project(":nms:nms-common"))
|
||||||
|
|
||||||
// Used for nms
|
// Used for nms
|
||||||
paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT")
|
paperweight.paperDevBundle("1.21.7-R0.1-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|
|
||||||
|
|
@ -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<HumanEntity, Component?, String?>,
|
||||||
|
val keepUserPreviousDialog: Supplier<Boolean>,
|
||||||
|
val maxLength: Supplier<Int>,
|
||||||
|
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<UUID, String>()
|
||||||
|
private val lastLeftItem = HashMap<UUID, String>()
|
||||||
|
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||||
|
|
||||||
|
private val containerField = CraftInventoryView::class.java.getDeclaredField("container")
|
||||||
|
|
||||||
|
init {
|
||||||
|
containerField.setAccessible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canSendDialog(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun makeDialog(initial: String?, callback: Consumer<String?>): 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]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import io.delilaheve.util.ConfigOptions;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
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.LoreEditConfigUtil;
|
||||||
import xyz.alexcrea.cuanvil.util.config.LoreEditType;
|
import xyz.alexcrea.cuanvil.util.config.LoreEditType;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,9 @@ public class PluginSetDefault {
|
||||||
|
|
||||||
int nbSet = 0;
|
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, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST);
|
||||||
nbSet += trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_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, 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, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR);
|
||||||
nbSet += trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_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, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST);
|
||||||
|
nbSet += trySetDefault(config, PER_COLOR_CODE_PERMISSION, DEFAULT_PER_COLOR_CODE_PERMISSION);
|
||||||
|
|
||||||
// Lore Edit defaults
|
// Lore Edit defaults
|
||||||
for (@NotNull LoreEditType value : LoreEditType.values()) {
|
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, 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) {
|
if (nbSet > 0) {
|
||||||
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
|
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
|
||||||
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
|
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,13 @@ object ConfigOptions {
|
||||||
const val ENCHANT_LIMIT_ROOT = "enchant_limits"
|
const val ENCHANT_LIMIT_ROOT = "enchant_limits"
|
||||||
const val ENCHANT_VALUES_ROOT = "enchant_values"
|
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 DISABLE_MERGE_OVER_ROOT = "disable-merge-over"
|
||||||
|
|
||||||
const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments"
|
const val IMMUTABLE_ENCHANTMENT_LIST = "immutable_enchantments"
|
||||||
|
|
@ -107,6 +114,12 @@ object ConfigOptions {
|
||||||
private const val DEFAULT_DEBUG_LOG = false
|
private const val DEFAULT_DEBUG_LOG = false
|
||||||
private const val DEFAULT_VERBOSE_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
|
// Config Ranges
|
||||||
// -------------
|
// -------------
|
||||||
|
|
@ -131,6 +144,9 @@ object ConfigOptions {
|
||||||
@JvmField
|
@JvmField
|
||||||
val USE_OF_COLOR_COST_RANGE = 0..1000
|
val USE_OF_COLOR_COST_RANGE = 0..1000
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val DIALOG_MAX_SIZE_RANGE = 0..Int.MAX_VALUE
|
||||||
|
|
||||||
// Valid range for an enchantment limit
|
// Valid range for an enchantment limit
|
||||||
const val ENCHANT_LIMIT = 255
|
const val ENCHANT_LIMIT = 255
|
||||||
|
|
||||||
|
|
@ -416,6 +432,48 @@ object ConfigOptions {
|
||||||
.getBoolean(VERBOSE_DEBUG_LOGGING, DEFAULT_VERBOSE_DEBUG_LOG)
|
.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
|
* Get the given [enchantment]'s limit
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import org.bukkit.event.Listener
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
import org.bukkit.inventory.AnvilInventory
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||||
|
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
|
||||||
|
|
||||||
class AnvilCloseListener(private val packetManager: PacketManager) : Listener {
|
class AnvilCloseListener(private val packetManager: PacketManager) : Listener {
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ class AnvilCloseListener(private val packetManager: PacketManager) : Listener {
|
||||||
packetManager.setInstantBuild(player, false)
|
packetManager.setInstantBuild(player, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnvilRenameDialogUtil.anvilRenameDialog.closeInventory(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -21,11 +21,14 @@ import org.bukkit.inventory.AnvilInventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta
|
||||||
import org.bukkit.inventory.meta.ItemMeta
|
import org.bukkit.inventory.meta.ItemMeta
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||||
|
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
|
||||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
|
||||||
import xyz.alexcrea.cuanvil.util.*
|
import xyz.alexcrea.cuanvil.util.*
|
||||||
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
|
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
|
||||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||||
|
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,6 +44,8 @@ class PrepareAnvilListener : Listener {
|
||||||
const val ANVIL_OUTPUT_SLOT = 2
|
const val ANVIL_OUTPUT_SLOT = 2
|
||||||
|
|
||||||
var IS_EMPTY_TEST = false
|
var IS_EMPTY_TEST = false
|
||||||
|
|
||||||
|
private const val RENAME_DIALOG_PERMISSION = "ca.rename.dialog"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -80,6 +85,8 @@ class PrepareAnvilListener : Listener {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tryRenameDialog(player, event)
|
||||||
|
|
||||||
// Test if the event should bypass custom anvil.
|
// Test if the event should bypass custom anvil.
|
||||||
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
|
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
|
||||||
// even if we got bypassed we still want to set price
|
// 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 {
|
private fun isImmutable(item: ItemStack?): Boolean {
|
||||||
if (item.isAir) return false
|
if (item.isAir) return false
|
||||||
|
|
||||||
|
|
@ -208,11 +245,8 @@ class PrepareAnvilListener : Listener {
|
||||||
var useColor = false
|
var useColor = false
|
||||||
if (ConfigOptions.renameColorPossible && renameText != null) {
|
if (ConfigOptions.renameColorPossible && renameText != null) {
|
||||||
val component = AnvilColorUtil.handleColor(
|
val component = AnvilColorUtil.handleColor(
|
||||||
renameText, player,
|
renameText,
|
||||||
ConfigOptions.permissionNeededForColor,
|
AnvilColorUtil.renamePermission(player))
|
||||||
ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, ConfigOptions.allowMinimessage,
|
|
||||||
AnvilColorUtil.ColorUseType.RENAME
|
|
||||||
)
|
|
||||||
|
|
||||||
if (component != null) {
|
if (component != null) {
|
||||||
renameText = MiniMessageUtil.legacy_mm.serialize(component)
|
renameText = MiniMessageUtil.legacy_mm.serialize(component)
|
||||||
|
|
@ -230,8 +264,13 @@ class PrepareAnvilListener : Listener {
|
||||||
else ChatColor.stripColor(it.displayName)
|
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)
|
it.setDisplayName(renameText)
|
||||||
|
processDialogPCD(it, player)
|
||||||
resultItem.itemMeta = it
|
resultItem.itemMeta = it
|
||||||
|
|
||||||
sumCost += ConfigOptions.itemRenameCost
|
sumCost += ConfigOptions.itemRenameCost
|
||||||
|
|
|
||||||
|
|
@ -60,25 +60,11 @@ object AnvilColorUtil {
|
||||||
return ColorPermissions(canUseColorCode, canUseHexColor, canUseMinimessage, player)
|
return ColorPermissions(canUseColorCode, canUseHexColor, canUseMinimessage, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun renamePermission(player: Permissible): ColorPermissions {
|
||||||
* Color a string depending on allowed color type, color use type and player permissions
|
return calculatePermissions(player,
|
||||||
* @return colored component or null if nothing has been colored
|
ConfigOptions.permissionNeededForColor,
|
||||||
*/
|
ConfigOptions.allowColorCode, ConfigOptions.allowHexadecimalColor, ConfigOptions.allowMinimessage,
|
||||||
fun handleColor(
|
ColorUseType.RENAME)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -101,6 +101,24 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
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
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
# Enchantments not listed here will use the value of default_limit
|
# Enchantments not listed here will use the value of default_limit
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,11 @@ permissions:
|
||||||
ca.lore_edit.paper:
|
ca.lore_edit.paper:
|
||||||
default: op
|
default: op
|
||||||
description: Allow player to edit lore via paper if enabled (toggleable)
|
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
|
# 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
|
# Also depend to other plugin for compatibility
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue