diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt index 643ef46ff..8b6330f6d 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt @@ -1,26 +1,67 @@ package at.hannibal2.skyhanni.data +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzActionBarEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.SeaCreatureFishEvent +import at.hannibal2.skyhanni.features.chat.ChatFilterGui import at.hannibal2.skyhanni.features.fishing.SeaCreatureManager +import at.hannibal2.skyhanni.utils.IdentityCharacteristics import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.makeAccessible +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.ChatLine +import net.minecraft.client.gui.GuiNewChat import net.minecraft.event.HoverEvent import net.minecraft.network.play.server.S02PacketChat +import net.minecraft.util.EnumChatFormatting import net.minecraft.util.IChatComponent import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.relauncher.ReflectionHelper +import java.lang.invoke.MethodHandles -class ChatManager { +object ChatManager { private val loggerAll = LorenzLogger("chat/all") private val loggerFiltered = LorenzLogger("chat/blocked") private val loggerAllowed = LorenzLogger("chat/allowed") private val loggerModified = LorenzLogger("chat/modified") private val loggerFilteredTypes = mutableMapOf<String, LorenzLogger>() + private val messageHistory = + object : LinkedHashMap<IdentityCharacteristics<IChatComponent>, MessageFilteringResult>() { + override fun removeEldestEntry(eldest: MutableMap.MutableEntry<IdentityCharacteristics<IChatComponent>, MessageFilteringResult>?): Boolean { + return size > 100 + } + } + + fun getRecentMessageHistory(): List<MessageFilteringResult> = messageHistory.toList().map { it.second } + + enum class ActionKind(format: Any) { + BLOCKED(EnumChatFormatting.RED.toString() + EnumChatFormatting.BOLD), + RETRACTED(EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.BOLD), + MODIFIED(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD), + ALLOWED(EnumChatFormatting.GREEN), + ; + + val renderedString = "$format$name" + + companion object { + val maxLength by lazy { + entries.maxOf { Minecraft.getMinecraft().fontRendererObj.getStringWidth(it.renderedString) } + } + } + } + + data class MessageFilteringResult( + val message: IChatComponent, + var actionKind: ActionKind, + var actionReason: String?, + val modified: IChatComponent? + ) @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) fun onActionBarPacket(event: PacketEvent.ReceiveEvent) { @@ -43,7 +84,7 @@ class ChatManager { val message = LorenzUtils.stripVanillaMessage(original.formattedText) if (message.startsWith("§f{\"server\":\"")) return - + val key = IdentityCharacteristics(original) val chatEvent = LorenzChatEvent(message, original) if (!isSoopyMessage(event.message)) { chatEvent.postAndCatch() @@ -56,6 +97,7 @@ class ChatManager { loggerAll.log("[$blockReason] $message") loggerFilteredTypes.getOrPut(blockReason) { LorenzLogger("chat/filter_blocked/$blockReason") } .log(message) + messageHistory.put(key, MessageFilteringResult(original, ActionKind.BLOCKED, blockReason, null)) return } @@ -67,6 +109,9 @@ class ChatManager { loggerModified.log(" ") loggerModified.log("[original] " + original.formattedText) loggerModified.log("[modified] " + modified.formattedText) + messageHistory.put(key, MessageFilteringResult(original, ActionKind.MODIFIED, null, modified)) + } else { + messageHistory.put(key, MessageFilteringResult(original, ActionKind.ALLOWED, null, null)) } } @@ -104,4 +149,28 @@ class ChatManager { val seaCreature = SeaCreatureManager.getSeaCreature(chatEvent.message) ?: return SeaCreatureFishEvent(seaCreature, chatEvent).postAndCatch() } + + fun openChatFilterGUI() { + SkyHanniMod.screenToOpen = ChatFilterGui(getRecentMessageHistory()) + } + + val chatLinesField by lazy { + MethodHandles.publicLookup().unreflectGetter( + ReflectionHelper.findField(GuiNewChat::class.java, "chatLines", "field_146252_h", "h") + .makeAccessible() + ) + } + + fun retractMessage(message: IChatComponent?, reason: String) { + if (message == null) return + val chatGUI = Minecraft.getMinecraft().ingameGUI.chatGUI + @Suppress("UNCHECKED_CAST") + val chatLines = chatLinesField.invokeExact(chatGUI) as MutableList<ChatLine> + if (!chatLines.removeIf { it.chatComponent === message }) return + chatGUI.refreshChat() + + val history = messageHistory[IdentityCharacteristics(message)] ?: return + history.actionKind = ActionKind.RETRACTED + history.actionReason = reason.uppercase() + } }
\ No newline at end of file |