From fe9cc2402fad58d3074f1511588afe7514ae6ff1 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 13 Aug 2026 01:51:03 +0200 Subject: [PATCH 01/13] language backend logic --- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 30 ++++-- .../cuanvil/command/ReloadExecutor.kt | 4 + .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 93 +++++++++++++++++++ .../xyz/alexcrea/cuanvil/lang/Language.kt | 56 +++++++++++ src/main/resources/config.yml | 5 + 5 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index a119bfc7..c88acfd3 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -17,6 +17,7 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant +import xyz.alexcrea.cuanvil.lang.Lang import xyz.alexcrea.cuanvil.listener.AnvilCloseListener import xyz.alexcrea.cuanvil.listener.AnvilResultListener import xyz.alexcrea.cuanvil.listener.ChatEventListener @@ -135,6 +136,25 @@ open class CustomAnvil : JavaPlugin() { */ override fun onEnable() { instance = this + // Load default configuration + try { + if(!ConfigHolder.loadDefaultConfig()) + throw RuntimeException("Error loading configuration file") + } catch (e: Exception) { + logger.log(Level.SEVERE, "error occurred loading default configuration", e) + MetricsUtil.trackError(e) + if(tryDirtyStart()) return + } + + // Load language + try { + Lang.reload() + } catch (e: Exception) { + logger.log(Level.SEVERE, "error occurred loading language file", e) + MetricsUtil.trackError(e) + if(tryDirtyStart()) return + } + try { legacyCheck() } catch (e: Exception) { @@ -143,6 +163,7 @@ open class CustomAnvil : JavaPlugin() { if(trySafeStart()) return } + // Add commands try { CustomAnvilCommand(this) @@ -152,15 +173,6 @@ open class CustomAnvil : JavaPlugin() { if(trySafeStart()) return } - // Load default configuration - try { - if(!ConfigHolder.loadDefaultConfig()) - throw RuntimeException("Error loading configuration file") - } catch (e: Exception) { - logger.log(Level.SEVERE, "error occurred loading default configuration", e) - MetricsUtil.trackError(e) - if(tryDirtyStart()) return - } // Load dependency try { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index d3df341a..bc9a80be 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -8,6 +8,7 @@ import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.gui.config.global.* +import xyz.alexcrea.cuanvil.lang.Lang import xyz.alexcrea.cuanvil.update.UpdateHandler class ReloadExecutor : CASubCommand { @@ -58,6 +59,9 @@ class ReloadExecutor : CASubCommand { try { if (!ConfigHolder.reloadAllFromDisk(hardfail)) return false + // reload language config + Lang.reload() + // Then update all global gui containing value from config BasicConfigGui.getInstance()?.updateGuiValues() EnchantCostConfigGui.getInstance()?.updateGuiValues() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt new file mode 100644 index 00000000..b89ca6bd --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt @@ -0,0 +1,93 @@ +package xyz.alexcrea.cuanvil.lang + +import io.delilaheve.CustomAnvil +import xyz.alexcrea.cuanvil.config.ConfigHolder + +object Lang { + + private val default = Language(DEFAULT_LANG, false) + private var lang = default + + fun reload() { + val langID = langID + if(lang.name == langID && lang != default) + lang.reload() + else + lang = Language(langID) + + if(default != lang) default.reload() + } + + fun String.translate(): String { + val value = lang.get(this) + if(value != null) return value + + CustomAnvil.log("Missing language data for ${lang.name} using default") + + return default.get(this) ?: this + } + + fun String.translate(vararg params: Pair): String { + return translate( + params.asSequence() + .map { Pair(it.first, it.second.toString()) } + .toMap() + ) + } + + fun String.translate(vararg params: Pair): String { + return translate( + params.asSequence() + .map { Pair(it.first.toString(), it.second.toString()) } + .toMap() + ) + } + + fun String.translate(vararg params: Pair): String { + return translate(params.toMap()) + } + + fun String.translate(vararg params: Pair): String { + return translate( + params.asSequence() + .map { Pair(it.first.toString(), it.second) } + .toMap() + ) + } + + fun String.translate(params: Map): String { + val builder = StringBuilder(translate()) + + // replace all placeholder thingy %key -> value + for((key, replacement) in params) { + var current = 0 + while(true) { + current = builder.indexOf('%', current) + 1 + if(current < 0 || current + key.length > builder.length) break // may be able to be removed if bound checked in startsWith ? + if(!builder.startsWith(key, current, false)) continue + + builder.replace(current - 1, current + key.length, replacement) + current = current - 1 + replacement.length + } + } + + return builder.toString() + } + + /* + * Config Options & get + */ + const val LANG_PATH = "language" + const val DEFAULT_LANG = "en" + + /** + * Value of an item rename + */ + private val langID: String + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getString(LANG_PATH, DEFAULT_LANG)!! + } + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt new file mode 100644 index 00000000..d06f9aba --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt @@ -0,0 +1,56 @@ +package xyz.alexcrea.cuanvil.lang + +import io.delilaheve.CustomAnvil +import org.bukkit.configuration.file.FileConfiguration +import org.bukkit.configuration.file.YamlConfiguration +import java.io.File +import java.io.InputStreamReader +import java.util.logging.Level + + +class Language(private val id: String, private val default: Boolean = false) { + + private val resourcePath: String + private val file: File + + private val conf: FileConfiguration + + init { + conf = YamlConfiguration() + resourcePath = "lang/$id.yml" + file = File(CustomAnvil.instance.dataFolder, resourcePath) + + reload() + } + + fun reload() { + if(file.exists() && !default) try { + conf.load(file) + return + } catch(e: Exception) { + CustomAnvil.instance.logger.log( + Level.SEVERE, + "Could not load custom Anvil config file. using to internal resource", + e + ) + } + + loadInternalResource() + } + + private fun loadInternalResource() { + val input = CustomAnvil.instance.getResource(resourcePath) + if(input != null) + conf.load(InputStreamReader(input)) + else + CustomAnvil.instance.logger.log(Level.SEVERE, "Language $id not found") + + } + + fun get(key: String): String? { + return conf.getString(key) + } + + val name: String + get() = conf.getString("name", id)!! +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 218c3a1f..f67ebb17 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,6 +16,11 @@ metric_type: auto # Accept true or false (true by default) metric_collect_errors: true +# Which language should the plugin should be +# If you like to add language yourself see TODO link to guide +# Currently available languages: en +language: en + # All anvil cost will be capped to limit_repair_value if enabled. # # In other words: From da49e79dbf57bc206c402a71bdaeb0bf998e3637 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 13 Aug 2026 10:10:37 +0200 Subject: [PATCH 02/13] translation key for load errors and warnings --- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 79 +++++++++++--------- src/main/resources/lang/en.yml | 29 +++++++ 2 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 src/main/resources/lang/en.yml diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index c88acfd3..8c284ef4 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -7,8 +7,6 @@ import org.bukkit.plugin.java.JavaPlugin import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent import xyz.alexcrea.cuanvil.api.event.CAEnchantRegistryReadyEvent import xyz.alexcrea.cuanvil.command.CustomAnvilCommand -import xyz.alexcrea.cuanvil.command.EditConfigExecutor -import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil @@ -18,6 +16,7 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.lang.Lang +import xyz.alexcrea.cuanvil.lang.Lang.translate import xyz.alexcrea.cuanvil.listener.AnvilCloseListener import xyz.alexcrea.cuanvil.listener.AnvilResultListener import xyz.alexcrea.cuanvil.listener.ChatEventListener @@ -109,11 +108,23 @@ open class CustomAnvil : JavaPlugin() { } } + /** + * Error Logging handler + */ + @JvmStatic fun logError(message: String, throwable: Throwable? = null, track: Boolean = true) { + instance.logger.log(Level.SEVERE, message, throwable) + addToLogQueue(message) + + if(track && throwable != null) { + MetricsUtil.trackError(throwable) + } + } } // stop plugin if we do not force a dirty start (true by default) // Return true if start was stopped private fun tryDirtyStart(): Boolean { + if(ConfigHolder.DEFAULT_CONFIG == null) return false if(!ConfigHolder.DEFAULT_CONFIG.config.getBoolean("dirty_start", false)) { Bukkit.getPluginManager().disablePlugin(this) return true @@ -124,6 +135,7 @@ open class CustomAnvil : JavaPlugin() { // stop plugin if we force a safe start (false by default) // Return true if start was stopped private fun trySafeStart(): Boolean { + if(ConfigHolder.DEFAULT_CONFIG == null) return false if(ConfigHolder.DEFAULT_CONFIG.config.getBoolean("safe_start", false)) { Bukkit.getPluginManager().disablePlugin(this) return true @@ -141,8 +153,7 @@ open class CustomAnvil : JavaPlugin() { if(!ConfigHolder.loadDefaultConfig()) throw RuntimeException("Error loading configuration file") } catch (e: Exception) { - logger.log(Level.SEVERE, "error occurred loading default configuration", e) - MetricsUtil.trackError(e) + logError("error occurred loading default configuration", e) if(tryDirtyStart()) return } @@ -150,16 +161,14 @@ open class CustomAnvil : JavaPlugin() { try { Lang.reload() } catch (e: Exception) { - logger.log(Level.SEVERE, "error occurred loading language file", e) - MetricsUtil.trackError(e) + logError("error occurred loading language file", e) if(tryDirtyStart()) return } try { legacyCheck() } catch (e: Exception) { - logger.log(Level.SEVERE, "error trying to check for legacy system", e) - MetricsUtil.trackError(e) + logError("error.load.legacy.failed".translate(), e) if(trySafeStart()) return } @@ -168,8 +177,7 @@ open class CustomAnvil : JavaPlugin() { try { CustomAnvilCommand(this) } catch (e: Exception) { - logger.log(Level.SEVERE, "error trying to register commands", e) - MetricsUtil.trackError(e) + logError("error.load.command-register".translate(), e) if(trySafeStart()) return } @@ -178,8 +186,7 @@ open class CustomAnvil : JavaPlugin() { try { DependencyManager.loadDependency() } catch (e: Exception) { - logger.log(Level.SEVERE, "error loading dependency compatibility", e) - MetricsUtil.trackError(e) + logError("error.load.compatibility".translate(), e) if(tryDirtyStart()) return } @@ -187,8 +194,7 @@ open class CustomAnvil : JavaPlugin() { try { registerListeners() } catch (e: Exception) { - logger.log(Level.SEVERE, "error registering listeners", e) - MetricsUtil.trackError(e) + logError("error.load.listeners".translate(), e) if(tryDirtyStart()) return } @@ -204,32 +210,22 @@ open class CustomAnvil : JavaPlugin() { MetricsUtil.shutdownMetrics() } - private fun loadEnchantmentSystemDirty() { - try { - loadEnchantmentSystem() - } catch (e: Exception) { - logger.log(Level.SEVERE, "error initializing enchantment system", e) - MetricsUtil.trackError(e) - tryDirtyStart() - } - } - private fun legacyCheck() { // Disable old plugin name if exist val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") if (potentialPlugin != null) { Bukkit.getPluginManager().disablePlugin(potentialPlugin) - logger.warning("An old version of this plugin was detected") - logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus") + logger.warning("warning.load.legacy.old-name.1".translate()) + logger.warning("warning.load.legacy.old-name.2".translate()) } val isPaper = PlatformUtil.isPaper if(!isPaper) { - logger.warning("It seems you are using spigot") - logger.warning("Please take notice that spigot is less supported than paper and derivatives") + logger.warning("warning.load.legacy.spigot.1".translate()) + logger.warning("warning.load.legacy.spigot.2".translate()) if(MinecraftVersionUtil.isTooNewForSpigot) { - logger.warning("If replace too expensive is not working this is likely because of spigot") - logger.warning("As native nms is not supported for spigot starting 26.1") + logger.warning("warning.load.legacy.spigot-old.1".translate()) + logger.warning("warning.load.legacy.spigot-old.1".translate()) } } @@ -242,13 +238,13 @@ open class CustomAnvil : JavaPlugin() { UpdateUtils.currentMinecraftVersion().toString()) .setFeatured(featured) .setOnError { - logger.log(Level.WARNING, "error trying to fetch latest update", it) + logger.log(Level.WARNING, "error.load.update.check-fail".translate(), it) } .checkVersion { latestVer: String? -> CustomAnvil.latestVer = latestVer if(latestVer == null || version.contains(latestVer)) return@checkVersion - logger.warning("An update may be available: $latestVer") + logger.warning("warning.load.update.available".translate(Pair("version", latestVer))) } } @@ -263,6 +259,15 @@ open class CustomAnvil : JavaPlugin() { server.pluginManager.registerEvents(AnvilCloseListener(DependencyManager.packetManager), this) } + private fun loadEnchantmentSystemDirty() { + try { + loadEnchantmentSystem() + } catch (e: Exception) { + logError("error.load.enchant-system".translate(), e) + tryDirtyStart() + } + } + private fun loadEnchantmentSystem(){ // Register enchantments CAEnchantmentRegistry.getInstance().registerBukkit() @@ -273,7 +278,7 @@ open class CustomAnvil : JavaPlugin() { // Load config if (!ConfigHolder.loadNonDefaultConfig()) { - logger.log(Level.SEVERE,"Plugin has an issue while trying to load non default config... exiting...") + logError("error.load.non-default-config".translate()) server.pluginManager.disablePlugin(this) return } @@ -327,15 +332,15 @@ open class CustomAnvil : JavaPlugin() { try { val configReader = FileReader(resourceFile) yamlConfig.load(configReader) - } catch (test: Exception) { + } catch (_: Exception) { if (hardFailSafe) { // This is important and may impact gameplay if it does not load. // Failsafe is to stop the plugin - logger.severe("Resource ${resourceFile.path} Could not be load or reload.") - logger.severe("Disabling plugin.") + logError("error.reload.resource.fail".translate(Pair("path", resourceFile.path))) + logError("error.reload.resource.hard-fail".translate()) Bukkit.getPluginManager().disablePlugin(this) } else { - logger.warning("Resource ${resourceFile.path} Could not be load or reload.") + logError("error.reload.resource.fail".translate(Pair("path", resourceFile.path))) } return null } diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml new file mode 100644 index 00000000..d466dd53 --- /dev/null +++ b/src/main/resources/lang/en.yml @@ -0,0 +1,29 @@ +name: English + +warning: + load: + legacy: + old-name: + 1: "An old version of this plugin was detected" + 2: "Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus" + spigot: + 1: "It seems you are using spigot" + 2: "Please take notice that spigot is less supported than paper and derivatives" + spigot-old: + 1: "If replace too expensive is not working this is likely because of spigot" + 2: "As native nms is not supported for spigot starting 26.1" + update.available: "An update may be available: %version" + +error: + load: + legacy.failed: "error trying to check for legacy system" + update.check-fail: "error trying to fetch latest update" + command-register: "error trying to register commands" + compatibility: "error loading dependency compatibility" + listeners: "error registering listeners" + enchant-system: "error initializing enchantment system" + non-default-config: "Plugin has an issue while trying to load non default config... exiting..." + reload: + resource: + fail: "Resource %path Could not be loaded or reloaded." + hard-fail: "Disabling plugin." From e6ebdcdfc0d4e7f4eb1f491427abdbb32eb81edc Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 13 Aug 2026 13:10:22 +0200 Subject: [PATCH 03/13] better translation system --- .../{PaperSpigotUtil.kt => PlatformUtil.kt} | 17 ++- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 51 ++++--- .../cuanvil/command/DiagnosticExecutor.kt | 3 +- .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 53 +------- .../xyz/alexcrea/cuanvil/lang/Language.kt | 1 - .../xyz/alexcrea/cuanvil/lang/Message.kt | 128 ++++++++++++++++++ .../kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt | 4 + .../xyz/alexcrea/cuanvil/lang/MsgError.kt | 26 ++++ .../xyz/alexcrea/cuanvil/lang/MsgWarning.kt | 17 +++ .../xyz/alexcrea/cuanvil/util/MetricsUtil.kt | 4 +- src/main/resources/lang/en.yml | 36 +++++ 11 files changed, 257 insertions(+), 83 deletions(-) rename nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/{PaperSpigotUtil.kt => PlatformUtil.kt} (88%) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt similarity index 88% rename from nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt rename to nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt index 20972bfa..3b47adaa 100644 --- a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt @@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.dependency.util import net.kyori.adventure.text.Component import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer -import org.bukkit.inventory.ItemStack +import org.bukkit.command.CommandSender import org.bukkit.inventory.meta.ItemMeta // Mostly made for paper, spigot and folia support @@ -100,4 +100,19 @@ object PlatformUtil { } } + /** + * Try to send paper component to the player + * + * @param component The used component + * @return true if sent, else otherwise + */ + fun CommandSender.sendPaperMessage(component: Component): Boolean { + if(isPaper) { + this.sendMessage(component) + return true + } + + return false + } + } diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 8c284ef4..df000bce 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -16,7 +16,8 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.lang.Lang -import xyz.alexcrea.cuanvil.lang.Lang.translate +import xyz.alexcrea.cuanvil.lang.MsgError +import xyz.alexcrea.cuanvil.lang.MsgWarning import xyz.alexcrea.cuanvil.listener.AnvilCloseListener import xyz.alexcrea.cuanvil.listener.AnvilResultListener import xyz.alexcrea.cuanvil.listener.ChatEventListener @@ -111,12 +112,12 @@ open class CustomAnvil : JavaPlugin() { /** * Error Logging handler */ - @JvmStatic fun logError(message: String, throwable: Throwable? = null, track: Boolean = true) { - instance.logger.log(Level.SEVERE, message, throwable) - addToLogQueue(message) + @JvmStatic fun logError(message: String, throwable: Throwable? = null, track: Boolean = true, level: Level = Level.SEVERE) { + instance.logger.log(level, message, throwable) + addToLogQueue("Error: $message") - if(track && throwable != null) { - MetricsUtil.trackError(throwable) + if(track) { + MetricsUtil.trackError(message, throwable) } } } @@ -168,7 +169,7 @@ open class CustomAnvil : JavaPlugin() { try { legacyCheck() } catch (e: Exception) { - logError("error.load.legacy.failed".translate(), e) + MsgError.LOAD_LEGACY_FAILED.log(e) if(trySafeStart()) return } @@ -177,7 +178,7 @@ open class CustomAnvil : JavaPlugin() { try { CustomAnvilCommand(this) } catch (e: Exception) { - logError("error.load.command-register".translate(), e) + MsgError.LOAD_COMMAND_REGISTER.log(e) if(trySafeStart()) return } @@ -186,7 +187,7 @@ open class CustomAnvil : JavaPlugin() { try { DependencyManager.loadDependency() } catch (e: Exception) { - logError("error.load.compatibility".translate(), e) + MsgError.LOAD_COMPATIBILITY.log(e) if(tryDirtyStart()) return } @@ -194,7 +195,7 @@ open class CustomAnvil : JavaPlugin() { try { registerListeners() } catch (e: Exception) { - logError("error.load.listeners".translate(), e) + MsgError.LOAD_LISTENERS.log(e) if(tryDirtyStart()) return } @@ -215,18 +216,15 @@ open class CustomAnvil : JavaPlugin() { val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") if (potentialPlugin != null) { Bukkit.getPluginManager().disablePlugin(potentialPlugin) - logger.warning("warning.load.legacy.old-name.1".translate()) - logger.warning("warning.load.legacy.old-name.2".translate()) + MsgWarning.LOAD_LEGACY_OLD_NAME.log() } val isPaper = PlatformUtil.isPaper if(!isPaper) { - logger.warning("warning.load.legacy.spigot.1".translate()) - logger.warning("warning.load.legacy.spigot.2".translate()) - if(MinecraftVersionUtil.isTooNewForSpigot) { - logger.warning("warning.load.legacy.spigot-old.1".translate()) - logger.warning("warning.load.legacy.spigot-old.1".translate()) - } + MsgWarning.LOAD_LEGACY_SPIGOT.log() + if(MinecraftVersionUtil.isTooNewForSpigot) + MsgWarning.LOAD_LEGACY_SPIGOT_OLD.log() + } val loader = if(isPaper) "paper" else "spigot" @@ -238,13 +236,13 @@ open class CustomAnvil : JavaPlugin() { UpdateUtils.currentMinecraftVersion().toString()) .setFeatured(featured) .setOnError { - logger.log(Level.WARNING, "error.load.update.check-fail".translate(), it) + MsgError.LOAD_UPDATE_CHECK_FAIL.log(it, level = Level.WARNING, track = false) } .checkVersion { latestVer: String? -> CustomAnvil.latestVer = latestVer if(latestVer == null || version.contains(latestVer)) return@checkVersion - logger.warning("warning.load.update.available".translate(Pair("version", latestVer))) + MsgWarning.LOAD_UPDATE_AVAILABLE.log(latestVer) } } @@ -263,7 +261,7 @@ open class CustomAnvil : JavaPlugin() { try { loadEnchantmentSystem() } catch (e: Exception) { - logError("error.load.enchant-system".translate(), e) + MsgError.LOAD_ENCHANT_SYSTEM.log(e) tryDirtyStart() } } @@ -278,7 +276,7 @@ open class CustomAnvil : JavaPlugin() { // Load config if (!ConfigHolder.loadNonDefaultConfig()) { - logError("error.load.non-default-config".translate()) + MsgError.LOAD_NON_DEFAULT_CONFIG.log() server.pluginManager.disablePlugin(this) return } @@ -332,16 +330,15 @@ open class CustomAnvil : JavaPlugin() { try { val configReader = FileReader(resourceFile) yamlConfig.load(configReader) - } catch (_: Exception) { + } catch (e: Exception) { + MsgError.RELOAD_FAIL.log(e, resourceFile.path) if (hardFailSafe) { // This is important and may impact gameplay if it does not load. // Failsafe is to stop the plugin - logError("error.reload.resource.fail".translate(Pair("path", resourceFile.path))) - logError("error.reload.resource.hard-fail".translate()) + MsgError.RELOAD_HARD_FAIL.log() Bukkit.getPluginManager().disablePlugin(this) - } else { - logError("error.reload.resource.fail".translate(Pair("path", resourceFile.path))) } + return null } return yamlConfig diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt index c2293afc..4998f14d 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt @@ -122,8 +122,7 @@ class DiagnosticExecutor : CASubCommand { if (sender is HumanEntity) { if (hasError) - sender.spigot() - .sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic")) + sender.sendMessage(ChatColor.RED.toString() + "There was an error running the diagnostic") val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data") message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt index b89ca6bd..db8a2b29 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt @@ -18,60 +18,13 @@ object Lang { if(default != lang) default.reload() } - fun String.translate(): String { - val value = lang.get(this) + fun getTranslated(key: String): String { + val value = lang.get(key) if(value != null) return value CustomAnvil.log("Missing language data for ${lang.name} using default") - return default.get(this) ?: this - } - - fun String.translate(vararg params: Pair): String { - return translate( - params.asSequence() - .map { Pair(it.first, it.second.toString()) } - .toMap() - ) - } - - fun String.translate(vararg params: Pair): String { - return translate( - params.asSequence() - .map { Pair(it.first.toString(), it.second.toString()) } - .toMap() - ) - } - - fun String.translate(vararg params: Pair): String { - return translate(params.toMap()) - } - - fun String.translate(vararg params: Pair): String { - return translate( - params.asSequence() - .map { Pair(it.first.toString(), it.second) } - .toMap() - ) - } - - fun String.translate(params: Map): String { - val builder = StringBuilder(translate()) - - // replace all placeholder thingy %key -> value - for((key, replacement) in params) { - var current = 0 - while(true) { - current = builder.indexOf('%', current) + 1 - if(current < 0 || current + key.length > builder.length) break // may be able to be removed if bound checked in startsWith ? - if(!builder.startsWith(key, current, false)) continue - - builder.replace(current - 1, current + key.length, replacement) - current = current - 1 + replacement.length - } - } - - return builder.toString() + return default.get(key) ?: key } /* diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt index d06f9aba..d6054ba2 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt @@ -7,7 +7,6 @@ import java.io.File import java.io.InputStreamReader import java.util.logging.Level - class Language(private val id: String, private val default: Boolean = false) { private val resourcePath: String diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt new file mode 100644 index 00000000..be4b8f41 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -0,0 +1,128 @@ +package xyz.alexcrea.cuanvil.lang + +import io.delilaheve.CustomAnvil +import net.kyori.adventure.text.Component +import org.bukkit.command.CommandSender +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage +import xyz.alexcrea.cuanvil.util.MiniMessageUtil +import java.util.logging.Level +import kotlin.math.min + +interface MessageLike { + + fun log(vararg params: Any) + + fun send(destination: CommandSender, vararg params: Any) +} + +enum class MessageType { + DEFAULT, + WARNING, + ERROR, +} + +open class Message(val key: String, vararg val params: String) : MessageLike { + + protected fun replaceParameters(stb: StringBuilder, vararg values: Any) { + // replace all placeholder thingy %key -> value + + for(i in 0 until min(params.size, values.size)) { + val key = params[i] + val replacement = values[i].toString() + + var current = 0 + while(true) { + current = stb.indexOf('%', current) + 1 + if(current < 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? + if(!stb.startsWith(key, current, false)) continue + + stb.replace(current - 1, current + key.length, replacement) + current = current - 1 + replacement.length + } + } + } + + fun unformatted(vararg params: Any): String { + val translated = Lang.getTranslated(key) + if(params.isEmpty()) return translated + + val stb = StringBuilder(translated) + replaceParameters(stb, *params) + return stb.toString() + } + + fun formatted(vararg params: Any): Component { + val unformatted = unformatted(*params) + + return MiniMessageUtil.mm.deserialize(unformatted) + } + + override fun log(vararg params: Any) { + val text = unformatted(*params) + + CustomAnvil.instance.logger.info(text) + } + + override fun send(destination: CommandSender, vararg params: Any) { + val message = formatted(*params) + if(!destination.sendPaperMessage(message)) + destination.sendMessage(MiniMessageUtil.legacy_mm.serialize(message)) + } +} + +class WarningMessage(key: String, vararg params: String) : Message("warning.$key", *params) { + + override fun log(vararg params: Any) { + val text = unformatted(*params) + + CustomAnvil.instance.logger.warning(text) + } + +} + +class ErrorMessage(key: String, vararg params: String) : Message("error.$key", *params) { + + override fun log(vararg params: Any) { + val text = unformatted(*params) + + CustomAnvil.logError(text) + } + + fun log(e: Throwable, vararg params: Any, level: Level = Level.SEVERE, track: Boolean = true) { + val text = unformatted(*params) + + CustomAnvil.logError(text, e, track, level) + } +} + +class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg params: String) : MessageLike { + + private val messages = ArrayList() + + init { + for(i in 1 until count + 1) { + val message = createNew(type, "$baseKey.$i", *params) + messages.add(message) + } + } + + private fun createNew(type: MessageType, key: String, vararg params: String): MessageLike { + return when(type) { + MessageType.DEFAULT -> Message(key, *params) + MessageType.WARNING -> WarningMessage(key, *params) + MessageType.ERROR -> ErrorMessage(key, *params) + } + } + + override fun log(vararg params: Any) { + for(message in messages) { + message.log(*params) + } + } + + override fun send(destination: CommandSender, vararg params: Any) { + for(message in messages) { + message.send(destination, *params) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt new file mode 100644 index 00000000..7823f79d --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt @@ -0,0 +1,4 @@ +package xyz.alexcrea.cuanvil.lang + +object Msg { +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt new file mode 100644 index 00000000..6e5e26fb --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt @@ -0,0 +1,26 @@ +package xyz.alexcrea.cuanvil.lang + +object MsgError { + + /* + * ----------------- + * Load and reload + * ----------------- + */ + val LOAD_UPDATE_CHECK_FAIL = ErrorMessage("load.update.check-fail") + val LOAD_LEGACY_FAILED = ErrorMessage("load.legacy.failed") + val LOAD_COMMAND_REGISTER = ErrorMessage("load.command-register") + val LOAD_COMPATIBILITY = ErrorMessage("load.compatibility") + val LOAD_LISTENERS = ErrorMessage("load.listeners") + val LOAD_ENCHANT_SYSTEM = ErrorMessage("load.enchant-system") + val LOAD_NON_DEFAULT_CONFIG = ErrorMessage("load.non-default-config") + + val RELOAD_FAIL = ErrorMessage("reload.resource.fail", "path") + val RELOAD_HARD_FAIL = ErrorMessage("reload.resource.hardfail") + + /* + * ---------- + * Commands + * ---------- + */ +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt new file mode 100644 index 00000000..aa7af304 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt @@ -0,0 +1,17 @@ +package xyz.alexcrea.cuanvil.lang + +object MsgWarning { + + /* + * --------------- + * Load and reload + * --------------- + */ + val LOAD_UPDATE_AVAILABLE = WarningMessage("load.update.available", "version") + + val LOAD_LEGACY_OLD_NAME = MultiLineMessage(MessageType.WARNING, "load.legacy.old-name", 2) + val LOAD_LEGACY_SPIGOT = MultiLineMessage(MessageType.WARNING, "load.legacy.spigot", 2) + val LOAD_LEGACY_SPIGOT_OLD = MultiLineMessage(MessageType.WARNING, "load.legacy.spigot", 2) + + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt index 1763db56..88004112 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt @@ -74,8 +74,8 @@ object MetricsUtil { lastError = e } - fun trackError(message: String) { - ERROR_TRACKER?.trackError(message) + fun trackError(message: String, cause: Throwable? = null) { + trackError(RuntimeException(message, cause)) } } diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index d466dd53..b0c96009 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -1,4 +1,5 @@ name: English +last-updated: 2.1.0 warning: load: @@ -27,3 +28,38 @@ error: resource: fail: "Resource %path Could not be loaded or reloaded." hard-fail: "Disabling plugin." + +command: + shared: + no-diag-permission: "You do not have permission to diagnostic this server" + # I try to avoid using & for color but this is for a bungee text component + hover-copy: "§7Click to copy" + warning: + missing-subcmd: "Need to specify a subcommand. for example %example1 or %example2" + root: + warning: + unknown-sub: "Invalid subcommand. run `%command help` to see available commands" + error: + generic: "Error running this command" + debug: + description: "Used to toggle debug logs and retrieve them" + log-cleared: "Log Cleared" + toggled: "Debug toggled to %type" + # I try to avoid using & for color but this is for a bungee text component + copy: "§aClick to copy log data" + data: + header: "Debug Log data:" + line-count: "Found %count lines" + warning: + unspecified-type: "Need to specify which type of debug to toggle: \"default\" or \"verbose\"" + no-log: "No log to show ? make sure you tried with debug log toggled (%command)" + diagnostic: + description: "Basic diagnostic of this plugin" + had-error: "There was an error running the diagnostic" + # I try to avoid using & for color but this is for a bungee text component + copy: "§aClick to copy diagnostic data" + config: + description: "Used to edit the configuration of the plugin" + + warning: + legacy-name: "/ca gui has been moved to /ca config" \ No newline at end of file From 3c3ee00a50d3e3c5b8af742c103170c0245a3e12 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sat, 15 Aug 2026 05:15:11 +0200 Subject: [PATCH 04/13] finished adding command text to trans file --- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 5 +- .../alexcrea/cuanvil/command/CASubCommand.kt | 3 +- .../cuanvil/command/CustomAnvilCommand.kt | 7 +- .../cuanvil/command/DebugToggleExecutor.kt | 68 +++++++++-------- .../cuanvil/command/DiagnosticExecutor.kt | 17 +++-- .../cuanvil/command/EditConfigExecutor.kt | 49 ++++++------ .../cuanvil/command/EnchantExecutor.kt | 54 +++++++------- .../alexcrea/cuanvil/command/HelpExecutor.kt | 31 ++++---- .../cuanvil/command/ReloadExecutor.kt | 34 +++++---- .../xyz/alexcrea/cuanvil/lang/Message.kt | 57 +++++++++++--- .../xyz/alexcrea/cuanvil/lang/MsgCommand.kt | 74 +++++++++++++++++++ .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 6 ++ .../xyz/alexcrea/cuanvil/lang/MsgWarning.kt | 25 +++++-- .../alexcrea/cuanvil/util/ComponentUtil.kt | 14 ++++ src/main/resources/lang/en.yml | 43 +++++++++-- 15 files changed, 334 insertions(+), 153 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index df000bce..7ff46191 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -1,6 +1,7 @@ package io.delilaheve import io.delilaheve.util.ConfigOptions +import net.kyori.adventure.text.Component import org.bukkit.Bukkit import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.plugin.java.JavaPlugin @@ -76,7 +77,7 @@ open class CustomAnvil : JavaPlugin() { var latestVer: String? = null // Debug - val debugStorageQueue = ArrayDeque() + val debugStorageQueue = ArrayDeque() private fun addToLogQueue(message: String) { if(debugStorageQueue.size >= 200) { @@ -84,7 +85,7 @@ open class CustomAnvil : JavaPlugin() { debugStorageQueue.removeFirst() } - debugStorageQueue.addLast(message) + debugStorageQueue.addLast(Component.text(message)) } /** diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt index ede87e9a..ec893559 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt @@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.command import org.bukkit.command.Command import org.bukkit.command.CommandSender import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry +import xyz.alexcrea.cuanvil.lang.MessageLike interface CASubCommand { @@ -21,7 +22,7 @@ interface CASubCommand { list: MutableList ) - fun description(): String + fun description(): MessageLike fun allEnchantmentsByName(): Collection { val names = mutableSetOf() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt index 1cae583f..ef4a3f41 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt @@ -6,6 +6,7 @@ import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter +import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.MetricsUtil class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { @@ -57,15 +58,15 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { } if (subcmd == null || !subcmd.allowed(sender)) { - sender.sendMessage("Invalid subcommand. run `$cmdstr help` to see available commands") + MsgCommand.ROOT_UNKNOWN_SUBCOMMAND.send(sender, cmdstr) return true } try { return subcmd.executeCommand(sender, cmd, subcmdStr, newargs) } catch (e: Throwable) { - MetricsUtil.trackError(e) - sender.sendMessage("§cError running this command") + CustomAnvil.logError("Error running /$cmdstr ${args.joinToString(" ")}", e) + MsgCommand.ROOT_ERROR_SUBCOMMAND.send(sender) return false } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index 302ff782..c0c4862f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -6,16 +6,17 @@ import net.md_5.bungee.api.chat.ClickEvent import net.md_5.bungee.api.chat.HoverEvent import net.md_5.bungee.api.chat.TextComponent import net.md_5.bungee.api.chat.hover.content.Text -import org.bukkit.ChatColor import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.Player -import xyz.alexcrea.cuanvil.command.DiagnosticExecutor.Companion.NO_DIAG_PERM +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand +import xyz.alexcrea.cuanvil.util.MiniMessageUtil class DebugToggleExecutor : CASubCommand { - override fun description(): String { - return "Used to toggle debug logs and retrieve it" + override fun description(): MessageLike { + return MsgCommand.DEBUG_DESCRIPTION } override fun allowed(sender: CommandSender): Boolean { @@ -26,18 +27,18 @@ class DebugToggleExecutor : CASubCommand { sender: CommandSender, cmd: Command, cmdstr: String, - args: Array + args: Array, ): Boolean { - if (!allowed(sender)) { - sender.sendMessage(NO_DIAG_PERM) + if(!allowed(sender)) { + MsgCommand.SHARED_NO_DIAG_PERM.send(sender) return false } - if (args.isEmpty()) { - sender.sendMessage("Need to specify a subcommand: \"toggle\" or \"get\"") + if(args.isEmpty()) { + MsgCommand.SHARED_MISSING_SUBCOMMAND.send(sender) return true } - when (args[0].lowercase()) { + when(args[0].lowercase()) { "toggle" -> executeToggle(sender, args) "get" -> executeGet(sender) "get-and-clear" -> { @@ -47,52 +48,57 @@ class DebugToggleExecutor : CASubCommand { "clear" -> { CustomAnvil.debugStorageQueue.clear() - sender.sendMessage("Log Cleared") + MsgCommand.DEBUG_LOG_CLEARED.send(sender) } - else -> return false + else -> { + MsgCommand.SHARED_UNKNOWN_SUB_COMMAND.send(sender) + return false + } } return true } private fun executeToggle(sender: CommandSender, args: Array) { - if (args.size < 2) { - sender.sendMessage("Need to specify which type of debug to toggle: \"default\" or \"verbose\"") + if(args.size < 2) { + MsgCommand.DEBUG_WARNING_UNSPECIFIED_TYPE.send(sender) return } - when (args[1].lowercase()) { + when(args[1].lowercase()) { "default" -> { ConfigOptions.OVERRIDE_DEBUG_LOG = !ConfigOptions.debugLog - sender.sendMessage("Debug toggle to: ${ConfigOptions.debugLog}") + MsgCommand.DEBUG_TOGGLED.send(sender, ConfigOptions.debugLog) } "verbose" -> { ConfigOptions.OVERRIDE_VERBOSE_DEBUG_LOG = !ConfigOptions.verboseDebugLog - sender.sendMessage("Debug toggle to: ${ConfigOptions.verboseDebugLog}") + MsgCommand.DEBUG_TOGGLED.send(sender, ConfigOptions.debugLog) } - else -> sender.sendMessage("Invalid debug type: ${args[1]}") + else -> MsgCommand.DEBUG_WARNING_INVALID_TYPE.send(sender, ConfigOptions.debugLog) } - } private fun executeGet(sender: CommandSender) { - val stb = StringBuilder("Debug Log data:") - if (CustomAnvil.debugStorageQueue.isEmpty()) { - sender.sendMessage("No log to show ? make sure you tried with debug log toggled (/ca debug toggle)") + if(CustomAnvil.debugStorageQueue.isEmpty()) { + MsgCommand.DEBUG_WARNING_NO_LOG.send(sender, "/ca debug toggle") return } - stb.append("\nFound ${CustomAnvil.debugStorageQueue.size} lines\n") - for (log in CustomAnvil.debugStorageQueue) { - stb.append('\n').append(log) + val stb = StringBuilder(MsgCommand.DEBUG_DATA_HEADER.unformatted()).append(' ') + stb.append(MsgCommand.DEBUG_DATA_LINE_COUNT.unformatted(CustomAnvil.debugStorageQueue.size)) + for(log in CustomAnvil.debugStorageQueue) { + stb.append('\n').append(MiniMessageUtil.plain_text_mm.serialize(log)) } - if (sender is Player) { - val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy log data") + if(sender is Player) { + val message = TextComponent(MsgCommand.DEBUG_COPY.legacy()) message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) - message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy")) + message.hoverEvent = HoverEvent( + HoverEvent.Action.SHOW_TEXT, + Text(MsgCommand.SHARED_HOVER_COPY.legacy()) + ) sender.spigot().sendMessage(message); } else { @@ -101,12 +107,12 @@ class DebugToggleExecutor : CASubCommand { } override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { - if (!allowed(sender)) return + if(!allowed(sender)) return list.addAll( - when (args.size) { + when(args.size) { 1 -> listOf("toggle", "get", "get-and-clear", "clear") - 2 -> when (args[0].lowercase()) { + 2 -> when(args[0].lowercase()) { "toggle" -> listOf("default", "verbose") else -> listOf() } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt index 4998f14d..b015fde0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt @@ -6,7 +6,6 @@ import net.md_5.bungee.api.chat.HoverEvent import net.md_5.bungee.api.chat.TextComponent import net.md_5.bungee.api.chat.hover.content.Text import org.bukkit.Bukkit -import org.bukkit.ChatColor import org.bukkit.Material import org.bukkit.command.Command import org.bukkit.command.CommandSender @@ -25,15 +24,17 @@ import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.util.MetricsUtil import java.util.* import java.util.stream.Collectors +@Suppress("UnstableApiUsage") class DiagnosticExecutor : CASubCommand { companion object { - const val NO_DIAG_PERM = "You do not have permission to diagnostic this server" fun fetchNMSType(): String { val packetManager = DependencyManager.packetManager @@ -101,7 +102,7 @@ class DiagnosticExecutor : CASubCommand { args: Array ): Boolean { if (!allowed(sender)) { - sender.sendMessage(NO_DIAG_PERM) + MsgCommand.SHARED_NO_DIAG_PERM.send(sender) return false } @@ -122,11 +123,11 @@ class DiagnosticExecutor : CASubCommand { if (sender is HumanEntity) { if (hasError) - sender.sendMessage(ChatColor.RED.toString() + "There was an error running the diagnostic") - val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data") + MsgCommand.DIAGNOSTIC_ERROR_GENERIC.send(sender) + val message = TextComponent(MsgCommand.DIAGNOSTIC_COPY.legacy()) message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) - message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy")) + message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text(MsgCommand.SHARED_HOVER_COPY.legacy())) sender.spigot().sendMessage(message) } else { @@ -213,8 +214,8 @@ class DiagnosticExecutor : CASubCommand { return this.name + " v" + this.description.version } - override fun description(): String { - return "Basic diagnostic of this plugin" + override fun description(): MessageLike { + return MsgCommand.DIAGNOSTIC_DESCRIPTION } private fun pluginListDiag(sender: CommandSender, stb: StringBuilder) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt index 79151cd3..0fc522d2 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt @@ -11,6 +11,8 @@ import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir @@ -20,42 +22,38 @@ class EditConfigExecutor : CASubCommand { return sender.hasPermission(CustomAnvil.editConfigPermission) } - override fun description(): String { - return "Gui to edit the plugin's config" + override fun description(): MessageLike { + return MsgCommand.CONFIG_DESCRIPTION } override fun executeCommand( sender: CommandSender, cmd: Command, cmdstr: String, - args: Array + args: Array, ): Boolean { - if (sender !is HumanEntity) return false + if(sender !is HumanEntity) return false - if (!allowed(sender)) { + if(!allowed(sender)) { sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) return false } - if (PlatformUtil.isFolia) { - sender.sendMessage("§cIt look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia.") - sender.sendMessage("§eIt is may come in a future version.") - sender.sendMessage("") - sender.sendMessage("§eCurrently you need to edit manually the config or copy from another server (spigot or better)") - sender.sendMessage("§eThen /ca reload after config file is edited") + if(PlatformUtil.isFolia) { + MsgCommand.CONFIG_FOLIA_ISSUE.send(sender) return false } - if ("gui".equals(cmdstr, ignoreCase = true)) { - sender.sendMessage("§c/ca gui has been moved to /ca config") + if("gui".equals(cmdstr, ignoreCase = true)) { + MsgCommand.CONFIG_LEGACY_NAME_WARNING.send(sender) } - if (args.isEmpty()) + if(args.isEmpty()) processOpen(sender) - else when (args[0].lowercase()) { + else when(args[0].lowercase()) { "open" -> processOpen(sender) "enchant" -> processEnchant(sender, args) "item" -> processItem(sender) - else -> sender.sendMessage("Unknown subcommand \"${args[0]}\"") + else -> MsgCommand.SHARED_UNKNOWN_SUB_COMMAND.send(sender) } return true @@ -63,31 +61,30 @@ class EditConfigExecutor : CASubCommand { private fun processEnchant(sender: HumanEntity, args: Array) { val enchantToFilter: Set - if (args.size <= 1) { + if(args.size <= 1) { val item = sender.inventory.itemInMainHand enchantToFilter = EnchantmentApi.getEnchantments(item).keys - if (enchantToFilter.isEmpty()) { - sender.sendMessage("No enchantment found in the item you are holding") + if(enchantToFilter.isEmpty()) { + MsgCommand.CONFIG_ENCHANTMENT_NO_IN_HAND.send(sender) return } } else { enchantToFilter = HashSet(EnchantmentApi.getByName(args[1].lowercase())) - if (enchantToFilter.isEmpty()) { - sender.sendMessage("No enchantment found with the name \"${args[1]}\"") + if(enchantToFilter.isEmpty()) { + MsgCommand.CONFIG_ENCHANTMENT_NO_NAME.send(sender, args[1]) return } } EnchantConfigGui(enchantToFilter).show(sender) - } private fun processItem(sender: HumanEntity) { val item = sender.inventory.itemInMainHand - if (item.isAir) { - sender.sendMessage("Cannot configure the item in hand") + if(item.isAir) { + MsgCommand.CONFIG_CANNOT_CONFIGURE_WARNING.send(sender) return } @@ -104,10 +101,10 @@ class EditConfigExecutor : CASubCommand { override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { list.addAll( - when (args.size) { + when(args.size) { 1 -> listOf("item", "enchant", "open") 2 -> { - when (args[0].lowercase()) { + when(args[0].lowercase()) { "enchant" -> allEnchantmentsByName() else -> listOf() } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt index 654df1a8..46b256f3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt @@ -10,6 +10,8 @@ import org.bukkit.command.CommandSender import org.bukkit.entity.HumanEntity import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.enchant.CAEnchantment +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir class EnchantExecutor : CASubCommand { @@ -19,74 +21,74 @@ class EnchantExecutor : CASubCommand { return sender.hasPermission(CustomAnvil.giveEnchantmentPermission) } - override fun description(): String { - return "Allows to set enchantment to holden item" + override fun description(): MessageLike { + return MsgCommand.ENCHANT_DESCRIPTION } override fun executeCommand( sender: CommandSender, cmd: Command, cmdstr: String, - args: Array + args: Array, ): Boolean { - if (sender !is HumanEntity) return true + if(sender !is HumanEntity) return true - if (!allowed(sender)) { - sender.sendMessage("No permission to execute this command") + if(!allowed(sender)) { + MsgCommand.SHARED_NO_PERMISSION.send(sender) return true } - when (args.size) { + when(args.size) { 0 -> { - sender.sendMessage("Missing enchantment parameter") + MsgCommand.ENCHANT_MISSING_PARAMETER_WARNING.send(sender) return true } } val enchant = firstEnchantment(args[0]) - if (enchant == null) { - sender.sendMessage("Enchantment not found: ${args[0]}") + if(enchant == null) { + MsgCommand.ENCHANT_NOT_FOUND_WARNING.send(sender, args[0]) return true } - val level = if (args.size > 1) + val level = if(args.size > 1) args[1].toIntOrNull()?.coerceIn(0, ConfigOptions.ENCHANT_LIMIT) else 1 - if (level == null) { - sender.sendMessage("Invalid number: ${args[1]}") + if(level == null) { + MsgCommand.ENCHANT_MALFORMED_NUMBER_WARNING.send(sender, args[1]) return true } val inHand = sender.inventory.itemInMainHand - if (inHand.isAir) { - sender.sendMessage("Cannot enchant this item") + if(inHand.isAir) { + MsgCommand.ENCHANT_CANNOT_ENCHANT_WARNING.send(sender) return true } - if (level == 0) { + if(level == 0) { enchant.removeFrom(inHand) - if (inHand.isEnchantedBook() && EnchantmentApi.getEnchantments(inHand).isEmpty()) + if(inHand.isEnchantedBook() && EnchantmentApi.getEnchantments(inHand).isEmpty()) inHand.type = Material.BOOK - sender.sendMessage("${enchant.prettyName} removed") + MsgCommand.ENCHANT_REMOVE.send(sender, enchant.prettyName) } else { - if (Material.BOOK == inHand.type) + if(Material.BOOK == inHand.type) inHand.type = Material.ENCHANTED_BOOK enchant.addEnchantmentUnsafe(inHand, level) - sender.sendMessage("${enchant.prettyName} set to level $level") + MsgCommand.ENCHANT_SET.send(sender, enchant.prettyName, level) } return true } override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { - if (sender !is HumanEntity) return + if(sender !is HumanEntity) return list.addAll( - when (args.size) { + when(args.size) { 1 -> allEnchantmentsByName() 2 -> findEnchantmentLevels(sender, args[0]) @@ -97,19 +99,19 @@ class EnchantExecutor : CASubCommand { private fun findEnchantmentLevels( sender: HumanEntity, - name: String + name: String, ): Collection { val enchant = firstEnchantment(name) ?: return listOf() val limit = ConfigOptions.enchantLimit(enchant) val result = mutableListOf() - for (i in 1 until limit + 1) { + for(i in 1 until limit + 1) { result.add(i.toString()) } val inHand = sender.inventory.itemInMainHand - if (enchant.isEnchantmentPresent(inHand)) + if(enchant.isEnchantmentPresent(inHand)) result.add("0") return result @@ -117,7 +119,7 @@ class EnchantExecutor : CASubCommand { private fun firstEnchantment(name: String): CAEnchantment? { val enchants = EnchantmentApi.getByName(name.lowercase()) - if (!enchants.isEmpty()) + if(!enchants.isEmpty()) return enchants.iterator().next() return EnchantmentApi.getByKey(NamespacedKey.fromString(name)) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt index c6c4d08c..1f669ac5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt @@ -1,29 +1,38 @@ package xyz.alexcrea.cuanvil.command import com.google.common.collect.ImmutableMap +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TextComponent import org.bukkit.command.Command import org.bukkit.command.CommandSender +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand +import xyz.alexcrea.cuanvil.util.ComponentUtil.send class HelpExecutor : CASubCommand { + override fun description(): MessageLike { + return MsgCommand.HELP_DESCRIPTION + } + lateinit var commands: ImmutableMap override fun executeCommand( sender: CommandSender, cmd: Command, cmdstr: String, - args: Array + args: Array, ): Boolean { + var text = MsgCommand.HELP_HEADER.formatted() + for((key, cmd) in commands) { + if(!cmd.allowed(sender)) continue - val stb = StringBuilder("List of available commands:") - for ((key, cmd) in commands) { - if (!cmd.allowed(sender)) continue - - stb.append("\n- $key: ").append(cmd.description()) + text = text.appendNewline() + .append(Component.text("- $key: ")) + .append(cmd.description().formatted()) } - sender.sendMessage(stb.toString()) - + text.send(sender) return true } @@ -34,12 +43,8 @@ class HelpExecutor : CASubCommand { override fun tabCompleter( sender: CommandSender, args: Array, - list: MutableList + list: MutableList, ) { } - override fun description(): String { - return "Help command" - } - } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index bc9a80be..f9d91ace 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -9,29 +9,35 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.gui.config.global.* import xyz.alexcrea.cuanvil.lang.Lang +import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.update.UpdateHandler class ReloadExecutor : CASubCommand { + override fun description(): MessageLike { + return MsgCommand.RELOAD_DESCRIPTION + } + override fun executeCommand( sender: CommandSender, cmd: Command, cmdstr: String, - args: Array + args: Array, ): Boolean { - if (!allowed(sender)) { - sender.sendMessage("§cYou do not have permission to reload the config") + if(!allowed(sender)) { + MsgCommand.SHARED_NO_PERMISSION.send(sender) return false } - sender.sendMessage("§eReloading config...") + MsgCommand.RELOAD_START.send(sender) val hardfail = args.isNotEmpty() && ("hard".equals(args[0], true)) val commandSuccess = commandBody(hardfail) - if (commandSuccess) { - sender.sendMessage("§aConfig reloaded !") + if(commandSuccess) { + MsgCommand.RELOAD_SUCCESS.send(sender) } else { - sender.sendMessage("§cConfig was not able to be reloaded...") - if (hardfail) { - sender.sendMessage("§4Hard fail, plugin disabled") + MsgCommand.RELOAD_FAIL.send(sender) + if(hardfail) { + MsgCommand.RELOAD_HARD_FAIL.send(sender) } } return commandSuccess @@ -44,20 +50,16 @@ class ReloadExecutor : CASubCommand { override fun tabCompleter( sender: CommandSender, args: Array, - list: MutableList + list: MutableList, ) { } - override fun description(): String { - return "Reload the configuration of this plugin" - } - /** * Execute the command, return true if success or false otherwise */ private fun commandBody(hardfail: Boolean): Boolean { try { - if (!ConfigHolder.reloadAllFromDisk(hardfail)) return false + if(!ConfigHolder.reloadAllFromDisk(hardfail)) return false // reload language config Lang.reload() @@ -83,7 +85,7 @@ class ReloadExecutor : CASubCommand { Bukkit.getServer().pluginManager.callEvent(configReadyEvent) return true - } catch (e: Exception) { + } catch(e: Exception) { e.printStackTrace() return false } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index be4b8f41..53b3dce5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.lang import io.delilaheve.CustomAnvil import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender -import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage +import xyz.alexcrea.cuanvil.util.ComponentUtil.send import xyz.alexcrea.cuanvil.util.MiniMessageUtil import java.util.logging.Level import kotlin.math.min @@ -13,18 +13,28 @@ interface MessageLike { fun log(vararg params: Any) fun send(destination: CommandSender, vararg params: Any) + + fun unformatted(vararg params: Any): String + + fun formatted(vararg params: Any): Component + + fun legacy(vararg params: Any): String { + val formated = formatted(*params) + return MiniMessageUtil.legacy_mm.serialize(formated) + } } enum class MessageType { - DEFAULT, - WARNING, - ERROR, + DEFAULT, WARNING, ERROR, COMMAND, UI, } open class Message(val key: String, vararg val params: String) : MessageLike { protected fun replaceParameters(stb: StringBuilder, vararg values: Any) { // replace all placeholder thingy %key -> value + if(params.size != values.size) { + CustomAnvil.log("Wrong number of argument for parameter for key $key (${params.size}/${values.size})") + } for(i in 0 until min(params.size, values.size)) { val key = params[i] @@ -33,7 +43,7 @@ open class Message(val key: String, vararg val params: String) : MessageLike { var current = 0 while(true) { current = stb.indexOf('%', current) + 1 - if(current < 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? + if(current <= 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? if(!stb.startsWith(key, current, false)) continue stb.replace(current - 1, current + key.length, replacement) @@ -42,16 +52,16 @@ open class Message(val key: String, vararg val params: String) : MessageLike { } } - fun unformatted(vararg params: Any): String { + override fun unformatted(vararg params: Any): String { val translated = Lang.getTranslated(key) - if(params.isEmpty()) return translated + if(params.isEmpty() && this.params.isEmpty()) return translated val stb = StringBuilder(translated) replaceParameters(stb, *params) return stb.toString() } - fun formatted(vararg params: Any): Component { + override fun formatted(vararg params: Any): Component { val unformatted = unformatted(*params) return MiniMessageUtil.mm.deserialize(unformatted) @@ -64,9 +74,7 @@ open class Message(val key: String, vararg val params: String) : MessageLike { } override fun send(destination: CommandSender, vararg params: Any) { - val message = formatted(*params) - if(!destination.sendPaperMessage(message)) - destination.sendMessage(MiniMessageUtil.legacy_mm.serialize(message)) + formatted(*params).send(destination) } } @@ -95,6 +103,10 @@ class ErrorMessage(key: String, vararg params: String) : Message("error.$key", * } } + +class CommandMessage(key: String, vararg params: String) : Message("command.$key", *params) +class UIMessage(key: String, vararg params: String) : Message("ui.$key", *params) + class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg params: String) : MessageLike { private val messages = ArrayList() @@ -111,6 +123,8 @@ class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg pa MessageType.DEFAULT -> Message(key, *params) MessageType.WARNING -> WarningMessage(key, *params) MessageType.ERROR -> ErrorMessage(key, *params) + MessageType.COMMAND -> CommandMessage(key, *params) + MessageType.UI -> UIMessage(key, *params) } } @@ -125,4 +139,25 @@ class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg pa message.send(destination, *params) } } + + override fun unformatted(vararg params: Any): String { + val stb = StringBuilder() + stb.append(messages[0].unformatted(*params)) + + for(i in 1 until messages.size) { + stb.append('\n').append(messages[i].unformatted(*params)) + } + + return stb.toString() + } + + override fun formatted(vararg params: Any): Component { + val component = messages[0].formatted(*params) + + for(i in 1 until messages.size) { + component.appendNewline().append(messages[i].formatted(*params)) + } + + return component + } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt new file mode 100644 index 00000000..fb2d882b --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt @@ -0,0 +1,74 @@ +package xyz.alexcrea.cuanvil.lang + +import xyz.alexcrea.cuanvil.lang.CommandMessage as Message + +object MsgCommand { + + fun multiLine(basekey: String, count: Int): MultiLineMessage { + return MultiLineMessage( + MessageType.COMMAND, basekey, count + ) + } + + // Root + val ROOT_UNKNOWN_SUBCOMMAND = Message("root.warning.unknown-sub", "command") + val ROOT_ERROR_SUBCOMMAND = Message("root.error.generic") + + // Shared + val SHARED_NO_DIAG_PERM = Message("shared.no-diag-permission") + val SHARED_HOVER_COPY = Message("shared.hover-copy") + val SHARED_MISSING_SUBCOMMAND = Message("shared.warning.missing-subcmd", "example1", "example2") + val SHARED_UNKNOWN_SUB_COMMAND = Message("shared.unknown-subcmd", "command") + val SHARED_NO_PERMISSION = Message("shared.no-permission") + + // Debug + val DEBUG_DESCRIPTION = Message("debug.description") + val DEBUG_LOG_CLEARED = Message("debug.log-cleared") + val DEBUG_TOGGLED = Message("debug.toggled", "type") + val DEBUG_COPY = Message("debug.copy") + + val DEBUG_DATA_HEADER = Message("debug.data.header") + val DEBUG_DATA_LINE_COUNT = Message("debug.data.line-count", "count") + + val DEBUG_WARNING_UNSPECIFIED_TYPE = Message("debug.warning.unspecified-type") + val DEBUG_WARNING_INVALID_TYPE = Message("debug.warning.invalid-type", "type") + val DEBUG_WARNING_NO_LOG = Message("debug.warning.no-log", "command") + + // Diagnostic + val DIAGNOSTIC_DESCRIPTION = Message("diagnostic.description") + val DIAGNOSTIC_ERROR_GENERIC = Message("diagnostic.had-error") + val DIAGNOSTIC_COPY = Message("diagnostic.copy") + + // Config + val CONFIG_DESCRIPTION = Message("config.description") + val CONFIG_LEGACY_NAME_WARNING = Message("config.warning.legacy-name") + val CONFIG_FOLIA_ISSUE = multiLine("config.folia-issue", 5) + + val CONFIG_ENCHANTMENT_NO_IN_HAND = Message("config.enchantment.no_hand") + val CONFIG_ENCHANTMENT_NO_NAME = Message("config.enchantment.no_name", "name") + + val CONFIG_CANNOT_CONFIGURE_WARNING = Message("config.warning.cannot_configure") + + // Enchant + val ENCHANT_DESCRIPTION = Message("enchant.description") + val ENCHANT_REMOVE = Message("enchant.remove.", "name") + val ENCHANT_SET = Message("enchant.set.", "name", "level") + + val ENCHANT_MISSING_PARAMETER_WARNING = Message("enchant.warning.missing_parameter") + val ENCHANT_NOT_FOUND_WARNING = Message("enchant.warning.not_found", "path") + val ENCHANT_MALFORMED_NUMBER_WARNING = Message("enchant.warning.malformed_number", "num") + val ENCHANT_CANNOT_ENCHANT_WARNING = Message("enchant.warning.cannot_enchant") + + // Help + val HELP_DESCRIPTION = Message("help.description") + val HELP_HEADER = Message("help.header") + + // Reload + val RELOAD_DESCRIPTION = Message("reload.description") + val RELOAD_START = Message("reload.start") + val RELOAD_SUCCESS = Message("reload.success") + val RELOAD_FAIL = Message("reload.fail") + val RELOAD_HARD_FAIL = Message("reload.hard-fail") + +} + diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt new file mode 100644 index 00000000..bb1c807b --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -0,0 +1,6 @@ +package xyz.alexcrea.cuanvil.lang + +object MsgUI { + + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt index aa7af304..f58dd814 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt @@ -1,17 +1,26 @@ package xyz.alexcrea.cuanvil.lang +import xyz.alexcrea.cuanvil.lang.WarningMessage as Message + object MsgWarning { + fun multiLine(basekey: String, count: Int): MultiLineMessage { + return MultiLineMessage( + MessageType.WARNING, + basekey, + count + ) + } + /* - * --------------- - * Load and reload - * --------------- + * ----------------- + * Load and reload + * ----------------- */ - val LOAD_UPDATE_AVAILABLE = WarningMessage("load.update.available", "version") - - val LOAD_LEGACY_OLD_NAME = MultiLineMessage(MessageType.WARNING, "load.legacy.old-name", 2) - val LOAD_LEGACY_SPIGOT = MultiLineMessage(MessageType.WARNING, "load.legacy.spigot", 2) - val LOAD_LEGACY_SPIGOT_OLD = MultiLineMessage(MessageType.WARNING, "load.legacy.spigot", 2) + val LOAD_UPDATE_AVAILABLE = Message("load.update.available", "version") + val LOAD_LEGACY_OLD_NAME = multiLine("load.legacy.old-name", 2) + val LOAD_LEGACY_SPIGOT = multiLine("load.legacy.spigot", 2) + val LOAD_LEGACY_SPIGOT_OLD = multiLine("load.legacy.spigot", 2) } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt new file mode 100644 index 00000000..884675be --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -0,0 +1,14 @@ +package xyz.alexcrea.cuanvil.util + +import net.kyori.adventure.text.Component +import org.bukkit.command.CommandSender +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage + +object ComponentUtil { + + fun Component.send(destination: CommandSender) { + if(!destination.sendPaperMessage(this)) + destination.sendMessage(MiniMessageUtil.legacy_mm.serialize(this)) + } + +} \ No newline at end of file diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index b0c96009..cfd9ce17 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -32,8 +32,9 @@ error: command: shared: no-diag-permission: "You do not have permission to diagnostic this server" - # I try to avoid using & for color but this is for a bungee text component - hover-copy: "§7Click to copy" + hover-copy: "Click to copy" + unknown-subcmd: "Unknown subcommand %command" + no-permission: "No permission to execute this command" warning: missing-subcmd: "Need to specify a subcommand. for example %example1 or %example2" root: @@ -45,21 +46,47 @@ command: description: "Used to toggle debug logs and retrieve them" log-cleared: "Log Cleared" toggled: "Debug toggled to %type" - # I try to avoid using & for color but this is for a bungee text component - copy: "§aClick to copy log data" + copy: "Click to copy log data" data: header: "Debug Log data:" line-count: "Found %count lines" warning: unspecified-type: "Need to specify which type of debug to toggle: \"default\" or \"verbose\"" + invalid-type: "Invalid debug type \"%type\"" no-log: "No log to show ? make sure you tried with debug log toggled (%command)" diagnostic: description: "Basic diagnostic of this plugin" had-error: "There was an error running the diagnostic" - # I try to avoid using & for color but this is for a bungee text component - copy: "§aClick to copy diagnostic data" + copy: "Click to copy diagnostic data" config: description: "Used to edit the configuration of the plugin" - + folia-issue: + 1: "It look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia." + 2: "It is may come in a future version." + 3: "" + 4: "Currently you need to edit manually the config or copy from another server (spigot or better)" + 5: "Then /ca reload after config file is edited" + enchantment: + no_hand: "No enchantment found in the item you are holding" + no_name: "No enchantment found with the name %name" warning: - legacy-name: "/ca gui has been moved to /ca config" \ No newline at end of file + legacy-name: "/ca gui has been moved to /ca config" + cannot_configure: "Cannot configure the item in hand" + enchant: + description: "Allows to set enchantment to holden item" + warning: + missing_parameter: "Missing enchantment parameter" + not_found: "Enchantment not found: %path" + malformed_number: "Invalid number: %num" + cannot_enchant: "Cannot enchant this item" + removed: "%name removed" + set: "%name set to level %level" + help: + description: "Help command" + header: "List of available commands:" + reload: + description: "Reload the configuration of this plugin" + start: "Reloading config..." + success: "Config reloaded !" + fail: "Config was not able to be reloaded..." + hard-fail: "Hard fail, plugin disabled" \ No newline at end of file From 7dacfbc303a9b537b9f1cbef0098f078c1de5bac Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sat, 15 Aug 2026 16:15:49 +0200 Subject: [PATCH 05/13] rework multiline --- .../alexcrea/cuanvil/anvil/AnvilMergeLogic.kt | 4 +- .../alexcrea/cuanvil/command/CASubCommand.kt | 4 +- .../cuanvil/command/DebugToggleExecutor.kt | 8 +- .../cuanvil/command/DiagnosticExecutor.kt | 4 +- .../cuanvil/command/EditConfigExecutor.kt | 4 +- .../cuanvil/command/EnchantExecutor.kt | 4 +- .../alexcrea/cuanvil/command/HelpExecutor.kt | 7 +- .../cuanvil/command/ReloadExecutor.kt | 4 +- .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 8 + .../xyz/alexcrea/cuanvil/lang/Language.kt | 5 + .../xyz/alexcrea/cuanvil/lang/Message.kt | 170 ++++++++---------- .../xyz/alexcrea/cuanvil/lang/MsgCommand.kt | 8 +- .../xyz/alexcrea/cuanvil/lang/MsgWarning.kt | 14 +- .../cuanvil/listener/AnvilResultListener.kt | 3 +- .../alexcrea/cuanvil/util/ComponentUtil.kt | 21 ++- .../alexcrea/cuanvil/util/MiniMessageUtil.kt | 5 - .../cuanvil/util/anvil/AnvilColorUtil.kt | 13 +- .../cuanvil/util/anvil/AnvilLoreEditUtil.kt | 5 +- 18 files changed, 147 insertions(+), 144 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index a1c411a3..7d1b745c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -22,6 +22,8 @@ import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.CasedStringUtil +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MiniMessageUtil @@ -151,7 +153,7 @@ object AnvilMergeLogic { ) if (component != null) { - renameText = MiniMessageUtil.legacy_mm.serialize(component) + renameText = component.serializeLegacy() sumCost += ConfigOptions.useOfColorCost useColor = true diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt index ec893559..e8d7f825 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt @@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.command import org.bukkit.command.Command import org.bukkit.command.CommandSender import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message interface CASubCommand { @@ -22,7 +22,7 @@ interface CASubCommand { list: MutableList ) - fun description(): MessageLike + fun description(): Message fun allEnchantmentsByName(): Collection { val names = mutableSetOf() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index c0c4862f..4ed7e0be 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -9,13 +9,13 @@ import net.md_5.bungee.api.chat.hover.content.Text import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.Player -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand -import xyz.alexcrea.cuanvil.util.MiniMessageUtil +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain class DebugToggleExecutor : CASubCommand { - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.DEBUG_DESCRIPTION } @@ -88,7 +88,7 @@ class DebugToggleExecutor : CASubCommand { val stb = StringBuilder(MsgCommand.DEBUG_DATA_HEADER.unformatted()).append(' ') stb.append(MsgCommand.DEBUG_DATA_LINE_COUNT.unformatted(CustomAnvil.debugStorageQueue.size)) for(log in CustomAnvil.debugStorageQueue) { - stb.append('\n').append(MiniMessageUtil.plain_text_mm.serialize(log)) + stb.append('\n').append(log.serializePlain()) } if(sender is Player) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt index b015fde0..0644a6fa 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt @@ -24,7 +24,7 @@ import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.util.MetricsUtil @@ -214,7 +214,7 @@ class DiagnosticExecutor : CASubCommand { return this.name + " v" + this.description.version } - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.DIAGNOSTIC_DESCRIPTION } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt index 0fc522d2..50bd186f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt @@ -11,7 +11,7 @@ import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir @@ -22,7 +22,7 @@ class EditConfigExecutor : CASubCommand { return sender.hasPermission(CustomAnvil.editConfigPermission) } - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.CONFIG_DESCRIPTION } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt index 46b256f3..d39acb3b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt @@ -10,7 +10,7 @@ import org.bukkit.command.CommandSender import org.bukkit.entity.HumanEntity import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.enchant.CAEnchantment -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir @@ -21,7 +21,7 @@ class EnchantExecutor : CASubCommand { return sender.hasPermission(CustomAnvil.giveEnchantmentPermission) } - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.ENCHANT_DESCRIPTION } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt index 1f669ac5..4d5c23de 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/HelpExecutor.kt @@ -2,16 +2,15 @@ package xyz.alexcrea.cuanvil.command import com.google.common.collect.ImmutableMap import net.kyori.adventure.text.Component -import net.kyori.adventure.text.TextComponent import org.bukkit.command.Command import org.bukkit.command.CommandSender -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.util.ComponentUtil.send class HelpExecutor : CASubCommand { - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.HELP_DESCRIPTION } @@ -23,7 +22,7 @@ class HelpExecutor : CASubCommand { cmdstr: String, args: Array, ): Boolean { - var text = MsgCommand.HELP_HEADER.formatted() + var text = MsgCommand.HELP_HEADER.formatted().first() for((key, cmd) in commands) { if(!cmd.allowed(sender)) continue diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index f9d91ace..f5b92b62 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -9,13 +9,13 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.gui.config.global.* import xyz.alexcrea.cuanvil.lang.Lang -import xyz.alexcrea.cuanvil.lang.MessageLike +import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand import xyz.alexcrea.cuanvil.update.UpdateHandler class ReloadExecutor : CASubCommand { - override fun description(): MessageLike { + override fun description(): Message { return MsgCommand.RELOAD_DESCRIPTION } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt index db8a2b29..18be75f6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.lang import io.delilaheve.CustomAnvil +import org.bukkit.configuration.ConfigurationSection import xyz.alexcrea.cuanvil.config.ConfigHolder object Lang { @@ -27,6 +28,13 @@ object Lang { return default.get(key) ?: key } + fun getSection(key: String): ConfigurationSection? { + val value = lang.getSection(key) + if(value != null) return value + + return default.getSection(key) + } + /* * Config Options & get */ diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt index d6054ba2..0a008bf0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.lang import io.delilaheve.CustomAnvil +import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.file.FileConfiguration import org.bukkit.configuration.file.YamlConfiguration import java.io.File @@ -50,6 +51,10 @@ class Language(private val id: String, private val default: Boolean = false) { return conf.getString(key) } + fun getSection(key: String): ConfigurationSection? { + return conf.getConfigurationSection(key) + } + val name: String get() = conf.getString("name", id)!! } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index 53b3dce5..b7f38551 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -3,32 +3,15 @@ package xyz.alexcrea.cuanvil.lang import io.delilaheve.CustomAnvil import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender +import org.bukkit.configuration.ConfigurationSection import xyz.alexcrea.cuanvil.util.ComponentUtil.send +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.MiniMessageUtil import java.util.logging.Level import kotlin.math.min -interface MessageLike { - - fun log(vararg params: Any) - - fun send(destination: CommandSender, vararg params: Any) - - fun unformatted(vararg params: Any): String - - fun formatted(vararg params: Any): Component - - fun legacy(vararg params: Any): String { - val formated = formatted(*params) - return MiniMessageUtil.legacy_mm.serialize(formated) - } -} - -enum class MessageType { - DEFAULT, WARNING, ERROR, COMMAND, UI, -} - -open class Message(val key: String, vararg val params: String) : MessageLike { +open class Message(val key: String, vararg val params: String) { protected fun replaceParameters(stb: StringBuilder, vararg values: Any) { // replace all placeholder thingy %key -> value @@ -52,7 +35,7 @@ open class Message(val key: String, vararg val params: String) : MessageLike { } } - override fun unformatted(vararg params: Any): String { + private fun unformattedMonoline(vararg params: Any): String { val translated = Lang.getTranslated(key) if(params.isEmpty() && this.params.isEmpty()) return translated @@ -61,19 +44,71 @@ open class Message(val key: String, vararg val params: String) : MessageLike { return stb.toString() } - override fun formatted(vararg params: Any): Component { - val unformatted = unformatted(*params) + private fun unformattedMultiline(section: ConfigurationSection, vararg params: Any): String { + val stb = StringBuilder() - return MiniMessageUtil.mm.deserialize(unformatted) + for(key in section.getKeys(false)) { + if(!section.isString(key)) continue + if(!stb.isEmpty()) stb.append('\n') + + stb.append(section.getString(key)) + } + + replaceParameters(stb, *params) + return stb.toString() } - override fun log(vararg params: Any) { - val text = unformatted(*params) + fun unformatted(vararg params: Any): String { + val section = Lang.getSection(key) + if(section != null) return unformattedMultiline(section, *params) - CustomAnvil.instance.logger.info(text) + return unformattedMonoline(*params) } - override fun send(destination: CommandSender, vararg params: Any) { + private fun formattedMultiline(section: ConfigurationSection, vararg params: Any): List { + val result = ArrayList() + + for(key in section.getKeys(false)) { + if(!section.isString(key)) continue + + val stb = StringBuilder(section.getString(key)) + replaceParameters(stb, *params) + + result.add(MiniMessageUtil.mm.deserialize(stb.toString())) + } + + return result + } + + fun formatted(vararg params: Any): List { + val section = Lang.getSection(key) + if(section != null) return formattedMultiline(section, *params) + + val translated = unformattedMonoline(key, *params) + + return listOf(MiniMessageUtil.mm.deserialize(translated)) + } + + fun legacy(vararg params: Any): String { + val formated = formatted(*params) + + val stb = StringBuilder() + for(component in formated) { + if(!stb.isEmpty()) stb.append('\n') + stb.append(component.serializeLegacy()) + } + return stb.toString() + } + + open fun log(vararg params: Any) { + val texts = formatted(*params) + + for(component in texts) { + CustomAnvil.instance.logger.info(component.serializePlain()) + } + } + + open fun send(destination: CommandSender, vararg params: Any) { formatted(*params).send(destination) } } @@ -81,83 +116,32 @@ open class Message(val key: String, vararg val params: String) : MessageLike { class WarningMessage(key: String, vararg params: String) : Message("warning.$key", *params) { override fun log(vararg params: Any) { - val text = unformatted(*params) + val texts = formatted(*params) - CustomAnvil.instance.logger.warning(text) + for(component in texts) { + CustomAnvil.instance.logger.warning(component.serializePlain()) + } } - } class ErrorMessage(key: String, vararg params: String) : Message("error.$key", *params) { override fun log(vararg params: Any) { - val text = unformatted(*params) + val texts = formatted(*params) - CustomAnvil.logError(text) + for(component in texts) { + CustomAnvil.logError(component.serializePlain()) + } } fun log(e: Throwable, vararg params: Any, level: Level = Level.SEVERE, track: Boolean = true) { - val text = unformatted(*params) + val texts = formatted(*params) - CustomAnvil.logError(text, e, track, level) + for(component in texts) { + CustomAnvil.logError(component.serializePlain(), e, track, level) + } } } - class CommandMessage(key: String, vararg params: String) : Message("command.$key", *params) -class UIMessage(key: String, vararg params: String) : Message("ui.$key", *params) - -class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg params: String) : MessageLike { - - private val messages = ArrayList() - - init { - for(i in 1 until count + 1) { - val message = createNew(type, "$baseKey.$i", *params) - messages.add(message) - } - } - - private fun createNew(type: MessageType, key: String, vararg params: String): MessageLike { - return when(type) { - MessageType.DEFAULT -> Message(key, *params) - MessageType.WARNING -> WarningMessage(key, *params) - MessageType.ERROR -> ErrorMessage(key, *params) - MessageType.COMMAND -> CommandMessage(key, *params) - MessageType.UI -> UIMessage(key, *params) - } - } - - override fun log(vararg params: Any) { - for(message in messages) { - message.log(*params) - } - } - - override fun send(destination: CommandSender, vararg params: Any) { - for(message in messages) { - message.send(destination, *params) - } - } - - override fun unformatted(vararg params: Any): String { - val stb = StringBuilder() - stb.append(messages[0].unformatted(*params)) - - for(i in 1 until messages.size) { - stb.append('\n').append(messages[i].unformatted(*params)) - } - - return stb.toString() - } - - override fun formatted(vararg params: Any): Component { - val component = messages[0].formatted(*params) - - for(i in 1 until messages.size) { - component.appendNewline().append(messages[i].formatted(*params)) - } - - return component - } -} \ No newline at end of file +class UIMessage(key: String, vararg params: String) : Message("ui.$key", *params) \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt index fb2d882b..2eed326b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt @@ -4,12 +4,6 @@ import xyz.alexcrea.cuanvil.lang.CommandMessage as Message object MsgCommand { - fun multiLine(basekey: String, count: Int): MultiLineMessage { - return MultiLineMessage( - MessageType.COMMAND, basekey, count - ) - } - // Root val ROOT_UNKNOWN_SUBCOMMAND = Message("root.warning.unknown-sub", "command") val ROOT_ERROR_SUBCOMMAND = Message("root.error.generic") @@ -42,7 +36,7 @@ object MsgCommand { // Config val CONFIG_DESCRIPTION = Message("config.description") val CONFIG_LEGACY_NAME_WARNING = Message("config.warning.legacy-name") - val CONFIG_FOLIA_ISSUE = multiLine("config.folia-issue", 5) + val CONFIG_FOLIA_ISSUE = Message("config.folia-issue") val CONFIG_ENCHANTMENT_NO_IN_HAND = Message("config.enchantment.no_hand") val CONFIG_ENCHANTMENT_NO_NAME = Message("config.enchantment.no_name", "name") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt index f58dd814..90eafa56 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt @@ -4,14 +4,6 @@ import xyz.alexcrea.cuanvil.lang.WarningMessage as Message object MsgWarning { - fun multiLine(basekey: String, count: Int): MultiLineMessage { - return MultiLineMessage( - MessageType.WARNING, - basekey, - count - ) - } - /* * ----------------- * Load and reload @@ -19,8 +11,8 @@ object MsgWarning { */ val LOAD_UPDATE_AVAILABLE = Message("load.update.available", "version") - val LOAD_LEGACY_OLD_NAME = multiLine("load.legacy.old-name", 2) - val LOAD_LEGACY_SPIGOT = multiLine("load.legacy.spigot", 2) - val LOAD_LEGACY_SPIGOT_OLD = multiLine("load.legacy.spigot", 2) + val LOAD_LEGACY_OLD_NAME = Message("load.legacy.old-name") + val LOAD_LEGACY_SPIGOT = Message("load.legacy.spigot") + val LOAD_LEGACY_SPIGOT_OLD = Message("load.legacy.spigot-old") } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 23641ef4..29a8d72c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -30,6 +30,7 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MiniMessageUtil @@ -541,7 +542,7 @@ class AnvilResultListener : Listener { if (bookPage.isNotEmpty()) bookPage.append('\n') if (it == null) return@forEach - bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it)) + bookPage.append(it.serializePlain()) } val resultPage = bookPage.toString() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt index 884675be..2d9ec351 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -8,7 +8,26 @@ object ComponentUtil { fun Component.send(destination: CommandSender) { if(!destination.sendPaperMessage(this)) - destination.sendMessage(MiniMessageUtil.legacy_mm.serialize(this)) + destination.sendMessage(this.serializeLegacy()) } + fun List.send(destination: CommandSender) { + for(component in this) + component.send(destination) + } + + fun Component.serializeMM(): String { + return MiniMessageUtil.mm.serialize(this) + } + fun Component.serializeMMColor(): String { + return MiniMessageUtil.color_only_mm.serialize(this) + } + fun Component.serializeLegacy(): String { + return MiniMessageUtil.legacy_mm.serialize(this) + } + fun Component.serializePlain(): String { + return MiniMessageUtil.plain_text_mm.serialize(this) + } + + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MiniMessageUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MiniMessageUtil.kt index c33cb9c5..6780049f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MiniMessageUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MiniMessageUtil.kt @@ -25,9 +25,4 @@ object MiniMessageUtil { val legacy_mm = LegacyComponentSerializer.legacySection() val plain_text_mm = PlainTextComponentSerializer.plainText() - // Keeping track of this as most use of this can be replaced later on v2 with pure component alternative - fun fromLegacy(legacyText: String): TextComponent { - return legacy_mm.deserialize(legacyText) - } - } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilColorUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilColorUtil.kt index 9564b2e9..44ae8faf 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilColorUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilColorUtil.kt @@ -3,6 +3,9 @@ package xyz.alexcrea.cuanvil.util.anvil import io.delilaheve.util.ConfigOptions import net.kyori.adventure.text.Component import org.bukkit.permissions.Permissible +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeMM +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.MiniMessageUtil import java.util.regex.Matcher import java.util.regex.Pattern @@ -103,10 +106,10 @@ object AnvilColorUtil { var result: Component = MiniMessageUtil.legacy_mm.deserialize(previousStr) if (permission.canUseMinimessage) { // we dance with formats here - val toMinimessage = MiniMessageUtil.mm.serialize(result) + val toMinimessage = result.serializeMM() val hackySolution = toMinimessage.replace("\\<", "<") val fromMinimessage = MiniMessageUtil.mm.deserialize(hackySolution) - val asPlain = MiniMessageUtil.plain_text_mm.serialize(fromMinimessage) + val asPlain = fromMinimessage.serializePlain() if (previousStr != asPlain) { useColor = true @@ -145,8 +148,8 @@ object AnvilColorUtil { ): String? { if (!permission.allowed() || component == null) return null - val transformed = MiniMessageUtil.mm.serialize(component) - val plainTransform = MiniMessageUtil.plain_text_mm.serialize(component) + val transformed = component.serializeMM() + val plainTransform = component.serializePlain() if (transformed == plainTransform) return null if (permission.onlyMinimessage()) { return transformed @@ -154,7 +157,7 @@ object AnvilColorUtil { // smol dance so we transform the component that may contain other tag into only decoration & color for legacy val coloredMessage = MiniMessageUtil.color_only_mm.deserialize(transformed) - val legacyMessage = StringBuilder(MiniMessageUtil.legacy_mm.serialize(coloredMessage)) + val legacyMessage = StringBuilder(coloredMessage.serializeLegacy()) // Reverse hex pattern if (permission.canUseHexColor) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilLoreEditUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilLoreEditUtil.kt index a021b468..ad827458 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilLoreEditUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilLoreEditUtil.kt @@ -10,6 +10,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore +import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditType @@ -320,7 +321,7 @@ object AnvilLoreEditUtil { hasUndidColor = true result = clearedLine } else { - result = MiniMessageUtil.plain_text_mm.serialize(line) + result = line.serializePlain() } lines[index] = MiniMessageUtil.plain_text_mm.deserialize(result) @@ -354,7 +355,7 @@ object AnvilLoreEditUtil { result = clearedLine } else { // Remove extra tags - result = MiniMessageUtil.plain_text_mm.serialize(coloredComponent) + result = coloredComponent.serializePlain() } line.set(MiniMessageUtil.plain_text_mm.deserialize(result)) From 19eccb5a086878f7cc1d0bc75ff2e5bf5c7d56cf Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sat, 15 Aug 2026 21:38:57 +0200 Subject: [PATCH 06/13] fix small translation issue --- .../kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt | 2 +- src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index 4ed7e0be..5c7bfee6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -35,7 +35,7 @@ class DebugToggleExecutor : CASubCommand { } if(args.isEmpty()) { - MsgCommand.SHARED_MISSING_SUBCOMMAND.send(sender) + MsgCommand.SHARED_MISSING_SUBCOMMAND.send(sender, "\"toggle\"", "\"get\"") return true } when(args[0].lowercase()) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index b7f38551..9c1dd596 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -84,7 +84,7 @@ open class Message(val key: String, vararg val params: String) { val section = Lang.getSection(key) if(section != null) return formattedMultiline(section, *params) - val translated = unformattedMonoline(key, *params) + val translated = unformattedMonoline(*params) return listOf(MiniMessageUtil.mm.deserialize(translated)) } From 0ffe7c70f949b76aac74569cf0e309f0560c95ab Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sun, 16 Aug 2026 07:26:08 +0200 Subject: [PATCH 07/13] progress on translation system --- .../gui/config/ask/ConfirmActionGui.java | 5 +++-- .../gui/config/ask/SelectItemTypeGui.java | 3 ++- .../list/MappedElementListConfigGui.java | 6 ++--- .../config/list/MappedGuiListConfigGui.java | 7 +++--- .../config/list/UnitRepairElementListGui.java | 5 +++-- .../elements/GroupConfigSubSettingGui.java | 3 ++- .../settings/MaterialSelectSettingGui.java | 3 ++- .../settings/WorkPenaltyTypeSettingGui.java | 3 ++- .../cuanvil/gui/util/GuiGlobalActions.java | 9 ++++---- .../cuanvil/command/CustomAnvilCommand.kt | 1 - .../cuanvil/command/EditConfigExecutor.kt | 4 ++-- .../cuanvil/dependency/DependencyManager.kt | 9 +++----- .../xyz/alexcrea/cuanvil/lang/Message.kt | 2 +- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 15 +++++++++++++ .../xyz/alexcrea/cuanvil/lang/MsgWarning.kt | 2 ++ src/main/resources/lang/en.yml | 22 ++++++++++++++++++- 16 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java index 58396638..0b5a08e7 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java @@ -11,6 +11,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.MetricsUtil; import java.util.Arrays; @@ -33,7 +34,7 @@ public class ConfirmActionGui extends AbstractAskGui { if (!player.hasPermission(CustomAnvil.editConfigPermission)) { player.closeInventory(); - player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player); return; } @@ -47,7 +48,7 @@ public class ConfirmActionGui extends AbstractAskGui { } if (!success) { - event.getWhoClicked().sendMessage("§cAction could not be completed. "); + MsgUI.INSTANCE.getCONFIRM_ACTION_FAILED().send(player); } backOnConfirm.show(player); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index 66411bd4..f0369e6d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.MaterialUtil; import java.util.Arrays; @@ -36,7 +37,7 @@ public class SelectItemTypeGui extends AbstractAskGui { if (!player.hasPermission(CustomAnvil.editConfigPermission)) { player.closeInventory(); - player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player); return; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java index 9b6c6100..7bfffdf8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.lang.MsgUI; import java.util.Arrays; import java.util.HashMap; @@ -52,13 +53,12 @@ public abstract class MappedElementListConfigGui extends ElementListConfig // check permission if (!player.hasPermission(CustomAnvil.editConfigPermission)) { player.closeInventory(); - player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player); return; } player.closeInventory(); - player.sendMessage("§eWrite the " + genericDisplayedName() + " name you want to create in the chat.\n" + - "§eOr write §ccancel §eto go back to " + genericDisplayedName() + " config menu"); + MsgUI.INSTANCE.getELEMENT_LIST_INSTRUCTION_NEW().send(player, genericDisplayedName()); CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player)); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index 8180694e..d25d6e72 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -8,6 +8,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.LazyValue; import java.util.Locale; @@ -69,13 +70,13 @@ public abstract class MappedGuiListConfigGuiReloading config..." success: "Config reloaded !" fail: "Config was not able to be reloaded..." - hard-fail: "Hard fail, plugin disabled" \ No newline at end of file + hard-fail: "Hard fail, plugin disabled" + +config-ui: + shared: + no-permission: "You do not have permission to edit the config" + confirm-action: + fail: "Action could not be completed." + element-list: + instruction-new: + 1: "Write the %type name you want to create in the chat." + 2: "Or write cancel to go back to %type config menu" + cancelled-new: "%type creation cancelled..." + duplicated-new: "Please enter a %type name that do not already exist..." + unit-repair: + element: + title: "Select item to be repaired." + description: + 1: "Click here with an item to set the item" + 2: "You like to be repaired by %name" + cannot-damage-new: "This item can't be damaged, so it can't be repaired." + same-type-new: "Item can't repair something of the same type." \ No newline at end of file From e1d8dd07ad1d57939f471d0fd07941ed40d894ad Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 17 Aug 2026 01:38:14 +0200 Subject: [PATCH 08/13] a lot of progress inside the ui --- .../cuanvil/dependency/util/PlatformUtil.kt | 20 +++++ .../gui/config/ask/AbstractAskGui.java | 6 +- .../gui/config/ask/ConfirmActionGui.java | 20 +++-- .../gui/config/ask/SelectItemTypeGui.java | 26 ++++--- .../global/AbstractEnchantConfigGui.java | 5 +- .../config/global/CustomRecipeConfigGui.java | 11 +-- .../gui/config/global/EnchantConflictGui.java | 11 +-- .../config/global/EnchantCostConfigGui.java | 6 +- .../config/global/EnchantLimitConfigGui.java | 5 +- .../global/EnchantMergeLimitConfigGui.java | 6 +- .../gui/config/global/GroupConfigGui.java | 5 +- .../config/global/UnitRepairConfigGui.java | 10 +-- .../gui/config/list/ElementListConfigGui.java | 20 ++--- .../list/MappedElementListConfigGui.java | 9 ++- .../config/list/MappedGuiListConfigGui.java | 17 ++++- .../config/list/SettingGuiListConfigGui.java | 17 ++++- .../config/list/UnitRepairElementListGui.java | 17 +++-- .../elements/CustomRecipeSubSettingGui.java | 30 ++++---- .../EnchantConflictSubSettingGui.java | 43 ++++++----- .../elements/GroupConfigSubSettingGui.java | 55 ++++++++++---- .../elements/MappedToListSubSettingGui.java | 6 +- .../settings/EnchantSelectSettingGui.java | 7 +- .../settings/GroupSelectSettingGui.java | 7 +- .../settings/MaterialSelectSettingGui.java | 10 ++- .../xyz/alexcrea/cuanvil/lang/Message.kt | 20 +++++ .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 43 ++++++++++- .../alexcrea/cuanvil/util/ComponentUtil.kt | 33 ++++++--- src/main/resources/lang/en.yml | 73 +++++++++++++++++-- 28 files changed, 386 insertions(+), 152 deletions(-) diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt index 3b47adaa..f1d6fe42 100644 --- a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt @@ -112,6 +112,26 @@ object PlatformUtil { return true } + return false + } /** + * Try to send paper component to the player + * + * @param component The used component + * @return true if sent, else otherwise + */ + + /** + * Try to set component lore of an item + * + * @param components The used component lore + * @return true if sent, else otherwise + */ + fun ItemMeta.setPaperLore(components: List): Boolean { + if(isPaper) { + this.lore(components) + return true + } + return false } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java index 66dd9363..75cdf236 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java @@ -10,13 +10,15 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; public abstract class AbstractAskGui extends ChestGui { protected PatternPane pane; - AbstractAskGui(int rows, @NotNull String name, + AbstractAskGui(int rows, + @NotNull Message name, @NotNull String param, Gui backOnCancel){ - super(rows, name, CustomAnvil.instance); + super(rows, name.textHolder(param), CustomAnvil.instance); Pattern pattern = getGuiPattern(); this.pane = new PatternPane(0, 0, pattern.getLength(), pattern.getHeight(), pattern); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java index 0b5a08e7..e3b02a12 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java @@ -9,21 +9,26 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil; +import java.awt.*; import java.util.Arrays; import java.util.function.Supplier; import java.util.logging.Level; public class ConfirmActionGui extends AbstractAskGui { - public ConfirmActionGui(@NotNull String title, String actionDescription, + public ConfirmActionGui(@NotNull Message title, @NotNull String titleParam, + @Nullable Message actionDescription, @NotNull String actionParam, Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm, boolean permanent) { - super(3, title, backOnCancel); + super(3, title, titleParam, backOnCancel); // Save item this.pane.bindItem('S', new GuiItem( @@ -42,7 +47,7 @@ public class ConfirmActionGui extends AbstractAskGui { try { success = onConfirm.get(); } catch (Exception e) { - CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e); + CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e); //TODO MESSAGE MetricsUtil.INSTANCE.trackError(e); success = false; } @@ -58,18 +63,19 @@ public class ConfirmActionGui extends AbstractAskGui { ItemStack infoItem = new ItemStack(Material.PAPER); ItemMeta infoMeta = infoItem.getItemMeta(); - infoMeta.setDisplayName("§eAre you sure ?"); + infoMeta.setDisplayName("§eAre you sure ?"); //TODO MESSAGE if(actionDescription != null){ - infoMeta.setLore(Arrays.asList(actionDescription.split("\n"))); + ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(), infoMeta); } infoItem.setItemMeta(infoMeta); pane.bindItem('I', new GuiItem(infoItem, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); } - public ConfirmActionGui(@NotNull String title, String actionDescription, + public ConfirmActionGui(@NotNull Message title, @NotNull String titleParam, + @Nullable Message actionDescription, @NotNull String actionParam, Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm){ - this(title, actionDescription, backOnCancel, backOnConfirm, onConfirm, true); + this(title, titleParam, actionDescription, actionParam, backOnCancel, backOnConfirm, onConfirm, true); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index f0369e6d..b4b10b6f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -12,7 +12,9 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil; import java.util.Arrays; @@ -22,12 +24,14 @@ import java.util.function.BiConsumer; public class SelectItemTypeGui extends AbstractAskGui { private ItemStack selectedItem; - public SelectItemTypeGui(@NotNull String title, - @NotNull String actionDescription, + public SelectItemTypeGui(@NotNull Message title, + @NotNull String titleParam, + @NotNull Message actionDescription, + @NotNull String descriptionParam, @NotNull Gui backOnCancel, @NotNull BiConsumer onSave, boolean materialOnly) { - super(3, title, backOnCancel); + super(3, title, titleParam, backOnCancel); this.selectedItem = null; // Save item @@ -47,7 +51,7 @@ public class SelectItemTypeGui extends AbstractAskGui { this.pane.bindItem('S', GuiGlobalItems.backgroundItem()); // Select item - ItemStack selectItem = setDisplayMeta(new ItemStack(Material.BARRIER), actionDescription); + ItemStack selectItem = setDisplayMeta(new ItemStack(Material.BARRIER), actionDescription, descriptionParam); AtomicReference selectGuiItem = new AtomicReference<>(); selectGuiItem.set(new GuiItem(selectItem, event -> { @@ -58,7 +62,7 @@ public class SelectItemTypeGui extends AbstractAskGui { ItemStack finalItem; if(materialOnly){ - finalItem = setDisplayMeta(new ItemStack(cursor.getType()), actionDescription); + finalItem = setDisplayMeta(new ItemStack(cursor.getType()), actionDescription, descriptionParam); }else{ finalItem = cursor.clone(); } @@ -76,14 +80,18 @@ public class SelectItemTypeGui extends AbstractAskGui { GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this); this.pane.bindItem('s', temporaryLeave); - } - private ItemStack setDisplayMeta(ItemStack item, String actionDescription){ + @NotNull + private ItemStack setDisplayMeta( + @NotNull ItemStack item, + @NotNull Message actionDescription, + @NotNull String param + ){ ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("§ePlace an item here"); - meta.setLore(Arrays.asList(actionDescription.split("\n"))); + meta.setDisplayName("§ePlace an item here"); //TODO MESSAGE + ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(param), meta); item.setItemMeta(meta); return item; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java index 5583b382..198f2149 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java @@ -9,6 +9,7 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import java.util.Collection; import java.util.Collections; @@ -27,11 +28,11 @@ public abstract class AbstractEnchantConfigGui getRecipeLore(AnvilCustomRecipe recipe) { boolean shouldWork = recipe.validate(); - ArrayList lore = new ArrayList<>(); + ArrayList lore = new ArrayList<>();//TODO MESSAGE lore.add("§7Is valid: §" + (shouldWork ? "aYes" : "cNo")); lore.add("§7Exact count: §" + (recipe.getExactCount() ? "aYes" : "cNo")); lore.add("§7Recipe Level Cost: §e" + recipe.getLevelCostPerCraft()); @@ -90,7 +91,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui { NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java index 19d31d9f..673c2ec8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import java.util.ArrayList; import java.util.Collection; @@ -32,16 +33,18 @@ public abstract class ElementListConfigGui extends ChestGui implements ValueU public static final int LIST_FILLER_LENGTH = 7; public static final int LIST_FILLER_HEIGHT = 4; - private final String namePrefix; + private final Message rawTitle; + private final String param; protected PatternPane backgroundPane; private Predicate filter = (t) -> true; private boolean hasDefaultFilter = true; - protected ElementListConfigGui(@NotNull String title, Gui parent) { - super(6, title, CustomAnvil.instance); - this.namePrefix = title; + protected ElementListConfigGui(@NotNull Message title, String param, Gui parent) { + super(6, title.textHolder(param, "", ""), CustomAnvil.instance); + this.rawTitle = title; + this.param = param; // Back item panel Pattern pattern = getBackgroundPattern(); @@ -259,13 +262,10 @@ public abstract class ElementListConfigGui extends ChestGui implements ValueU // and add actual page addPane(page); - // set title - StringBuilder title = new StringBuilder(this.namePrefix); + // intended parameter: (page/max_page) //TODO MESSAGE CHECK CHILDS int pagesSize = this.pages.size(); - if (pagesSize > 1) { - title.append(" (").append(pageID + 1).append('/').append(pagesSize).append(')'); - } - setTitle(title.toString()); + var title = this.rawTitle.textHolder(param, pageID + 1, pagesSize); + setTitle(title); super.show(humanEntity); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java index 7bfffdf8..2406fddc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import java.util.Arrays; @@ -20,14 +21,14 @@ public abstract class MappedElementListConfigGui extends ElementListConfig protected final HashMap elementGuiMap; - protected MappedElementListConfigGui(@NotNull String title, @NotNull Gui parent) { - super(title, parent); + protected MappedElementListConfigGui(@NotNull Message title, @NotNull String param, @NotNull Gui parent) { + super(title, param, parent); this.elementGuiMap = new HashMap<>(); } - protected MappedElementListConfigGui(@NotNull String title) { - this(title, MainConfigGui.getInstance()); + protected MappedElementListConfigGui(@NotNull Message title, @NotNull String param) { + this(title, param, MainConfigGui.getInstance()); } @Override diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index d25d6e72..5d346a43 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -8,6 +8,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.LazyValue; @@ -19,12 +20,20 @@ import java.util.function.Supplier; public abstract class MappedGuiListConfigGui> extends MappedElementListConfigGui { - protected MappedGuiListConfigGui(@NotNull String title) { - super(title); + protected MappedGuiListConfigGui(@NotNull Message title, @NotNull String param) { + super(title, param); } - protected MappedGuiListConfigGui(@NotNull String title, @NotNull Gui parent) { - super(title, parent); + protected MappedGuiListConfigGui(@NotNull Message title, @NotNull String param, @NotNull Gui parent) { + super(title, param, parent); + } + + protected MappedGuiListConfigGui(@NotNull Message title) { + super(title, ""); + } + + protected MappedGuiListConfigGui(@NotNull Message title, @NotNull Gui parent) { + super(title, "", parent); } @Override diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java index cb55ed08..b7bf0002 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; +import xyz.alexcrea.cuanvil.lang.Message; import java.util.HashMap; import java.util.List; @@ -20,16 +21,26 @@ public abstract class SettingGuiListConfigGui guiItemMap; protected HashMap factoryMap; - protected SettingGuiListConfigGui(@NotNull String title, Gui parent) { - super(title, parent); + protected SettingGuiListConfigGui(@NotNull Message title, Gui parent) { + super(title, "", parent); this.guiItemMap = new HashMap<>(); this.factoryMap = new HashMap<>(); } - protected SettingGuiListConfigGui(@NotNull String title) { + protected SettingGuiListConfigGui(@NotNull Message title) { this(title, MainConfigGui.getInstance()); } + protected SettingGuiListConfigGui(@NotNull Message title, @NotNull String param, Gui parent) { + super(title, param, parent); + this.guiItemMap = new HashMap<>(); + this.factoryMap = new HashMap<>(); + } + + protected SettingGuiListConfigGui(@NotNull Message title, @NotNull String param) { + this(title, param, MainConfigGui.getInstance()); + } + @Override protected GuiItem prepareCreateNewItem() { ItemStack createItem = new ItemStack(Material.PAPER); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java index f39b7aaf..fcbfa733 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java @@ -33,12 +33,16 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui { ItemMeta meta = itemStack.getItemMeta(); NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); if (!(meta instanceof Damageable)) { - MsgUI.INSTANCE.getUNIT_REPAIR_ELEMENT_CANNOT_REPAIR_NEW().send(player); + MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR().send(player); return; } if (type.equals(this.parentMaterial)) { - MsgUI.INSTANCE.getUNIT_REPAIR_ELEMENT_SAME_TYPE_NEW().send(player); + MsgUI.INSTANCE.getUNIT_REPAIR_NEW_ELEMENT_SAME_TYPE().send(player); return; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java index 9db6d622..83159d04 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java @@ -19,6 +19,7 @@ import xyz.alexcrea.cuanvil.gui.config.settings.ItemSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager; import xyz.alexcrea.cuanvil.util.CasedStringUtil; @@ -36,7 +37,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { public CustomRecipeSubSettingGui( @NotNull CustomRecipeConfigGui parent, @NotNull AnvilCustomRecipe anvilRecipe) { - super(4, "§e" + CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString()) + " §8Config"); + super(4, CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString())); this.parent = parent; this.anvilRecipe = anvilRecipe; @@ -73,19 +74,19 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { ItemMeta deleteMeta = deleteItem.getItemMeta(); assert deleteMeta != null; - deleteMeta.setDisplayName("§4DELETE RECIPE"); - deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); + deleteMeta.setDisplayName("§4DELETE RECIPE");//TODO MESSAGE + deleteMeta.setLore(Collections.singletonList("§cCaution with this button !"));//TODO MESSAGE deleteItem.setItemMeta(deleteMeta); this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); // Displayed item will be updated later IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE(); - this.exactCountFactory = new BoolSettingsGui.BoolSettingFactory("§8Exact count ?", this, + this.exactCountFactory = new BoolSettingsGui.BoolSettingFactory("§8Exact count ?", this,//TODO MESSAGE ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG); - this.removeExactLinearXpFactory = new BoolSettingsGui.BoolSettingFactory("§8Remove exact linear xp ?", this, + this.removeExactLinearXpFactory = new BoolSettingsGui.BoolSettingFactory("§8Remove exact linear xp ?", this,//TODO MESSAGE ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe + "." + AnvilCustomRecipe.REMOVE_EXACT_XP_CONFIG, AnvilCustomRecipe.DEFAULT_REMOVE_EXACT_XP_CONFIG); @@ -93,18 +94,18 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { ItemMeta meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§cRemove exact linear xp ?"); - meta.setLore(Collections.singletonList("§7Not usable if linear cost is 0")); + meta.setDisplayName("§cRemove exact linear xp ?");//TODO MESSAGE + meta.setLore(Collections.singletonList("§7Not usable if linear cost is 0"));//TODO MESSAGE item.setItemMeta(meta); this.noRemoveExactLinearXp = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); - this.levelCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Level Cost", this, + this.levelCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Level Cost", this,//TODO MESSAGE this.anvilRecipe + "." + AnvilCustomRecipe.XP_LEVEL_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, null, costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_LEVEL_COST_CONFIG, 1, 5, 10); - this.linearXpCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Linear Xp Cost", this, + this.linearXpCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Linear Xp Cost", this,//TODO MESSAGE this.anvilRecipe + "." + AnvilCustomRecipe.LINEAR_XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, null, @@ -117,21 +118,21 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(), "§7Set the left item of the custom craft", - "§7\u25A0 + \u25A1 = \u25A1"); + "§7■ + □ = □");//TODO MESSAGE this.rightItemFactory = new ItemSettingGui.ItemSettingFactory("§eRecipe Right §8Item", this, this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(), "§7Set the right item of the custom craft", - "§7\u25A1 + \u25A0 = \u25A1"); + "§7□ + ■ = □");//TODO MESSAGE this.resultItemFactory = new ItemSettingGui.ItemSettingFactory("§aRecipe Result §8Item", this, this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(), "§7Set the result item of the custom craft", - "§7\u25A1 + \u25A1 = \u25A0"); + "§7□ + □ = ■");//TODO MESSAGE // Now we update the items updateLocal(); @@ -162,8 +163,9 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { return success; }; - return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.anvilRecipe.toString()) + "§c?", - "§7Confirm that you want to delete this conflict.", + var type = CasedStringUtil.snakeToUpperSpacedCase(this.anvilRecipe.toString()); + return new ConfirmActionGui(MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_TITLE(), type, + MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION(), type, this, this.parent, deleteSupplier ); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java index 97bdfcb2..3e109873 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java @@ -24,6 +24,7 @@ import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil; @@ -41,8 +42,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl public EnchantConflictSubSettingGui( @NotNull EnchantConflictGui parent, @NotNull EnchantConflictGroup enchantConflict) { - super(3, - "§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + " §8Config"); + super(3, CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString())); this.parent = parent; this.enchantConflict = enchantConflict; @@ -71,8 +71,8 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl ItemMeta deleteMeta = deleteItem.getItemMeta(); assert deleteMeta != null; - deleteMeta.setDisplayName("§4DELETE CONFLICT"); - deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); + deleteMeta.setDisplayName("§4DELETE CONFLICT");//TODO MESSAGE + deleteMeta.setLore(Collections.singletonList("§cCaution with this button !"));//TODO MESSAGE deleteItem.setItemMeta(deleteMeta); this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); @@ -80,22 +80,24 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl // Displayed item will be updated later this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), event -> { event.setCancelled(true); + var type = CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()); EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui( - "§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + "§5", + MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS(), type, this, this); enchantGui.show(event.getWhoClicked()); }, CustomAnvil.instance); this.groupSettingItem = new GuiItem(new ItemStack(Material.PAPER), event -> { event.setCancelled(true); + var type = CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()); GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( - "§e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + " §3Groups", + MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS(), type, this, this, 0); enchantGui.show(event.getWhoClicked()); }, CustomAnvil.instance); this.minBeforeActiveSettingFactory = new IntSettingsGui.IntSettingFactory( - "§8Minimum enchantment count", + "§8Minimum enchantment count",//TODO MESSAGE this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER, Arrays.asList( "§7Minimum enchantment count set to X mean only X enchantment can be put", @@ -137,8 +139,9 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl return success; }; - return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + "§c?", - "§7Confirm that you want to delete this conflict.", + var type = CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()); + return new ConfirmActionGui(MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE(), type, + MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION(), type, this, this.parent, deleteSupplier ); } @@ -159,12 +162,12 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl // Prepare enchantment lore ArrayList enchantLore = new ArrayList<>(); - enchantLore.add("§7Allow you to select a list of §5Enchantments §7that this conflict should include"); + enchantLore.add("§7Allow you to select a list of §5Enchantments §7that this conflict should include");//TODO MESSAGE Set enchants = getSelectedEnchantments(); if (enchants.isEmpty()) { - enchantLore.add("§7There is no included enchantment for this conflict."); + enchantLore.add("§7There is no included enchantment for this conflict.");//TODO MESSAGE } else { - enchantLore.add("§7List of included enchantment for this conflict:"); + enchantLore.add("§7List of included enchantment for this conflict:");//TODO MESSAGE Iterator enchantIterator = enchants.iterator(); boolean greaterThanMax = enchants.size() > 5; @@ -175,7 +178,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl enchantLore.add("§7- §5" + formattedName); } if (greaterThanMax) { - enchantLore.add("§7And " + (enchants.size() - 4) + " more..."); + enchantLore.add("§7And " + (enchants.size() - 4) + " more...");//TODO MESSAGE } } @@ -188,7 +191,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl ItemMeta enchantMeta = enchantItem.getItemMeta(); assert enchantMeta != null; - enchantMeta.setDisplayName("§aSelect included §5Enchantments §aSettings"); + enchantMeta.setDisplayName("§aSelect included §5Enchantments §aSettings");//TODO MESSAGE enchantMeta.setLore(enchantLore); enchantItem.setItemMeta(enchantMeta); @@ -200,7 +203,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl ItemMeta groupMeta = groupItem.getItemMeta(); assert groupMeta != null; - groupMeta.setDisplayName("§aSelect Excluded §3Groups §aSettings"); + groupMeta.setDisplayName("§aSelect Excluded §3Groups §aSettings");//TODO MESSAGE groupMeta.setLore(groupLore); groupItem.setItemMeta(groupMeta); @@ -208,7 +211,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl this.groupSettingItem.setItem(groupItem); // Just in case this.pane.bindItem('M', this.minBeforeActiveSettingFactory.getItem(Material.COMMAND_BLOCK, - "Minimum Enchantment Count")); + "Minimum Enchantment Count"));//TODO MESSAGE update(); } @@ -246,7 +249,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl @Override public boolean setSelectedEnchantments(Set enchantments) { if (!this.shouldWork) { - CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict + " enchants but sub config is destroyed"); + CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict + " enchants but sub config is destroyed");//TODO MESSAGE return false; } @@ -264,7 +267,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl try { updateGuiValues(); } catch (Exception e) { - CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e); + CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e);//TODO MESSAGE MetricsUtil.INSTANCE.trackError(e); } @@ -291,7 +294,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl @Override public boolean setSelectedGroups(Set groups) { if (!this.shouldWork) { - CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.toString() + " groups but sub config is destroyed"); + CustomAnvil.instance.getLogger().info("Trying to save " + enchantConflict.toString() + " groups but sub config is destroyed");//TODO MESSAGE return false; } @@ -309,7 +312,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl try { updateGuiValues(); } catch (Exception e) { - CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e); + CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e);//TODO MESSAGE MetricsUtil.INSTANCE.trackError(e); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java index d26c33fe..be841d09 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java @@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil; import xyz.alexcrea.cuanvil.group.*; import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; import xyz.alexcrea.cuanvil.gui.config.SelectMaterialContainer; @@ -20,11 +21,11 @@ import xyz.alexcrea.cuanvil.gui.config.ask.ConfirmActionGui; import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; import xyz.alexcrea.cuanvil.gui.config.settings.GroupSelectSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.MaterialSelectSettingGui; -import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.*; import java.util.function.Consumer; @@ -40,8 +41,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen public GroupConfigSubSettingGui( @NotNull GroupConfigGui parent, @NotNull IncludeGroup group) { - super(3, - "§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " §rConfig"); + super(3, CasedStringUtil.snakeToUpperSpacedCase(group.getName())); this.parent = parent; this.group = group; @@ -66,38 +66,60 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA); ItemMeta deleteMeta = deleteItem.getItemMeta(); - deleteMeta.setDisplayName("§4DELETE GROUP"); - deleteMeta.setLore(Collections.singletonList("§cCaution with this button !")); + assert deleteMeta != null; + PlatformUtil.INSTANCE.setComponentDisplayName( + deleteMeta, + MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME().formattedConcatenated(), + null + ); + ComponentUtil.INSTANCE.applyLore( + MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE().formatted(), + deleteMeta + ); deleteItem.setItemMeta(deleteMeta); this.pane.bindItem('D', new GuiItem(deleteItem, openGuiAndCheckAction(), CustomAnvil.instance)); // Displayed item will be updated later - String materialSelectionName = "§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " §rMaterials"; + var materialSelectionName = MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS(); + var name = CasedStringUtil.snakeToUpperSpacedCase(group.getName()); + ItemStack selectItem = new ItemStack(Material.DIAMOND_SWORD); ItemMeta selectItemMeta = selectItem.getItemMeta(); - selectItemMeta.setDisplayName(materialSelectionName); + assert selectItemMeta != null; + + PlatformUtil.INSTANCE.setComponentDisplayName( + selectItemMeta, + materialSelectionName.formattedConcatenated(name), + null + ); selectItem.setItemMeta(selectItemMeta); this.materialSelection = new GuiItem(selectItem, (event) -> { event.setCancelled(true); MaterialSelectSettingGui selectGui = new MaterialSelectSettingGui(this, - materialSelectionName + materialSelectionName, name , this); selectGui.show(event.getWhoClicked()); }, CustomAnvil.instance); - String selectGroupName = "§e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.getName()) + " §rGroups"; + var selectGroupName = MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS(); ItemStack selectGroup = new ItemStack(Material.CHEST); ItemMeta selectGroupMeta = selectGroup.getItemMeta(); - selectGroupMeta.setDisplayName(selectGroupName); + assert selectGroupMeta != null; + + PlatformUtil.INSTANCE.setComponentDisplayName( + selectGroupMeta, + selectGroupName.formattedConcatenated(name), + null + ); selectGroup.setItemMeta(selectGroupMeta); this.groupSelection = new GuiItem(selectGroup, (event) -> { event.setCancelled(true); GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( - selectGroupName, + selectGroupName, name, this, this, 0); enchantGui.show(event.getWhoClicked()); }, CustomAnvil.instance); @@ -152,8 +174,9 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen return success; }; - return new ConfirmActionGui("§cDelete §e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.toString()) + "§c?", - "§7Confirm that you want to delete this group.", + var type = CasedStringUtil.snakeToUpperSpacedCase(this.group.toString()); + return new ConfirmActionGui(MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_TITLE(), type, + MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION(), type, this, this.parent, deleteSupplier ); } @@ -226,7 +249,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemStack matSelectItem = this.materialSelection.getItem(); ItemMeta matSelectMeta = matSelectItem.getItemMeta(); - matSelectMeta.setDisplayName("§aSelect included §eMaterials §aSettings"); + assert matSelectMeta != null; + matSelectMeta.setDisplayName("§aSelect included §eMaterials §aSettings");//TODO MESSAGE matSelectMeta.setLore(matLore); matSelectMeta.addItemFlags(ItemFlag.values()); @@ -238,7 +262,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemStack groupSelectItem = this.groupSelection.getItem(); ItemMeta groupSelectMeta = groupSelectItem.getItemMeta(); - groupSelectMeta.setDisplayName("§aSelect included §3Groups §aSettings"); + assert groupSelectMeta != null; + groupSelectMeta.setDisplayName("§aSelect included §3Groups §aSettings");//TODO MESSAGE groupSelectMeta.setLore(groupLore); groupSelectItem.setItemMeta(groupSelectMeta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java index 1d867812..935e8671 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java @@ -1,18 +1,18 @@ package xyz.alexcrea.cuanvil.gui.config.list.elements; -import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; +import xyz.alexcrea.cuanvil.lang.MsgUI; public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui { protected MappedToListSubSettingGui( int rows, - @NotNull String title) { - super(rows, title, CustomAnvil.instance); + @NotNull String type) { + super(rows, MsgUI.INSTANCE.getSHARED_TYPED_CONFIG_TITLE().textHolder(type), CustomAnvil.instance); } @Override diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java index 4473eb29..54251a61 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java @@ -20,6 +20,7 @@ import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.util.CasedStringUtil; import java.util.*; @@ -35,8 +36,10 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui(enchantContainer.getSelectedEnchantments()); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java index 578ca89e..2db12c20 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java @@ -19,6 +19,7 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; import xyz.alexcrea.cuanvil.gui.config.list.ElementListConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.util.CasedStringUtil; import java.util.Collections; @@ -34,8 +35,10 @@ public class GroupSelectSettingGui extends AbstractSettingGui { Set selectedGroups; - public GroupSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectGroupContainer groupContainer, int page) { - super(6, title, parent); + public GroupSelectSettingGui( + @NotNull Message title, @NotNull String param, + ValueUpdatableGui parent, SelectGroupContainer groupContainer, int page) { + super(6, title.textHolder(param), parent); this.groupContainer = groupContainer; //Not used but planned this.page = page; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java index 0f5759e0..102e1c9f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java @@ -18,6 +18,7 @@ import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil; @@ -38,9 +39,10 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui { removeMaterial(material); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index 5e9276d3..640ae297 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -1,5 +1,7 @@ package xyz.alexcrea.cuanvil.lang +import com.github.stefvanschie.inventoryframework.adventuresupport.ComponentHolder +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder import io.delilaheve.CustomAnvil import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender @@ -22,6 +24,7 @@ open class Message(val key: String, vararg val params: String) { for(i in 0 until min(params.size, values.size)) { val key = params[i] val replacement = values[i].toString() + if(replacement.isEmpty()) continue //May not be good but can be changed if cause an issue var current = 0 while(true) { @@ -77,9 +80,11 @@ open class Message(val key: String, vararg val params: String) { result.add(MiniMessageUtil.mm.deserialize(stb.toString())) } + if(result.isEmpty()) return listOf(Component.text(key)) return result } + // return a list of AT LEAST 1 element. calling first is safe fun formatted(vararg params: Any): List { val section = Lang.getSection(key) if(section != null) return formattedMultiline(section, *params) @@ -89,6 +94,21 @@ open class Message(val key: String, vararg val params: String) { return listOf(MiniMessageUtil.mm.deserialize(translated)) } + fun formattedConcatenated(vararg params: Any): Component { + val formated = formatted(*params) + + var result = formated.first() + for(i in 1 until formated.size) { + result = result.appendNewline().append(formated[i]) + } + + return result + } + + fun textHolder(vararg params: Any): TextHolder { + return ComponentHolder.of(formattedConcatenated(*params)) + } + fun legacy(vararg params: Any): String { val formated = formatted(*params) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt index c144f1fc..c11456be 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -5,6 +5,7 @@ import xyz.alexcrea.cuanvil.lang.UIMessage as Message object MsgUI { val SHARED_CONFIG_NO_EDIT_PERM = Message("shared.no-permission") + val SHARED_TYPED_CONFIG_TITLE = Message("shared.typed-config-title", "type") val CONFIRM_ACTION_FAILED = Message("confirm-action.fail") @@ -12,10 +13,44 @@ object MsgUI { val ELEMENT_LIST_CANCELLED_NEW = Message("element-list.cancelled-new", "type") val ELEMENT_LIST_DUPLICATED_NEW = Message("element-list.duplicated-new", "type") - val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element.title") - val UNIT_REPAIR_ELEMENT_DESCRIPTION = Message("unit-repair.element.description") - val UNIT_REPAIR_ELEMENT_CANNOT_REPAIR_NEW = Message("unit-repair.element.cannot-damage-new") - val UNIT_REPAIR_ELEMENT_SAME_TYPE_NEW = Message("unit-repair.element.same-type-new") + val UNIT_REPAIR_TITLE = Message("unit-repair.title") + val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element_title") + val UNIT_REPAIR_NEW_TITLE = Message("unit-repair.new.title") + val UNIT_REPAIR_NEW_DESCRIPTION = Message("unit-repair.new.description") + val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", "name") + val UNIT_REPAIR_NEW_ELEMENT_DESCRIPTION = Message("unit-repair.element.new.description", "name") + val UNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR = Message("unit-repair.element.new.cannot-damage") + val UNIT_REPAIR_NEW_ELEMENT_SAME_TYPE = Message("unit-repair.element.new.same-type") + + val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title") + + val CUSTOM_RECIPE_ELEMENT_DELETE_TITLE = Message("custom-recipe.element.delete.title", "type") + val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", "type") + + val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title") + + val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title") + + val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title") + + val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title") + val ENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS = Message("enchant-conflict.element.selected-enchantments", "group") + val ENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS = Message("enchant-conflict.element.selected-sub-groups", "group") + + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE = Message("enchant-conflict.element.delete.title", "type") + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", "type") + + val MATERIAL_GROUP_TITLE = Message("material-group.title") + val MATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS = Message("material-group.element.selected-materials", "group") + val MATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS = Message("material-group.element.selected-sub-groups", "group") + + val MATERIAL_GROUP_ELEMENT_DELETE_TITLE = Message("material-group.element.delete.title", "type") + val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", "type") + val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME = Message("material-group.element.delete.button.name") + val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE = Message("material-group.element.delete.button.lore") + + val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.confirm.title","name") + val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.confirm.description","name") } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt index 2d9ec351..76bc7287 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -2,10 +2,28 @@ package xyz.alexcrea.cuanvil.util import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender +import org.bukkit.inventory.meta.ItemMeta import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setPaperLore object ComponentUtil { + fun Component.serializeMM(): String { + return MiniMessageUtil.mm.serialize(this) + } + + fun Component.serializeMMColor(): String { + return MiniMessageUtil.color_only_mm.serialize(this) + } + + fun Component.serializeLegacy(): String { + return MiniMessageUtil.legacy_mm.serialize(this) + } + + fun Component.serializePlain(): String { + return MiniMessageUtil.plain_text_mm.serialize(this) + } + fun Component.send(destination: CommandSender) { if(!destination.sendPaperMessage(this)) destination.sendMessage(this.serializeLegacy()) @@ -16,18 +34,9 @@ object ComponentUtil { component.send(destination) } - fun Component.serializeMM(): String { - return MiniMessageUtil.mm.serialize(this) + fun List.applyLore(meta: ItemMeta) { + if(!meta.setPaperLore(this)) + meta.lore = this.map {obj -> obj.serializeLegacy()} } - fun Component.serializeMMColor(): String { - return MiniMessageUtil.color_only_mm.serialize(this) - } - fun Component.serializeLegacy(): String { - return MiniMessageUtil.legacy_mm.serialize(this) - } - fun Component.serializePlain(): String { - return MiniMessageUtil.plain_text_mm.serialize(this) - } - } \ No newline at end of file diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 75483d16..c6d043a9 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -24,6 +24,7 @@ error: listeners: "error registering listeners" enchant-system: "error initializing enchantment system" non-default-config: "Plugin has an issue while trying to load non default config... exiting..." + reload: resource: fail: "Resource %path Could not be loaded or reloaded." @@ -37,11 +38,13 @@ command: no-permission: "No permission to execute this command" warning: missing-subcmd: "Need to specify a subcommand. for example %example1 or %example2" + root: warning: unknown-sub: "Invalid subcommand. run `%command help` to see available commands" error: generic: "Error running this command" + debug: description: "Used to toggle debug logs and retrieve them" log-cleared: "Log Cleared" @@ -54,10 +57,12 @@ command: unspecified-type: "Need to specify which type of debug to toggle: \"default\" or \"verbose\"" invalid-type: "Invalid debug type \"%type\"" no-log: "No log to show ? make sure you tried with debug log toggled (%command)" + diagnostic: description: "Basic diagnostic of this plugin" had-error: "There was an error running the diagnostic" copy: "Click to copy diagnostic data" + config: description: "Used to edit the configuration of the plugin" folia-issue: @@ -72,6 +77,7 @@ command: warning: legacy-name: "/ca gui has been moved to /ca config" cannot_configure: "Cannot configure the item in hand" + enchant: description: "Allows to set enchantment to holden item" warning: @@ -81,9 +87,11 @@ command: cannot_enchant: "Cannot enchant this item" removed: "%name removed" set: "%name set to level %level" + help: description: "Help command" header: "List of available commands:" + reload: description: "Reload the configuration of this plugin" start: "Reloading config..." @@ -94,19 +102,74 @@ command: config-ui: shared: no-permission: "You do not have permission to edit the config" + typed-config-title: "%type Config" + confirm-action: fail: "Action could not be completed." + element-list: instruction-new: 1: "Write the %type name you want to create in the chat." 2: "Or write cancel to go back to %type config menu" cancelled-new: "%type creation cancelled..." duplicated-new: "Please enter a %type name that do not already exist..." + unit-repair: - element: - title: "Select item to be repaired." + tile: "Unit Repair Config" + new: + title: "Select unit repair item." description: 1: "Click here with an item to set the item" - 2: "You like to be repaired by %name" - cannot-damage-new: "This item can't be damaged, so it can't be repaired." - same-type-new: "Item can't repair something of the same type." \ No newline at end of file + 2: "You like to be an unit repair item" + element: + title: "%type Unit repair" + new: + title: "Select item to be repaired." + description: + 1: "Click here with an item to set the item" + 2: "You like to be repaired by %name" + cannot-damage: "This item can't be damaged, so it can't be repaired." + same-type: "Item can't repair something of the same type." + + custom-recipe: + title: "Custom Recipe Config" + element: + delete: + title: "Delete %type?" + description: "Confirm that you want to delete this recipe." + + enchant-level-cost: + title: "Enchantment Level Limit" + + enchant-level-limit: + title: "Enchantment Level Limit" + + enchant-merge-limit: + title: "Enchantment Maximum Merge Level" + + enchant-conflict: + title: "Conflict Config" + element: + selected-enchantments: "%group" # likely need page and max page + selected-sub-groups: "%group Groups" + delete: + title: "Delete %type?" + description: "Confirm that you want to delete this conflict." + + material-group: + title: "Group Config" + element: + selected-materials: "%group Materials" + selected-sub-groups: "%group Groups" + delete: + title: "Delete %type?" + description: "Confirm that you want to delete this group." + button: + name: "DELETE GROUP" + lore: "Caution with this button !" + + material-select: + new: + confirm: + title: "Remove %name" + description: "Confirm Remove %name from this list." From e4dd8062677f136fffa129786226ab36bf438239 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 17 Aug 2026 02:12:10 +0200 Subject: [PATCH 09/13] ask gui translatable --- .../gui/config/ask/ConfirmActionGui.java | 11 +++++----- .../gui/config/ask/SelectItemTypeGui.java | 5 ++--- .../elements/GroupConfigSubSettingGui.java | 21 ++++-------------- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 2 +- .../alexcrea/cuanvil/anvil/AnvilMergeLogic.kt | 2 -- .../cuanvil/command/ReloadExecutor.kt | 2 +- .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 22 ++++++++++++++++--- .../xyz/alexcrea/cuanvil/lang/MsgError.kt | 9 +++++--- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 3 +++ .../cuanvil/listener/AnvilResultListener.kt | 1 - .../alexcrea/cuanvil/util/ComponentUtil.kt | 6 +++++ src/main/resources/lang/en.yml | 7 ++++++ 12 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java index e3b02a12..b570e1d5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java @@ -13,12 +13,11 @@ import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgError; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.ComponentUtil; -import xyz.alexcrea.cuanvil.util.MetricsUtil; import java.awt.*; -import java.util.Arrays; import java.util.function.Supplier; import java.util.logging.Level; @@ -47,8 +46,7 @@ public class ConfirmActionGui extends AbstractAskGui { try { success = onConfirm.get(); } catch (Exception e) { - CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e); //TODO MESSAGE - MetricsUtil.INSTANCE.trackError(e); + CustomAnvil.Companion.logError(MsgError.INSTANCE.getCONFIRM_ACTION_GENERIC().unformatted(), e, true, Level.WARNING); success = false; } @@ -62,10 +60,11 @@ public class ConfirmActionGui extends AbstractAskGui { // Info item ItemStack infoItem = new ItemStack(Material.PAPER); ItemMeta infoMeta = infoItem.getItemMeta(); + assert infoMeta != null; - infoMeta.setDisplayName("§eAre you sure ?"); //TODO MESSAGE + ComponentUtil.INSTANCE.setMessageName(infoMeta, MsgUI.INSTANCE.getCONFIRM_ACTION_ARE_YOU_SURE()); if(actionDescription != null){ - ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(), infoMeta); + ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(actionParam), infoMeta); } infoItem.setItemMeta(infoMeta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index b4b10b6f..fc96c282 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -9,7 +9,6 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; -import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.lang.Message; @@ -17,7 +16,6 @@ import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.ComponentUtil; import xyz.alexcrea.cuanvil.util.MaterialUtil; -import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; @@ -89,8 +87,9 @@ public class SelectItemTypeGui extends AbstractAskGui { @NotNull String param ){ ItemMeta meta = item.getItemMeta(); + assert meta != null; - meta.setDisplayName("§ePlace an item here"); //TODO MESSAGE + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getSELECT_ITEM_TYPE_PLACE_HERE()); ComponentUtil.INSTANCE.applyLore(actionDescription.formatted(param), meta); item.setItemMeta(meta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java index be841d09..045fdcbe 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java @@ -13,7 +13,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; -import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil; import xyz.alexcrea.cuanvil.group.*; import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; import xyz.alexcrea.cuanvil.gui.config.SelectMaterialContainer; @@ -65,13 +64,9 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen // Delete item ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA); ItemMeta deleteMeta = deleteItem.getItemMeta(); - assert deleteMeta != null; - PlatformUtil.INSTANCE.setComponentDisplayName( - deleteMeta, - MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME().formattedConcatenated(), - null - ); + + ComponentUtil.INSTANCE.setMessageName(deleteMeta, MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME()); ComponentUtil.INSTANCE.applyLore( MsgUI.INSTANCE.getMATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE().formatted(), deleteMeta @@ -88,11 +83,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemMeta selectItemMeta = selectItem.getItemMeta(); assert selectItemMeta != null; - PlatformUtil.INSTANCE.setComponentDisplayName( - selectItemMeta, - materialSelectionName.formattedConcatenated(name), - null - ); + ComponentUtil.INSTANCE.setMessageName(selectItemMeta, materialSelectionName); selectItem.setItemMeta(selectItemMeta); this.materialSelection = new GuiItem(selectItem, (event) -> { @@ -109,11 +100,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemMeta selectGroupMeta = selectGroup.getItemMeta(); assert selectGroupMeta != null; - PlatformUtil.INSTANCE.setComponentDisplayName( - selectGroupMeta, - selectGroupName.formattedConcatenated(name), - null - ); + ComponentUtil.INSTANCE.setMessageName(selectGroupMeta, selectGroupName); selectGroup.setItemMeta(selectGroupMeta); this.groupSelection = new GuiItem(selectGroup, (event) -> { diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 7ff46191..d9dfa0a4 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -161,7 +161,7 @@ open class CustomAnvil : JavaPlugin() { // Load language try { - Lang.reload() + Lang.loadDefault() } catch (e: Exception) { logError("error occurred loading language file", e) if(tryDirtyStart()) return diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index 7d1b745c..8503fc74 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -23,10 +23,8 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.CasedStringUtil import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy -import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir -import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index f5b92b62..9b0bae17 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -62,7 +62,7 @@ class ReloadExecutor : CASubCommand { if(!ConfigHolder.reloadAllFromDisk(hardfail)) return false // reload language config - Lang.reload() + if(!Lang.reload()) return false // Then update all global gui containing value from config BasicConfigGui.getInstance()?.updateGuiValues() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt index 18be75f6..f164b9af 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt @@ -6,10 +6,26 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder object Lang { - private val default = Language(DEFAULT_LANG, false) - private var lang = default + private lateinit var default: Language + private lateinit var lang: Language - fun reload() { + fun loadDefault() { + default = Language(DEFAULT_LANG, false) + lang = default + reload() + } + + fun reload(): Boolean { + try { + unsafeReload() + return true + } catch(e: Exception) { + CustomAnvil.logError("Error loading language $langID", e, false) + return false + } + } + + private fun unsafeReload() { val langID = langID if(lang.name == langID && lang != default) lang.reload() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt index 6e5e26fb..f0b32e26 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt @@ -19,8 +19,11 @@ object MsgError { val RELOAD_HARD_FAIL = ErrorMessage("reload.resource.hardfail") /* - * ---------- - * Commands - * ---------- + * ---- + * UI + * ---- */ + val CONFIRM_ACTION_GENERIC = ErrorMessage("confirm-action.generic") + + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt index c11456be..6036069e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -8,6 +8,9 @@ object MsgUI { val SHARED_TYPED_CONFIG_TITLE = Message("shared.typed-config-title", "type") val CONFIRM_ACTION_FAILED = Message("confirm-action.fail") + val CONFIRM_ACTION_ARE_YOU_SURE = Message("confirm-action.is-user-sure") + + val SELECT_ITEM_TYPE_PLACE_HERE = Message("select-item-type.place-here") val ELEMENT_LIST_INSTRUCTION_NEW = Message("element-list.instruction-new", "type") val ELEMENT_LIST_CANCELLED_NEW = Message("element-list.cancelled-new", "type") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 29a8d72c..21b4bffc 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -33,7 +33,6 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir -import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt index 76bc7287..bd8014a6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -4,7 +4,9 @@ import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender import org.bukkit.inventory.meta.ItemMeta import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.sendPaperMessage +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setPaperLore +import xyz.alexcrea.cuanvil.lang.Message object ComponentUtil { @@ -39,4 +41,8 @@ object ComponentUtil { meta.lore = this.map {obj -> obj.serializeLegacy()} } + fun ItemMeta.setMessageName(message: Message) { + this.setComponentDisplayName(message.formattedConcatenated()) + } + } \ No newline at end of file diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index c6d043a9..26d7efbc 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -30,6 +30,9 @@ error: fail: "Resource %path Could not be loaded or reloaded." hard-fail: "Disabling plugin." + confirm-action: + generic: "Could not process confirmation supplier." + command: shared: no-diag-permission: "You do not have permission to diagnostic this server" @@ -106,6 +109,10 @@ config-ui: confirm-action: fail: "Action could not be completed." + is-user-sure: "Are you sure ?" + + select-item-type: + place-here: "Place an item here" element-list: instruction-new: From 85236076576c783c9b84fc60ed8e20090584a2b1 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 17 Aug 2026 13:54:41 +0200 Subject: [PATCH 10/13] add lang debug command and fix found translation issue --- .../elements/GroupConfigSubSettingGui.java | 4 +- .../cuanvil/command/DebugToggleExecutor.kt | 141 +++++++++++++++++- .../cuanvil/dependency/DependencyManager.kt | 4 +- .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 13 ++ .../xyz/alexcrea/cuanvil/lang/Language.kt | 39 +++++ .../xyz/alexcrea/cuanvil/lang/Message.kt | 15 +- .../kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt | 4 - .../xyz/alexcrea/cuanvil/lang/MsgCommand.kt | 5 +- .../xyz/alexcrea/cuanvil/lang/MsgError.kt | 2 +- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 28 ++-- .../xyz/alexcrea/cuanvil/lang/MsgWarning.kt | 2 +- .../alexcrea/cuanvil/util/ComponentUtil.kt | 4 +- src/main/resources/lang/en.yml | 19 ++- 13 files changed, 240 insertions(+), 40 deletions(-) delete mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java index 045fdcbe..ec8f8617 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java @@ -83,7 +83,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemMeta selectItemMeta = selectItem.getItemMeta(); assert selectItemMeta != null; - ComponentUtil.INSTANCE.setMessageName(selectItemMeta, materialSelectionName); + ComponentUtil.INSTANCE.setMessageName(selectItemMeta, materialSelectionName, name); selectItem.setItemMeta(selectItemMeta); this.materialSelection = new GuiItem(selectItem, (event) -> { @@ -100,7 +100,7 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen ItemMeta selectGroupMeta = selectGroup.getItemMeta(); assert selectGroupMeta != null; - ComponentUtil.INSTANCE.setMessageName(selectGroupMeta, selectGroupName); + ComponentUtil.INSTANCE.setMessageName(selectGroupMeta, selectGroupName, name); selectGroup.setItemMeta(selectGroupMeta); this.groupSelection = new GuiItem(selectGroup, (event) -> { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index 5c7bfee6..d42c8d22 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -9,11 +9,16 @@ import net.md_5.bungee.api.chat.hover.content.Text import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.Player +import xyz.alexcrea.cuanvil.lang.Lang import xyz.alexcrea.cuanvil.lang.Message import xyz.alexcrea.cuanvil.lang.MsgCommand +import xyz.alexcrea.cuanvil.lang.MsgError +import xyz.alexcrea.cuanvil.lang.MsgUI +import xyz.alexcrea.cuanvil.lang.MsgWarning import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain +import java.util.Locale -class DebugToggleExecutor : CASubCommand { +class DebugToggleExecutor: CASubCommand { override fun description(): Message { return MsgCommand.DEBUG_DESCRIPTION @@ -51,6 +56,10 @@ class DebugToggleExecutor : CASubCommand { MsgCommand.DEBUG_LOG_CLEARED.send(sender) } + "lang" -> { + executeLanguageDebug(sender, args) + } + else -> { MsgCommand.SHARED_UNKNOWN_SUB_COMMAND.send(sender) return false @@ -106,14 +115,142 @@ class DebugToggleExecutor : CASubCommand { } } + private fun executeLanguageDebug(sender: CommandSender, args: Array) { + if(args.size > 1 && "details".contentEquals(args[1], ignoreCase = true)) + detailedLangDebug(sender) + else + simpleLangDebug(sender) + + } + + private fun simpleLangDebug(sender: CommandSender) { + var validCount = 0 + // load key from all provider class + MsgCommand.DEBUG_DATA_HEADER + MsgUI.SHARED_CONFIG_NO_EDIT_PERM + MsgError.LOAD_LISTENERS + MsgWarning.ANVIL_GENERIC_EXCEPTION + + val registeredKeys = Message.getValues() + + for(message in registeredKeys) + if(Lang.has(message.key)) validCount++ + + val valid = (100.0 * validCount) / registeredKeys.size + sender.sendMessage("Translated (${Lang.currentLang()}): ${"%.1f".format(Locale.ROOT, valid)}% ($validCount/${registeredKeys.size})") + } + + private fun detailedLangDebug(sender: CommandSender) { + simpleLangDebug(sender) + + val stb = StringBuilder("Report of potential issue for language ${Lang.currentLang()}:\n") + + var hadAny = false + val keySet = mutableSetOf() + val registeredKeys = Message.getValues() + + for(message in registeredKeys) { + val key = message.key + if(!Lang.has(key)) { + stb.append("Missing key inside translation file: $key\n") + hadAny = true + } else if(hashParamIssue(message, stb)) + hadAny = true + + if(keySet.contains(key)) { + stb.append("Duplicate registered key: $key\n") + hadAny = true + } else keySet.add(key) + } + + for(key in Lang.getKeys()) { + if(!keySet.contains(key)) { + stb.append("Found unregistered key: $key\n") + hadAny = true + } + } + + if(hadAny) { + val message = TextComponent(MsgCommand.DEBUG_LANG_COPY.legacy()) + + message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) + message.hoverEvent = HoverEvent( + HoverEvent.Action.SHOW_TEXT, + Text(MsgCommand.SHARED_HOVER_COPY.legacy()) + ) + + sender.spigot().sendMessage(message); + } else { + sender.sendMessage("No additional issue found") + } + } + + private fun hashParamIssue(message: Message, stb: StringBuilder): Boolean { + val section = Lang.getSection(message.key) + val texts = if(section == null) + listOf(Lang.getTranslated(message.key)) + else + section.getValues(false).map { it.value.toString() } + + val textParams = ArrayList() + + for(text in texts) { + var index = 0 + while(true) { + index = text.indexOf('%', index) + //TODO add \% to "ignore" % as param inside param finder + if(index > 0 && text[index-1] == '\\') { + index++ + continue + } + if(index++ < 0) break + + var end = text.indexOf(' ', index) + if(end == -1) end = text.length + val param = text.substring(index, end) + if(!textParams.contains(param)) textParams.add(param) + } + } + + var hadIssue = false + // Check all parameter are valid + val usedParam = mutableSetOf() + for(textParam in textParams) { + var found = false + for(param in message.params) { + if(param.isEmpty()) continue + if(textParam.startsWith(param)) { + found = true + usedParam.add(param) + break + } + } + + if(!found) { + hadIssue = true + stb.append("Did not found param %$textParam in register list for ${message.key}\n") + } + } + + for(param in message.params) { + if(usedParam.contains(param)) continue + if("unused".contentEquals(param)) continue + hadIssue = true + stb.append("Param %$param is not used for key ${message.key}\n") + } + + return hadIssue + } + override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { if(!allowed(sender)) return list.addAll( when(args.size) { - 1 -> listOf("toggle", "get", "get-and-clear", "clear") + 1 -> listOf("toggle", "get", "get-and-clear", "clear", "lang") 2 -> when(args[0].lowercase()) { "toggle" -> listOf("default", "verbose") + "lang" -> listOf("details") else -> listOf() } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index e12aed14..8c22d880 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -3,7 +3,6 @@ package xyz.alexcrea.cuanvil.dependency import io.delilaheve.CustomAnvil import net.kyori.adventure.text.Component import org.bukkit.Bukkit -import org.bukkit.ChatColor import org.bukkit.command.CommandSender import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player @@ -32,7 +31,6 @@ import xyz.alexcrea.cuanvil.lang.MsgWarning import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import java.lang.IllegalStateException -import java.util.logging.Level @Suppress("UnstableApiUsage") object DependencyManager { @@ -166,7 +164,7 @@ object DependencyManager { trackError(e) // Finally, warn the player - MsgWarning.DEPENDENCY_GENERIC_EXCEPTION.send(target) + MsgWarning.ANVIL_GENERIC_EXCEPTION.send(target) } private fun logExceptionAndClear(view: AnvilView, e: Exception) { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt index f164b9af..b559af19 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt @@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.lang import io.delilaheve.CustomAnvil import org.bukkit.configuration.ConfigurationSection import xyz.alexcrea.cuanvil.config.ConfigHolder +import java.util.stream.Stream object Lang { @@ -51,6 +52,18 @@ object Lang { return default.getSection(key) } + fun currentLang(): String { + return lang.name + } + + fun has(key: String): Boolean { + return lang.has(key) + } + + fun getKeys(): Collection { + return lang.getFilteredKeys() + } + /* * Config Options & get */ diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt index 0a008bf0..88b36b99 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Language.kt @@ -55,6 +55,45 @@ class Language(private val id: String, private val default: Boolean = false) { return conf.getConfigurationSection(key) } + fun has(key: String): Boolean { + if(conf.isString(key)) return true + + // we want at all child key as valid numbers and valid key if claimed to be multi line + val section = getSection(key) ?: return false + for(key in section.getKeys(false)) { + if(key.toUIntOrNull() == null) return false + if(!section.isString(key)) return false + } + + return true + } + + fun getFilteredKeys(): Collection { + val result = ArrayList() + + // First pass we ignore key from root + for(root in conf.getKeys(false)) { + val section = conf.getConfigurationSection(root) ?: continue + + exploreDeeper(section, root, result) + } + + return result + } + + private fun exploreDeeper(section: ConfigurationSection, root: String, result: ArrayList) { + for(key in section.getKeys(false)) { + val newRoot = "$root.$key" + if(has(key)) { + result.add(newRoot) + continue + } + + val newSection = section.getConfigurationSection(key) ?: continue + exploreDeeper(newSection, newRoot, result) + } + } + val name: String get() = conf.getString("name", id)!! } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index 640ae297..64d9242d 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -10,10 +10,23 @@ import xyz.alexcrea.cuanvil.util.ComponentUtil.send import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.MiniMessageUtil +import java.util.Collections import java.util.logging.Level import kotlin.math.min -open class Message(val key: String, vararg val params: String) { +open class Message(val key: String, vararg val params: String, register: Boolean = true) { + + companion object { + private val values = ArrayList() + + fun getValues(): Collection { + return Collections.unmodifiableCollection(values) + } + } + + init { + if(register) values.add(this) + } protected fun replaceParameters(stb: StringBuilder, vararg values: Any) { // replace all placeholder thingy %key -> value diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt deleted file mode 100644 index 7823f79d..00000000 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Msg.kt +++ /dev/null @@ -1,4 +0,0 @@ -package xyz.alexcrea.cuanvil.lang - -object Msg { -} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt index 2eed326b..d135634e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgCommand.kt @@ -20,6 +20,7 @@ object MsgCommand { val DEBUG_LOG_CLEARED = Message("debug.log-cleared") val DEBUG_TOGGLED = Message("debug.toggled", "type") val DEBUG_COPY = Message("debug.copy") + val DEBUG_LANG_COPY = Message("debug.copy-lang") val DEBUG_DATA_HEADER = Message("debug.data.header") val DEBUG_DATA_LINE_COUNT = Message("debug.data.line-count", "count") @@ -45,8 +46,8 @@ object MsgCommand { // Enchant val ENCHANT_DESCRIPTION = Message("enchant.description") - val ENCHANT_REMOVE = Message("enchant.remove.", "name") - val ENCHANT_SET = Message("enchant.set.", "name", "level") + val ENCHANT_REMOVE = Message("enchant.removed", "name") + val ENCHANT_SET = Message("enchant.set", "name", "level") val ENCHANT_MISSING_PARAMETER_WARNING = Message("enchant.warning.missing_parameter") val ENCHANT_NOT_FOUND_WARNING = Message("enchant.warning.not_found", "path") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt index f0b32e26..f5d6e826 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgError.kt @@ -16,7 +16,7 @@ object MsgError { val LOAD_NON_DEFAULT_CONFIG = ErrorMessage("load.non-default-config") val RELOAD_FAIL = ErrorMessage("reload.resource.fail", "path") - val RELOAD_HARD_FAIL = ErrorMessage("reload.resource.hardfail") + val RELOAD_HARD_FAIL = ErrorMessage("reload.resource.hard-fail") /* * ---- diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt index 6036069e..1a876e6e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -16,44 +16,44 @@ object MsgUI { val ELEMENT_LIST_CANCELLED_NEW = Message("element-list.cancelled-new", "type") val ELEMENT_LIST_DUPLICATED_NEW = Message("element-list.duplicated-new", "type") - val UNIT_REPAIR_TITLE = Message("unit-repair.title") - val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element_title") + val UNIT_REPAIR_TITLE = Message("unit-repair.title", "unused", "page", "max_page") + val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element.title", "type", "page", "max_page") val UNIT_REPAIR_NEW_TITLE = Message("unit-repair.new.title") val UNIT_REPAIR_NEW_DESCRIPTION = Message("unit-repair.new.description") - val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", "name") + val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", "unused") val UNIT_REPAIR_NEW_ELEMENT_DESCRIPTION = Message("unit-repair.element.new.description", "name") val UNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR = Message("unit-repair.element.new.cannot-damage") val UNIT_REPAIR_NEW_ELEMENT_SAME_TYPE = Message("unit-repair.element.new.same-type") - val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title") + val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title", "unused", "page", "max_page") val CUSTOM_RECIPE_ELEMENT_DELETE_TITLE = Message("custom-recipe.element.delete.title", "type") - val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", "type") + val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", "unused") - val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title") + val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title", "unused", "page", "max_page") - val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title") + val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title", "unused", "page", "max_page") - val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title") + val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title", "unused", "page", "max_page") - val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title") + val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title", "unused", "page", "max_page") val ENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS = Message("enchant-conflict.element.selected-enchantments", "group") val ENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS = Message("enchant-conflict.element.selected-sub-groups", "group") val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE = Message("enchant-conflict.element.delete.title", "type") - val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", "type") + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", "unused") - val MATERIAL_GROUP_TITLE = Message("material-group.title") + val MATERIAL_GROUP_TITLE = Message("material-group.title", "unused", "page", "max_page") val MATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS = Message("material-group.element.selected-materials", "group") val MATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS = Message("material-group.element.selected-sub-groups", "group") val MATERIAL_GROUP_ELEMENT_DELETE_TITLE = Message("material-group.element.delete.title", "type") - val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", "type") + val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", "unused") val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME = Message("material-group.element.delete.button.name") val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE = Message("material-group.element.delete.button.lore") - val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.confirm.title","name") - val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.confirm.description","name") + val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.new.confirm.title","name") + val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.new.confirm.description","name") } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt index 486f589d..fb9d6e64 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgWarning.kt @@ -15,6 +15,6 @@ object MsgWarning { val LOAD_LEGACY_SPIGOT = Message("load.legacy.spigot") val LOAD_LEGACY_SPIGOT_OLD = Message("load.legacy.spigot-old") - val DEPENDENCY_GENERIC_EXCEPTION = Message("config-ui.shared.no-permission") + val ANVIL_GENERIC_EXCEPTION = Message("anvil.generic") } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt index bd8014a6..261e085a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -41,8 +41,8 @@ object ComponentUtil { meta.lore = this.map {obj -> obj.serializeLegacy()} } - fun ItemMeta.setMessageName(message: Message) { - this.setComponentDisplayName(message.formattedConcatenated()) + fun ItemMeta.setMessageName(message: Message, vararg params: Any) { + this.setComponentDisplayName(message.formattedConcatenated(*params)) } } \ No newline at end of file diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 26d7efbc..87527ea1 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -14,6 +14,8 @@ warning: 1: "If replace too expensive is not working this is likely because of spigot" 2: "As native nms is not supported for spigot starting 26.1" update.available: "An update may be available: %version" + anvil: + generic: "[CustomAnvil] Error while handling the anvil." error: load: @@ -53,6 +55,7 @@ command: log-cleared: "Log Cleared" toggled: "Debug toggled to %type" copy: "Click to copy log data" + copy-lang: "Click to copy detailed lang issues" data: header: "Debug Log data:" line-count: "Found %count lines" @@ -122,14 +125,14 @@ config-ui: duplicated-new: "Please enter a %type name that do not already exist..." unit-repair: - tile: "Unit Repair Config" + title: "Unit Repair Config (%page/%max_page)" new: title: "Select unit repair item." description: 1: "Click here with an item to set the item" 2: "You like to be an unit repair item" element: - title: "%type Unit repair" + title: "%type Unit repair (%page/%max_page)" new: title: "Select item to be repaired." description: @@ -139,23 +142,23 @@ config-ui: same-type: "Item can't repair something of the same type." custom-recipe: - title: "Custom Recipe Config" + title: "Custom Recipe Config (%page/%max_page)" element: delete: title: "Delete %type?" description: "Confirm that you want to delete this recipe." enchant-level-cost: - title: "Enchantment Level Limit" + title: "Enchantment Level Limit (%page/%max_page)" enchant-level-limit: - title: "Enchantment Level Limit" + title: "Enchantment Level Limit (%page/%max_page)" enchant-merge-limit: - title: "Enchantment Maximum Merge Level" + title: "Enchantment Maximum Merge Level (%page/%max_page)" enchant-conflict: - title: "Conflict Config" + title: "Conflict Config (%page/%max_page)" element: selected-enchantments: "%group" # likely need page and max page selected-sub-groups: "%group Groups" @@ -164,7 +167,7 @@ config-ui: description: "Confirm that you want to delete this conflict." material-group: - title: "Group Config" + title: "Group Config (%page/%max_page)" element: selected-materials: "%group Materials" selected-sub-groups: "%group Groups" From 185a5bc8a2f8642903361d04064e43bb1c33a73e Mon Sep 17 00:00:00 2001 From: alexcrea Date: Wed, 19 Aug 2026 15:03:26 +0200 Subject: [PATCH 11/13] more ui translations --- .../gui/config/ask/AbstractAskGui.java | 9 +- .../gui/config/ask/ConfirmActionGui.java | 18 +- .../gui/config/ask/SelectItemTypeGui.java | 9 +- .../global/AbstractEnchantConfigGui.java | 13 +- .../gui/config/global/BasicConfigGui.java | 195 +++++++------- .../config/global/CustomRecipeConfigGui.java | 2 +- .../config/global/EnchantCostConfigGui.java | 33 +-- .../config/global/EnchantLimitConfigGui.java | 11 +- .../global/EnchantMergeLimitConfigGui.java | 19 +- .../config/list/UnitRepairElementListGui.java | 42 +-- .../elements/CustomRecipeSubSettingGui.java | 58 ++-- .../EnchantConflictSubSettingGui.java | 18 +- .../config/settings/AbstractSettingGui.java | 7 +- .../gui/config/settings/BoolSettingsGui.java | 64 +++-- .../gui/config/settings/DoubleSettingGui.java | 63 +++-- .../settings/EnchantCostSettingsGui.java | 24 +- .../gui/config/settings/EnumSettingGui.java | 7 +- .../gui/config/settings/IntSettingsGui.java | 80 +++--- .../gui/config/settings/ItemSettingGui.java | 18 +- .../settings/WorkPenaltyTypeSettingGui.java | 89 ++++--- .../cuanvil/gui/util/GuiGlobalItems.java | 37 ++- .../cuanvil/command/DebugToggleExecutor.kt | 38 ++- .../cuanvil/command/DiagnosticExecutor.kt | 4 +- .../xyz/alexcrea/cuanvil/lang/Message.kt | 84 ++++-- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 137 ++++++++-- .../alexcrea/cuanvil/util/ComponentUtil.kt | 21 +- src/main/resources/lang/en.yml | 252 ++++++++++++++++-- 27 files changed, 910 insertions(+), 442 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java index 75cdf236..d7913020 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/AbstractAskGui.java @@ -15,9 +15,12 @@ import xyz.alexcrea.cuanvil.lang.Message; public abstract class AbstractAskGui extends ChestGui { protected PatternPane pane; - AbstractAskGui(int rows, - @NotNull Message name, @NotNull String param, - Gui backOnCancel){ + + AbstractAskGui( + int rows, + @NotNull Message name, @NotNull String param, + Gui backOnCancel + ) { super(rows, name.textHolder(param), CustomAnvil.instance); Pattern pattern = getGuiPattern(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java index b570e1d5..d98cc399 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java @@ -23,10 +23,12 @@ import java.util.logging.Level; public class ConfirmActionGui extends AbstractAskGui { - public ConfirmActionGui(@NotNull Message title, @NotNull String titleParam, - @Nullable Message actionDescription, @NotNull String actionParam, - Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm, - boolean permanent) { + public ConfirmActionGui( + @NotNull Message title, @NotNull String titleParam, + @Nullable Message actionDescription, @NotNull String actionParam, + Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm, + boolean permanent + ) { super(3, title, titleParam, backOnCancel); // Save item @@ -71,9 +73,11 @@ public class ConfirmActionGui extends AbstractAskGui { pane.bindItem('I', new GuiItem(infoItem, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); } - public ConfirmActionGui(@NotNull Message title, @NotNull String titleParam, - @Nullable Message actionDescription, @NotNull String actionParam, - Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm){ + public ConfirmActionGui( + @NotNull Message title, @NotNull String titleParam, + @Nullable Message actionDescription, @NotNull String actionParam, + Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm + ){ this(title, titleParam, actionDescription, actionParam, backOnCancel, backOnConfirm, onConfirm, true); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index fc96c282..c3f52388 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -22,6 +22,7 @@ import java.util.function.BiConsumer; public class SelectItemTypeGui extends AbstractAskGui { private ItemStack selectedItem; + public SelectItemTypeGui(@NotNull Message title, @NotNull String titleParam, @NotNull Message actionDescription, @@ -37,7 +38,7 @@ public class SelectItemTypeGui extends AbstractAskGui { event.setCancelled(true); HumanEntity player = event.getWhoClicked(); - if (!player.hasPermission(CustomAnvil.editConfigPermission)) { + if(!player.hasPermission(CustomAnvil.editConfigPermission)) { player.closeInventory(); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player); return; @@ -59,9 +60,9 @@ public class SelectItemTypeGui extends AbstractAskGui { if(MaterialUtil.INSTANCE.isAir(cursor)) return; ItemStack finalItem; - if(materialOnly){ + if(materialOnly) { finalItem = setDisplayMeta(new ItemStack(cursor.getType()), actionDescription, descriptionParam); - }else{ + } else { finalItem = cursor.clone(); } this.selectedItem = finalItem.clone(); @@ -85,7 +86,7 @@ public class SelectItemTypeGui extends AbstractAskGui { @NotNull ItemStack item, @NotNull Message actionDescription, @NotNull String param - ){ + ) { ItemMeta meta = item.getItemMeta(); assert meta != null; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java index 198f2149..f2ee0529 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java @@ -21,7 +21,7 @@ import java.util.function.Consumer; * * @param Type of the factory of the type of setting the gui should edit. */ -public abstract class AbstractEnchantConfigGui extends SettingGuiListConfigGui{ +public abstract class AbstractEnchantConfigGui extends SettingGuiListConfigGui { /** * Constructor for a gui displaying available enchantment to edit a enchantment setting. @@ -47,7 +47,7 @@ public abstract class AbstractEnchantConfigGui getCreateItemLore() { return Collections.emptyList(); } + @Override protected Consumer getCreateClickConsumer() { return null; 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 51936c7e..149a4aa0 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 @@ -14,7 +14,6 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; -import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil; import xyz.alexcrea.cuanvil.dependency.packet.PacketManager; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; @@ -24,10 +23,11 @@ import xyz.alexcrea.cuanvil.gui.config.settings.WorkPenaltyTypeSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; /** * Global config to edit basic basic settings. @@ -42,11 +42,12 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { } private final PacketManager packetManager; + /** * Constructor of this Global gui for basic settings. */ public BasicConfigGui(PacketManager packetManager) { - super(4, "§8Basic Config", CustomAnvil.instance); + super(4, MsgUI.INSTANCE.getBASIC_TITLE().textHolder(), CustomAnvil.instance); if(INSTANCE == null) INSTANCE = this; this.packetManager = packetManager; @@ -101,61 +102,60 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { */ protected void prepareValues() { // cap anvil cost - this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory("§8Cap Anvil Cost ?", this, + this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, - "§7All anvil cost will be capped to §aMax Anvil Cost§7 if enabled.", - "§7In other words:", - "§7For any anvil cost greater than §aMax Anvil Cost§7, Cost will be set to §aMax Anvil Cost§7."); + null, MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DESCRIPTION() + ); // cap anvil cost not needed ItemStack item = new ItemStack(Material.BARRIER); ItemMeta meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§cCap Anvil Cost ?"); - meta.setLore(Collections.singletonList("§7This config only work if §cLimit Repair Cost§7 is disabled.")); + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DISABLED_TITLE()); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_DISABLED_DESCRIPTION().formatted(), meta); + item.setItemMeta(meta); this.noCapRepairItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); // repair cost item IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; - this.maxAnvilCost = new IntSettingsGui.IntSettingFactory("§8Max Anvil Cost", this, + this.maxAnvilCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_TITLE(), this, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7Max cost the Anvil can get to.", - "§7Valid values include §e0 §7to §e1000§7.", - "§7Cost will be displayed as §cToo Expensive§7:", - "§7- If Cost is above §e39", - "§7- And §eReplace Too Expensive§7 is disabled" - ), + MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_MAX_ANVIL_COST, - 1, 5, 10); + 1, 5, 10 + ); // max anvil cost not needed item = new ItemStack(Material.BARRIER); meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§cMax Anvil Cost"); - meta.setLore(Collections.singletonList("§7This config only work if §cLimit Repair Cost§7 is disabled.")); + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DISABLED_TITLE()); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DISABLED_DESCRIPTION().formatted(), meta); item.setItemMeta(meta); this.noMaxCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); // remove repair limit item - this.removeAnvilCostLimit = new BoolSettingsGui.BoolSettingFactory("§8Remove Anvil Cost Limit ?", this, + this.removeAnvilCostLimit = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT, - "§7Whether the anvil's cost limit should be removed entirely.", - "§7The anvil will still visually display §cToo Expensive§7 if §eReplace Too Expensive§7 is disabled.", - "§7However, the action will be completable if xp requirement is meet."); + null, MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_DESCRIPTION() + ); // replace too expensive item - this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory("§8Replace Too Expensive ?", this, + this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, - getReplaceToExpensiveLore()); + null, getReplaceToExpensiveLore() + ); // ------------ // Cost config @@ -163,132 +163,118 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // item repair cost range = ConfigOptions.REPAIR_COST_RANGE; - this.itemRepairCost = new IntSettingsGui.IntSettingFactory("§8Item Repair Cost", this, + this.itemRepairCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_TITLE(), this, ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7XP Level amount added to the anvil when the item", - "§7is repaired by another item of the same type." - ), + MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_REPAIR_COST, - 1, 5, 10, 50, 100); + 1, 5, 10, 50, 100 + ); // unit repair cost - this.unitRepairCost = new IntSettingsGui.IntSettingFactory("§8Unit Repair Cost", this, + this.unitRepairCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_TITLE(), this, ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7XP Level amount added to the anvil when the item is repaired by an §eunit§7.", - "§7For example: a Diamond on a Diamond Sword.", - "§7What's considered unit for what can be edited on the unit repair configuration." - ), + MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_UNIT_REPAIR_COST, - 1, 5, 10, 50, 100); + 1, 5, 10, 50, 100 + ); // item rename cost range = ConfigOptions.ITEM_RENAME_COST_RANGE; - this.itemRenameCost = new IntSettingsGui.IntSettingFactory("§8Rename Cost", this, + this.itemRenameCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_TITLE(), this, ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7XP Level amount added to the anvil when the item is renamed." - ), + MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_RENAME_COST, - 1, 5, 10, 50, 100); + 1, 5, 10, 50, 100 + ); // sacrifice illegal enchant cost range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE; - this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory("§8Sacrifice Illegal Enchant Cost", this, + this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_TITLE(), this, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7XP Level amount added to the anvil when a sacrifice enchantment", - "§7conflict With one of the left item enchantment" - ), + MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, - 1, 5, 10, 50, 100); + 1, 5, 10, 50, 100 + ); // ------------- // Color config // ------------- // Allow us of color code - this.allowColorCode = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Color Code ?", this, + this.allowColorCode = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_COLOR_CODE_LIMIT_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, - "§7Whether players can use color code.", - "§7Color code a formatted like §a&a§7 and is used in the rename field of the anvil.", - "§7Player may need permission to use color code if §ePlayer need permission to use color§7 is enabled."); + null, MsgUI.INSTANCE.getBASIC_COLOR_CODE_LIMIT_DESCRIPTION() + ); // Allow us of hexadecimal color - this.allowHexColor = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Hexadecimal Color ?", this, + this.allowHexColor = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_COLOR_HEX_LIMIT_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, - "§7Whether players can use hexadecimal color.", - "§7Color code a formatted like §2#012345 §7and is used in the rename field of the anvil.", - "§7Player may need permission to use color code if §ePermission Needed For Color§7 is enabled."); + null, MsgUI.INSTANCE.getBASIC_COLOR_HEX_LIMIT_DESCRIPTION() + ); // Permission needed for color - this.permissionNeededForColor = new BoolSettingsGui.BoolSettingFactory("§8Need Permission To Use Color ?", this, + this.permissionNeededForColor = new BoolSettingsGui.BoolSettingFactory( + MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_TITLE(), this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, - "§7Whether players should have permission to be able to use colors.", - "§7Give player §eca.color.code§7 Permission to allow use of color code.", - "§7Give player §eca.color.hex§7 Permission to allow use of hexadecimal color."); + null, MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DESCRIPTION() + ); // Permission needed for color not necessary item = new ItemStack(Material.BARRIER); meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§cNeed Permission To Use Color ?"); - meta.setLore(Arrays.asList("§7This config can do something only if one of the following config is enabled:", - "§7- §aAllow Use Of Color Code", - "§7- §aAllow Use Of Hexadecimal Color")); + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DISABLED_TITLE()); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_COLOR_PERMISSION_DISABLED_DESCRIPTION().formatted(), meta); 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 = new IntSettingsGui.IntSettingFactory("§8Cost Of Using Color", this, + this.useOfColorCost = new IntSettingsGui.IntSettingFactory( + MsgUI.INSTANCE.getBASIC_COLOR_COST_TITLE(), this, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, - Arrays.asList( - "§7XP level cost when using color code or hexadecimal color using the anvil.", - "§7conflict With one of the left item enchantment" - ), + MsgUI.INSTANCE.getBASIC_COLOR_COST_DESCRIPTION(), range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_USE_OF_COLOR_COST, - 1, 5, 10, 50, 100); + 1, 5, 10, 50, 100 + ); // Permission needed for color not necessary item = new ItemStack(Material.BARRIER); meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§cCost Of Using Color"); - meta.setLore(Arrays.asList("§7This config can do something only if one of the following config is enabled:", - "§7- §aAllow Use Of Color Code", - "§7- §aAllow Use Of Hexadecimal Color")); + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getBASIC_COLOR_COST_DISABLED_TITLE()); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getBASIC_COLOR_COST_DISABLED_DESCRIPTION().formatted(), meta); + item.setItemMeta(meta); this.noColorCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); } @NotNull - private String[] getReplaceToExpensiveLore() { - ArrayList lore = new ArrayList<>(); - lore.add("§7Whenever anvil cost is above §e39§7 should display the true price and not §cToo Expensive§7."); - lore.add("§7However, when bypassing §cToo Expensive§7, anvil price will be displayed as §aGreen§7."); - lore.add("§7Even if cost is displayed as §aGreen§7:"); - lore.add("§7If the player do not have the required xp level, the action will not be completable."); + private Message[] getReplaceToExpensiveLore() { + ArrayList lore = new ArrayList<>(); + lore.add(MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION()); - if(!this.packetManager.getCanSetInstantBuild()){ - lore.add(""); - lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a paper server."); - lore.add("§cCurrently ProtocoLib is not detected."); - } + if(!this.packetManager.getCanSetInstantBuild()) + lore.add(MsgUI.INSTANCE.getBASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION_NO_NMS()); - String[] loreAsArray = new String[lore.size()]; + Message[] loreAsArray = new Message[lore.size()]; return lore.toArray(loreAsArray); } @@ -297,9 +283,14 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // limit and cap anvil cost item GuiItem capAnvilCostItem; GuiItem maxAnvilCostItem; - if (!this.removeAnvilCostLimit.getConfiguredValue()) { - capAnvilCostItem = this.capAnvilCost.getItem("Cap Anvil Cost"); - maxAnvilCostItem = this.maxAnvilCost.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); + if(!this.removeAnvilCostLimit.getConfiguredValue()) { + capAnvilCostItem = this.capAnvilCost.getItem( + MsgUI.INSTANCE.getBASIC_CAP_ANVIL_COST_ITEM() + ); + maxAnvilCostItem = this.maxAnvilCost.getItem( + Material.EXPERIENCE_BOTTLE, + MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_ITEM() + ); } else { capAnvilCostItem = this.noCapRepairItem; maxAnvilCostItem = this.noMaxCostItem; @@ -309,7 +300,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { pane.bindItem('C', maxAnvilCostItem); // remove repair limit item - GuiItem removeRepairLimitItem = this.removeAnvilCostLimit.getItem("Remove Anvil Cost Limit"); + GuiItem removeRepairLimitItem = this.removeAnvilCostLimit.getItem( + MsgUI.INSTANCE.getBASIC_REMOVE_COST_LIMIT_ITEM() + ); pane.bindItem('R', removeRepairLimitItem); // replace too expensive item @@ -334,7 +327,11 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { pane.bindItem('S', illegalCostItem); // work penalty type - GuiItem workPenaltyType = WorkPenaltyTypeSettingGui.getDisplayItem(this, Material.DAMAGED_ANVIL, "§aWork Penalty Type"); + GuiItem workPenaltyType = WorkPenaltyTypeSettingGui.getDisplayItem( + this, + Material.DAMAGED_ANVIL, + MsgUI.INSTANCE.getBASIC_WORK_PENALTY_ITEM() + ); pane.bindItem('W', workPenaltyType); // allow color code @@ -346,20 +343,22 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { pane.bindItem('h', allowHexColorItem); // True if player could place color - if(ConfigOptions.INSTANCE.getRenameColorPossible()){ + 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"); + GuiItem useColorCostItem = this.useOfColorCost.getItem( + Material.EXPERIENCE_BOTTLE, + MsgUI.INSTANCE.getBASIC_COLOR_COST_ITEM() + ); pane.bindItem('P', useColorCostItem); - }else{ + } else { pane.bindItem('p', this.noPermissionNeededItem); pane.bindItem('P', this.noColorCostItem); } - update(); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java index 060ff35a..c0c32471 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java @@ -61,7 +61,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " Custom recipe");//TODO MESSAGE meta.addItemFlags(ItemFlag.values()); meta.setLore(getRecipeLore(recipe)); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java index a531798a..c9938fd5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -11,9 +12,12 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; +import java.awt.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -59,13 +63,10 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui lore = new ArrayList<>(); - lore.add("§7Item Cost: §e" + itemCost); - lore.add("§7Book Cost: §e" + bookCost); + List lore = new ArrayList<>(); + lore.addAll(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST().formatted(itemCost)); + lore.addAll(MsgUI.INSTANCE.getENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST().formatted(bookCost)); - List displayLore = factory.getDisplayLore(); - if (!displayLore.isEmpty()) { - lore.add(""); - lore.addAll(displayLore); + List displayLore = factory.getDisplayLore(); + if (displayLore != null) { + lore.add(Component.empty()); + lore.addAll(ComponentUtil.INSTANCE.asComponents(displayLore, factory.getParam())); } // Edit name and lore - itemMeta.setDisplayName(itemName); - itemMeta.setLore(lore); + ComponentUtil.INSTANCE.setMessageName(itemMeta, itemName, factory.getParam()); + ComponentUtil.INSTANCE.applyLore(lore, itemMeta); item.setItemMeta(itemMeta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java index 4ed529cf..e1a2759e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java @@ -54,11 +54,10 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui getCreateItemLore() { - return Arrays.asList( + return Arrays.asList(//TODO MESSAGE "§7Select a new item to be repairable.", "§7You will be asked the material to use." ); @@ -60,7 +60,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui getCreateClickConsumer() { return event -> { event.setCancelled(true); - if (!this.shouldWork) { + if(!this.shouldWork) { return; } event.setCancelled(true); @@ -73,11 +73,11 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui getEveryInstanceOfGeneric() { Set keys = new HashSet<>(); - if (!this.shouldWork) { + if(!this.shouldWork) { return keys; } @@ -155,10 +157,10 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui keys) { - if (section == null) return; - for (var key : section.getKeys(false)) { + if(section == null) return; + for(var key : section.getKeys(false)) { var material = NamespacedKey.fromString(key); - if (material == null) continue; + if(material == null) continue; keys.add(material); } @@ -166,7 +168,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui valueLore = new ArrayList<>(); - if(!holder.displayLore.isEmpty()){ - valueLore.addAll(holder.displayLore); - valueLore.add(""); + ArrayList valueLore = new ArrayList<>(); + if(holder.displayLore != null){ + valueLore.addAll(ComponentUtil.INSTANCE.asComponents(holder.displayLore)); + valueLore.add(Component.empty()); } - valueLore.add(AbstractSettingGui.CLICK_LORE); + valueLore.addAll(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted()); ItemStack valueItemStack = new ItemStack(displayedMat); ItemMeta valueMeta = valueItemStack.getItemMeta(); assert valueMeta != null; - valueMeta.setDisplayName(displayedName); - valueMeta.setLore(valueLore); + valueMeta.setDisplayName(displayedName);//TODO MESSAGE ? + ComponentUtil.INSTANCE.applyLore(valueLore, valueMeta); valueItemStack.setItemMeta(valueMeta); + GuiItem resultItem = new GuiItem(valueItemStack, inverseNowConsumer(), CustomAnvil.instance); pane.bindItem('v', resultItem); @@ -166,13 +172,15 @@ public class BoolSettingsGui extends AbstractSettingGui { */ public static class BoolSettingFactory extends SettingGuiFactory { @NotNull - String title; + Message title; @NotNull ValueUpdatableGui parent; boolean defaultVal; - @NotNull - List displayLore; + @Nullable + List displayLore; + @Nullable + Object param; /** * Constructor for a boolean setting gui factory. @@ -185,22 +193,25 @@ public class BoolSettingsGui extends AbstractSettingGui { * @param displayLore Gui display item lore. */ public BoolSettingFactory( - @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull ConfigHolder config, @NotNull String configPath, - boolean defaultVal, String... displayLore) { + boolean defaultVal, + @Nullable Object param, @Nullable Message... displayLore) { super(configPath, config); this.title = title; this.parent = parent; this.defaultVal = defaultVal; - this.displayLore = Arrays.asList(displayLore); + + this.displayLore = displayLore == null ? null : Arrays.asList(displayLore); + this.param = param; } /** * @return Get setting's gui title. */ @NotNull - public String getTitle() { + public Message getTitle() { return title; } @@ -225,25 +236,36 @@ public class BoolSettingsGui extends AbstractSettingGui { * The item will have its value written in the lore part of the item. * * @param name Name of the item. + * @param params parameters for the given name. * @return A formatted GuiItem that will create and open a GUI for the boolean setting. */ - public GuiItem getItem(String name){ + public GuiItem getItem( + @NotNull Message name, + Object... params + ){ // Get item properties boolean value = getConfiguredValue(); Material itemMat; - StringBuilder itemName = new StringBuilder("§e"); + Component itemName = name.formattedConcatenated(params); + String finalValue; if (value) { itemMat = Material.GREEN_TERRACOTTA; - finalValue = "§aYes"; + finalValue = "Yes";//TODO MESSAGE } else { itemMat = Material.RED_TERRACOTTA; - finalValue = "§cNo"; + finalValue = "No";//TODO MESSAGE } - itemName.append(name); - return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, finalValue, this.displayLore, false); + return GuiGlobalItems.createGuiItemFromProperties( + this, + itemMat, itemName, + finalValue, + this.displayLore, + false, + this.param + ); } /** @@ -258,7 +280,7 @@ public class BoolSettingsGui extends AbstractSettingGui { // Get item properties String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); - return getItem(CasedStringUtil.detectToUpperSpacedCase(configPath)); + return getItem(MsgUI.INSTANCE.getSHARED_YELLOW_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath)); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java index c0dcff60..1d14a566 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java @@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import io.delilaheve.CustomAnvil; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; @@ -17,7 +18,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.math.BigDecimal; import java.math.RoundingMode; @@ -166,7 +170,7 @@ public class DoubleSettingGui extends AbstractSettingGui { ItemMeta resultMeta = resultPaper.getItemMeta(); assert resultMeta != null; - resultMeta.setDisplayName("§fValue: §e" + displayValue(now)); + resultMeta.setDisplayName("Value: " + displayValue(now)); resultPaper.setItemMeta(resultMeta); GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); @@ -185,12 +189,12 @@ public class DoubleSettingGui extends AbstractSettingGui { private GuiItem getSetValueItem(Material mat, BigDecimal planned, String numberPrefix){ // Create set item lore - ArrayList setLoreItem = new ArrayList<>(); - if(!holder.displayLore.isEmpty()){ - setLoreItem.addAll(holder.displayLore); - setLoreItem.add(""); + ArrayList setLoreItem = new ArrayList<>(); + if(holder.displayLore != null){ + setLoreItem.addAll(holder.displayLore.formatted(holder.param, holder.param2)); + setLoreItem.add(Component.empty()); } - setLoreItem.add(AbstractSettingGui.CLICK_LORE); + setLoreItem.addAll(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted()); // Create & return set value item ItemStack item = new ItemStack(mat); @@ -199,7 +203,7 @@ public class DoubleSettingGui extends AbstractSettingGui { meta.setDisplayName("§e" + displayValue(now) + " §f-> §e" + displayValue(planned) + " §r(" + numberPrefix + (displayValue(planned.subtract(now).abs()) + "§r)")); - meta.setLore(setLoreItem); + ComponentUtil.INSTANCE.applyLore(setLoreItem, meta); item.setItemMeta(meta); return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); @@ -357,7 +361,7 @@ public class DoubleSettingGui extends AbstractSettingGui { */ public static class DoubleSettingFactory extends SettingGuiFactory { @NotNull - String title; + Message title; @NotNull ValueUpdatableGui parent; @@ -369,8 +373,12 @@ public class DoubleSettingGui extends AbstractSettingGui { BigDecimal defaultVal; BigDecimal[] steps; - @NotNull - List displayLore; + @Nullable + Message displayLore; + @Nullable + Object param; + @Nullable + Object param2; /** * Constructor for a double setting gui factory. @@ -392,10 +400,11 @@ public class DoubleSettingGui extends AbstractSettingGui { * If step only contain 1 value, no step item should be displayed. */ public DoubleSettingFactory( - @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull ConfigHolder config, @NotNull String configPath, - @Nullable List displayLore, + @Nullable Message displayLore, + @Nullable Object param, @Nullable Object param2, int scale, boolean asPercentage, boolean nullOnZero, double min, double max, double defaultVal, double... steps) { super(configPath, config); @@ -413,18 +422,16 @@ public class DoubleSettingGui extends AbstractSettingGui { this.steps[i] = BigDecimal.valueOf(steps[i]).setScale(scale, RoundingMode.HALF_UP); } - if(displayLore == null){ - this.displayLore = Collections.emptyList(); - }else { - this.displayLore = displayLore; - } + this.displayLore = displayLore; + this.param = param; + this.param2 = param2; } /** * @return Get setting's gui title */ @NotNull - public String getTitle() { + public Message getTitle() { return title; } @@ -448,21 +455,29 @@ public class DoubleSettingGui extends AbstractSettingGui { } - public GuiItem getItem(Material itemMat, String name){ + public GuiItem getItem( + @NotNull Material itemMat, + @NotNull Message name, + Object... params + ){ // Get item properties BigDecimal value = getConfiguredValue(); - StringBuilder itemName = new StringBuilder("§a").append(name); - return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, - "§e" + displayValue(value, this.asPercentage), - this.displayLore, true); + var itemName = name.formattedConcatenated(params); + + return GuiGlobalItems.createGuiItemFromProperties( + this, itemMat, itemName, + "" + displayValue(value, this.asPercentage), //TODO MESSAGE ? maybe ? + Collections.singletonList(this.displayLore), true, + this.param, this.param2 + ); } public GuiItem getItem(Material itemMat){ // Get item properties String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); - return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); + return getItem(itemMat, MsgUI.INSTANCE.getSHARED_GREEN_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath)); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java index 0d4bc89a..1e880512 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java @@ -19,6 +19,9 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.Arrays; import java.util.Collections; @@ -150,7 +153,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui { assert meta != null; meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§c-" + (nowBook - planned) + "§r)"); - meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta); item.setItemMeta(meta); minusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); @@ -167,8 +170,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui { ItemMeta meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§a+" + (planned - nowBook) + "§r)"); - meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); + meta.setDisplayName("§e" + nowBook + " §f-> §e" + planned + " §r(§a+" + (planned - nowBook) + "§r)");//TODO MESSAGE + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta); item.setItemMeta(meta); plusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); @@ -182,9 +185,9 @@ public class EnchantCostSettingsGui extends IntSettingsGui { ItemMeta nowMeta = nowPaper.getItemMeta(); assert nowMeta != null; - nowMeta.setDisplayName("§fValue: §e" + nowBook); - if (!holder.displayLore.isEmpty()) { - nowMeta.setLore(holder.displayLore); + nowMeta.setDisplayName("Value: " + nowBook);//TODO MESSAGE + if (holder.displayLore != null) { + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(holder.displayLore, holder.param), nowMeta); } nowPaper.setItemMeta(nowMeta); @@ -263,15 +266,15 @@ public class EnchantCostSettingsGui extends IntSettingsGui { * If step only contain 1 value, no step item should be displayed. */ public EnchantCostSettingFactory( - @NotNull String title, ValueUpdatableGui parent, + @NotNull Message title, ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, - @Nullable List displayLore, + @Nullable Message displayLore, @Nullable Object param, @NotNull CAEnchantment enchantment, int min, int max, int... steps) { super(title, parent, configPath, config, - displayLore, + displayLore, param, min, max, enchantment.defaultRarity().getItemValue(), steps); @@ -302,7 +305,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui { return new EnchantCostSettingsGui(this, nowItem); } - public List getDisplayLore() { + @Nullable + public List getDisplayLore() { return this.displayLore; } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java index 5bf4c24e..9ff90d8a 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java @@ -15,6 +15,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import java.util.Collections; import java.util.List; @@ -137,7 +138,7 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> */ public abstract static class EnumSettingFactory & ConfigurableEnum> extends SettingGuiFactory { @NotNull - String title; + Message title; @NotNull ValueUpdatableGui parent; @@ -150,7 +151,7 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> * @param config Configuration holder of this setting. */ protected EnumSettingFactory( - @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config) { super(configPath, config); this.title = title; @@ -161,7 +162,7 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> * @return Get setting's gui title. */ @NotNull - public String getTitle() { + public Message getTitle() { return title; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java index c32d22ca..13cf72e5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java @@ -5,6 +5,9 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import io.delilaheve.CustomAnvil; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; @@ -16,7 +19,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.Collections; import java.util.List; @@ -71,8 +77,8 @@ public class IntSettingsGui extends AbstractSettingGui { ItemMeta meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§eReset to default value"); - meta.setLore(Collections.singletonList("§7Default value is §e" + + meta.setDisplayName("§eReset to default value");//TODO MESSAGE + meta.setLore(Collections.singletonList("§7Default value is §e" +//TODO MESSAGE holder.valueDisplayName(ValueDisplayType.RESET, holder.defaultVal))); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { @@ -91,7 +97,7 @@ public class IntSettingsGui extends AbstractSettingGui { // minus item GuiItem minusItem; - if (now > holder.min) { + if(now > holder.min) { int planned = Math.max(holder.min, now - step); minusItem = valueEditItem(Material.RED_TERRACOTTA, ValueDisplayType.REMOVE, planned); } else { @@ -101,7 +107,7 @@ public class IntSettingsGui extends AbstractSettingGui { //plus item GuiItem plusItem; - if (now < holder.max) { + if(now < holder.max) { int planned = Math.min(holder.max, now + step); plusItem = valueEditItem(Material.GREEN_TERRACOTTA, ValueDisplayType.ADD, planned); } else { @@ -114,8 +120,9 @@ public class IntSettingsGui extends AbstractSettingGui { ItemMeta resultMeta = resultPaper.getItemMeta(); assert resultMeta != null; - resultMeta.setDisplayName("§fValue: §e" + holder.valueDisplayName(ValueDisplayType.CURRENT, now)); - resultMeta.setLore(holder.displayLore); + resultMeta.setDisplayName("Value: " + holder.valueDisplayName(ValueDisplayType.CURRENT, now));//TODO MESSAGE + if(holder.displayLore != null) + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(holder.displayLore, holder.param), resultMeta); resultPaper.setItemMeta(resultMeta); @@ -125,7 +132,7 @@ public class IntSettingsGui extends AbstractSettingGui { // reset to default GuiItem returnToDefault; - if (now != holder.defaultVal) { + if(now != holder.defaultVal) { returnToDefault = this.returnToDefault; } else { returnToDefault = GuiGlobalItems.backgroundItem(); @@ -142,9 +149,9 @@ public class IntSettingsGui extends AbstractSettingGui { var nowDisplay = holder.valueDisplayName(type, now); var plannedDisplay = holder.valueDisplayName(type, planned); var deltaDisplay = holder.deltaDisplay(type, now, planned); - meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)"); + meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)");//TODO MESSAGE - meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); + ComponentUtil.INSTANCE.applyLore(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted(), meta); item.setItemMeta(meta); return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); } @@ -170,7 +177,7 @@ public class IntSettingsGui extends AbstractSettingGui { GuiItem background = GuiGlobalItems.backgroundItem(); PatternPane pane = getPane(); - for (char i = 'a'; i < (getMidStepChar() - 'a') * 2 + 1; i++) { + for(char i = 'a'; i < (getMidStepChar() - 'a') * 2 + 1; i++) { pane.bindItem(i, background); } // Then update legit step values @@ -181,7 +188,7 @@ public class IntSettingsGui extends AbstractSettingGui { * Update steps items value. */ protected void updateStepValue() { - if (holder.steps.length <= 1) return; + if(holder.steps.length <= 1) return; // We assume steps have a length of 2k+1 cause its more pretty char val = getMidStepChar(); // Offset to start (not the best way to do it) @@ -189,7 +196,7 @@ public class IntSettingsGui extends AbstractSettingGui { // Then place items PatternPane pane = getPane(); - for (int i = 0; i < holder.steps.length; i++) { + for(int i = 0; i < holder.steps.length; i++) { pane.bindItem(val + i, stepGuiItem(i)); } @@ -218,7 +225,7 @@ public class IntSettingsGui extends AbstractSettingGui { StringBuilder stepName = new StringBuilder("§"); List stepLore; Consumer clickEvent; - if (stepValue == step) { + if(stepValue == step) { stepMat = Material.GREEN_STAINED_GLASS_PANE; stepName.append('a'); stepLore = Collections.singletonList("§7Value is changing by " + stepValue); @@ -261,7 +268,7 @@ public class IntSettingsGui extends AbstractSettingGui { public boolean onSave() { holder.config.getConfig().set(holder.configPath, now); - if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { + if(GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); } return true; @@ -278,7 +285,7 @@ public class IntSettingsGui extends AbstractSettingGui { public static class IntSettingFactory extends SettingGuiFactory { @NotNull - String title; + Message title; @NotNull ValueUpdatableGui parent; int min; @@ -286,8 +293,11 @@ public class IntSettingsGui extends AbstractSettingGui { int defaultVal; int[] steps; - @NotNull - List displayLore; + @Nullable + List displayLore; + + @Nullable + Object param; /** * Constructor for an int setting gui factory. @@ -306,9 +316,9 @@ public class IntSettingsGui extends AbstractSettingGui { * If step only contain 1 value, no step item should be displayed. */ public IntSettingFactory( - @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, - @Nullable List displayLore, + @Nullable Message displayLore, @Nullable Object param, int min, int max, int defaultVal, int... steps) { super(configPath, config); this.title = title; @@ -317,19 +327,15 @@ public class IntSettingsGui extends AbstractSettingGui { this.max = max; this.defaultVal = defaultVal; this.steps = steps; - - if (displayLore == null) { - this.displayLore = Collections.emptyList(); - } else { - this.displayLore = displayLore; - } + this.displayLore = displayLore == null ? null : Collections.singletonList(displayLore); + this.param = param; } /** * @return Get setting's gui title */ @NotNull - public String getTitle() { + public Message getTitle() { return title; } @@ -355,19 +361,24 @@ public class IntSettingsGui extends AbstractSettingGui { * * @param itemMat Displayed material of the item. * @param name Name of the item. + * @param params parameters for the given name. * @return A formatted GuiItem that will create and open a GUI for the int setting. */ public GuiItem getItem( @NotNull Material itemMat, - @NotNull String name + @NotNull Message name, + Object... params ) { // Get item properties int value = getConfiguredValue(); - StringBuilder itemName = new StringBuilder("§a").append(name); + var itemName = name.formattedConcatenated(params); - return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, - "§e" + value, - this.displayLore, true); + return GuiGlobalItems.createGuiItemFromProperties( + this, itemMat, itemName, + "" + value, //TODO MESSAGE ? maybe ? + this.displayLore, true, + this.param + ); } /** @@ -383,7 +394,7 @@ public class IntSettingsGui extends AbstractSettingGui { @NotNull Material itemMat ) { String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); - return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); + return getItem(itemMat, MsgUI.INSTANCE.getSHARED_GREEN_GET_ITEM(), CasedStringUtil.detectToUpperSpacedCase(configPath)); } protected String valueDisplayName(ValueDisplayType type, int value) { @@ -392,10 +403,13 @@ public class IntSettingsGui extends AbstractSettingGui { protected String deltaDisplay(ValueDisplayType type, int now, int planned) { var delta = planned - now; - if (delta < 0) return "§c" + delta; + if(delta < 0) return "§c" + delta; else return "§a+" + delta; } + public @Nullable Object getParam() { + return param; + } } public enum ValueDisplayType { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java index 3df2af8c..81de4586 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java @@ -17,8 +17,11 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; +import java.awt.*; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -168,13 +171,13 @@ public class ItemSettingGui extends AbstractSettingGui { */ public static class ItemSettingFactory extends SettingGuiFactory { @NotNull - String title; + Message title; @NotNull ValueUpdatableGui parent; @Nullable ItemStack defaultVal; @NotNull - List displayLore; + List displayLore; /** * Constructor for an item setting gui factory. @@ -187,10 +190,10 @@ public class ItemSettingGui extends AbstractSettingGui { * @param displayLore Gui display item lore. */ public ItemSettingFactory( - @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, @Nullable ItemStack defaultVal, - String... displayLore) { + Message... displayLore) { super(configPath, config); this.title = title; this.parent = parent; @@ -203,7 +206,7 @@ public class ItemSettingGui extends AbstractSettingGui { * @return Get setting's gui title. */ @NotNull - public String getTitle() { + public Message getTitle() { return title; } @@ -215,7 +218,7 @@ public class ItemSettingGui extends AbstractSettingGui { } @NotNull - public List getDisplayLore() { + public List getDisplayLore() { return this.displayLore; } @@ -245,8 +248,9 @@ public class ItemSettingGui extends AbstractSettingGui { ItemMeta meta = item.getItemMeta(); assert meta != null; + //TODO MESSAGE name ? meta.setDisplayName("§a" + name); - meta.setLore(getDisplayLore()); + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(getDisplayLore()), meta); meta.addItemFlags(ItemFlag.values()); item.setItemMeta(meta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java index 8cc3d2ce..439376aa 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/WorkPenaltyTypeSettingGui.java @@ -15,55 +15,48 @@ import xyz.alexcrea.cuanvil.anvil.AnvilUseType; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.WorkPenaltyType; import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui; -import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.ArrayList; import java.util.EnumMap; -import java.util.List; import java.util.Map; public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { - private static final String INCREASING_EXPLANATION = "§eIncreasing§7: will penalty be increased (in item)"; - private static final String ADDING_EXPLANATION = "§eAdditive§7: will penalty be added to the cost"; - - private static final String SHARED_EXPLANATION = "§eShared§7: Vanilla, shared penalty. it will be kept from before the plugin installation."; - private static final String EXCLUSIVE_EXPLANATION = "§eExclusive§7: Custom, per anvil use type penalty. it will be lost after plugin uninstallation"; - private final @NotNull WorkPenaltyType currentType; private final @NotNull Map items; public WorkPenaltyTypeSettingGui(@NotNull BasicConfigGui parent) { - super(4, "§8Work Penalty Type", parent); + super(4, MsgUI.INSTANCE.getBASIC_WORK_PENALTY_TITLE(), parent); this.currentType = ConfigOptions.INSTANCE.getWorkPenaltyType(); this.items = new EnumMap<>(this.currentType.getPartMap()); - for (AnvilUseType type : useTypes.keySet()) { + for(AnvilUseType type : useTypes.keySet()) { updateGuiForType(type); } } public static GuiItem getDisplayItem(@NotNull BasicConfigGui parent, @NotNull Material itemMat, - @NotNull String name) { - List displayLore = new ArrayList<>(); + @NotNull Message name) { + var item = new ItemStack(itemMat); - displayLore.add("§7Work penalty increase the price for every anvil use."); - displayLore.add("§7This config allow you to choose the comportment of work penalty."); - displayLore.add(INCREASING_EXPLANATION); - displayLore.add(ADDING_EXPLANATION); - displayLore.add(""); - displayLore.add("§7About shared/exclusive penalty:"); - displayLore.add(SHARED_EXPLANATION); - displayLore.add(EXCLUSIVE_EXPLANATION); + var meta = item.getItemMeta(); + assert meta != null; - ItemStack item = new ItemStack(itemMat); + var lore = new ArrayList(); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_LORE()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_LORE_BREAK()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE()); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(name); - meta.setLore(displayLore); + ComponentUtil.INSTANCE.setMessageName(meta, name); + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta); item.setItemMeta(meta); @@ -72,7 +65,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { HumanEntity player = event.getWhoClicked(); // Do not allow to open inventory if player do not have edit configuration permission - if (!player.hasPermission(CustomAnvil.editConfigPermission)) { + if(!player.hasPermission(CustomAnvil.editConfigPermission)) { player.closeInventory(); MsgUI.INSTANCE.getSHARED_CONFIG_NO_EDIT_PERM().send(player); return; @@ -111,6 +104,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { char exclusiveAdditive = typeVals.charAt(4); WorkPenaltyType.WorkPenaltyPart part = items.get(type); + //TODO MESSAGE String increasingStr = (part.penaltyIncrease() ? "§a" : "§c") + "Increasing"; String additiveStr = (part.penaltyAdditive() ? "§a" : "§c") + "Additive"; String exclusiveIncreasingStr = (part.exclusivePenaltyIncrease() ? "§a" : "§c") + "Increasing"; @@ -124,6 +118,7 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { displayLore.add("§eExclusive§7: " + exclusiveAdditiveStr + " §7| " + exclusiveIncreasingStr); ItemMeta meta = displayItem.getItemMeta(); + assert meta != null; meta.setDisplayName("§e" + type.getDisplayName()); meta.setLore(displayLore); displayItem.setItemMeta(meta); @@ -137,9 +132,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { ItemStack incrementItem = new ItemStack(part.penaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); meta = incrementItem.getItemMeta(); + assert meta != null; meta.setDisplayName(increasingStr); - meta.setLore(List.of(INCREASING_EXPLANATION)); - meta.setLore(List.of(SHARED_EXPLANATION)); + + var lore = new ArrayList(); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED()); + + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta); incrementItem.setItemMeta(meta); pane.bindItem(increment, new GuiItem(incrementItem, (event) -> { @@ -157,9 +157,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { ItemStack additiveItem = new ItemStack(part.penaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); meta = additiveItem.getItemMeta(); + assert meta != null; meta.setDisplayName(additiveStr); - meta.setLore(List.of(ADDING_EXPLANATION)); - meta.setLore(List.of(SHARED_EXPLANATION)); + + lore.clear(); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_SHARED()); + + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta); additiveItem.setItemMeta(meta); pane.bindItem(additive, new GuiItem(additiveItem, (event) -> { @@ -177,9 +182,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { ItemStack exclusiveIncrementItem = new ItemStack(part.exclusivePenaltyIncrease() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); meta = exclusiveIncrementItem.getItemMeta(); + assert meta != null; meta.setDisplayName(exclusiveIncreasingStr); - meta.setLore(List.of(INCREASING_EXPLANATION)); - meta.setLore(List.of(EXCLUSIVE_EXPLANATION)); + + lore.clear(); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_INCREASING()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE()); + + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta); exclusiveIncrementItem.setItemMeta(meta); pane.bindItem(exclusiveIncrement, new GuiItem(exclusiveIncrementItem, (event) -> { @@ -197,9 +207,14 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { ItemStack exclusiveAdditiveItem = new ItemStack(part.exclusivePenaltyAdditive() ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA); meta = exclusiveAdditiveItem.getItemMeta(); + assert meta != null; meta.setDisplayName(exclusiveAdditiveStr); - meta.setLore(List.of(ADDING_EXPLANATION)); - meta.setLore(List.of(EXCLUSIVE_EXPLANATION)); + + lore.clear(); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_ADDITIVE()); + lore.add(MsgUI.INSTANCE.getBASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE()); + + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(lore), meta); exclusiveAdditiveItem.setItemMeta(meta); pane.bindItem(exclusiveAdditive, new GuiItem(exclusiveAdditiveItem, (event) -> { @@ -224,9 +239,9 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { FileConfiguration config = configHolder.getConfig(); partEnum.forEach((key, value) -> { - String partPath = key.getPath(); + String partPath = key.getPath(); - if (key.getDefaultPenalty().equals(value)) { + if(key.getDefaultPenalty().equals(value)) { config.set(partPath, null); return; } @@ -242,8 +257,8 @@ public class WorkPenaltyTypeSettingGui extends AbstractSettingGui { @Override public boolean hadChange() { - for (AnvilUseType type : items.keySet()) { - if (!currentType.getPenaltyInfo(type).equals(items.get(type))) { + for(AnvilUseType type : items.keySet()) { + if(!currentType.getPenaltyInfo(type).equals(items.get(type))) { return true; } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java index 79f1462e..d0d7cd4f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java @@ -4,14 +4,20 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.pane.PatternPane; import io.delilaheve.CustomAnvil; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; +import xyz.alexcrea.cuanvil.lang.Message; +import xyz.alexcrea.cuanvil.lang.MsgUI; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.ArrayList; import java.util.Collections; @@ -184,9 +190,6 @@ public class GuiGlobalItems { return new GuiItem(item, GuiGlobalActions.openSettingGuiAction(factory), CustomAnvil.instance); } - // Prefix of the one line lore that will be added to setting's item. - public static final String SETTING_ITEM_LORE_PREFIX = "§7value: "; - /** * Create an arbitrary GuiItem from a unique setting and item's property. * @@ -201,17 +204,23 @@ public class GuiGlobalItems { public static GuiItem createGuiItemFromProperties( @NotNull SettingGui.SettingGuiFactory factory, @NotNull Material itemMat, - @NotNull StringBuilder itemName, - @NotNull Object value, - @NotNull List displayLore, - boolean displayValuePrefix + @NotNull Component itemName, + @NotNull Object value,//TODO ???? + @Nullable List displayLore, + boolean displayValuePrefix, + @Nullable Object... params ) { // Prepare lore - ArrayList lore = new ArrayList<>(); - lore.add((displayValuePrefix ? SETTING_ITEM_LORE_PREFIX : "") + value); - if(!displayLore.isEmpty()){ - lore.add(""); - lore.addAll(displayLore); + var loreHeader = (displayValuePrefix ? + MsgUI.INSTANCE.getGLOBAL_ITEM_ITEM_LORE_PREFIX() : + MsgUI.INSTANCE.getGLOBAL_ITEM_ITEM_LORE_PREFIX_ALONE()); + + List lore = loreHeader.formatted(value); + if(displayLore != null){ + lore.add(Component.empty()); + for(Message message : displayLore) { + lore.addAll(message.formatted(params)); + } } // Create & initialise item @@ -219,8 +228,8 @@ public class GuiGlobalItems { ItemMeta itemMeta = item.getItemMeta(); assert itemMeta != null; - itemMeta.setDisplayName(itemName.toString()); - itemMeta.setLore(lore); + PlatformUtil.INSTANCE.setComponentDisplayName(itemMeta, itemName, null); + ComponentUtil.INSTANCE.applyLore(lore, itemMeta); itemMeta.addItemFlags(ItemFlag.values()); item.setItemMeta(itemMeta); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index d42c8d22..17ae3796 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -109,7 +109,7 @@ class DebugToggleExecutor: CASubCommand { Text(MsgCommand.SHARED_HOVER_COPY.legacy()) ) - sender.spigot().sendMessage(message); + sender.spigot().sendMessage(message) } else { sender.sendMessage(stb.toString()) } @@ -137,7 +137,14 @@ class DebugToggleExecutor: CASubCommand { if(Lang.has(message.key)) validCount++ val valid = (100.0 * validCount) / registeredKeys.size - sender.sendMessage("Translated (${Lang.currentLang()}): ${"%.1f".format(Locale.ROOT, valid)}% ($validCount/${registeredKeys.size})") + sender.sendMessage( + "Translated (${Lang.currentLang()}): ${ + "%.1f".format( + Locale.ROOT, + valid + ) + }% ($validCount/${registeredKeys.size})" + ) } private fun detailedLangDebug(sender: CommandSender) { @@ -179,7 +186,7 @@ class DebugToggleExecutor: CASubCommand { Text(MsgCommand.SHARED_HOVER_COPY.legacy()) ) - sender.spigot().sendMessage(message); + sender.spigot().sendMessage(message) } else { sender.sendMessage("No additional issue found") } @@ -190,7 +197,7 @@ class DebugToggleExecutor: CASubCommand { val texts = if(section == null) listOf(Lang.getTranslated(message.key)) else - section.getValues(false).map { it.value.toString() } + section.getValues(false).map {it.value.toString()} val textParams = ArrayList() @@ -198,8 +205,7 @@ class DebugToggleExecutor: CASubCommand { var index = 0 while(true) { index = text.indexOf('%', index) - //TODO add \% to "ignore" % as param inside param finder - if(index > 0 && text[index-1] == '\\') { + if(index > 0 && text[index - 1] == '\\') { index++ continue } @@ -218,23 +224,29 @@ class DebugToggleExecutor: CASubCommand { for(textParam in textParams) { var found = false for(param in message.params) { - if(param.isEmpty()) continue + if(param == null) continue if(textParam.startsWith(param)) { found = true usedParam.add(param) break } } + if(found) break - if(!found) { - hadIssue = true - stb.append("Did not found param %$textParam in register list for ${message.key}\n") - } + hadIssue = true + stb.append("Did not found param %$textParam in register list for ${message.key}\n") } for(param in message.params) { - if(usedParam.contains(param)) continue - if("unused".contentEquals(param)) continue + if(param == null) continue + var found = false + for(used in usedParam) { + if(!used.startsWith(param)) continue + found = true + break + } + + if(found) continue hadIssue = true stb.append("Param %$param is not used for key ${message.key}\n") } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt index 0644a6fa..07f03ab0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt @@ -219,8 +219,8 @@ class DiagnosticExecutor : CASubCommand { } private fun pluginListDiag(sender: CommandSender, stb: StringBuilder) { - val enabledPlugins: MutableList = ArrayList() - val disabledPlugins: MutableList = ArrayList() + val enabledPlugins: MutableList = ArrayList() + val disabledPlugins: MutableList = ArrayList() for (plugin in Bukkit.getPluginManager().plugins) { if (plugin.isEnabled) { enabledPlugins.add(plugin) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index 64d9242d..82a43ba5 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -12,9 +12,10 @@ import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain import xyz.alexcrea.cuanvil.util.MiniMessageUtil import java.util.Collections import java.util.logging.Level +import kotlin.math.max import kotlin.math.min -open class Message(val key: String, vararg val params: String, register: Boolean = true) { +open class Message(val key: String, vararg val params: String?, register: Boolean = true) { companion object { private val values = ArrayList() @@ -28,30 +29,61 @@ open class Message(val key: String, vararg val params: String, register: Boolean if(register) values.add(this) } - protected fun replaceParameters(stb: StringBuilder, vararg values: Any) { + protected fun replaceParameters(stb: StringBuilder, vararg values: Any?) { // replace all placeholder thingy %key -> value if(params.size != values.size) { CustomAnvil.log("Wrong number of argument for parameter for key $key (${params.size}/${values.size})") + for(i in 0 until max(params.size, values.size)) { + val key = if(i >= params.size) "NOT KEY" + else params[i] + val value = if(i >= values.size) "NOT VALUE" + else values[i] + + CustomAnvil.log("Parameter ${i + 1} is $key with value $value") + } } + var foundBackslashPercent = false for(i in 0 until min(params.size, values.size)) { - val key = params[i] - val replacement = values[i].toString() - if(replacement.isEmpty()) continue //May not be good but can be changed if cause an issue + val key = params[i] ?: continue + val value = values[i] + if(value == null) { + CustomAnvil.log("Passed a null value for key ${this.key} for Parameter $key (${i + 1})") + continue + } + + val replacement = value.toString() + if(replacement.isEmpty()) continue //May not be good but can be changed if cause an issue //TODO REPLACE WITH NULL var current = 0 while(true) { - current = stb.indexOf('%', current) + 1 - if(current <= 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? + current = stb.indexOf('%', current) + if(current > 0 && stb[current - 1] == '\\') { + foundBackslashPercent = true + continue + } + if(++current <= 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? if(!stb.startsWith(key, current, false)) continue stb.replace(current - 1, current + key.length, replacement) current = current - 1 + replacement.length } } + + if(foundBackslashPercent) { + // Remove the \% to \ + var current = 0 + while(true) { + current = stb.indexOf("\\%", current) + if(current < 0) break + + stb.replace(current, current + 2, "%") + current++ + } + } } - private fun unformattedMonoline(vararg params: Any): String { + private fun unformattedMonoline(vararg params: Any?): String { val translated = Lang.getTranslated(key) if(params.isEmpty() && this.params.isEmpty()) return translated @@ -60,7 +92,7 @@ open class Message(val key: String, vararg val params: String, register: Boolean return stb.toString() } - private fun unformattedMultiline(section: ConfigurationSection, vararg params: Any): String { + private fun unformattedMultiline(section: ConfigurationSection, vararg params: Any?): String { val stb = StringBuilder() for(key in section.getKeys(false)) { @@ -74,14 +106,14 @@ open class Message(val key: String, vararg val params: String, register: Boolean return stb.toString() } - fun unformatted(vararg params: Any): String { + fun unformatted(vararg params: Any?): String { val section = Lang.getSection(key) if(section != null) return unformattedMultiline(section, *params) return unformattedMonoline(*params) } - private fun formattedMultiline(section: ConfigurationSection, vararg params: Any): List { + private fun formattedMultiline(section: ConfigurationSection, vararg params: Any?): MutableList { val result = ArrayList() for(key in section.getKeys(false)) { @@ -93,21 +125,21 @@ open class Message(val key: String, vararg val params: String, register: Boolean result.add(MiniMessageUtil.mm.deserialize(stb.toString())) } - if(result.isEmpty()) return listOf(Component.text(key)) + if(result.isEmpty()) return mutableListOf(Component.text(key)) return result } // return a list of AT LEAST 1 element. calling first is safe - fun formatted(vararg params: Any): List { + fun formatted(vararg params: Any?): MutableList { val section = Lang.getSection(key) if(section != null) return formattedMultiline(section, *params) val translated = unformattedMonoline(*params) - return listOf(MiniMessageUtil.mm.deserialize(translated)) + return mutableListOf(MiniMessageUtil.mm.deserialize(translated)) } - fun formattedConcatenated(vararg params: Any): Component { + fun formattedConcatenated(vararg params: Any?): Component { val formated = formatted(*params) var result = formated.first() @@ -118,11 +150,11 @@ open class Message(val key: String, vararg val params: String, register: Boolean return result } - fun textHolder(vararg params: Any): TextHolder { + fun textHolder(vararg params: Any?): TextHolder { return ComponentHolder.of(formattedConcatenated(*params)) } - fun legacy(vararg params: Any): String { + fun legacy(vararg params: Any?): String { val formated = formatted(*params) val stb = StringBuilder() @@ -133,7 +165,7 @@ open class Message(val key: String, vararg val params: String, register: Boolean return stb.toString() } - open fun log(vararg params: Any) { + open fun log(vararg params: Any?) { val texts = formatted(*params) for(component in texts) { @@ -141,14 +173,14 @@ open class Message(val key: String, vararg val params: String, register: Boolean } } - open fun send(destination: CommandSender, vararg params: Any) { + open fun send(destination: CommandSender, vararg params: Any?) { formatted(*params).send(destination) } } -class WarningMessage(key: String, vararg params: String) : Message("warning.$key", *params) { +class WarningMessage(key: String, vararg params: String): Message("warning.$key", *params) { - override fun log(vararg params: Any) { + override fun log(vararg params: Any?) { val texts = formatted(*params) for(component in texts) { @@ -157,9 +189,9 @@ class WarningMessage(key: String, vararg params: String) : Message("warning.$key } } -class ErrorMessage(key: String, vararg params: String) : Message("error.$key", *params) { +class ErrorMessage(key: String, vararg params: String): Message("error.$key", *params) { - override fun log(vararg params: Any) { + override fun log(vararg params: Any?) { val texts = formatted(*params) for(component in texts) { @@ -167,7 +199,7 @@ class ErrorMessage(key: String, vararg params: String) : Message("error.$key", * } } - fun log(e: Throwable, vararg params: Any, level: Level = Level.SEVERE, track: Boolean = true) { + fun log(e: Throwable, vararg params: Any?, level: Level = Level.SEVERE, track: Boolean = true) { val texts = formatted(*params) for(component in texts) { @@ -176,5 +208,5 @@ class ErrorMessage(key: String, vararg params: String) : Message("error.$key", * } } -class CommandMessage(key: String, vararg params: String) : Message("command.$key", *params) -class UIMessage(key: String, vararg params: String) : Message("config-ui.$key", *params) \ No newline at end of file +class CommandMessage(key: String, vararg params: String): Message("command.$key", *params) +class UIMessage(key: String, vararg params: String): Message("config-ui.$key", *params) \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt index 1a876e6e..a5734d44 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -6,6 +6,12 @@ object MsgUI { val SHARED_CONFIG_NO_EDIT_PERM = Message("shared.no-permission") val SHARED_TYPED_CONFIG_TITLE = Message("shared.typed-config-title", "type") + val SHARED_CLICK_TO_CHANGE = Message("shared.click-to-change") + val SHARED_GREEN_GET_ITEM = Message("shared.green-get-item", "name") + val SHARED_YELLOW_GET_ITEM = Message("shared.yellow-get-item", "name") + + val GLOBAL_ITEM_ITEM_LORE_PREFIX = Message("global-item.item-lore-prefix", "value") + val GLOBAL_ITEM_ITEM_LORE_PREFIX_ALONE = Message("global-item.item-lore-prefix-alone", "value") val CONFIRM_ACTION_FAILED = Message("confirm-action.fail") val CONFIRM_ACTION_ARE_YOU_SURE = Message("confirm-action.is-user-sure") @@ -16,44 +22,145 @@ object MsgUI { val ELEMENT_LIST_CANCELLED_NEW = Message("element-list.cancelled-new", "type") val ELEMENT_LIST_DUPLICATED_NEW = Message("element-list.duplicated-new", "type") - val UNIT_REPAIR_TITLE = Message("unit-repair.title", "unused", "page", "max_page") + val UNIT_REPAIR_TITLE = Message("unit-repair.title", null, "page", "max_page") + val UNIT_REPAIR_ITEM = Message("unit-repair.item", "name", "unit") val UNIT_REPAIR_ELEMENT_TITLE = Message("unit-repair.element.title", "type", "page", "max_page") - val UNIT_REPAIR_NEW_TITLE = Message("unit-repair.new.title") - val UNIT_REPAIR_NEW_DESCRIPTION = Message("unit-repair.new.description") + val UNIT_REPAIR_NEW_TITLE = Message("unit-repair.new.title", null) + val UNIT_REPAIR_NEW_DESCRIPTION = Message("unit-repair.new.description", null) - val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", "unused") + val UNIT_REPAIR_ELEMENT_VALUE_TITLE = Message("unit-repair.element.value.title", "name", null) + val UNIT_REPAIR_ELEMENT_VALUE_DESCRIPTION = Message("unit-repair.element.value.description", "name", "unit") + + val UNIT_REPAIR_NEW_ELEMENT_TITLE = Message("unit-repair.element.new.title", null) val UNIT_REPAIR_NEW_ELEMENT_DESCRIPTION = Message("unit-repair.element.new.description", "name") val UNIT_REPAIR_NEW_ELEMENT_CANNOT_REPAIR = Message("unit-repair.element.new.cannot-damage") val UNIT_REPAIR_NEW_ELEMENT_SAME_TYPE = Message("unit-repair.element.new.same-type") - val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title", "unused", "page", "max_page") + val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title", null, "page", "max_page") + + val CUSTOM_RECIPE_ELEMENT_EXACT_COUNT_TITLE = Message("custom-recipe.element.exact-count") + val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_TITLE = Message("custom-recipe.element.linear-xp.title") + val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_NAME = Message("custom-recipe.element.linear-xp.name") + val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_LORE = Message("custom-recipe.element.linear-xp.lore") + val CUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP = Message("custom-recipe.element.recipe-cost.level") + val CUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP = Message("custom-recipe.element.recipe-cost.xp") + + val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_TITLE = Message("custom-recipe.element.item.left.title") + val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION = Message("custom-recipe.element.item.left.description") + val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_TITLE = Message("custom-recipe.element.item.right.title") + val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION = Message("custom-recipe.element.item.right.description") + val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_TITLE = Message("custom-recipe.element.item.result.title") + val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION = Message("custom-recipe.element.item.result.description") val CUSTOM_RECIPE_ELEMENT_DELETE_TITLE = Message("custom-recipe.element.delete.title", "type") - val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", "unused") + val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", null) + val CUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_NAME = Message("custom-recipe.element.delete.button.name") + val CUSTOM_RECIPE_ELEMENT_DELETE_BUTTON_LORE = Message("custom-recipe.element.delete.button.lore") - val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title", "unused", "page", "max_page") + val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title", null, "page", "max_page") + val ENCHANTMENT_LEVEL_COST_ELEMENT_TITLE = Message("enchant-level-cost.element.title", "name") + val ENCHANTMENT_LEVEL_COST_ELEMENT_DESCRIPTION = Message("enchant-level-cost.element.description", "name") + val ENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST = Message("enchant-level-cost.element.item-cost") + val ENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST = Message("enchant-level-cost.element.book-cost") - val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title", "unused", "page", "max_page") + val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title", null, "page", "max_page") + val ENCHANTMENT_LEVEL_LIMIT_ELEMENT_TITLE = Message("enchant-level-limit.element.title", "name") + val ENCHANTMENT_LEVEL_LIMIT_ELEMENT_DESCRIPTION = Message("enchant-level-limit.element.description", "name") - val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title", "unused", "page", "max_page") + val ENCHANTMENT_MERGE_LIMIT_TITLE = Message("enchant-merge-limit.title", null, "page", "max_page") + val ENCHANTMENT_MERGE_LIMIT_ELEMENT_TITLE = Message("enchant-merge-limit.element.title", "name") + val ENCHANTMENT_MERGE_LIMIT_ELEMENT_DESCRIPTION = Message("enchant-merge-limit.element.description", "name") - val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title", "unused", "page", "max_page") + val ENCHANTMENT_CONFLICT_TITLE = Message("enchant-conflict.title", null, "page", "max_page") val ENCHANTMENT_CONFLICT_ELEMENT_ENCHANTMENTS = Message("enchant-conflict.element.selected-enchantments", "group") val ENCHANTMENT_CONFLICT_ELEMENT_SUB_GROUPS = Message("enchant-conflict.element.selected-sub-groups", "group") val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_TITLE = Message("enchant-conflict.element.delete.title", "type") - val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", "unused") + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", null) + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_NAME = Message("enchant-conflict.element.delete.button.name") + val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_LORE = Message("enchant-conflict.element.delete.button.lore") + val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE = Message("enchant-conflict.element.min-before-count.title") + val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION = Message("enchant-conflict.element.min-before-count.description") + val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_ITEM = Message("enchant-conflict.element.min-before-count.item") - val MATERIAL_GROUP_TITLE = Message("material-group.title", "unused", "page", "max_page") + val MATERIAL_GROUP_TITLE = Message("material-group.title", null, "page", "max_page") val MATERIAL_GROUP_ELEMENT_SELECTED_MATERIALS = Message("material-group.element.selected-materials", "group") val MATERIAL_GROUP_ELEMENT_SELECTED_SUB_GROUPS = Message("material-group.element.selected-sub-groups", "group") val MATERIAL_GROUP_ELEMENT_DELETE_TITLE = Message("material-group.element.delete.title", "type") - val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", "unused") + val MATERIAL_GROUP_ELEMENT_DELETE_DESCRIPTION = Message("material-group.element.delete.description", null) val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_NAME = Message("material-group.element.delete.button.name") val MATERIAL_GROUP_ELEMENT_DELETE_BUTTON_LORE = Message("material-group.element.delete.button.lore") - val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.new.confirm.title","name") - val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.new.confirm.description","name") + val MATERIAL_SELECT_CONFIRM_TITLE = Message("material-select.new.confirm.title", "name") + val MATERIAL_SELECT_CONFIRM_DESCRIPTION = Message("material-select.new.confirm.description", "name") + + /* + * ------------------ + * Basic Config Gui + * ------------------ + */ + val BASIC_TITLE = Message("basic-config.title") + + val BASIC_CAP_ANVIL_COST_TITLE = Message("basic-config.cap-anvil-cost.title") + val BASIC_CAP_ANVIL_COST_DESCRIPTION = Message("basic-config.cap-anvil-cost.description") + val BASIC_CAP_ANVIL_COST_ITEM = Message("basic-config.cap-anvil-cost-cost.item") + val BASIC_CAP_ANVIL_COST_DISABLED_TITLE = Message("basic-config.cap-anvil-cost.disabled.title") + val BASIC_CAP_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.cap-anvil-cost.disabled.description") + + val BASIC_MAX_ANVIL_COST_TITLE = Message("basic-config.max-anvil-cost.title") + val BASIC_MAX_ANVIL_COST_DESCRIPTION = Message("basic-config.max-anvil-cost.description") + val BASIC_MAX_ANVIL_COST_ITEM = Message("basic-config.max-anvil-cost.item") + val BASIC_MAX_ANVIL_COST_DISABLED_TITLE = Message("basic-config.max-anvil-cost.disabled.title") + val BASIC_MAX_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.max-anvil-cost.disabled.description") + + val BASIC_REMOVE_COST_LIMIT_TITLE = Message("basic-config.remove-cost-limit.title") + val BASIC_REMOVE_COST_LIMIT_DESCRIPTION = Message("basic-config.remove-cost-limit.description") + val BASIC_REMOVE_COST_LIMIT_ITEM = Message("basic-config.remove-cost-limit.item") + + val BASIC_REPLACE_TOO_EXPENSIVE_TITLE = Message("basic-config.remove-too-expensive.title") + val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION = Message("basic-config.remove-too-expensive.description") + val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION_NO_NMS = Message("basic-config.remove-too-expensive.description-no-nms") + + val BASIC_ITEM_REPAIR_COST_TITLE = Message("basic-config.item-repair-cost.title") + val BASIC_ITEM_REPAIR_COST_DESCRIPTION = Message("basic-config.item-repair-cost.description") + + val BASIC_ITEM_RENAME_COST_TITLE = Message("basic-config.item-rename-cost.title") + val BASIC_ITEM_RENAME_COST_DESCRIPTION = Message("basic-config.item-rename-cost.description") + + val BASIC_UNIT_REPAIR_COST_TITLE = Message("basic-config.unit-repair-cost.title") + val BASIC_UNIT_REPAIR_COST_DESCRIPTION = Message("basic-config.unit-repair-cost.description") + + val BASIC_SACRIFICE_ILLEGAL_COST_TITLE = Message("basic-config.sacrifice-illegal-cost.title") + val BASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION = Message("basic-config.sacrifice-illegal-cost.description") + + + val BASIC_COLOR_CODE_LIMIT_TITLE = Message("basic-config.color-code.title") + val BASIC_COLOR_CODE_LIMIT_DESCRIPTION = Message("basic-config.color-code.description") + + val BASIC_COLOR_HEX_LIMIT_TITLE = Message("basic-config.color-hex.title") + val BASIC_COLOR_HEX_LIMIT_DESCRIPTION = Message("basic-config.color-hex.description") + + val BASIC_COLOR_PERMISSION_TITLE = Message("basic-config.color-permission.title") + val BASIC_COLOR_PERMISSION_DESCRIPTION = Message("basic-config.color-permission.description") + val BASIC_COLOR_PERMISSION_DISABLED_TITLE = Message("basic-config.color-permission.disabled.title") + val BASIC_COLOR_PERMISSION_DISABLED_DESCRIPTION = Message("basic-config.color-permission.disabled.description") + + val BASIC_COLOR_COST_TITLE = Message("basic-config.color-cost.title") + val BASIC_COLOR_COST_DESCRIPTION = Message("basic-config.color-cost.description") + val BASIC_COLOR_COST_ITEM = Message("basic-config.color-cost.item") + val BASIC_COLOR_COST_DISABLED_TITLE = Message("basic-config.color-cost.disabled.title") + val BASIC_COLOR_COST_DISABLED_DESCRIPTION = Message("basic-config.color-cost.disabled.description") + + val BASIC_WORK_PENALTY_TITLE = Message("basic-config.work-penalty.title") + val BASIC_WORK_PENALTY_ITEM = Message("basic-config.work-penalty.item") + val BASIC_WORK_PENALTY_LORE = Message("basic-config.work-penalty.lore") + val BASIC_WORK_PENALTY_LORE_BREAK = Message("basic-config.work-penalty.lore-break") + val BASIC_WORK_PENALTY_EXPLAIN_INCREASING = Message("basic-config.work-penalty.explanation.increasing") + val BASIC_WORK_PENALTY_EXPLAIN_ADDITIVE = Message("basic-config.work-penalty.explanation.additive") + val BASIC_WORK_PENALTY_EXPLAIN_SHARED = Message("basic-config.work-penalty.explanation.shared") + val BASIC_WORK_PENALTY_EXPLAIN_EXCLUSIVE = Message("basic-config.work-penalty.explanation.exclusive") + + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt index 261e085a..a9171131 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/ComponentUtil.kt @@ -31,7 +31,7 @@ object ComponentUtil { destination.sendMessage(this.serializeLegacy()) } - fun List.send(destination: CommandSender) { + fun Collection.send(destination: CommandSender) { for(component in this) component.send(destination) } @@ -41,8 +41,25 @@ object ComponentUtil { meta.lore = this.map {obj -> obj.serializeLegacy()} } - fun ItemMeta.setMessageName(message: Message, vararg params: Any) { + fun ItemMeta.setMessageName(message: Message, vararg params: Any?) { this.setComponentDisplayName(message.formattedConcatenated(*params)) } + fun List.asComponents(vararg params: Any?): List { + val result = ArrayList() + for(message in this) { + result.addAll(message.formatted(*params)) + } + return result + } + + fun Array.asComponents(vararg params: Any?): List { + val result = ArrayList() + for(message in this) { + result.addAll(message.formatted(*params)) + } + return result + } + + } \ No newline at end of file diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 87527ea1..4f90bb34 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -1,8 +1,7 @@ name: English last-updated: 2.1.0 -warning: - load: +warning.load: legacy: old-name: 1: "An old version of this plugin was detected" @@ -14,11 +13,11 @@ warning: 1: "If replace too expensive is not working this is likely because of spigot" 2: "As native nms is not supported for spigot starting 26.1" update.available: "An update may be available: %version" - anvil: + +warning.anvil: generic: "[CustomAnvil] Error while handling the anvil." -error: - load: +error.load: legacy.failed: "error trying to check for legacy system" update.check-fail: "error trying to fetch latest update" command-register: "error trying to register commands" @@ -27,16 +26,15 @@ error: enchant-system: "error initializing enchantment system" non-default-config: "Plugin has an issue while trying to load non default config... exiting..." - reload: +error.reload: resource: fail: "Resource %path Could not be loaded or reloaded." hard-fail: "Disabling plugin." - confirm-action: +error.confirm-action: generic: "Could not process confirmation supplier." -command: - shared: +command.shared: no-diag-permission: "You do not have permission to diagnostic this server" hover-copy: "Click to copy" unknown-subcmd: "Unknown subcommand %command" @@ -44,13 +42,13 @@ command: warning: missing-subcmd: "Need to specify a subcommand. for example %example1 or %example2" - root: +command.root: warning: unknown-sub: "Invalid subcommand. run `%command help` to see available commands" error: generic: "Error running this command" - debug: +command.debug: description: "Used to toggle debug logs and retrieve them" log-cleared: "Log Cleared" toggled: "Debug toggled to %type" @@ -64,12 +62,12 @@ command: invalid-type: "Invalid debug type \"%type\"" no-log: "No log to show ? make sure you tried with debug log toggled (%command)" - diagnostic: +command.diagnostic: description: "Basic diagnostic of this plugin" had-error: "There was an error running the diagnostic" copy: "Click to copy diagnostic data" - config: +command.config: description: "Used to edit the configuration of the plugin" folia-issue: 1: "It look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia." @@ -84,7 +82,7 @@ command: legacy-name: "/ca gui has been moved to /ca config" cannot_configure: "Cannot configure the item in hand" - enchant: +command.enchant: description: "Allows to set enchantment to holden item" warning: missing_parameter: "Missing enchantment parameter" @@ -94,38 +92,46 @@ command: removed: "%name removed" set: "%name set to level %level" - help: +command.help: description: "Help command" header: "List of available commands:" - reload: +command.reload: description: "Reload the configuration of this plugin" start: "Reloading config..." success: "Config reloaded !" fail: "Config was not able to be reloaded..." hard-fail: "Hard fail, plugin disabled" -config-ui: - shared: + +config-ui.shared: no-permission: "You do not have permission to edit the config" typed-config-title: "%type Config" + click-to-change: "Click Here to change the value" + green-get-item: "%name" + yellow-get-item: "%name" - confirm-action: +config-ui.global-item: + item-lore-prefix: "value: %value" + item-lore-prefix-alone: "%value" + +config-ui.confirm-action: fail: "Action could not be completed." is-user-sure: "Are you sure ?" - select-item-type: +config-ui.select-item-type: place-here: "Place an item here" - element-list: +config-ui.element-list: instruction-new: 1: "Write the %type name you want to create in the chat." 2: "Or write cancel to go back to %type config menu" cancelled-new: "%type creation cancelled..." duplicated-new: "Please enter a %type name that do not already exist..." - unit-repair: +config-ui.unit-repair: title: "Unit Repair Config (%page/%max_page)" + item: "\\%%name repaired by %unit" new: title: "Select unit repair item." description: @@ -133,6 +139,11 @@ config-ui: 2: "You like to be an unit repair item" element: title: "%type Unit repair (%page/%max_page)" + value: + title: "\\%%name Repair" + description: + 1: "Click here to change how many \\% of %name" + 2: "Should get repaired by %unit" new: title: "Select item to be repaired." description: @@ -141,23 +152,71 @@ config-ui: cannot-damage: "This item can't be damaged, so it can't be repaired." same-type: "Item can't repair something of the same type." - custom-recipe: +config-ui.custom-recipe: title: "Custom Recipe Config (%page/%max_page)" element: + exact-count: "Exact count ?" + linear-xp: + title: "Remove exact linear xp ?" + name: "Remove exact linear xp ?" + lore: "Not usable if linear cost is 0" + recipe-cost: + level: "recipe Level Cost" + xp: "Recipe Linear Xp Cost" + item: + left: + title: "Recipe Left Item" + description: + 1: "Set the left item of the custom craft" + 2: "■ + □ = □" + right: + title: "Recipe Right Item" + description: + 1: "Set the right item of the custom craft" + 2: "□ + ■ = □" + result: + title: "Recipe Result Item" + description: + 1: "Set the result item of the custom craft" + 2: "□ + □ = ■" delete: title: "Delete %type?" description: "Confirm that you want to delete this recipe." + button: + name: "DELETE RECIPE" + lore: "Caution with this button !" - enchant-level-cost: +config-ui.enchant-level-cost: title: "Enchantment Level Limit (%page/%max_page)" + element: + title: "%name Cost" + description: + 1: "How many level should %name" + 2: "cost when applied by book or by another item." - enchant-level-limit: + item-cost: "Item Cost: %cost" + book-cost: "Book Cost: %cost" + +config-ui.enchant-level-limit: title: "Enchantment Level Limit (%page/%max_page)" + element: + title: "%name Limit" + description: + 1: "Maximum applied level of %name" - enchant-merge-limit: +config-ui.enchant-merge-limit: title: "Enchantment Maximum Merge Level (%page/%max_page)" + element: + title: "%name Merge Limit" + description: + 1: "Maximum merge level for for %name" + 2: "" + 3: "For example, if set to 2, lvl1 + lvl1 of will give a lvl2" + 4: "But lvl2 + lvl2 will not give a lv3." + 5: "Will still not merge above max enchantment level" + 6: "-1 (default) will set the merge limit to enchantment's maximum level" - enchant-conflict: +config-ui.enchant-conflict: title: "Conflict Config (%page/%max_page)" element: selected-enchantments: "%group" # likely need page and max page @@ -165,8 +224,17 @@ config-ui: delete: title: "Delete %type?" description: "Confirm that you want to delete this conflict." + button: + name: "DELETE CONFLICT" + lore: "Caution with this button !" + min-before-count: + item: "Minimum Enchantment Count" + title: "Minimum enchantment count" + description: + 1: "Minimum enchantment count set to X mean only X enchantment can be put" + 2: "on an item before the conflict is active." - material-group: +config-ui.material-group: title: "Group Config (%page/%max_page)" element: selected-materials: "%group Materials" @@ -178,8 +246,134 @@ config-ui: name: "DELETE GROUP" lore: "Caution with this button !" - material-select: +config-ui.material-select: new: confirm: title: "Remove %name" description: "Confirm Remove %name from this list." + +config-ui.basic-config: + title: "Basic Config" + +config-ui.basic-config.cap-anvil-cost: + item: "Cap Anvil Cost" + title: "Cap Anvil Cost ?" + description: + 1: "All anvil cost will be capped to Max Anvil Cost if enabled." + 2: "In other words:" + 3: "For any anvil cost greater than Max Anvil Cost, Cost will be set to Max Anvil Cost." + disabled: + title: "Cap Anvil Cost ?" + description: "This config only work if Limit Repair Cost is disabled." + +config-ui.basic-config.max-anvil-cost: + item: "Max Anvil Cost" + title: "Max Anvil Cost" + description: + 1: "Max cost the Anvil can get to." + 2: "Valid values include 0 to 1000." + 3: "Cost will be displayed as Too Expensive:" + 4: "- If Cost is above 39" + 5: "- And Replace Too Expensive is disabled" + disabled: + title: "Max Anvil Cost" + description: "This config only work if Limit Repair Cost is disabled." + +config-ui.basic-config.remove-cost-limit: + item: "Remove Anvil Cost Limit" + title: "Remove Anvil Cost Limit ?" + description: + 1: "Whether the anvil's cost limit should be removed entirely." + 2: "The anvil will still visually display Too Expensive if Replace Too Expensive is disabled." + 3: "However, the action will be completable if xp requirement is meet." + +config-ui.basic-config.remove-too-expensive: + title: "Replace Too Expensive ?" + description: + 1: "Whenever anvil cost is above 39 should display the true price and not Too Expensive." + 2: "However, when bypassing Too Expensive, anvil price will be displayed as Green." + 3: "Even if cost is displayed as Green:" + 4: "If the player do not have the required xp level, the action will not be completable." + description-no-nms: + 1: "" + 2: "/!\\Caution/!\\ You need ProtocoLib installed and working, or a paper server." + 3: "Currently ProtocoLib is not detected." + +config-ui.basic-config.item-repair-cost: + title: "Item Repair Cost" + description: + 1: "XP Level amount added to the anvil when the item" + 2: "is repaired by another item of the same type." + +config-ui.basic-config.item-rename-cost: + title: "Rename Cost" + description: + 1: "XP Level amount added to the anvil when the item is renamed." + +config-ui.basic-config.unit-repair-cost: + title: "Unit Repair Cost" + description: + 1: "XP Level amount added to the anvil when the item is repaired by an unit." + 2: "For example: a Diamond on a Diamond Sword." + 3: "What's considered unit for what can be edited on the unit repair configuration." + +config-ui.basic-config.sacrifice-illegal-cost: + title: "Sacrifice Illegal Enchant Cost" + description: + 1: "XP Level amount added to the anvil when a sacrifice enchantment" + 2: "conflict With one of the left item enchantment" + +config-ui.basic-config.color-code: + title: "Allow Use Of Color Code ?" + description: + 1: "Whether players can use color code." + 2: "Color code a formatted like &a and is used in the rename field of the anvil." + 3: "Player may need permission to use color code if Player need permission to use color is enabled." + +config-ui.basic-config.color-hex: + title: "Allow Use Of Hexadecimal Color ?" + description: + 1: "Whether players can use hexadecimal color." + 2: "Color code a formatted like #012345 and is used in the rename field of the anvil." + 3: "Player may need permission to use color code if Permission Needed For Color is enabled." + +config-ui.basic-config.color-permission: + title: "Need Permission To Use Color ?" + description: + 1: "Whether players should have permission to be able to use colors." + 2: "Give player ca.color.code Permission to allow use of color code." + 3: "Give player ca.color.hex Permission to allow use of hexadecimal color." + disabled: + title: "Need Permission To Use Color ?" + description: + 1: "This config can do something only if one of the following config is enabled:" + 2: "- Allow Use Of Color Code" + 3: "- Allow Use Of Hexadecimal Color" + +config-ui.basic-config.color-cost: + item: "Cost Of Using Color" + title: "Cost Of Using Color" + description: + 1: "XP level cost when using color code or hexadecimal color using the anvil." + 2: "conflict With one of the left item enchantment" + disabled: + title: "Cost Of Using Color" + description: + 1: "This config can do something only if one of the following config is enabled:" + 2: "- Allow Use Of Color Code" + 3: "- Allow Use Of Hexadecimal Color" + +config-ui.basic-config.work-penalty: + title: "Work Penalty Type" + item: "Work Penalty Type" + lore: + 1: "Work penalty increase the price for every anvil use." + 2: "This config allow you to choose the comportment of work penalty." + lore-break: + 1: "" + 2: "About shared/exclusive penalty:" + explanation: + increasing: "Increasing: will penalty be increased (in item)" + additive: "Additive: will penalty be added to the cost" + shared: "Shared: Vanilla, shared penalty. it will be kept from before the plugin installation." + exclusive: "Exclusive: Custom, per anvil use type penalty. it will be lost after plugin uninstallation" \ No newline at end of file From 7a92b94437b042d04d960990684c7726d839a429 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 20 Aug 2026 14:23:11 +0200 Subject: [PATCH 12/13] fix small issues --- .../gui/config/global/BasicConfigGui.java | 12 +-- .../elements/CustomRecipeSubSettingGui.java | 10 +-- .../EnchantConflictSubSettingGui.java | 2 +- .../config/settings/AbstractSettingGui.java | 10 ++- .../gui/config/settings/BoolSettingsGui.java | 4 +- .../gui/config/settings/DoubleSettingGui.java | 2 +- .../gui/config/settings/EnumSettingGui.java | 11 ++- .../gui/config/settings/IntSettingsGui.java | 2 +- .../gui/config/settings/ItemSettingGui.java | 9 ++- .../cuanvil/command/DebugToggleExecutor.kt | 2 +- .../xyz/alexcrea/cuanvil/lang/Message.kt | 10 +-- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 78 +++++++++---------- src/main/resources/lang/en.yml | 12 +-- 13 files changed, 89 insertions(+), 75 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 149a4aa0..3f958e57 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 @@ -125,7 +125,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.maxAnvilCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_TITLE(), this, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_MAX_ANVIL_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_MAX_ANVIL_COST, 1, 5, 10 @@ -166,7 +166,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.itemRepairCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_TITLE(), this, ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_ITEM_REPAIR_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_REPAIR_COST, 1, 5, 10, 50, 100 @@ -176,7 +176,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.unitRepairCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_TITLE(), this, ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_UNIT_REPAIR_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_UNIT_REPAIR_COST, 1, 5, 10, 50, 100 @@ -187,7 +187,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.itemRenameCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_TITLE(), this, ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_ITEM_RENAME_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_RENAME_COST, 1, 5, 10, 50, 100 @@ -198,7 +198,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_TITLE(), this, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, 1, 5, 10, 50, 100 @@ -247,7 +247,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { this.useOfColorCost = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getBASIC_COLOR_COST_TITLE(), this, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, - MsgUI.INSTANCE.getBASIC_COLOR_COST_DESCRIPTION(), + MsgUI.INSTANCE.getBASIC_COLOR_COST_DESCRIPTION(), null, range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_USE_OF_COLOR_COST, 1, 5, 10, 50, 100 diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java index 47d4380f..8f5fb0f0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/CustomRecipeSubSettingGui.java @@ -112,7 +112,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP(), this, this.anvilRecipe + "." + AnvilCustomRecipe.XP_LEVEL_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, - null, + null, null, costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_LEVEL_COST_CONFIG, 1, 5, 10 ); @@ -120,7 +120,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP(), this, this.anvilRecipe + "." + AnvilCustomRecipe.LINEAR_XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, - null, + null, null, 0, Integer.MAX_VALUE, AnvilCustomRecipe.DEFAULT_LINEAR_XP_COST_CONFIG, 1, 10, 100, 1000, 10000 ); @@ -131,7 +131,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(), - MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION() + null, MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION() ); this.rightItemFactory = new ItemSettingGui.ItemSettingFactory( @@ -139,7 +139,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(), - MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION() + null, MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION() ); this.resultItemFactory = new ItemSettingGui.ItemSettingFactory( @@ -147,7 +147,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui { this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(), - MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION() + null, MsgUI.INSTANCE.getCUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION() ); // Now we update the items diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java index 0c352286..093e9f6f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/EnchantConflictSubSettingGui.java @@ -100,7 +100,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl this.minBeforeActiveSettingFactory = new IntSettingsGui.IntSettingFactory( MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE(), this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER, - MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION(), + MsgUI.INSTANCE.getENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION(), null, 0, 255, 0, 1 ); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java index 3544017a..8c6f1cb2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java @@ -8,6 +8,7 @@ import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import io.delilaheve.CustomAnvil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; @@ -39,8 +40,13 @@ public abstract class AbstractSettingGui extends ChestGui implements SettingGui * @param title Title of this gui. * @param parent Parent gui to go back when completed. */ - protected AbstractSettingGui(int rows, @NotNull Message title, ValueUpdatableGui parent) { - this(rows, title.textHolder(), parent); + protected AbstractSettingGui( + int rows, + @NotNull Message title, + ValueUpdatableGui parent, + @Nullable Object... params + ) { + this(rows, title.textHolder(params), parent); } protected GuiItem saveItem; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java index f02b731b..00053e3f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java @@ -43,7 +43,7 @@ public class BoolSettingsGui extends AbstractSettingGui { * @param now The defined value of this setting. */ protected BoolSettingsGui(BoolSettingFactory holder, boolean now) { - super(3, holder.getTitle(), holder.parent); + super(3, holder.getTitle(), holder.parent, holder.param); this.holder = holder; this.before = now; this.now = now; @@ -112,7 +112,7 @@ public class BoolSettingsGui extends AbstractSettingGui { // create & set Value item ArrayList valueLore = new ArrayList<>(); if(holder.displayLore != null){ - valueLore.addAll(ComponentUtil.INSTANCE.asComponents(holder.displayLore)); + valueLore.addAll(ComponentUtil.INSTANCE.asComponents(holder.displayLore, holder.param)); valueLore.add(Component.empty()); } valueLore.addAll(MsgUI.INSTANCE.getSHARED_CLICK_TO_CHANGE().formatted()); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java index 1d14a566..e5f23bdf 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java @@ -52,7 +52,7 @@ public class DoubleSettingGui extends AbstractSettingGui { */ protected DoubleSettingGui(DoubleSettingFactory holder, @NotNull BigDecimal now, boolean asPercentage, boolean nullOnZero) { - super(3, holder.getTitle(), holder.parent); + super(3, holder.getTitle(), holder.parent, holder.param, holder.param2); assert holder.steps.length > 0 && holder.steps.length <= 9; this.holder = holder; this.asPercentage = asPercentage; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java index 9ff90d8a..04011b88 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnumSettingGui.java @@ -11,6 +11,7 @@ import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; @@ -34,7 +35,7 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> * @param now The defined value of this setting. */ protected EnumSettingGui(EnumSettingFactory holder, T now) { - super(3, holder.getTitle(), holder.parent); + super(3, holder.getTitle(), holder.parent, holder.param); this.holder = holder; this.before = now; this.now = now; @@ -139,6 +140,8 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> public abstract static class EnumSettingFactory & ConfigurableEnum> extends SettingGuiFactory { @NotNull Message title; + @Nullable + Object param; @NotNull ValueUpdatableGui parent; @@ -151,12 +154,14 @@ public class EnumSettingGui & EnumSettingGui.ConfigurableEnum> * @param config Configuration holder of this setting. */ protected EnumSettingFactory( - @NotNull Message title, @NotNull ValueUpdatableGui parent, + @NotNull Message title, @Nullable Object param, + @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config) { super(configPath, config); this.title = title; - this.parent = parent; + this.param = param; + this.parent = parent; } /** * @return Get setting's gui title. diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java index 13cf72e5..fa9e852e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java @@ -45,7 +45,7 @@ public class IntSettingsGui extends AbstractSettingGui { * @param now The defined value of this setting. */ protected IntSettingsGui(IntSettingFactory holder, int now) { - super(3, holder.getTitle(), holder.parent); + super(3, holder.getTitle(), holder.parent, holder.param); assert holder.steps.length > 0 && holder.steps.length <= 9; this.holder = holder; this.before = now; diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java index 81de4586..9e45ccc9 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java @@ -43,7 +43,7 @@ public class ItemSettingGui extends AbstractSettingGui { * @param now The defined value of this setting. */ protected ItemSettingGui(ItemSettingFactory holder, ItemStack now) { - super(3, holder.getTitle(), holder.parent); + super(3, holder.getTitle(), holder.parent, holder.param); this.holder = holder; this.before = now; this.now = now; @@ -178,6 +178,8 @@ public class ItemSettingGui extends AbstractSettingGui { ItemStack defaultVal; @NotNull List displayLore; + @Nullable + Object param; /** * Constructor for an item setting gui factory. @@ -193,13 +195,14 @@ public class ItemSettingGui extends AbstractSettingGui { @NotNull Message title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, @Nullable ItemStack defaultVal, - Message... displayLore) { + @Nullable Object param, Message... displayLore) { super(configPath, config); this.title = title; this.parent = parent; this.defaultVal = defaultVal; this.displayLore = Arrays.asList(displayLore); + this.param = param; } /** @@ -250,7 +253,7 @@ public class ItemSettingGui extends AbstractSettingGui { //TODO MESSAGE name ? meta.setDisplayName("§a" + name); - ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(getDisplayLore()), meta); + ComponentUtil.INSTANCE.applyLore(ComponentUtil.INSTANCE.asComponents(getDisplayLore(), param), meta); meta.addItemFlags(ItemFlag.values()); item.setItemMeta(meta); diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt index 17ae3796..e33b841c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DebugToggleExecutor.kt @@ -231,7 +231,7 @@ class DebugToggleExecutor: CASubCommand { break } } - if(found) break + if(found) continue hadIssue = true stb.append("Did not found param %$textParam in register list for ${message.key}\n") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt index 82a43ba5..9215e7e0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/Message.kt @@ -53,13 +53,13 @@ open class Message(val key: String, vararg val params: String?, register: Boolea } val replacement = value.toString() - if(replacement.isEmpty()) continue //May not be good but can be changed if cause an issue //TODO REPLACE WITH NULL var current = 0 while(true) { current = stb.indexOf('%', current) if(current > 0 && stb[current - 1] == '\\') { foundBackslashPercent = true + current++ continue } if(++current <= 0 || current + key.length > stb.length) break // may be able to be removed if bound checked in startsWith ? @@ -178,7 +178,7 @@ open class Message(val key: String, vararg val params: String?, register: Boolea } } -class WarningMessage(key: String, vararg params: String): Message("warning.$key", *params) { +class WarningMessage(key: String, vararg params: String?): Message("warning.$key", *params) { override fun log(vararg params: Any?) { val texts = formatted(*params) @@ -189,7 +189,7 @@ class WarningMessage(key: String, vararg params: String): Message("warning.$key" } } -class ErrorMessage(key: String, vararg params: String): Message("error.$key", *params) { +class ErrorMessage(key: String, vararg params: String?): Message("error.$key", *params) { override fun log(vararg params: Any?) { val texts = formatted(*params) @@ -208,5 +208,5 @@ class ErrorMessage(key: String, vararg params: String): Message("error.$key", *p } } -class CommandMessage(key: String, vararg params: String): Message("command.$key", *params) -class UIMessage(key: String, vararg params: String): Message("config-ui.$key", *params) \ No newline at end of file +class CommandMessage(key: String, vararg params: String?): Message("command.$key", *params) +class UIMessage(key: String, vararg params: String?): Message("config-ui.$key", *params) \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt index a5734d44..c042b97c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt @@ -38,19 +38,19 @@ object MsgUI { val CUSTOM_RECIPE_TITLE = Message("custom-recipe.title", null, "page", "max_page") - val CUSTOM_RECIPE_ELEMENT_EXACT_COUNT_TITLE = Message("custom-recipe.element.exact-count") - val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_TITLE = Message("custom-recipe.element.linear-xp.title") + val CUSTOM_RECIPE_ELEMENT_EXACT_COUNT_TITLE = Message("custom-recipe.element.exact-count", null) + val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_TITLE = Message("custom-recipe.element.linear-xp.title", null) val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_NAME = Message("custom-recipe.element.linear-xp.name") val CUSTOM_RECIPE_ELEMENT_LINEAR_XP_LORE = Message("custom-recipe.element.linear-xp.lore") - val CUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP = Message("custom-recipe.element.recipe-cost.level") - val CUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP = Message("custom-recipe.element.recipe-cost.xp") + val CUSTOM_RECIPE_ELEMENT_COST_LEVEL_XP = Message("custom-recipe.element.recipe-cost.level", null) + val CUSTOM_RECIPE_ELEMENT_COST_LINEAR_XP = Message("custom-recipe.element.recipe-cost.xp", null) - val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_TITLE = Message("custom-recipe.element.item.left.title") - val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION = Message("custom-recipe.element.item.left.description") - val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_TITLE = Message("custom-recipe.element.item.right.title") - val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION = Message("custom-recipe.element.item.right.description") - val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_TITLE = Message("custom-recipe.element.item.result.title") - val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION = Message("custom-recipe.element.item.result.description") + val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_TITLE = Message("custom-recipe.element.item.left.title", null) + val CUSTOM_RECIPE_ELEMENT_ITEM_LEFT_DESCRIPTION = Message("custom-recipe.element.item.left.description", null) + val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_TITLE = Message("custom-recipe.element.item.right.title", null) + val CUSTOM_RECIPE_ELEMENT_ITEM_RIGHT_DESCRIPTION = Message("custom-recipe.element.item.right.description", null) + val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_TITLE = Message("custom-recipe.element.item.result.title", null) + val CUSTOM_RECIPE_ELEMENT_ITEM_RESULT_DESCRIPTION = Message("custom-recipe.element.item.result.description", null) val CUSTOM_RECIPE_ELEMENT_DELETE_TITLE = Message("custom-recipe.element.delete.title", "type") val CUSTOM_RECIPE_ELEMENT_DELETE_DESCRIPTION = Message("custom-recipe.element.delete.description", null) @@ -60,8 +60,8 @@ object MsgUI { val ENCHANTMENT_LEVEL_COST_TITLE = Message("enchant-level-cost.title", null, "page", "max_page") val ENCHANTMENT_LEVEL_COST_ELEMENT_TITLE = Message("enchant-level-cost.element.title", "name") val ENCHANTMENT_LEVEL_COST_ELEMENT_DESCRIPTION = Message("enchant-level-cost.element.description", "name") - val ENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST = Message("enchant-level-cost.element.item-cost") - val ENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST = Message("enchant-level-cost.element.book-cost") + val ENCHANTMENT_LEVEL_COST_ELEMENT_ITEM_COST = Message("enchant-level-cost.element.item-cost", "cost") + val ENCHANTMENT_LEVEL_COST_ELEMENT_BOOK_COST = Message("enchant-level-cost.element.book-cost", "cost") val ENCHANTMENT_LEVEL_LIMIT_TITLE = Message("enchant-level-limit.title", null, "page", "max_page") val ENCHANTMENT_LEVEL_LIMIT_ELEMENT_TITLE = Message("enchant-level-limit.element.title", "name") @@ -79,8 +79,8 @@ object MsgUI { val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_DESCRIPTION = Message("enchant-conflict.element.delete.description", null) val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_NAME = Message("enchant-conflict.element.delete.button.name") val ENCHANTMENT_CONFLICT_ELEMENT_DELETE_BUTTON_LORE = Message("enchant-conflict.element.delete.button.lore") - val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE = Message("enchant-conflict.element.min-before-count.title") - val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION = Message("enchant-conflict.element.min-before-count.description") + val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_TITLE = Message("enchant-conflict.element.min-before-count.title", null) + val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_DESCRIPTION = Message("enchant-conflict.element.min-before-count.description", null) val ENCHANTMENT_CONFLICT_ELEMENT_MIN_BEFORE_COUNT_ITEM = Message("enchant-conflict.element.min-before-count.item") val MATERIAL_GROUP_TITLE = Message("material-group.title", null, "page", "max_page") @@ -102,52 +102,52 @@ object MsgUI { */ val BASIC_TITLE = Message("basic-config.title") - val BASIC_CAP_ANVIL_COST_TITLE = Message("basic-config.cap-anvil-cost.title") - val BASIC_CAP_ANVIL_COST_DESCRIPTION = Message("basic-config.cap-anvil-cost.description") - val BASIC_CAP_ANVIL_COST_ITEM = Message("basic-config.cap-anvil-cost-cost.item") + val BASIC_CAP_ANVIL_COST_TITLE = Message("basic-config.cap-anvil-cost.title", null) + val BASIC_CAP_ANVIL_COST_DESCRIPTION = Message("basic-config.cap-anvil-cost.description", null) + val BASIC_CAP_ANVIL_COST_ITEM = Message("basic-config.cap-anvil-cost.item") val BASIC_CAP_ANVIL_COST_DISABLED_TITLE = Message("basic-config.cap-anvil-cost.disabled.title") val BASIC_CAP_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.cap-anvil-cost.disabled.description") - val BASIC_MAX_ANVIL_COST_TITLE = Message("basic-config.max-anvil-cost.title") - val BASIC_MAX_ANVIL_COST_DESCRIPTION = Message("basic-config.max-anvil-cost.description") + val BASIC_MAX_ANVIL_COST_TITLE = Message("basic-config.max-anvil-cost.title", null) + val BASIC_MAX_ANVIL_COST_DESCRIPTION = Message("basic-config.max-anvil-cost.description", null) val BASIC_MAX_ANVIL_COST_ITEM = Message("basic-config.max-anvil-cost.item") val BASIC_MAX_ANVIL_COST_DISABLED_TITLE = Message("basic-config.max-anvil-cost.disabled.title") val BASIC_MAX_ANVIL_COST_DISABLED_DESCRIPTION = Message("basic-config.max-anvil-cost.disabled.description") - val BASIC_REMOVE_COST_LIMIT_TITLE = Message("basic-config.remove-cost-limit.title") - val BASIC_REMOVE_COST_LIMIT_DESCRIPTION = Message("basic-config.remove-cost-limit.description") + val BASIC_REMOVE_COST_LIMIT_TITLE = Message("basic-config.remove-cost-limit.title", null) + val BASIC_REMOVE_COST_LIMIT_DESCRIPTION = Message("basic-config.remove-cost-limit.description", null) val BASIC_REMOVE_COST_LIMIT_ITEM = Message("basic-config.remove-cost-limit.item") - val BASIC_REPLACE_TOO_EXPENSIVE_TITLE = Message("basic-config.remove-too-expensive.title") - val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION = Message("basic-config.remove-too-expensive.description") + val BASIC_REPLACE_TOO_EXPENSIVE_TITLE = Message("basic-config.remove-too-expensive.title", null) + val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION = Message("basic-config.remove-too-expensive.description", null) val BASIC_REPLACE_TOO_EXPENSIVE_DESCRIPTION_NO_NMS = Message("basic-config.remove-too-expensive.description-no-nms") - val BASIC_ITEM_REPAIR_COST_TITLE = Message("basic-config.item-repair-cost.title") - val BASIC_ITEM_REPAIR_COST_DESCRIPTION = Message("basic-config.item-repair-cost.description") + val BASIC_ITEM_REPAIR_COST_TITLE = Message("basic-config.item-repair-cost.title", null) + val BASIC_ITEM_REPAIR_COST_DESCRIPTION = Message("basic-config.item-repair-cost.description", null) - val BASIC_ITEM_RENAME_COST_TITLE = Message("basic-config.item-rename-cost.title") - val BASIC_ITEM_RENAME_COST_DESCRIPTION = Message("basic-config.item-rename-cost.description") + val BASIC_ITEM_RENAME_COST_TITLE = Message("basic-config.item-rename-cost.title", null) + val BASIC_ITEM_RENAME_COST_DESCRIPTION = Message("basic-config.item-rename-cost.description", null) - val BASIC_UNIT_REPAIR_COST_TITLE = Message("basic-config.unit-repair-cost.title") - val BASIC_UNIT_REPAIR_COST_DESCRIPTION = Message("basic-config.unit-repair-cost.description") + val BASIC_UNIT_REPAIR_COST_TITLE = Message("basic-config.unit-repair-cost.title", null) + val BASIC_UNIT_REPAIR_COST_DESCRIPTION = Message("basic-config.unit-repair-cost.description", null) - val BASIC_SACRIFICE_ILLEGAL_COST_TITLE = Message("basic-config.sacrifice-illegal-cost.title") - val BASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION = Message("basic-config.sacrifice-illegal-cost.description") + val BASIC_SACRIFICE_ILLEGAL_COST_TITLE = Message("basic-config.sacrifice-illegal-cost.title", null) + val BASIC_SACRIFICE_ILLEGAL_COST_DESCRIPTION = Message("basic-config.sacrifice-illegal-cost.description", null) - val BASIC_COLOR_CODE_LIMIT_TITLE = Message("basic-config.color-code.title") - val BASIC_COLOR_CODE_LIMIT_DESCRIPTION = Message("basic-config.color-code.description") + val BASIC_COLOR_CODE_LIMIT_TITLE = Message("basic-config.color-code.title", null) + val BASIC_COLOR_CODE_LIMIT_DESCRIPTION = Message("basic-config.color-code.description", null) - val BASIC_COLOR_HEX_LIMIT_TITLE = Message("basic-config.color-hex.title") - val BASIC_COLOR_HEX_LIMIT_DESCRIPTION = Message("basic-config.color-hex.description") + val BASIC_COLOR_HEX_LIMIT_TITLE = Message("basic-config.color-hex.title", null) + val BASIC_COLOR_HEX_LIMIT_DESCRIPTION = Message("basic-config.color-hex.description", null) - val BASIC_COLOR_PERMISSION_TITLE = Message("basic-config.color-permission.title") - val BASIC_COLOR_PERMISSION_DESCRIPTION = Message("basic-config.color-permission.description") + val BASIC_COLOR_PERMISSION_TITLE = Message("basic-config.color-permission.title", null) + val BASIC_COLOR_PERMISSION_DESCRIPTION = Message("basic-config.color-permission.description", null) val BASIC_COLOR_PERMISSION_DISABLED_TITLE = Message("basic-config.color-permission.disabled.title") val BASIC_COLOR_PERMISSION_DISABLED_DESCRIPTION = Message("basic-config.color-permission.disabled.description") - val BASIC_COLOR_COST_TITLE = Message("basic-config.color-cost.title") - val BASIC_COLOR_COST_DESCRIPTION = Message("basic-config.color-cost.description") + val BASIC_COLOR_COST_TITLE = Message("basic-config.color-cost.title", null) + val BASIC_COLOR_COST_DESCRIPTION = Message("basic-config.color-cost.description", null) val BASIC_COLOR_COST_ITEM = Message("basic-config.color-cost.item") val BASIC_COLOR_COST_DISABLED_TITLE = Message("basic-config.color-cost.disabled.title") val BASIC_COLOR_COST_DISABLED_DESCRIPTION = Message("basic-config.color-cost.disabled.description") diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 4f90bb34..fe116e8d 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -356,12 +356,12 @@ config-ui.basic-config.color-cost: description: 1: "XP level cost when using color code or hexadecimal color using the anvil." 2: "conflict With one of the left item enchantment" - disabled: - title: "Cost Of Using Color" - description: - 1: "This config can do something only if one of the following config is enabled:" - 2: "- Allow Use Of Color Code" - 3: "- Allow Use Of Hexadecimal Color" + disabled: + title: "Cost Of Using Color" + description: + 1: "This config can do something only if one of the following config is enabled:" + 2: "- Allow Use Of Color Code" + 3: "- Allow Use Of Hexadecimal Color" config-ui.basic-config.work-penalty: title: "Work Penalty Type" From dd8f145e1260a5bac792cbd26d8e038e2b4dd723 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Fri, 21 Aug 2026 16:33:21 +0200 Subject: [PATCH 13/13] add translation for more gui --- .../config/global/CustomRecipeConfigGui.java | 44 ++++++++++++------- .../gui/config/global/EnchantConfigGui.java | 14 +++++- .../gui/config/global/EnchantConflictGui.java | 23 +++++----- .../config/global/EnchantLimitConfigGui.java | 9 ++-- .../gui/config/global/GroupConfigGui.java | 27 +++++++----- .../gui/config/global/ItemConfigGui.java | 8 ++-- .../config/global/UnitRepairConfigGui.java | 11 ++--- .../list/MappedElementListConfigGui.java | 3 +- .../config/list/MappedGuiListConfigGui.java | 2 +- .../elements/GroupConfigSubSettingGui.java | 4 +- .../settings/MaterialSelectSettingGui.java | 5 +-- .../kotlin/xyz/alexcrea/cuanvil/lang/Lang.kt | 5 ++- .../kotlin/xyz/alexcrea/cuanvil/lang/MsgUI.kt | 32 ++++++++++++-- src/main/resources/lang/en.yml | 39 +++++++++++++++- 14 files changed, 159 insertions(+), 67 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java index c0c32471..894b36f2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -12,12 +13,14 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.CustomRecipeSubSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; -import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.ArrayList; import java.util.Collection; +import java.util.List; public class CustomRecipeConfigGui extends MappedGuiListConfigGui> { @@ -31,7 +34,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " Custom recipe");//TODO MESSAGE meta.addItemFlags(ItemFlag.values()); - - meta.setLore(getRecipeLore(recipe)); + ComponentUtil.INSTANCE.setMessageName(meta, MsgUI.INSTANCE.getCUSTOM_RECIPE_NAME()); + ComponentUtil.INSTANCE.applyLore(getRecipeLore(recipe), meta); displayedItem.setItemMeta(meta); return displayedItem; } - private static @NotNull ArrayList getRecipeLore(AnvilCustomRecipe recipe) { + private static @NotNull List getRecipeLore(AnvilCustomRecipe recipe) { boolean shouldWork = recipe.validate(); - ArrayList lore = new ArrayList<>();//TODO MESSAGE - lore.add("§7Is valid: §" + (shouldWork ? "aYes" : "cNo")); - lore.add("§7Exact count: §" + (recipe.getExactCount() ? "aYes" : "cNo")); - lore.add("§7Recipe Level Cost: §e" + recipe.getLevelCostPerCraft()); - lore.add("§7Recipe Linear Xp Cost: §e" + recipe.getXpCostPerCraft()); - if (recipe.getXpCostPerCraft() != 0) { - lore.add("§7Exact Linear xp remove: §" + (recipe.getRemoveExactLinearXp() ? "aYes" : "cNo")); + var shouldWorkMsg = MsgUI.INSTANCE.booleanMessage(shouldWork); + var exactCount = MsgUI.INSTANCE.booleanMessage(recipe.getExactCount()); + + ArrayList lore = new ArrayList<>(MsgUI.INSTANCE.getCUSTOM_RECIPE_LORE_DEFAULT() + .formatted( + shouldWorkMsg, + exactCount, + recipe.getLevelCostPerCraft(), + recipe.getXpCostPerCraft() + )); + + if(recipe.getXpCostPerCraft() != 0) { + var removeExact = MsgUI.INSTANCE.booleanMessage(recipe.getRemoveExactLinearXp()); + lore.addAll(MsgUI.INSTANCE.getCUSTOM_RECIPE_LORE_LINEAR().formatted(removeExact)); } return lore; } @@ -90,8 +99,8 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui enchantments) { + if(enchantments.size() == 1) { + return enchantments.stream().findFirst().get().getPrettyName(); + } + + return MsgUI.INSTANCE.getENCHANT_CONFIG_MULTIPLES_NAME().unformatted(); + } + public EnchantConfigGui(@NotNull Set enchantments) { super(3, - "Configuring Enchantments", + MsgUI.INSTANCE.getENCHANT_CONFIG_TITLE().textHolder(selectName(enchantments)), CustomAnvil.instance); this.enchantments = enchantments; @@ -57,7 +67,7 @@ public class EnchantConfigGui extends ChestGui implements ValueUpdatableGui { ItemMeta displayMeta = displayItemstack.getItemMeta(); assert displayMeta != null; - displayMeta.setDisplayName("§aConfiguring Enchantments:"); + ComponentUtil.INSTANCE.setMessageName(displayMeta, MsgUI.INSTANCE.getENCHANT_CONFIG_NAME(), selectName(enchantments)); displayItemstack.setItemMeta(displayMeta); // Set enchantments diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java index 4762ce57..e566ef91 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java @@ -14,10 +14,11 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.EnchantConflictSubSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.ComponentUtil; -import java.util.Arrays; import java.util.Collection; public class EnchantConflictGui extends MappedGuiListConfigGui "Default (" + defaultValue + ")"; - case RESET -> String.valueOf(defaultValue); - default -> "Default"; + case CURRENT -> MsgUI.INSTANCE.getSHARED_VALUED_DEFAULT().unformatted(defaultValueStr); + case RESET -> defaultValueStr; + default -> MsgUI.INSTANCE.getSHARED_DEFAULT().unformatted(); }; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java index 68e06f01..2154794c 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java @@ -15,12 +15,12 @@ import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.group.ItemGroupManager; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui; +import xyz.alexcrea.cuanvil.lang.Message; import xyz.alexcrea.cuanvil.lang.MsgUI; import xyz.alexcrea.cuanvil.util.CasedStringUtil; -import xyz.alexcrea.cuanvil.util.LazyValue; +import xyz.alexcrea.cuanvil.util.ComponentUtil; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; public class GroupConfigGui extends MappedGuiListConfigGui> { @@ -56,12 +56,19 @@ public class GroupConfigGui extends MappedGuiListConfigGui extends ElementListConfig protected abstract Consumer prepareCreateItemConsumer(HumanEntity player); - protected abstract String genericDisplayedName(); + protected abstract Message genericDisplayedName(); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index 5d346a43..d48ef8fe 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -123,7 +123,7 @@ public abstract class MappedGuiListConfigGui { event.setCancelled(true); MaterialSelectSettingGui selectGui = new MaterialSelectSettingGui(this, - materialSelectionName, name + materialSelectionName, name//TODO MESSAGE maybe need (%page/%max_page) , this); selectGui.show(event.getWhoClicked()); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java index 102e1c9f..0c378c64 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java @@ -15,7 +15,6 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.config.SelectMaterialContainer; import xyz.alexcrea.cuanvil.gui.config.ask.ConfirmActionGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui; -import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.lang.Message; @@ -42,7 +41,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGuiConfig was not able to be reloaded..." hard-fail: "Hard fail, plugin disabled" - config-ui.shared: no-permission: "You do not have permission to edit the config" typed-config-title: "%type Config" click-to-change: "Click Here to change the value" green-get-item: "%name" yellow-get-item: "%name" + formated-yes: "Yes" + formated-no: "No" + default: "Default" + valued-default: "Default (%value)" config-ui.global-item: item-lore-prefix: "value: %value" @@ -154,6 +157,15 @@ config-ui.unit-repair: config-ui.custom-recipe: title: "Custom Recipe Config (%page/%max_page)" + generic-name: "custom recipe" + name: "%name Custom recipe" + lore: + default: + 1: "Is valid: %should_work" + 2: "Exact count: %exact_count" + 3: "Recipe Level Cost: %per_craft_lv_cost" + 4: "Recipe Linear Xp Cost: %per_craft_xp_cost" + linear: "Exact Linear xp remove: %exact_linear" element: exact-count: "Exact count ?" linear-xp: @@ -218,6 +230,13 @@ config-ui.enchant-merge-limit: config-ui.enchant-conflict: title: "Conflict Config (%page/%max_page)" + name: "%name Conflict" + lore: + 1: "Enchantment count: %enchantment_count" + 2: "Group count: %group_count" + 3: "Min enchantments count: %min_count" + generic-name: "conflict" + default-new: "new_group" element: selected-enchantments: "%group" # likely need page and max page selected-sub-groups: "%group Groups" @@ -236,6 +255,13 @@ config-ui.enchant-conflict: config-ui.material-group: title: "Group Config (%page/%max_page)" + generic-name: "material group" + name: "%name Group" + lore: + 1: "Number of selected groups : %groups" + 2: "Number of included material : %materials" + 3: "" + 4: "Total number of included material %size" element: selected-materials: "%group Materials" selected-sub-groups: "%group Groups" @@ -252,6 +278,15 @@ config-ui.material-select: title: "Remove %name" description: "Confirm Remove %name from this list." +config-ui.enchant-config: + title: "Configuring %name" + name: "Configuring %name:" + multiples-name: "Enchantments" + +config-ui.item-config: + title: "%name Config" + name: "Configuring %name" + config-ui.basic-config: title: "Basic Config" @@ -376,4 +411,4 @@ config-ui.basic-config.work-penalty: increasing: "Increasing: will penalty be increased (in item)" additive: "Additive: will penalty be added to the cost" shared: "Shared: Vanilla, shared penalty. it will be kept from before the plugin installation." - exclusive: "Exclusive: Custom, per anvil use type penalty. it will be lost after plugin uninstallation" \ No newline at end of file + exclusive: "Exclusive: Custom, per anvil use type penalty. it will be lost after plugin uninstallation"