From ce43d92584b785650b35d5a6ebdbfddd7d31661c Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Sat, 17 Sep 2022 17:40:44 +0200 Subject: mark players in chat --- .../java/at/hannibal2/skyhanni/SkyHanniMod.java | 8 +- .../at/hannibal2/skyhanni/config/Features.java | 12 +- .../skyhanni/config/commands/Commands.java | 4 +- .../skyhanni/config/features/MarkedPlayers.java | 23 ++ .../java/at/hannibal2/skyhanni/data/EntityData.kt | 6 +- .../skyhanni/events/PlayerSendChatEvent.kt | 3 +- .../skyhanni/features/MarkedPlayerManager.kt | 135 ++++++++++ .../at/hannibal2/skyhanni/features/PlayerMarker.kt | 90 ------- .../skyhanni/features/chat/HideFarDeathMessages.kt | 64 ----- .../skyhanni/features/chat/PlayerChatFormatter.kt | 286 -------------------- .../skyhanni/features/chat/PlayerDeathMessages.kt | 82 ++++++ .../skyhanni/features/chat/PlayerMessageChannel.kt | 17 -- .../chat/playerchat/PlayerChatFormatter.kt | 296 +++++++++++++++++++++ .../chat/playerchat/PlayerMessageChannel.kt | 17 ++ 14 files changed, 575 insertions(+), 468 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayers.java create mode 100644 src/main/java/at/hannibal2/skyhanni/features/MarkedPlayerManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/PlayerMarker.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/HideFarDeathMessages.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFormatter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFormatter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerMessageChannel.kt (limited to 'src/main/java/at/hannibal2/skyhanni') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index cf310e364..1dd8ad6ef 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -11,8 +11,8 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarApi; import at.hannibal2.skyhanni.features.bazaar.BazaarBestSellMethod; import at.hannibal2.skyhanni.features.bazaar.BazaarOrderHelper; import at.hannibal2.skyhanni.features.chat.ChatFilter; -import at.hannibal2.skyhanni.features.chat.HideFarDeathMessages; -import at.hannibal2.skyhanni.features.chat.PlayerChatFormatter; +import at.hannibal2.skyhanni.features.chat.PlayerDeathMessages; +import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatFormatter; import at.hannibal2.skyhanni.features.commands.WikiCommand; import at.hannibal2.skyhanni.features.damageindicator.DamageIndicatorManager; import at.hannibal2.skyhanni.features.dungeon.*; @@ -119,9 +119,9 @@ public class SkyHanniMod { registerEvent(new SummoningMobManager()); registerEvent(new VoidlingExtremistColor()); registerEvent(new CorruptedMobHighlight()); - registerEvent(new PlayerMarker()); + registerEvent(new MarkedPlayerManager()); registerEvent(new HighlightSlayerMiniboss()); - registerEvent(new HideFarDeathMessages()); + registerEvent(new PlayerDeathMessages()); registerEvent(new HighlightDungeonDeathmite()); registerEvent(new DungeonHideItems()); registerEvent(new DungeonCopilot()); diff --git a/src/main/java/at/hannibal2/skyhanni/config/Features.java b/src/main/java/at/hannibal2/skyhanni/config/Features.java index 70307c9f4..3e5c4af7f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Features.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Features.java @@ -8,7 +8,8 @@ import at.hannibal2.skyhanni.config.core.config.Position; import at.hannibal2.skyhanni.config.core.config.annotations.Category; import at.hannibal2.skyhanni.config.core.config.gui.GuiPositionEditor; import at.hannibal2.skyhanni.config.features.*; -import at.hannibal2.skyhanni.features.chat.PlayerChatFormatter; +import at.hannibal2.skyhanni.features.MarkedPlayerManager; +import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatFormatter; import com.google.gson.annotations.Expose; import net.minecraft.client.Minecraft; @@ -95,6 +96,11 @@ public class Features extends Config { PlayerChatFormatter.Companion.testGuildChat(); return; } + + if (runnableId.equals("markOwnPlayer")) { + MarkedPlayerManager.toggleOwn(); + return; + } } @Expose @@ -145,6 +151,10 @@ public class Features extends Config { @Category(name = "Commands", desc = "Enable or disable mod commands") public CommandsFeatures commands = new CommandsFeatures(); + @Expose + @Category(name = "Marked Players", desc = "Players that got marked with /shmarkplayer") + public MarkedPlayers markedPlayers = new MarkedPlayers(); + @Expose @Category(name = "Misc", desc = "Settings without a category.") public Misc misc = new Misc(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.java b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.java index 460de1b7f..275a6eaaf 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.java +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.java @@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.config.commands; import at.hannibal2.skyhanni.SkyHanniMod; import at.hannibal2.skyhanni.config.ConfigEditor; import at.hannibal2.skyhanni.config.core.GuiScreenElementWrapper; -import at.hannibal2.skyhanni.features.PlayerMarker; +import at.hannibal2.skyhanni.features.MarkedPlayerManager; import at.hannibal2.skyhanni.test.LorenzTest; import at.hannibal2.skyhanni.test.command.CopyItemCommand; import at.hannibal2.skyhanni.test.command.CopyNearbyEntitiesCommand; @@ -93,7 +93,7 @@ public class Commands { "shmarkplayer", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { - PlayerMarker.Companion.command(args); + MarkedPlayerManager.Companion.command(args); } } ) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayers.java b/src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayers.java new file mode 100644 index 000000000..7bff63e95 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayers.java @@ -0,0 +1,23 @@ +package at.hannibal2.skyhanni.config.features; + +import at.hannibal2.skyhanni.config.core.config.annotations.ConfigEditorBoolean; +import at.hannibal2.skyhanni.config.core.config.annotations.ConfigOption; +import com.google.gson.annotations.Expose; + +public class MarkedPlayers { + + @Expose + @ConfigOption(name = "Highlight in World", desc = "Highlight marked players in the world.") + @ConfigEditorBoolean + public boolean highlightInWorld = true; + + @Expose + @ConfigOption(name = "Highlight in Chat", desc = "Highlight marked player names in chat.") + @ConfigEditorBoolean + public boolean highlightInChat = true; + + @Expose + @ConfigOption(name = "Mark Own Name", desc = "Mark own player name.") + @ConfigEditorBoolean(runnableId = "markOwnPlayer") + public boolean markOwnName = false; +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt index 79d0107c7..f306bcdf8 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt @@ -16,7 +16,7 @@ class EntityData { if (packet !is S1CPacketEntityMetadata) return if (packet == null) { - LorenzUtils.debug("packet is null in CorruptedMobHigh light!") + LorenzUtils.debug("packet is null in EntityData!") return } @@ -26,12 +26,12 @@ class EntityData { val theWorld = Minecraft.getMinecraft().theWorld if (theWorld == null) { - LorenzUtils.debug("theWorld is null in CorruptedMobHighlight!") + LorenzUtils.debug("theWorld is null in EntityData!") continue } val entityId = packet.entityId if (entityId == null) { - LorenzUtils.debug("entityId is null in CorruptedMobHighlight!") + LorenzUtils.debug("entityId is null in EntityData!") continue } diff --git a/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt index bf392939a..4ed17e749 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.events -import at.hannibal2.skyhanni.features.chat.PlayerMessageChannel +import at.hannibal2.skyhanni.features.chat.playerchat.PlayerMessageChannel +import net.minecraft.util.ChatComponentText class PlayerSendChatEvent( val channel: PlayerMessageChannel, diff --git a/src/main/java/at/hannibal2/skyhanni/features/MarkedPlayerManager.kt b/src/main/java/at/hannibal2/skyhanni/features/MarkedPlayerManager.kt new file mode 100644 index 000000000..48570898d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/MarkedPlayerManager.kt @@ -0,0 +1,135 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.PlayerSendChatEvent +import at.hannibal2.skyhanni.events.RenderMobColoredEvent +import at.hannibal2.skyhanni.events.ResetEntityHurtEvent +import at.hannibal2.skyhanni.events.withAlpha +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraft.util.EnumChatFormatting +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class MarkedPlayerManager { + + companion object { + private val playerNamesToMark = mutableListOf() + private val markedPlayers = mutableMapOf() + + fun command(args: Array) { + if (args.size != 1) { + LorenzUtils.chat("§cUsage: /shmarkplayer ") + return + } + + val displayName = args[0] + val name = displayName.lowercase() + + + if (name == Minecraft.getMinecraft().thePlayer.name.lowercase()) { + LorenzUtils.chat("§c[SkyHanni] You can't add or remove yourself this way! Go to the settings and toggle 'Mark your own name'.") + return + } + + if (name !in playerNamesToMark) { + playerNamesToMark.add(name) + findPlayers() + LorenzUtils.chat("§e[SkyHanni] §aMarked §eplayer §b$displayName§e!") + } else { + playerNamesToMark.remove(name) + markedPlayers.remove(name) + LorenzUtils.chat("§e[SkyHanni] §cUnmarked §eplayer §b$displayName§e!") + } + } + + private fun findPlayers() { + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityOtherPlayerMP) { + if (entity in markedPlayers.values) continue + + val name = entity.name.lowercase() + if (name in playerNamesToMark) { + markedPlayers[name] = entity + } + } + } + } + + fun isMarkedPlayer(player: String): Boolean = player.lowercase() in playerNamesToMark + + @JvmStatic + fun toggleOwn() { + val ownName = SkyHanniMod.feature.markedPlayers.markOwnName + val name = Minecraft.getMinecraft().thePlayer.name + if (ownName) { + if (!playerNamesToMark.contains(name)) { + playerNamesToMark.add(name) + } + } else { + playerNamesToMark.remove(name) + } + } + } + + var tick = 0 + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!LorenzUtils.inSkyblock) return + + if (tick++ % 20 == 0) { + findPlayers() + } + } + + @SubscribeEvent + fun onRenderMobColored(event: RenderMobColoredEvent) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return + + val entity = event.entity + if (entity in markedPlayers.values) { + event.color = LorenzColor.YELLOW.toColor().withAlpha(127) + } + } + + @SubscribeEvent + fun onResetEntityHurtTime(event: ResetEntityHurtEvent) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return + + val entity = event.entity + if (entity in markedPlayers.values) { + event.shouldReset = true + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + if (Minecraft.getMinecraft().thePlayer == null) return + + markedPlayers.clear() + if (SkyHanniMod.feature.markedPlayers.markOwnName) { + val name = Minecraft.getMinecraft().thePlayer.name + if (!playerNamesToMark.contains(name)) { + playerNamesToMark.add(name) + } + } + } + + @SubscribeEvent(receiveCanceled = true) + fun onMarkedChatMessage(event: PlayerSendChatEvent) { + if (!LorenzUtils.inSkyblock) return + + for (chatComponent in event.chatComponents) { + val text = chatComponent.unformattedText + if (isMarkedPlayer(text) && SkyHanniMod.feature.markedPlayers.highlightInChat) { + chatComponent.chatStyle.color = EnumChatFormatting.YELLOW + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/PlayerMarker.kt b/src/main/java/at/hannibal2/skyhanni/features/PlayerMarker.kt deleted file mode 100644 index eac2f2575..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/PlayerMarker.kt +++ /dev/null @@ -1,90 +0,0 @@ -package at.hannibal2.skyhanni.features - -import at.hannibal2.skyhanni.events.RenderMobColoredEvent -import at.hannibal2.skyhanni.events.ResetEntityHurtEvent -import at.hannibal2.skyhanni.events.withAlpha -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraft.client.entity.EntityOtherPlayerMP -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -class PlayerMarker { - - companion object { - private val playerNamesToMark = mutableListOf() - private val markedPlayers = mutableMapOf() - - fun command(args: Array) { - if (args.size != 1) { - LorenzUtils.chat("§cUsage: /shmarkplayer ") - return - } - - val displayName = args[0] - val name = displayName.lowercase() - if (name !in playerNamesToMark) { - playerNamesToMark.add(name) - findPlayers() - LorenzUtils.chat("§e[SkyHanni] §aMarked §eplayer §b$displayName!") - } else { - playerNamesToMark.remove(name) - markedPlayers.remove(name) - LorenzUtils.chat("§e[SkyHanni] §cUnmarked §eplayer §b$displayName!") - } - } - - private fun findPlayers() { - for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { - if (entity is EntityOtherPlayerMP) { - if (entity in markedPlayers.values) continue - - val name = entity.name.lowercase() - if (name in playerNamesToMark) { - markedPlayers[name] = entity - } - } - } - } - } - - var tick = 0 - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - - if (tick++ % 20 == 0) { - findPlayers() - } - } - - @SubscribeEvent - fun onRenderMobColored(event: RenderMobColoredEvent) { - if (!isEnabled()) return - val entity = event.entity - if (entity in markedPlayers.values) { - event.color = LorenzColor.YELLOW.toColor().withAlpha(127) - } - } - - @SubscribeEvent - fun onResetEntityHurtTime(event: ResetEntityHurtEvent) { - if (!isEnabled()) return - val entity = event.entity - if (entity in markedPlayers.values) { - event.shouldReset = true - } - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - markedPlayers.clear() - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/HideFarDeathMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/HideFarDeathMessages.kt deleted file mode 100644 index 0a3ead47d..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/HideFarDeathMessages.kt +++ /dev/null @@ -1,64 +0,0 @@ -package at.hannibal2.skyhanni.features.chat - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.HypixelData -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LocationUtils -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.getLorenzVec -import net.minecraft.client.Minecraft -import net.minecraft.client.entity.EntityOtherPlayerMP -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.regex.Pattern - -class HideFarDeathMessages { - - private var tick = 0 - private val lastTimePlayerSeen = mutableMapOf() - - //§c ☠ §r§7§r§bZeroHazel§r§7 was killed by §r§8§lAshfang§r§7§r§7. - private val pattern = Pattern.compile("§c ☠ §r§7§r§.(.+)§r§7 (.+)") - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - - if (tick++ % 20 == 0) { - checkOtherPlayers() - } - } - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!isEnabled()) return - - val message = event.message - val matcher = pattern.matcher(message) - if (matcher.matches()) { - val name = matcher.group(1) - if (System.currentTimeMillis() > lastTimePlayerSeen.getOrDefault(name, 0) + 30_000) { - event.blockedReason = "far_away_player_death" - } - } - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - HypixelData.skyblock = false - } - - private fun checkOtherPlayers() { - val location = LocationUtils.playerLocation() - for (otherPlayer in Minecraft.getMinecraft().theWorld.loadedEntityList - .filterIsInstance() - .filter { it.getLorenzVec().distance(location) < 25 }) { - lastTimePlayerSeen[otherPlayer.name] = System.currentTimeMillis() - } - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.chat.hideFarDeathMessages && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFormatter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFormatter.kt deleted file mode 100644 index 36a9e057c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFormatter.kt +++ /dev/null @@ -1,286 +0,0 @@ -package at.hannibal2.skyhanni.features.chat - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PlayerSendChatEvent -import at.hannibal2.skyhanni.utils.LorenzLogger -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.event.ClickEvent -import net.minecraft.event.HoverEvent -import net.minecraft.util.ChatComponentText -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.regex.Pattern - -class PlayerChatFormatter { - - private val loggerPlayerChat = LorenzLogger("chat/player") - - private val sbaIconList = listOf( - "§5ቾ", // mage - "§c⚒", // barbarian - "§7♲", // ironman - //TODO test if bingo is working - "§aⒷ", // bingo rank 1 - "§9Ⓑ", // bingo rank 2 - "§5Ⓑ" // bingo rank 3 - - //maybe coming soon - //"§6Ⓑ" // bingo rank 4 - ) - - //§6[⌬57] §r§8[§r§b235§r§8] §r§6[MVP§r§c++§r§6] hannibal2§r§f: Hello World! - private val patternElitePrefix = Pattern.compile("§6\\[⌬(\\d+)] (.+)") - - //§8[§9109§8] §b[MVP§c+§b] 4Apex§f§r§f: omg selling - private val patternSkyBlockLevel = Pattern.compile("§8\\[§(.)(\\d+)§8] (.+)") - - // SBA is adding another §d in front of the message - //§dTo §r§b[MVP§r§3+§r§b] Skyfall55§r§7: §r§7hello :) - private var patternPrivateMessage: Pattern = Pattern.compile("(§d)+(To|From) §r(.+)§r§7: §r§7(.+)") - - private val patternUrl = - Pattern.compile("^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$") - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.isOnHypixel) return - - if (shouldBlock(event.message)) { - event.blockedReason = "player_chat" - } - } - - private fun shouldBlock(originalMessage: String): Boolean { - if (handlePrivateMessage(originalMessage)) return true - - //since hypixel sends own chat messages really weird " §r§8[§r§d205§r§8] §r§6[MVP§r§c++§r§6] hannibal2" - var rawMessage = originalMessage.replace("§r", "").trim() - - val matcherElite = patternElitePrefix.matcher(rawMessage) - val elitePrefix = if (matcherElite.matches()) { - val elitePosition = matcherElite.group(1).toInt() - rawMessage = matcherElite.group(2) - when (SkyHanniMod.feature.chat.eliteFormat) { - 0 -> "§6[⌬$elitePosition] " - 1 -> "§6§l⌬$elitePosition " - 2 -> "" - else -> "" - } - } else { - "" - } - - - val level: Int - val levelColor: String - val matcher = patternSkyBlockLevel.matcher(rawMessage) - if (matcher.matches()) { - levelColor = matcher.group(1) - level = matcher.group(2).toInt() - rawMessage = matcher.group(3) - } else { - level = -1 - levelColor = "" - } - - val split = if (rawMessage.contains("§7§7: ")) { - rawMessage.split("§7§7: ") - } else if (rawMessage.contains("§f: ")) { - rawMessage.split("§f: ") - } else { - return false - } - - var rawName = split[0] - val channel = grabChannel(rawName) - - rawName = rawName.substring(channel.originalPrefix.length) - - val sbaData = fetchSBAIcons(rawName) - val sbaIcons = sbaData.first - rawName = sbaData.second - - val name = grabName(rawName) ?: return false - - val message = split[1].removeColor() - callEvent(channel, name, message, level, levelColor, elitePrefix, sbaIcons) - return true - } - - private fun fetchSBAIcons(rawName: String): Pair { - val iconsSplit = rawName.split(" ") - var sbaIcons = "" - var toRemove = 0 - for (text in iconsSplit) { - sbaIconList.find { text.contains(it) }?.let { - sbaIcons += " $it" - toRemove++ - } - } - var name = iconsSplit.dropLast(toRemove).joinToString(" ") - - // Test if any unknown icons are left - if (!name.split(" ").last().any { it in 'A'..'Z' || it in 'a'..'z' }) { - println(" ") - println("Unknown chat icon detected!") - LorenzUtils.chat("§c[SkyHanni] Unknown chat icon detected!") - println("name 1: '$rawName'") - println("name 2: '$name'") - name = rawName - } - - return Pair(sbaIcons, name) - } - - private fun handlePrivateMessage(originalMessage: String): Boolean { - val matcher = patternPrivateMessage.matcher(originalMessage) - if (!matcher.matches()) return false - val direction = matcher.group(2) - var rawName = matcher.group(3) - - val sbaData = fetchSBAIcons(rawName) - val sbaIcons = sbaData.first - rawName = sbaData.second - - val name = grabName(rawName) ?: return false - - val message = matcher.group(4) - val colon = if (SkyHanniMod.feature.chat.playerColonHider) "" else ":" - LorenzUtils.chat("§d$direction $name$sbaIcons§f$colon $message") - loggerPlayerChat.log("[Msg_$direction] $name: $message") - return true - } - - private fun grabChannel(name: String): PlayerMessageChannel { - return PlayerMessageChannel.values() - .find { it != PlayerMessageChannel.ALL && name.startsWith(it.originalPrefix) } - ?: PlayerMessageChannel.ALL - } - - private fun grabName(rawName: String, clean: Boolean = false): String? { - val nameSplit = rawName.removeColor().split(" ") - val last = nameSplit.last() - val cleanName = if (last.endsWith("]")) { - nameSplit[nameSplit.size - 2] - } else { - last - } - - val first = nameSplit[0] - if (first != cleanName) { - if (!first.contains("VIP") && !first.contains("MVP")) { - //TODO support yt + admin - return null - } - } - - if (clean) { - return cleanName - } - - return if (SkyHanniMod.feature.chat.playerRankHider) { - "§b$cleanName" - } else { - rawName - } - } - - private fun callEvent( - channel: PlayerMessageChannel, - formattedName: String, - message: String, - level: Int, - levelColor: String, - elitePrefix: String, - sbaIcons: String, - ) { - val cleanName = grabName(formattedName, true)!! - loggerPlayerChat.log("[$channel] $cleanName: $message") - val event = PlayerSendChatEvent(channel, cleanName, message) - event.postAndCatch() - - if (event.cancelledReason != "") { - loggerPlayerChat.log("cancelled: " + event.cancelledReason) - return - } - - val channelPrefix = getChannelPrefix(channel) - val colon = if (SkyHanniMod.feature.chat.playerColonHider) "" else ":" - val levelFormat = getLevelFormat(formattedName + sbaIcons, level, levelColor) - - val nameText = ChatComponentText("$channelPrefix$elitePrefix$levelFormat§f$colon") - if (SkyHanniMod.feature.chat.neuProfileViewer) { - nameText.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/pv $cleanName") - nameText.chatStyle.chatHoverEvent = HoverEvent( - HoverEvent.Action.SHOW_TEXT, - ChatComponentText("§7Click to open the §cNEU Profile Viewer §7for $formattedName") - ) - } - - addChat(nameText, event.message) - } - - private fun addChat(text: ChatComponentText, message: String) { - val fullText = ChatComponentText("") - fullText.appendSibling(text) - for (word in message.split(" ")) { - fullText.appendSibling(ChatComponentText(" ")) - if (patternUrl.matcher(word).matches()) { - val oneWord = ChatComponentText(word) - oneWord.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.OPEN_URL, word) - fullText.appendSibling(oneWord) - } else { - fullText.appendSibling(ChatComponentText(word)) - } - } - - Minecraft.getMinecraft().thePlayer.addChatMessage(fullText) - } - - private fun getLevelFormat(name: String, level: Int, levelColor: String): String { - if (level == -1) return name - - return when (SkyHanniMod.feature.chat.skyblockLevelDesign) { - 0 -> "§8[§${levelColor}${level}§8] $name" - 1 -> "§${levelColor}§l${level} $name" - 2 -> "$name §8[§${levelColor}${level}§8]" - 3 -> name - else -> "§8[§${levelColor}${level}§8] $name" - } - } - - private fun getChannelPrefix(channel: PlayerMessageChannel): String { - if (channel == PlayerMessageChannel.ALL && !SkyHanniMod.feature.chat.allChannelPrefix) return "" - - val color = channel.prefixColor - val small = channel.prefixSmall - val large = channel.prefixLarge - return when (SkyHanniMod.feature.chat.channelDesign) { - 0 -> "$color$large §8> " - 1 -> "$color$small> " - 2 -> "§8<$color$small§8> " - 3 -> "§8[$color$small§8] " - 4 -> "§8($color$small§8) " - else -> "$color$large §8> " - } - } - - companion object { - - fun testAllChat() { - val name = Minecraft.getMinecraft().thePlayer.name - val message = - "§6[⌬499] §8[§b123§8] §6[MVP§c++§6] $name§f: This is a all chat test message and will not be sent to hypixel." - LorenzChatEvent(message, ChatComponentText(message)).postAndCatch() - } - - fun testGuildChat() { - val name = Minecraft.getMinecraft().thePlayer.name - val message = - "§2Guild > §6[MVP§f++§6] $name §2[GuildRank]§f: This is a guild chat test message and will not be sent to hypixel." - LorenzChatEvent(message, ChatComponentText(message)).postAndCatch() - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt new file mode 100644 index 000000000..4e1e26fdb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt @@ -0,0 +1,82 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.HypixelData +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.MarkedPlayerManager +import at.hannibal2.skyhanni.utils.LocationUtils +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.util.regex.Pattern + +class PlayerDeathMessages { + + private var tick = 0 + private val lastTimePlayerSeen = mutableMapOf() + + //§c ☠ §r§7§r§bZeroHazel§r§7 was killed by §r§8§lAshfang§r§7§r§7. + private val pattern = Pattern.compile("§c ☠ §r§7§r§.(.+)§r§7 (.+)") + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!isHideFarDeathsEnabled()) return + + if (tick++ % 20 == 0) { + checkOtherPlayers() + } + } + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + + val message = event.message + val matcher = pattern.matcher(message) + if (matcher.matches()) { + val name = matcher.group(1) + if (SkyHanniMod.feature.markedPlayers.highlightInChat && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight) { + if (MarkedPlayerManager.isMarkedPlayer(name)) { + val reason = matcher.group(2).removeColor() + LorenzUtils.chat(" §c☠ §e$name §7$reason") + event.blockedReason = "marked_player_death" + return + } + } + + + if (isHideFarDeathsEnabled()) { + if (System.currentTimeMillis() > lastTimePlayerSeen.getOrDefault(name, 0) + 30_000) { + event.blockedReason = "far_away_player_death" + } + } + } else { + if (message.contains("☠")) { + println("wrong death message: '$message'") + } + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + HypixelData.skyblock = false + } + + private fun checkOtherPlayers() { + val location = LocationUtils.playerLocation() + for (otherPlayer in Minecraft.getMinecraft().theWorld.loadedEntityList + .filterIsInstance() + .filter { it.getLorenzVec().distance(location) < 25 }) { + lastTimePlayerSeen[otherPlayer.name] = System.currentTimeMillis() + } + } + + private fun isHideFarDeathsEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.chat.hideFarDeathMessages && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt deleted file mode 100644 index e457bea8f..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt +++ /dev/null @@ -1,17 +0,0 @@ -package at.hannibal2.skyhanni.features.chat - -enum class PlayerMessageChannel( - val prefixColor: String, - val prefixSmall: String, - val prefixLarge: String, - val originalPrefix: String, -) { - - ALL("§f", "A", "All", ""), - ALL_GUESTING("§a", "g", "Guest", "§a[✌] "), - ALL_DUNGEON_DEAD("§7", "D", "Dead", "§7[GHOST] "), - PARTY("§9", "P", "Party", "§9Party §8> "), - GUILD("§2", "G", "Guild", "§2Guild > "), - COOP("§b", "CC", "Co-op", "§bCo-op > "), - -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFormatter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFormatter.kt new file mode 100644 index 000000000..39b8458f2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFormatter.kt @@ -0,0 +1,296 @@ +package at.hannibal2.skyhanni.features.chat.playerchat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PlayerSendChatEvent +import at.hannibal2.skyhanni.features.MarkedPlayerManager +import at.hannibal2.skyhanni.utils.LorenzLogger +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import net.minecraft.client.Minecraft +import net.minecraft.event.ClickEvent +import net.minecraft.event.HoverEvent +import net.minecraft.util.ChatComponentText +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class PlayerChatFormatter { + + private val loggerPlayerChat = LorenzLogger("chat/player") + + private val sbaIconList = listOf( + "§5ቾ", // mage + "§c⚒", // barbarian + "§7♲", // ironman + //TODO test if bingo is working + "§aⒷ", // bingo rank 1 + "§9Ⓑ", // bingo rank 2 + "§5Ⓑ" // bingo rank 3 + + //maybe coming soon + //"§6Ⓑ" // bingo rank 4 + ) + + //§6[⌬57] §r§8[§r§b235§r§8] §r§6[MVP§r§c++§r§6] hannibal2§r§f: Hello World! + private val patternElitePrefix = Pattern.compile("§6\\[⌬(\\d+)] (.+)") + + //§8[§9109§8] §b[MVP§c+§b] 4Apex§f§r§f: omg selling + private val patternSkyBlockLevel = Pattern.compile("§8\\[§(.)(\\d+)§8] (.+)") + + // SBA is adding another §d in front of the message + //§dTo §r§b[MVP§r§3+§r§b] Skyfall55§r§7: §r§7hello :) + private var patternPrivateMessage: Pattern = Pattern.compile("(§d)+(To|From) §r(.+)§r§7: §r§7(.+)") + + private val patternUrl = + Pattern.compile("^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$") + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.isOnHypixel) return + + if (shouldBlock(event.message)) { + event.blockedReason = "player_chat" + } + } + + private fun shouldBlock(originalMessage: String): Boolean { + if (handlePrivateMessage(originalMessage)) return true + + //since hypixel sends own chat messages really weird " §r§8[§r§d205§r§8] §r§6[MVP§r§c++§r§6] hannibal2" + var rawMessage = originalMessage.replace("§r", "").trim() + + val matcherElite = patternElitePrefix.matcher(rawMessage) + val elitePrefix = if (matcherElite.matches()) { + val elitePosition = matcherElite.group(1).toInt() + rawMessage = matcherElite.group(2) + when (SkyHanniMod.feature.chat.eliteFormat) { + 0 -> "§6[⌬$elitePosition] " + 1 -> "§6§l⌬$elitePosition " + 2 -> "" + else -> "" + } + } else { + "" + } + + + val level: Int + val levelColor: String + val matcher = patternSkyBlockLevel.matcher(rawMessage) + if (matcher.matches()) { + levelColor = matcher.group(1) + level = matcher.group(2).toInt() + rawMessage = matcher.group(3) + } else { + level = -1 + levelColor = "" + } + + val split = if (rawMessage.contains("§7§7: ")) { + rawMessage.split("§7§7: ") + } else if (rawMessage.contains("§f: ")) { + rawMessage.split("§f: ") + } else { + return false + } + + var rawName = split[0] + val channel = grabChannel(rawName) + + rawName = rawName.substring(channel.originalPrefix.length) + + val sbaData = fetchSBAIcons(rawName) + val sbaIcons = sbaData.first + rawName = sbaData.second + + val name = grabName(rawName) ?: return false + + val message = split[1].removeColor() + callEvent(channel, name, message, level, levelColor, elitePrefix, sbaIcons) + return true + } + + private fun fetchSBAIcons(rawName: String): Pair { + val iconsSplit = rawName.split(" ") + var sbaIcons = "" + var toRemove = 0 + for (text in iconsSplit) { + sbaIconList.find { text.contains(it) }?.let { + sbaIcons += " $it" + toRemove++ + } + } + var name = iconsSplit.dropLast(toRemove).joinToString(" ") + + // Test if any unknown icons are left + if (!name.split(" ").last().any { it in 'A'..'Z' || it in 'a'..'z' }) { + println(" ") + println("Unknown chat icon detected!") + LorenzUtils.chat("§c[SkyHanni] Unknown chat icon detected!") + println("name 1: '$rawName'") + println("name 2: '$name'") + name = rawName + } + + return Pair(sbaIcons, name) + } + + private fun handlePrivateMessage(originalMessage: String): Boolean { + val matcher = patternPrivateMessage.matcher(originalMessage) + if (!matcher.matches()) return false + val direction = matcher.group(2) + var rawName = matcher.group(3) + + val sbaData = fetchSBAIcons(rawName) + val sbaIcons = sbaData.first + rawName = sbaData.second + + val name = grabName(rawName) ?: return false + + val message = matcher.group(4) + val colon = if (SkyHanniMod.feature.chat.playerColonHider) "" else ":" + LorenzUtils.chat("§d$direction $name$sbaIcons§f$colon $message") + loggerPlayerChat.log("[Msg_$direction] $name: $message") + return true + } + + private fun grabChannel(name: String): PlayerMessageChannel { + return PlayerMessageChannel.values() + .find { it != PlayerMessageChannel.ALL && name.startsWith(it.originalPrefix) } + ?: PlayerMessageChannel.ALL + } + + private fun grabName(rawName: String, clean: Boolean = false): String? { + val nameSplit = rawName.removeColor().split(" ") + val last = nameSplit.last() + val cleanName = if (last.endsWith("]")) { + nameSplit[nameSplit.size - 2] + } else { + last + } + + val first = nameSplit[0] + if (first != cleanName) { + if (!first.contains("VIP") && !first.contains("MVP")) { + //TODO support yt + admin + return null + } + } + + if (clean) { + return cleanName + } + + val markedPlayer = MarkedPlayerManager.isMarkedPlayer(cleanName) && SkyHanniMod.feature.markedPlayers.highlightInChat + return if (SkyHanniMod.feature.chat.playerRankHider) { + if (markedPlayer) "§e$cleanName" else "§b$cleanName" + } else { + if (markedPlayer) { + if (rawName.contains(" ")) { + rawName[0] + " §e" + cleanName + } else { + "§e$cleanName" + } + } else { + rawName + } + } + } + + private fun callEvent( + channel: PlayerMessageChannel, + formattedName: String, + message: String, + level: Int, + levelColor: String, + elitePrefix: String, + sbaIcons: String, + ) { + val cleanName = grabName(formattedName, true)!! + loggerPlayerChat.log("[$channel] $cleanName: $message") + val event = PlayerSendChatEvent(channel, cleanName, message) + event.postAndCatch() + + if (event.cancelledReason != "") { + loggerPlayerChat.log("cancelled: " + event.cancelledReason) + return + } + + val channelPrefix = getChannelPrefix(channel) + val colon = if (SkyHanniMod.feature.chat.playerColonHider) "" else ":" + val levelFormat = getLevelFormat(formattedName + sbaIcons, level, levelColor) + + val nameText = ChatComponentText("$channelPrefix$elitePrefix$levelFormat§f$colon") + if (SkyHanniMod.feature.chat.neuProfileViewer) { + nameText.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/pv $cleanName") + nameText.chatStyle.chatHoverEvent = HoverEvent( + HoverEvent.Action.SHOW_TEXT, + ChatComponentText("§7Click to open the §cNEU Profile Viewer §7for $formattedName") + ) + } + + addChat(nameText, event.message) + } + + private fun addChat(text: ChatComponentText, message: String) { + val fullText = ChatComponentText("") + fullText.appendSibling(text) + for (word in message.split(" ")) { + fullText.appendSibling(ChatComponentText(" ")) + if (patternUrl.matcher(word).matches()) { + val oneWord = ChatComponentText(word) + oneWord.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.OPEN_URL, word) + fullText.appendSibling(oneWord) + } else { + fullText.appendSibling(ChatComponentText(word)) + } + } + + Minecraft.getMinecraft().thePlayer.addChatMessage(fullText) + } + + private fun getLevelFormat(name: String, level: Int, levelColor: String): String { + if (level == -1) return name + + return when (SkyHanniMod.feature.chat.skyblockLevelDesign) { + 0 -> "§8[§${levelColor}${level}§8] $name" + 1 -> "§${levelColor}§l${level} $name" + 2 -> "$name §8[§${levelColor}${level}§8]" + 3 -> name + else -> "§8[§${levelColor}${level}§8] $name" + } + } + + private fun getChannelPrefix(channel: PlayerMessageChannel): String { + if (channel == PlayerMessageChannel.ALL && !SkyHanniMod.feature.chat.allChannelPrefix) return "" + + val color = channel.prefixColor + val small = channel.prefixSmall + val large = channel.prefixLarge + return when (SkyHanniMod.feature.chat.channelDesign) { + 0 -> "$color$large §8> " + 1 -> "$color$small> " + 2 -> "§8<$color$small§8> " + 3 -> "§8[$color$small§8] " + 4 -> "§8($color$small§8) " + else -> "$color$large §8> " + } + } + + companion object { + + fun testAllChat() { + val name = Minecraft.getMinecraft().thePlayer.name + val message = + "§6[⌬499] §8[§b123§8] §6[MVP§c++§6] $name§f: This is a all chat test message and will not be sent to hypixel." + LorenzChatEvent(message, ChatComponentText(message)).postAndCatch() + } + + fun testGuildChat() { + val name = Minecraft.getMinecraft().thePlayer.name + val message = + "§2Guild > §6[MVP§f++§6] $name §2[GuildRank]§f: This is a guild chat test message and will not be sent to hypixel." + LorenzChatEvent(message, ChatComponentText(message)).postAndCatch() + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerMessageChannel.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerMessageChannel.kt new file mode 100644 index 000000000..b75f2c970 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerMessageChannel.kt @@ -0,0 +1,17 @@ +package at.hannibal2.skyhanni.features.chat.playerchat + +enum class PlayerMessageChannel( + val prefixColor: String, + val prefixSmall: String, + val prefixLarge: String, + val originalPrefix: String, +) { + + ALL("§f", "A", "All", ""), + ALL_GUESTING("§a", "g", "Guest", "§a[✌] "), + ALL_DUNGEON_DEAD("§7", "D", "Dead", "§7[GHOST] "), + PARTY("§9", "P", "Party", "§9Party §8> "), + GUILD("§2", "G", "Guild", "§2Guild > "), + COOP("§b", "CC", "Co-op", "§bCo-op > "), + +} \ No newline at end of file -- cgit