From 80a73550a90ce6c131c79e0de1bfd769ca2a3cb3 Mon Sep 17 00:00:00 2001 From: cxntered Date: Sun, 11 May 2025 16:48:56 +1000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20cache=20ex?= =?UTF-8?q?panded=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../textreplacer/mixin/FontRendererMixin.java | 4 +- .../dev/cxntered/textreplacer/TextReplacer.kt | 58 ++++++++++--------- .../cxntered/textreplacer/config/Replacer.kt | 2 + .../elements/ReplacerTextField.kt | 4 +- .../textreplacer/elements/WrappedReplacer.kt | 5 +- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/main/java/dev/cxntered/textreplacer/mixin/FontRendererMixin.java b/src/main/java/dev/cxntered/textreplacer/mixin/FontRendererMixin.java index 54f8f19..3104b35 100644 --- a/src/main/java/dev/cxntered/textreplacer/mixin/FontRendererMixin.java +++ b/src/main/java/dev/cxntered/textreplacer/mixin/FontRendererMixin.java @@ -13,13 +13,13 @@ public abstract class FontRendererMixin { private String textreplacer$spoofRenderString(String string) { if (string == null) return null; if (!TextReplacerConfig.INSTANCE.enabled) return string; - return TextReplacer.INSTANCE.getString(string); + return TextReplacer.getString(string); } @ModifyVariable(method = "getStringWidth", at = @At("HEAD"), argsOnly = true) private String textreplacer$spoofGetStringWidth(String string) { if (string == null) return null; if (!TextReplacerConfig.INSTANCE.enabled) return string; - return TextReplacer.INSTANCE.getString(string); + return TextReplacer.getString(string); } } diff --git a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt index 33bbf74..7632c7c 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt @@ -1,8 +1,8 @@ package dev.cxntered.textreplacer -import cc.polyfrost.oneconfig.libs.universal.UMinecraft import cc.polyfrost.oneconfig.renderer.asset.SVG import cc.polyfrost.oneconfig.utils.commands.CommandManager +import cc.polyfrost.oneconfig.utils.dsl.mc import dev.cxntered.textreplacer.command.TextReplacerCommand import dev.cxntered.textreplacer.config.TextReplacerConfig import dev.cxntered.textreplacer.elements.ReplacerListOption @@ -30,48 +30,50 @@ object TextReplacer { CommandManager.INSTANCE.registerCommand(TextReplacerCommand()) } + @JvmStatic fun getString(input: String): String { var string = input for (wrapper in ReplacerListOption.wrappedReplacers) { - with (wrapper.replacer) { - if (!enabled) return@with - if (text.isEmpty() || replacementText.isEmpty()) return@with + with(wrapper.replacer) { + if (!enabled || text.isEmpty() || replacementText.isEmpty()) return@with - text = replaceVariables(text) - replacementText = replaceVariables(replacementText) + if (expandedText.isEmpty()) + expandedText = expandText(text) + if (expandedReplacementText.isEmpty()) + expandedReplacementText = expandText(replacementText) - if (string.contains(text)) { - string = string.replace(text, replacementText) - } + string = string.replace(expandedText, expandedReplacementText) } } return string } - private fun replaceVariables(input: String): String { + fun expandText(input: String): String { + if (input.isEmpty() || !input.contains('¶')) return input var string = input - val mc = UMinecraft.getMinecraft() - - string = string.replace("¶username", mc.session.profile.name) - - if (!mc.isSingleplayer && mc.currentServerData != null) { - var serverIp: String = mc.currentServerData.serverIP - if (serverIp.contains(":")) - serverIp = serverIp.split(":")[0] - - string = string.replace("¶serverIp", serverIp) - - if (!InetAddressUtils.isIPv4Address(serverIp) && !InetAddressUtils.isIPv6Address(serverIp)) { - val parts = serverIp.split(".") - val serverDomain = parts[parts.size - 2] - - string = string.replace("¶serverDomain", serverDomain) - } + val serverIp = mc.currentServerData?.serverIP?.split(":")?.firstOrNull() + + val variables = mapOf( + "¶username" to mc.session.profile.name, + "¶serverIp" to serverIp, + "¶serverDomain" to run { + if (serverIp != null && + !InetAddressUtils.isIPv4Address(serverIp) && + !InetAddressUtils.isIPv6Address(serverIp) + ) { + val parts = serverIp.split(".") + parts[parts.size - 2] + } else null + }, // hypixel, for some reason, puts 🎂 in their scoreboard IP - string = string.replace("¶hypixelScoreboardIp", "www.hypixel.ne\uD83C\uDF82§et") + "¶hypixelScoreboardIp" to "www.hypixel.ne\uD83C\uDF82§et" + ) + + for ((variable, value) in variables) { + if (value != null) string = string.replace(variable, value.toString()) } return string diff --git a/src/main/kotlin/dev/cxntered/textreplacer/config/Replacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/config/Replacer.kt index f86d145..98d1c2c 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/config/Replacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/config/Replacer.kt @@ -4,4 +4,6 @@ data class Replacer( var enabled: Boolean = true, var text: String = "", var replacementText: String = "", + @Transient var expandedText: String = "", + @Transient var expandedReplacementText: String = "", ) diff --git a/src/main/kotlin/dev/cxntered/textreplacer/elements/ReplacerTextField.kt b/src/main/kotlin/dev/cxntered/textreplacer/elements/ReplacerTextField.kt index ff4f5a2..639165d 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/elements/ReplacerTextField.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/elements/ReplacerTextField.kt @@ -3,14 +3,15 @@ package dev.cxntered.textreplacer.elements import cc.polyfrost.oneconfig.gui.elements.text.TextInputField import cc.polyfrost.oneconfig.internal.assets.SVGs import cc.polyfrost.oneconfig.utils.InputHandler +import dev.cxntered.textreplacer.TextReplacer import kotlin.reflect.KMutableProperty0 @Suppress("UnstableAPIUsage") class ReplacerTextField( private val textProperty: KMutableProperty0, + private val expandedTextProperty: KMutableProperty0, defaultText: String ) : TextInputField(432, 32, defaultText, false, false, SVGs.TEXT_INPUT, 12F) { - override fun draw(vg: Long, x: Float, y: Float, inputHandler: InputHandler) { input = textProperty.get() super.draw(vg, x, y, inputHandler) @@ -20,6 +21,7 @@ class ReplacerTextField( if (!isToggled) return false keyTyped(key, keyCode) textProperty.set(input) + expandedTextProperty.set(TextReplacer.expandText(input)) return true } } \ No newline at end of file diff --git a/src/main/kotlin/dev/cxntered/textreplacer/elements/WrappedReplacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/elements/WrappedReplacer.kt index 59cf3e0..fd908f6 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/elements/WrappedReplacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/elements/WrappedReplacer.kt @@ -13,8 +13,9 @@ class WrappedReplacer( private val removeButton = BasicButton(32, 32, TextReplacer.MINUS_ICON, BasicButton.ALIGNMENT_CENTER, ColorPalette.PRIMARY_DESTRUCTIVE) private val checkbox = ReplacerCheckbox(replacer) - private val textField = ReplacerTextField(replacer::text, "Text to replace") - private val replacementTextField = ReplacerTextField(replacer::replacementText, "Replacement text") + private val textField = ReplacerTextField(replacer::text, replacer::expandedText, "Text to replace") + private val replacementTextField = + ReplacerTextField(replacer::replacementText, replacer::expandedReplacementText, "Replacement text") init { removeButton.setClickAction { From 93fb1cdbfe49fd788262af5f3a4a6ada78234ed3 Mon Sep 17 00:00:00 2001 From: cxntered Date: Sun, 11 May 2025 17:18:47 +1000 Subject: [PATCH 2/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20properly?= =?UTF-8?q?=20cache=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/cxntered/textreplacer/TextReplacer.kt | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt index 7632c7c..3b7c1e4 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt @@ -24,6 +24,10 @@ object TextReplacer { val PLUS_ICON = SVG("/assets/textreplacer/icons/plus.svg") val MINUS_ICON = SVG("/assets/textreplacer/icons/minus.svg") + private var cachedUsername: String? = null + private var cachedServerIp: String? = null + private var cachedServerDomain: String? = null + @Mod.EventHandler fun onInit(event: FMLInitializationEvent) { TextReplacerConfig.initialize() @@ -33,14 +37,33 @@ object TextReplacer { @JvmStatic fun getString(input: String): String { var string = input + var shouldExpand = false + + val currentUsername = mc.session.profile.name + if (currentUsername != cachedUsername) { + cachedUsername = currentUsername + shouldExpand = true + } + + val currentServerIp = mc.currentServerData?.serverIP + if (currentServerIp != cachedServerIp) { + cachedServerIp = currentServerIp + cachedServerDomain = currentServerIp?.let { ip -> + val baseAddress = ip.split(":").first() + baseAddress.takeIf { + !InetAddressUtils.isIPv4Address(it) && !InetAddressUtils.isIPv6Address(it) + }?.split(".")?.dropLast(1)?.last() + } + shouldExpand = true + } for (wrapper in ReplacerListOption.wrappedReplacers) { with(wrapper.replacer) { if (!enabled || text.isEmpty() || replacementText.isEmpty()) return@with - if (expandedText.isEmpty()) + if (shouldExpand || expandedText.isEmpty()) expandedText = expandText(text) - if (expandedReplacementText.isEmpty()) + if (shouldExpand || expandedReplacementText.isEmpty()) expandedReplacementText = expandText(replacementText) string = string.replace(expandedText, expandedReplacementText) @@ -54,20 +77,10 @@ object TextReplacer { if (input.isEmpty() || !input.contains('¶')) return input var string = input - val serverIp = mc.currentServerData?.serverIP?.split(":")?.firstOrNull() - val variables = mapOf( - "¶username" to mc.session.profile.name, - "¶serverIp" to serverIp, - "¶serverDomain" to run { - if (serverIp != null && - !InetAddressUtils.isIPv4Address(serverIp) && - !InetAddressUtils.isIPv6Address(serverIp) - ) { - val parts = serverIp.split(".") - parts[parts.size - 2] - } else null - }, + "¶username" to cachedUsername, + "¶serverIp" to cachedServerIp?.split(":")?.firstOrNull(), + "¶serverDomain" to cachedServerDomain, // hypixel, for some reason, puts 🎂 in their scoreboard IP "¶hypixelScoreboardIp" to "www.hypixel.ne\uD83C\uDF82§et" ) From 0452cf739db8eaec158eb1511441e8217debd16d Mon Sep 17 00:00:00 2001 From: cxntered Date: Sun, 11 May 2025 17:25:42 +1000 Subject: [PATCH 3/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20simplify?= =?UTF-8?q?=20replacing=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/cxntered/textreplacer/TextReplacer.kt | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt index 3b7c1e4..e2be377 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt @@ -36,7 +36,6 @@ object TextReplacer { @JvmStatic fun getString(input: String): String { - var string = input var shouldExpand = false val currentUsername = mc.session.profile.name @@ -57,25 +56,22 @@ object TextReplacer { shouldExpand = true } - for (wrapper in ReplacerListOption.wrappedReplacers) { + return ReplacerListOption.wrappedReplacers.fold(input) { string, wrapper -> with(wrapper.replacer) { - if (!enabled || text.isEmpty() || replacementText.isEmpty()) return@with + if (!enabled || text.isEmpty() || replacementText.isEmpty()) return@with string if (shouldExpand || expandedText.isEmpty()) expandedText = expandText(text) if (shouldExpand || expandedReplacementText.isEmpty()) expandedReplacementText = expandText(replacementText) - string = string.replace(expandedText, expandedReplacementText) + string.replace(expandedText, expandedReplacementText) } } - - return string } fun expandText(input: String): String { if (input.isEmpty() || !input.contains('¶')) return input - var string = input val variables = mapOf( "¶username" to cachedUsername, @@ -85,10 +81,8 @@ object TextReplacer { "¶hypixelScoreboardIp" to "www.hypixel.ne\uD83C\uDF82§et" ) - for ((variable, value) in variables) { - if (value != null) string = string.replace(variable, value.toString()) + return variables.entries.fold(input) { text, (variable, value) -> + if (value != null) text.replace(variable, value.toString()) else text } - - return string } } \ No newline at end of file From af7d8505bd5e232183f6be00c9b50f12e910acd0 Mon Sep 17 00:00:00 2001 From: cxntered Date: Sun, 11 May 2025 17:28:26 +1000 Subject: [PATCH 4/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20make=20com?= =?UTF-8?q?mand=20a=20nested=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/cxntered/textreplacer/TextReplacer.kt | 11 ++++++++++- .../textreplacer/command/TextReplacerCommand.kt | 14 -------------- 2 files changed, 10 insertions(+), 15 deletions(-) delete mode 100644 src/main/kotlin/dev/cxntered/textreplacer/command/TextReplacerCommand.kt diff --git a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt index e2be377..3a32ca0 100644 --- a/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt +++ b/src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt @@ -2,8 +2,9 @@ package dev.cxntered.textreplacer import cc.polyfrost.oneconfig.renderer.asset.SVG import cc.polyfrost.oneconfig.utils.commands.CommandManager +import cc.polyfrost.oneconfig.utils.commands.annotations.Command +import cc.polyfrost.oneconfig.utils.commands.annotations.Main import cc.polyfrost.oneconfig.utils.dsl.mc -import dev.cxntered.textreplacer.command.TextReplacerCommand import dev.cxntered.textreplacer.config.TextReplacerConfig import dev.cxntered.textreplacer.elements.ReplacerListOption import net.minecraftforge.fml.common.Mod @@ -85,4 +86,12 @@ object TextReplacer { if (value != null) text.replace(variable, value.toString()) else text } } + + @Command(value = MODID, description = "Access the $NAME GUI.") + class TextReplacerCommand { + @Main + fun handle() { + TextReplacerConfig.openGui() + } + } } \ No newline at end of file diff --git a/src/main/kotlin/dev/cxntered/textreplacer/command/TextReplacerCommand.kt b/src/main/kotlin/dev/cxntered/textreplacer/command/TextReplacerCommand.kt deleted file mode 100644 index 4ab50bc..0000000 --- a/src/main/kotlin/dev/cxntered/textreplacer/command/TextReplacerCommand.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.cxntered.textreplacer.command - -import cc.polyfrost.oneconfig.utils.commands.annotations.Command -import cc.polyfrost.oneconfig.utils.commands.annotations.Main -import dev.cxntered.textreplacer.TextReplacer -import dev.cxntered.textreplacer.config.TextReplacerConfig - -@Command(value = TextReplacer.MODID, aliases = ["tr"], description = "Access the ${TextReplacer.NAME} GUI.") -class TextReplacerCommand { - @Main - fun main() { - TextReplacerConfig.openGui() - } -} \ No newline at end of file