diff options
| author | Linnea Gräf <nea@nea.moe> | 2024-05-03 17:25:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-03 17:25:52 +0200 |
| commit | 323cd55125f1485c71c49568aa919e5311c6263f (patch) | |
| tree | c4c246921fad48623fb81b769ee78f5fa1873993 | |
| parent | 5b2a2d067e68d500bd1c19088dae9e624eeae51f (diff) | |
| download | SkyHanni-323cd55125f1485c71c49568aa919e5311c6263f.tar.gz SkyHanni-323cd55125f1485c71c49568aa919e5311c6263f.tar.bz2 SkyHanni-323cd55125f1485c71c49568aa919e5311c6263f.zip | |
Add hover/click events back to custom chat messages (#1516)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
17 files changed, 513 insertions, 235 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerChatManager.kt index 96fad9711..f60247c0d 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerChatManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerChatManager.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.data.hypixel.chat import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.hypixel.chat.event.AbstractChatEvent +import at.hannibal2.skyhanni.data.hypixel.chat.event.CoopChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.GuildChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.NpcChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.PartyChatEvent @@ -10,180 +11,188 @@ import at.hannibal2.skyhanni.data.hypixel.chat.event.PlayerShowItemChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.PrivateMessageChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.SystemMessageEvent import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.groupOrNull +import at.hannibal2.skyhanni.utils.ComponentMatcher +import at.hannibal2.skyhanni.utils.ComponentMatcherUtils.intoSpan +import at.hannibal2.skyhanni.utils.ComponentMatcherUtils.matchStyledMatcher +import at.hannibal2.skyhanni.utils.ComponentSpan import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland -import at.hannibal2.skyhanni.utils.NumberUtil.formatInt -import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.util.IChatComponent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.regex.Matcher /** - * Reading normal chat events, and splitting them up into many different player chat events, with all avaliable extra information + * Reading normal chat events, and splitting them up into many different player chat events, with all available extra information */ class PlayerChatManager { private val patternGroup = RepoPattern.group("data.chat.player") /** - * REGEX-TEST: §8[§r§6428§r§8] §r§b[MVP§5+§b] Alea1337§f: t - * REGEX-TEST: §8[§r§e102§r§8] §r§7☠ §r§b[MVP§d+§b] cobyjoey§f§r§f: first person to type "halo0011 is my favorite player on the game I love halo0011!!!" - * REGEX-TEST: §8[§r§5396§r§8] §r§7☢ §r§b[MVP§c+§b] hannibal2§f: hello - * REGEX-TEST: §8[§r§e97§r§8] §r§7☃ §r§7Tambaloo§7§r§7: i did capital i - * REGEX-TEST: §8[§r§f76§r§8] §r§7❂ §r§a[VIP] Asymmetrically§f§r§f: i need to put on my necron - * REGEX-TEST: §8[§r§c446§r§8] §r§b§l⚛ §r§6[MVP§1++§6] XueRuu§f§r§f: TROPHY FISH! You caught a Lavahorse DIAMOND. - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f: test + * REGEX-TEST: [58] §7nea89o§7: haiiiii + * REGEX-TEST: [266] ♫ §b[MVP§d+§b] lrg89§f: a */ private val globalPattern by patternGroup.pattern( "global", - "(?:§8\\[§r(?<levelColor>§.)(?<level>\\d+)§r§8] §r)?(?<author>§.+)(?<chatColor>§f|§7§r§7): (?<message>.*)" + "(?:\\[(?<level>\\d+)] )?(?<author>.+)(?<chatColor>§f|§7): (?<message>.*)" ) /** - * REGEX-TEST: §9Party §8> §b§l⚛ §b[MVP§f+§b] Dankbarkeit§f: §rx: -190, y: 5, z: -163 - * REGEX-TEST: §9Party §8> §6⚔ §6[MVP§3++§6] RealBacklight§f: §r!warp - * REGEX-TEST: §9Party §8> §b[MVP§3+§b] Eisengolem§f: §r!pt + * REGEX-TEST: §9Party §8> §b[MVP§d+§b] lrg89§f: peee + * REGEX-TEST: §9Party §8> §7nea89o§f: peee */ private val partyPattern by patternGroup.pattern( "party", - "§9Party §8> (?<author>[^:]*): §r(?<message>.*)" + "§9Party §8> (?<author>[^:]*)§f: (?<message>.*)" ) /** - * REGEX-TEST: §2Guild > §b§l⚛ §b[MVP§f+§b] Dankbarkeit§f: §rx: -190, y: 5, z: -163 - * REGEX-TEST: §2Guild > §6⚔ §6[MVP§3++§6] RealBacklight§f: §r!warp - * REGEX-TEST: §2Guild > §b[MVP§3+§b] Eisengolem§f: §r!pt - * REGEX-TEST: §2Guild > §b[MVP§d+§b] zunoff §e[VET]§f: §rwas löuft - * REGEX-TEST: §2Guild > §7stinkywinkyowo §6[O]§f: §rraven____ > hi + * REGEX-TEST: §bCo-op > §7nea89o§f: hallooooo + */ + private val coopPattern by patternGroup.pattern( + "coop", + "§bCo-op > (?<author>[^:]+)§f: (?<message>.*)" + ) + + /** + * REGEX-TEST: §2Guild > §b[MVP§d+§b] infave §e[Em]§f: CEMENT DRINKERS INCORPORATED + * REGEX-TEST: §2Guild > §6⚔ §6[MVP§3++§6] RealBacklight§f: !warp + * REGEX-TEST: §2Guild > §b[MVP§d+§b] lrg89 §e[Iron]§f: h */ private val guildPattern by patternGroup.pattern( "guild", - "§2Guild > (?<author>§.+?)(?<guildRank> §.\\[\\w*])?§f: §r(?<message>.*)" + "§2Guild > (?<author>.+?)(?<guildRank> §e\\[\\w*])?§f: (?<message>.*)" ) /** - * REGEX-TEST: §dFrom §r§b[MVP§r§3+§r§b] Eisengolem§r§7: §r§7Baum - * REGEX-TEST: §dTo §r§b[MVP§r§3+§r§b] Eisengolem§r§7: §r§7hey - * REGEX-TEST: §dTo §r§b[MVP§r§5+§r§b] Alea1337§r§7: §r§d§lBoop! + * REGEX-TEST: To nea89o: lol + * REGEX-TEST: From nea89o: hiii + * REGEX-TEST: To [MVP+] Eisengolem: Boop! + * REGEX-TEST: From [MVP+] Eisengolem: Boop! + * REGEX-TEST: To [MVP+] Eisengolem: danke */ private val privateMessagePattern by patternGroup.pattern( "privatemessage", - "§d(?<direction>From|To) §r(?<author>[^:]*)§7: §r(?<message>.*)" + "(?<direction>From|To) (?<author>[^:]*): (?<message>.*)" ) /** - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is holding §r§8[§6Heroic Aspect of the Void§8] - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is holding §r§8[§7[Lvl 2] §dSpider§8] - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is friends with a §r§8[§7[Lvl 200] §8[§6103§8§4✦§8] §6Golden Dragon§8] - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is wearing §r§8[§5Glistening Implosion Belt§8] - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is friends with a §r§8[§7[Lvl 100] §dEnderman§8] - * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 has §r§8[§6Heroic Aspect of the Void§8] - * REGEX-TEST: §8[§5396§8] §7☢ §r§b[MVP§c+§b] hannibal2§f§7 is holding §r§8[§6Buzzing InfiniVacuum™ Hooverius§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is holding §8[§6Heroic Aspect of the Void§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is holding §8[§7[Lvl 2] §dSpider§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is friends with a §8[§7[Lvl 200] §8[§6103§8§4✦§8] §6Golden Dragon§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is wearing §8[§5Glistening Implosion Belt§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 is friends with a §8[§7[Lvl 100] §dEnderman§8] + * REGEX-TEST: §b[MVP§c+§b] hannibal2§f§7 has §8[§6Heroic Aspect of the Void§8] + * REGEX-TEST: §8[§b209§8] §b[MVP§d+§b] lrg89§f§7 is holding §8[§5Heroic Aspect of the Void§8] */ private val itemShowPattern by patternGroup.pattern( "itemshow", - "(?:§8\\[(?<levelColor>§.)(?<level>\\d+)§8] )?(?<author>.*)§f§7 (?<action>is (?:holding|friends with a|wearing)|has) §r(?<itemName>.*)" + "(?:§8\\[(?<levelColor>§.)(?<level>\\d+)§8] )?(?<author>.*)§f§7 (?<action>is (?:holding|friends with a|wearing)|has) (?<itemName>.*)" ) /** - * REGEX-TEST: §c[Tiffany] §b[MVP§c+§b] hannibal2 - * REGEX-TEST: §b[MVP§c+§b] hannibal2 - * REGEX-TEST: §6§l℻ §r§f[Gamer] §b[MVP§f+§b] SchrankLP§f§r + * REGEX-TEST: ♫ §c[Buddy ツ] §b[MVP§d+§b] lrg89 + * REGEX-TEST: ℻ §b[MVP§5+§b] Alea1337 */ private val privateIslandRankPattern by patternGroup.pattern( "privateislandrank", - ".*(?<privateIslandRank>§.\\[\\w+]).*" + "(?<prefix>.*?)(?<privateIslandRank>§.\\[(?!MVP(§.\\++)?§.]|VIP\\+*|YOU§.TUBE|ADMIN|MOD|GM)[^]]+\\])(?<suffix>.*)" ) /** - * REGEX-TEST: §8[§r§5396§r§8] §r§7☢ §r§a[✌] §b[MVP§c+§b] hannibal2§f: hey - * REGEX-TEST: §b[MVP§c+§b] hannibal2 - * REGEX-TEST: §6§l℻ §r§f[Gamer] §b[MVP§f+§b] SchrankLP§f§r - * REGEX-TEST: §7☢ §r§a[✌] §b[MVP§c+§b] hannibal2 + * REGEX-TEST: ♫ §a[✌] §f[Gamer] §b[MVP§d+§b] lrg89 + * REGEX-TEST: ℻ §b[MVP§5+§b] Alea1337 + * REGEX-TEST: ♫ §a[✌] §c[Buddy ツ] §b[MVP§d+§b] lrg89 */ - private val prrivateIslandGuestPattern by patternGroup.pattern( + private val privateIslandGuestPattern by patternGroup.pattern( "privateislandguest", - ".*(?<guest>§r§a\\[✌]).*" + "(?<prefix>.*)(?<guest>§a\\[✌] )(?<suffix>.*)" ) @SubscribeEvent fun onChat(event: LorenzChatEvent) { - val chatComponent = event.chatComponent - partyPattern.matchMatcher(event.message) { - val author = group("author") - val message = group("message") - PartyChatEvent(author, message, chatComponent).postChat(event) + val chatComponent = event.chatComponent.intoSpan().stripHypixelMessage() + coopPattern.matchStyledMatcher(chatComponent) { + val author = groupOrThrow("author") + val message = groupOrThrow("message") + CoopChatEvent(author, message, event.chatComponent).postChat(event) + return + } + partyPattern.matchStyledMatcher(chatComponent) { + PartyChatEvent(groupOrThrow("author"), groupOrThrow("message"), event.chatComponent) + .postChat(event) return } - guildPattern.matchMatcher(event.message) { - val author = group("author") - val message = group("message") - val guildRank = groupOrNull("guildRank") - GuildChatEvent(author, message, guildRank, chatComponent).postChat(event) + guildPattern.matchStyledMatcher(chatComponent) { + GuildChatEvent( + groupOrThrow("author"), + groupOrThrow("message"), + group("guildRank"), + event.chatComponent + ).postChat(event) return } - privateMessagePattern.matchMatcher(event.message) { - val direction = group("direction") - val author = group("author") - val message = group("message") - PrivateMessageChatEvent(direction, author, message, chatComponent).postChat(event) + privateMessagePattern.matchStyledMatcher(chatComponent) { + val direction = groupOrThrow("direction").getText() + val author = groupOrThrow("author") + val message = groupOrThrow("message") + PrivateMessageChatEvent(direction, author, message, event.chatComponent).postChat(event) return } - itemShowPattern.matchMatcher(event.message) { - val levelColor = groupOrNull("levelColor") - val level = groupOrNull("level")?.formatInt() - val author = group("author") - val action = group("action") - val itemName = group("itemName") - - // for consistency - val message = "§7$action §r$itemName" - PlayerShowItemChatEvent(levelColor, level, author, message, action, itemName, chatComponent).postChat(event) + itemShowPattern.matchStyledMatcher(chatComponent) { + val level = group("level") + val author = groupOrThrow("author") + val action = groupOrThrow("action") + val itemName = groupOrThrow("itemName") + + PlayerShowItemChatEvent( + level, + action, + author, + itemName, + author + action + itemName, + event.chatComponent + ).postChat(event) return } - globalPattern.matchMatcher(event.message) { + globalPattern.matchStyledMatcher(chatComponent) { if (isGlobalChat(event)) return } sendSystemMessage(event) } - private fun Matcher.isGlobalChat(event: LorenzChatEvent): Boolean { - var author = group("author") - val message = LorenzUtils.stripVanillaMessage(group("message")) - if (author.contains("[NPC]")) { - NpcChatEvent(author, message.removePrefix("§f"), event.chatComponent).postChat(event) + private fun ComponentMatcher.isGlobalChat(event: LorenzChatEvent): Boolean { + var author = groupOrThrow("author") + val message = groupOrThrow("message").removePrefix("§f") + if (author.getText().contains("[NPC]")) { + NpcChatEvent(author, message, event.chatComponent).postChat(event) return true } - var privateIslandRank: String? = null - var isAGuest = false + var privateIslandRank: ComponentSpan? = null + var privateIslandGuest: ComponentSpan? = null if (IslandType.PRIVATE_ISLAND.isInIsland() || IslandType.PRIVATE_ISLAND_GUEST.isInIsland()) { - privateIslandRankPattern.matchMatcher(author) { - val rank = group("privateIslandRank") - privateIslandRank = rank - author = author.replace(rank, "") + privateIslandGuestPattern.matchStyledMatcher(author) { + privateIslandGuest = groupOrThrow("guest") + val prefix = groupOrThrow("prefix") + val suffix = groupOrThrow("suffix") + author = prefix + suffix } - prrivateIslandGuestPattern.matchMatcher(author) { - val guest = group("guest") - isAGuest = true - author = author.replace(guest, "") + privateIslandRankPattern.matchStyledMatcher(author) { + privateIslandRank = groupOrThrow("privateIslandRank") + val prefix = groupOrThrow("prefix") + val suffix = groupOrThrow("suffix") + author = prefix + suffix } } - val chatColor = group("chatColor") - val levelColor = groupOrNull("levelColor") - val level = groupOrNull("level")?.formatInt() PlayerAllChatEvent( - levelColor = levelColor, - level = level, + levelComponent = group("level"), privateIslandRank = privateIslandRank, - isAGuest = isAGuest, - author = author, - chatColor = chatColor, - message = message, + privateIslandGuest = privateIslandGuest, + chatColor = groupOrThrow("chatColor").getText(), + authorComponent = author, + messageComponent = message, chatComponent = event.chatComponent, ).postChat(event) return true diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt index 55735413b..35c1e8cd1 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.data.hypixel.chat import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.features.chat.PlayerMessagesConfig +import at.hannibal2.skyhanni.data.hypixel.chat.event.CoopChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.GuildChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.PartyChatEvent import at.hannibal2.skyhanni.data.hypixel.chat.event.PlayerAllChatEvent @@ -12,14 +13,19 @@ import at.hannibal2.skyhanni.features.bingo.BingoAPI import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatFilter import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager import at.hannibal2.skyhanni.features.misc.compacttablist.AdvancedPlayerList +import at.hannibal2.skyhanni.utils.ChatComponentUtils +import at.hannibal2.skyhanni.utils.ComponentMatcherUtils.matchStyledMatcher +import at.hannibal2.skyhanni.utils.ComponentSpan import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.StringUtils +import at.hannibal2.skyhanni.utils.StringUtils.applyFormattingFrom import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName -import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.replaceAll +import at.hannibal2.skyhanni.utils.StringUtils.toCleanChatComponent import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import com.google.gson.JsonArray import com.google.gson.JsonNull +import net.minecraft.util.ChatComponentText +import net.minecraft.util.IChatComponent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent /** @@ -37,111 +43,143 @@ class PlayerNameFormatter { * REGEX-TEST: §7☢ §r§bhannibal2 * REGEX-TEST: §7☢ §rhannibal2 * REGEX-TEST: §7☢ §b[MVP§c+§b] hannibal2 + * REGEX-TEST: ♫ §b[MVP§d+§b] lrg89 */ private val emblemPattern by patternGroup.pattern( "emblem", - "(?<emblem>(?:§.){1,2}.) (?<author>.*)" + "(?<emblem>(?:§.){0,2}.) (?<author>.*)" ) + private val empty: IChatComponent = ChatComponentText("") + @SubscribeEvent fun onPlayerAllChat(event: PlayerAllChatEvent) { if (!isEnabled()) return val levelColor = event.levelColor - val level = event.level - val message = event.message - val author = event.author + val levelComponent = event.levelComponent + val message = event.messageComponent + val authorComponent = event.authorComponent val privateIslandRank = event.privateIslandRank - val isAGuest = event.isAGuest + val privateIslandGuest = event.privateIslandGuest - val shouldFilter = config.chatFilter && PlayerChatFilter.shouldChatFilter(message) + val shouldFilter = config.chatFilter && PlayerChatFilter.shouldChatFilter(message.intoComponent()) val chatColor = if (shouldFilter) "§7" else if (config.sameChatColor) "§f" else event.chatColor - val name = nameFormat(author, levelColor, level, privateIslandRank = privateIslandRank, isAGuest = isAGuest) - val newMessage = "$name$chatColor: $message" - - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, newMessage) ?: return + val name = nameFormat( + authorComponent, + levelColor?.toString(), + level = levelComponent, + privateIslandRank = privateIslandRank, + privateIslandGuest = privateIslandGuest + ) + val all = ChatComponentText("") + all.appendSibling(name) + all.appendText(": ") + all.appendSibling(chatColor.toCleanChatComponent()) + all.appendSibling(message.intoComponent()) + event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, all) ?: return } @SubscribeEvent - fun onPartyChat(event: PartyChatEvent) { + fun onCoopChat(event: CoopChatEvent) { if (!isEnabled()) return - val message = event.message - val author = event.author - val name = nameFormat(author) - val newMessage = "§9Party §8> $name§f: $message" - - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, newMessage) ?: return + event.chatComponent = StringUtils.replaceIfNeeded( + event.chatComponent, + ChatComponentUtils.text("§bCo-Op > ") { + appendSibling(nameFormat(event.authorComponent)) + appendText("§f: ") + appendSibling(event.messageComponent.intoComponent()) + } + ) ?: return } @SubscribeEvent fun onGuildChat(event: GuildChatEvent) { if (!isEnabled()) return - val message = event.message - val author = event.author - val guildRank = event.guildRank - val name = nameFormat(author, guildRank = guildRank) - val newMessage = "§2Guild > $name§f: $message" - - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, newMessage) ?: return + event.chatComponent = StringUtils.replaceIfNeeded( + event.chatComponent, + ChatComponentUtils.text("§2Guild > ") { + appendSibling(nameFormat(event.authorComponent, guildRank = event.guildRank)) + appendText("§f: ") + appendSibling(event.messageComponent.intoComponent()) + } + ) ?: return } @SubscribeEvent - fun onPrivateMessageChat(event: PrivateMessageChatEvent) { + fun onPartyChat(event: PartyChatEvent) { if (!isEnabled()) return - val direction = event.direction - val message = event.message - val author = event.author - val name = nameFormat(author) - val newMessage = "§d$direction §f$name§7: §f$message" + event.chatComponent = StringUtils.replaceIfNeeded( + event.chatComponent, + ChatComponentUtils.text("§9Party §8> ") { + appendSibling(nameFormat(event.authorComponent)) + appendText("§f: ") + appendSibling(event.messageComponent.intoComponent()) + } + ) ?: return + } - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, newMessage) ?: return + @SubscribeEvent + fun onPrivateChat(event: PrivateMessageChatEvent) { + if (!isEnabled()) return + event.chatComponent = + StringUtils.replaceIfNeeded(event.chatComponent, ChatComponentUtils.text("§d${event.direction}") { + appendText(" ") + appendSibling(nameFormat(event.authorComponent)) + appendText("§f: ") + appendSibling(event.messageComponent.intoComponent()) + }) ?: return } + @SubscribeEvent fun onPlayerShowItemChat(event: PlayerShowItemChatEvent) { if (!isEnabled()) return - val author = event.author - val action = event.action - val itemName = event.itemName - val levelColor = event.levelColor - val level = event.level - val name = nameFormat(author, levelColor = levelColor, level = level) - val newMessage = "$name §7$action §r$itemName" - - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, newMessage) ?: return + event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, ChatComponentUtils.text("") { + appendSibling( + nameFormat( + event.authorComponent, + levelColor = event.levelComponent?.sampleStyleAtStart()?.color?.toString(), + level = event.levelComponent + ) + ) + appendSibling(event.action.intoComponent()) + appendText(" ") + appendSibling(event.item.intoComponent()) + }) ?: return } private fun nameFormat( - author: String, + author: ComponentSpan, levelColor: String? = null, - level: Int? = null, - guildRank: String? = null, - privateIslandRank: String? = null, - isAGuest: Boolean = false, - ): String { + level: ComponentSpan? = null, + guildRank: ComponentSpan? = null, + privateIslandRank: ComponentSpan? = null, + privateIslandGuest: ComponentSpan? = null, + ): ChatComponentText { var cleanAuthor = cleanAuthor(author) - var emblemFormat = "" - emblemPattern.matchMatcher(author) { - emblemFormat = group("emblem") - cleanAuthor = LorenzUtils.stripVanillaMessage(group("author")) + var emblemFormat = empty + emblemPattern.matchStyledMatcher(author) { + emblemFormat = componentOrThrow("emblem") + cleanAuthor = groupOrThrow("author").stripHypixelMessage() } - val name = formatAuthor(cleanAuthor, levelColor) + val name = formatAuthor(cleanAuthor.getText(), levelColor).applyFormattingFrom(cleanAuthor) val levelFormat = formatLevel(levelColor, level) - val guildRankFormat = guildRank ?: "" - val privateIslandRankFormat = privateIslandRank ?: "" - val privateIslandGuestFormat = if (isAGuest) "§a[✌]" else "" + val guildRankFormat = guildRank?.intoComponent() ?: empty + val privateIslandRankFormat = privateIslandRank?.intoComponent() ?: empty + val privateIslandGuestFormat = privateIslandGuest?.intoComponent() ?: empty - val cleanName = cleanAuthor.cleanPlayerName() + val cleanName = cleanAuthor.getText().cleanPlayerName() val (faction, ironman, bingo) = AdvancedPlayerList.tabPlayerData[cleanName]?.let { - val faction = it.faction.icon - val ironman = if (it.ironman) "§7♲" else "" - val bingo = it.bingoLevel?.let { level -> BingoAPI.getBingoIcon(level) } ?: "" + val faction = it.faction.icon.toCleanChatComponent() + val ironman = if (it.ironman) "§7♲".toCleanChatComponent() else empty + val bingo = it.bingoLevel?.let { level -> BingoAPI.getBingoIcon(level).toCleanChatComponent() } ?: empty listOf(faction, ironman, bingo) - } ?: listOf("", "", "") + } ?: listOf(empty, empty, empty) - val map = mutableMapOf<PlayerMessagesConfig.MessagePart, String>() + val map = mutableMapOf<PlayerMessagesConfig.MessagePart, IChatComponent>() map[PlayerMessagesConfig.MessagePart.SKYBLOCK_LEVEL] = levelFormat map[PlayerMessagesConfig.MessagePart.EMBLEM] = emblemFormat map[PlayerMessagesConfig.MessagePart.PLAYER_NAME] = name @@ -152,19 +190,46 @@ class PlayerNameFormatter { map[PlayerMessagesConfig.MessagePart.PRIVATE_ISLAND_RANK] = privateIslandRankFormat map[PlayerMessagesConfig.MessagePart.PRIVATE_ISLAND_GUEST] = privateIslandGuestFormat - return config.partsOrder.map { map[it] }.joinToString(" ").replaceAll(" ", " ").trim() + val all = ChatComponentText("") + for (text in config.partsOrder.mapNotNull { map[it] }) { + all.appendSibling(text) + if (!all.unformattedText.endsWith(" ")) { + all.appendText(" ") + } + } + + return all +// return config.partsOrder.map { map[it] }.joinToString(" ").replaceAll(" ", " ").trim() } - private fun formatLevel(rawColor: String?, rawLevel: Int?): String { - val color = rawColor ?: return "" - val level = rawLevel ?: error("level is null, color is not null") +// private fun String.add(iChatComponent: IChatComponent): ChatComponentText { +// val style = findStyle(iChatComponent) +// val text = ChatComponentText(this.trim()) +// text.chatStyle = style +// +// return text +// } +// +// private fun String.findStyle(iChatComponent: IChatComponent): ChatStyle? { +// for (sibling in iChatComponent.siblings) { +// if (sibling.unformattedText.contains(this)) { +// return sibling.chatStyle +// } +// } +// return null +// } + + private fun formatLevel(rawColor: String?, rawLevel: ComponentSpan?): IChatComponent { + val color = rawColor ?: return empty + val level = rawLevel?.getText() ?: error("level is null, color is not null") val levelData = "$color$level" - return if (config.hideLevelBrackets) levelData else "§8[${levelData}§8]" + val result = if (config.hideLevelBrackets) levelData else "§8[${levelData}§8]" + return result.applyFormattingFrom(rawLevel) } - private fun cleanAuthor(author: String): String { - val text = LorenzUtils.stripVanillaMessage(author) - return text.removeSuffix("§f") + private fun cleanAuthor(author: ComponentSpan): ComponentSpan { + // TODO: I don't think we even need to strip this ??? + return author.stripHypixelMessage().removePrefix("§f") } private fun formatAuthor(author: String, levelColor: String?): String { diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/AbstractChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/AbstractChatEvent.kt index cd0a8f92b..d7dce85c7 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/AbstractChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/AbstractChatEvent.kt @@ -1,11 +1,15 @@ package at.hannibal2.skyhanni.data.hypixel.chat.event import at.hannibal2.skyhanni.events.LorenzEvent +import at.hannibal2.skyhanni.utils.ComponentSpan import net.minecraft.util.IChatComponent open class AbstractChatEvent( - val author: String, - val message: String, + val authorComponent: ComponentSpan, + val messageComponent: ComponentSpan, var chatComponent: IChatComponent, var blockedReason: String? = null, -) : LorenzEvent() +) : LorenzEvent() { + val message by lazy { messageComponent.getText() } + val author by lazy { authorComponent.getText() } +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/CoopChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/CoopChatEvent.kt new file mode 100644 index 000000000..2aa075dc6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/CoopChatEvent.kt @@ -0,0 +1,11 @@ +package at.hannibal2.skyhanni.data.hypixel.chat.event + +import at.hannibal2.skyhanni.utils.ComponentSpan +import net.minecraft.util.IChatComponent + +class CoopChatEvent( + authorComponent: ComponentSpan, + messageComponent: ComponentSpan, + chatComponent: IChatComponent, + blockedReason: String? = null, +) : AbstractChatEvent(authorComponent, messageComponent, chatComponent, blockedReason) diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/GuildChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/GuildChatEvent.kt index dd3867106..c07985d94 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/GuildChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/GuildChatEvent.kt @@ -1,11 +1,13 @@ package at.hannibal2.skyhanni.data.hypixel.chat.event +import at.hannibal2.skyhanni.utils.ComponentSpan import net.minecraft.util.IChatComponent + class GuildChatEvent( - author: String, - message: String, - val guildRank: String? = null, + author: ComponentSpan, + message: ComponentSpan, + val guildRank: ComponentSpan?, chatComponent: IChatComponent, blockedReason: String? = null, ) : AbstractChatEvent(author, message, chatComponent, blockedReason) diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/NpcChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/NpcChatEvent.kt index 574324520..fb0bd38a4 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/NpcChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/event/NpcChatEvent.kt @@ -1,10 +1,11 @@ package at.hannibal2.skyhanni.data.hypixel.chat.event +import at.hannibal2.skyhanni.utils.ComponentSpan import net.minecraft.util.IChatComponent |
