Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
86 changes: 52 additions & 34 deletions src/main/kotlin/dev/cxntered/textreplacer/TextReplacer.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
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 dev.cxntered.textreplacer.command.TextReplacerCommand
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.config.TextReplacerConfig
import dev.cxntered.textreplacer.elements.ReplacerListOption
import net.minecraftforge.fml.common.Mod
Expand All @@ -24,56 +25,73 @@ 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()
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
var shouldExpand = false

text = replaceVariables(text)
replacementText = replaceVariables(replacementText)
val currentUsername = mc.session.profile.name
if (currentUsername != cachedUsername) {
cachedUsername = currentUsername
shouldExpand = true
}

if (string.contains(text)) {
string = string.replace(text, replacementText)
}
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
}

return string
}

private fun replaceVariables(input: String): String {
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]
return ReplacerListOption.wrappedReplacers.fold(input) { string, wrapper ->
with(wrapper.replacer) {
if (!enabled || text.isEmpty() || replacementText.isEmpty()) return@with string

Copy link

Copilot AI May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment to clarify that the expandedText update only happens when a server or username change triggers shouldExpand; this helps future maintainers understand that additional changes in replacer.text are expected to be handled elsewhere.

Suggested change
// Update expandedText and expandedReplacementText only when shouldExpand is true
// (triggered by server or username changes) or when they are empty.
// Changes to replacer.text are expected to be handled elsewhere.

Copilot uses AI. Check for mistakes.
string = string.replace("¶serverIp", serverIp)
if (shouldExpand || expandedText.isEmpty())
expandedText = expandText(text)
if (shouldExpand || expandedReplacementText.isEmpty())
expandedReplacementText = expandText(replacementText)

if (!InetAddressUtils.isIPv4Address(serverIp) && !InetAddressUtils.isIPv6Address(serverIp)) {
val parts = serverIp.split(".")
val serverDomain = parts[parts.size - 2]

string = string.replace("¶serverDomain", serverDomain)
string.replace(expandedText, expandedReplacementText)
}
Comment on lines +61 to 70
Copy link

Copilot AI May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Although the functional style with fold is correct, assigning the result of replace explicitly or refactoring this lambda to be more self-explanatory could improve clarity.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please explain what you mean by this GitHub Copilot!
thanks, cxntered

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it even reply to me or do i have to request another review

}
}

fun expandText(input: String): String {
if (input.isEmpty() || !input.contains('¶')) return input

val variables = mapOf(
"¶username" to cachedUsername,
"¶serverIp" to cachedServerIp?.split(":")?.firstOrNull(),
"¶serverDomain" to cachedServerDomain,
// 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"
)

return variables.entries.fold(input) { text, (variable, value) ->
if (value != null) text.replace(variable, value.toString()) else text
}
}

return string
@Command(value = MODID, description = "Access the $NAME GUI.")
class TextReplacerCommand {
@Main
fun handle() {
TextReplacerConfig.openGui()
}
}
}

This file was deleted.

2 changes: 2 additions & 0 deletions src/main/kotlin/dev/cxntered/textreplacer/config/Replacer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "",
)
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
private val expandedTextProperty: KMutableProperty0<String>,
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)
Expand All @@ -20,6 +21,7 @@ class ReplacerTextField(
if (!isToggled) return false
keyTyped(key, keyCode)
textProperty.set(input)
expandedTextProperty.set(TextReplacer.expandText(input))
Copy link

Copilot AI May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this expansion is called on every key input, consider debouncing or throttling this operation to reduce unnecessary recalculations during rapid typing.

Copilot uses AI. Check for mistakes.
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down