From f617d59f1c52ad77f23ce28fb14bf44986e38ed1 Mon Sep 17 00:00:00 2001 From: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> Date: Sat, 23 Sep 2023 21:36:29 +1000 Subject: chat message changes #482 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add chat component functions * reword + remove empty text * remove type * isPlayerMessage * include the other stuff in the translator pr plus format * Merge branch 'hannibal002:beta' into chat_component_stuff * Merge remote-tracking branch 'origin/chat_component_stuff' into chat_… * allow to work with priv messages + get ready for future --- .../hannibal2/skyhanni/events/LorenzChatEvent.kt | 7 ++- .../hannibal2/skyhanni/features/chat/Translator.kt | 24 +++++---- .../features/inventory/HighlightBonzoMasks.kt | 7 +-- .../transformers/AccessorChatComponentText.java | 14 ++++++ .../at/hannibal2/skyhanni/utils/StringUtils.kt | 57 ++++++++++++++++++++++ src/main/resources/mixins.skyhanni.json | 1 + 6 files changed, 92 insertions(+), 18 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/transformers/AccessorChatComponentText.java (limited to 'src/main') diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzChatEvent.kt index e20e05b01..6b50e2092 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/LorenzChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzChatEvent.kt @@ -2,5 +2,8 @@ package at.hannibal2.skyhanni.events import net.minecraft.util.IChatComponent -class LorenzChatEvent(val message: String, var chatComponent: IChatComponent, var blockedReason: String = "") : - LorenzEvent() \ No newline at end of file +class LorenzChatEvent( + var message: String, + var chatComponent: IChatComponent, + var blockedReason: String = "" +) : LorenzEvent() \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt index 1274fbdf2..300f8805b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt @@ -1,16 +1,17 @@ package at.hannibal2.skyhanni.features.chat import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.test.command.CopyErrorCommand import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.OSUtils +import at.hannibal2.skyhanni.utils.StringUtils.getPlayerName import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.gson.* import net.minecraft.event.ClickEvent import net.minecraft.event.HoverEvent import net.minecraft.util.ChatComponentText import net.minecraft.util.ChatStyle -import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import org.apache.http.client.config.RequestConfig @@ -23,26 +24,24 @@ import java.net.URLDecoder import java.net.URLEncoder class Translator { - private val messageContentRegex = Regex(".*: (.*)") // Logic for listening for a user click on a chat message is from NotEnoughUpdates - @SubscribeEvent(priority = EventPriority.LOWEST, receiveCanceled = true) - fun onGuiChat(e: ClientChatReceivedEvent) { + @SubscribeEvent(priority = EventPriority.LOWEST) + fun onGuiChat(e: LorenzChatEvent) { if (!SkyHanniMod.feature.chat.translator) return - if (e.type != 0.toByte()) return // If this is not a player-sent message, return - val chatComponent = e.message - val message = chatComponent.unformattedText - if (!messageContentRegex.matches(message.removeColor())) return + val message = e.message + if (message.getPlayerName() == "-") return + + val editedComponent = if (e.chatComponent.siblings.size > 0) e.chatComponent.siblings.last() else e.chatComponent - val clickStyle = createClickStyle(message) - chatComponent.siblings.last().setChatStyle(clickStyle) + val clickStyle = createClickStyle(message.removeColor(), editedComponent.chatStyle) + editedComponent.setChatStyle(clickStyle) } - private fun createClickStyle(message: String): ChatStyle { - val style = ChatStyle() + private fun createClickStyle(message: String, style: ChatStyle): ChatStyle { style.setChatClickEvent( ClickEvent( ClickEvent.Action.RUN_COMMAND, @@ -212,5 +211,4 @@ class Translator { OSUtils.copyToClipboard(translation) } } - } \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt index 72c265cc6..6c0be90d3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt @@ -3,12 +3,13 @@ package at.hannibal2.skyhanni.features.inventory import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old import at.hannibal2.skyhanni.utils.RenderUtils.highlight import at.hannibal2.skyhanni.utils.RenderUtils.interpolate +import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.item.ItemStack -import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.awt.Color import kotlin.time.* @@ -57,8 +58,8 @@ class HighlightBonzoMasks { } @SubscribeEvent - fun onChatReceived(event: ClientChatReceivedEvent) { - val message = event.message.unformattedText + fun onChatReceived(event: LorenzChatEvent) { + val message = event.message.removeColor() if (bonzoMaskMessage.matches(message)) { maskTimers["BONZO_MASK"] = CooldownTimer(TimeSource.Monotonic.markNow(), bonzoMaskCooldown) } else if (spiritMaskMessage.matches(message)) { diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/AccessorChatComponentText.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/AccessorChatComponentText.java new file mode 100644 index 000000000..70ce499d2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/AccessorChatComponentText.java @@ -0,0 +1,14 @@ +package at.hannibal2.skyhanni.mixins.transformers; + +import net.minecraft.util.ChatComponentText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ChatComponentText.class) +public interface AccessorChatComponentText { + @Accessor("text") + void setText_skyhanni(String text); + + @Accessor("text") + String text_skyhanni(); +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index f0eb8e059..591519a82 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -1,15 +1,21 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.mixins.transformers.AccessorChatComponentText import at.hannibal2.skyhanni.utils.GuiRenderUtils.darkenColor import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiUtilRenderComponents import net.minecraft.util.ChatComponentText +import net.minecraft.util.IChatComponent import org.intellij.lang.annotations.Language import java.util.* +import java.util.function.Predicate import java.util.regex.Matcher import java.util.regex.Pattern object StringUtils { + private val playerChatPattern = ".*§[f7]: .*".toPattern() + private val chatUsernamePattern = "^(?:\\[\\d+] )?(?:\\S )?(?:\\[\\w.+] )?(?\\w+)(?: \\[.+?])?\$".toPattern() + fun String.firstLetterUppercase(): String { if (isEmpty()) return this @@ -159,4 +165,55 @@ object StringUtils { i < limit } } + + // recursively goes through the chat component until an action is completed + fun modifyFirstChatComponent(chatComponent: IChatComponent, action: Predicate): Boolean { + if (action.test(chatComponent)) { + return true + } + for (sibling in chatComponent.siblings) { + if (modifyFirstChatComponent(sibling, action)) { + return true + } + } + return false + } + + // replaces a word without breaking any chat components + fun replaceFirstChatText(chatComponent: IChatComponent, toReplace: String, replacement: String): IChatComponent { + modifyFirstChatComponent(chatComponent) { component -> + if (component is ChatComponentText) { + component as AccessorChatComponentText + if (component.text_skyhanni().contains(toReplace)) { + component.setText_skyhanni(component.text_skyhanni().replace(toReplace, replacement)) + return@modifyFirstChatComponent true + } + return@modifyFirstChatComponent false + } + return@modifyFirstChatComponent false + } + return chatComponent + } + + fun String.getPlayerName(): String { + if (!playerChatPattern.matcher(this).matches()) return "-" + + var username = this.removeColor().split(":")[0] + + if (username.contains(">")) { + username = username.substring(username.indexOf('>') + 1).trim() + } + if (username.startsWith("From ")) { + username = username.removePrefix("From ") + } + if (username.startsWith("To ")) { + username = username.removePrefix("To ") + } + + val matcher = chatUsernamePattern.matcher(username) + + if (!matcher.matches()) return "-" + username = matcher.group("username") + return username + } } \ No newline at end of file diff --git a/src/main/resources/mixins.skyhanni.json b/src/main/resources/mixins.skyhanni.json index 69b41eb4b..8daf1a330 100644 --- a/src/main/resources/mixins.skyhanni.json +++ b/src/main/resources/mixins.skyhanni.json @@ -3,6 +3,7 @@ "refmap": "mixins.skyhanni.refmap.json", "compatibilityLevel": "JAVA_8", "mixins": [ + "AccessorChatComponentText", "AccessorGuiPlayerTabOverlay", "MixinBlockFire", "MixinEntityBlaze", -- cgit