diff options
author | nea <nea@nea.moe> | 2023-08-03 20:12:53 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-08-03 21:55:21 +0200 |
commit | 5198a5eca8257ee05e4846dc7ef46c983f7752d0 (patch) | |
tree | de470324a8737eccf4222ece4b795c40ca5fb5f6 | |
parent | 5dee3f298497dae472e80235091b659e4042fd49 (diff) | |
download | skyhanni-5198a5eca8257ee05e4846dc7ef46c983f7752d0.tar.gz skyhanni-5198a5eca8257ee05e4846dc7ef46c983f7752d0.tar.bz2 skyhanni-5198a5eca8257ee05e4846dc7ef46c983f7752d0.zip |
Add chat filter gui
4 files changed, 168 insertions, 2 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 14650eff9..7e314e16d 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -135,7 +135,7 @@ class SkyHanniMod { // utils loadModule(this) - loadModule(ChatManager()) + loadModule(ChatManager) loadModule(HypixelData()) loadModule(DungeonData()) loadModule(ScoreboardData()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index 66f291f26..4c73c6113 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -4,9 +4,11 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigGuiManager import at.hannibal2.skyhanni.config.commands.SimpleCommand.ProcessCommandRunnable import at.hannibal2.skyhanni.data.ApiDataLoader +import at.hannibal2.skyhanni.data.ChatManager import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper +import at.hannibal2.skyhanni.features.chat.ChatFilterGui import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper import at.hannibal2.skyhanni.features.event.diana.InquisitorWaypointShare import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -186,6 +188,7 @@ object Commands { private fun developersCodingHelp() { registerCommand("shtest", "Unused test command.") { SkyHanniTestCommand.testCommand(it) } registerCommand("shreloadlocalrepo", "Reloading the local repo data") { SkyHanniMod.repo.reloadLocalRepo() } + registerCommand("shchathistory", "Show the unfiltered chat history") { ChatManager.openChatFilterGUI() } registerCommand( "shstoplisteners", "Unregistering all loaded forge event listeners" diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt index 643ef46ff..399517d2a 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt @@ -1,26 +1,62 @@ 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.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft 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 java.util.LinkedHashMap -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<Object, MessageFilteringResult>() { + override fun removeEldestEntry(eldest: MutableMap.MutableEntry<Object, MessageFilteringResult>?): Boolean { + return size > 100 + } + } + + fun getRecentMessageHistory(): List<MessageFilteringResult> { + return messageHistory.toList().map { it.second } + } + + enum class ActionKind(format: Any) { + BLOCKED(EnumChatFormatting.RED.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, + val actionKind: ActionKind, + val actionReason: String?, + val modified: IChatComponent? + ) @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) fun onActionBarPacket(event: PacketEvent.ReceiveEvent) { @@ -56,6 +92,7 @@ class ChatManager { loggerAll.log("[$blockReason] $message") loggerFilteredTypes.getOrPut(blockReason) { LorenzLogger("chat/filter_blocked/$blockReason") } .log(message) + messageHistory.put(Object(), MessageFilteringResult(original, ActionKind.BLOCKED, blockReason, null)) return } @@ -67,6 +104,9 @@ class ChatManager { loggerModified.log(" ") loggerModified.log("[original] " + original.formattedText) loggerModified.log("[modified] " + modified.formattedText) + messageHistory.put(Object(), MessageFilteringResult(original, ActionKind.MODIFIED, null, modified)) + } else { + messageHistory.put(Object(), MessageFilteringResult(original, ActionKind.ALLOWED, null, null)) } } @@ -104,4 +144,8 @@ class ChatManager { val seaCreature = SeaCreatureManager.getSeaCreature(chatEvent.message) ?: return SeaCreatureFishEvent(seaCreature, chatEvent).postAndCatch() } + + fun openChatFilterGUI() { + SkyHanniMod.screenToOpen = (ChatFilterGui(getRecentMessageHistory())) + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt new file mode 100644 index 000000000..f9566cdf1 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt @@ -0,0 +1,119 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.data.ChatManager +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.OSUtils +import io.github.moulberry.moulconfig.internal.GlScissorStack +import io.github.moulberry.moulconfig.internal.RenderUtils +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiScreen +import net.minecraft.client.gui.GuiUtilRenderComponents +import net.minecraft.client.gui.ScaledResolution +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.util.IChatComponent +import org.lwjgl.input.Mouse + +class ChatFilterGui(private val history: List<ChatManager.MessageFilteringResult>) : GuiScreen() { + private var scroll = -1.0 + private val w = 500 + private var wasMouseButtonDown = false + private val h = 300 + private val reasonMaxLength = + history.maxOf { it.actionReason?.let { Minecraft.getMinecraft().fontRendererObj.getStringWidth(it) } ?: 0 } + private val historySize by lazy { + history.sumOf { splitLine(it.message).size * 10 + if (it.modified != null) splitLine(it.modified).size * 10 else 0 } + } + + override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { + super.drawScreen(mouseX, mouseY, partialTicks) + drawDefaultBackground() + GlStateManager.pushMatrix() + val l = (width / 2.0 - w / 2.0).toInt() + val t = (height / 2.0 - h / 2.0).toInt() + val sr = ScaledResolution(mc) + GlStateManager.translate(l + 0.0, t + 0.0, 0.0) + RenderUtils.drawFloatingRectDark(0, 0, w, h) + GlStateManager.translate(5.0, 5.0 - scroll, 0.0) + var mouseX = mouseX - (l) + val isMouseButtonDown = if (mouseX in 0..w && mouseY in t..(t + h)) + Mouse.isButtonDown(0) + else false + var mouseY = mouseY - (t - scroll).toInt() + GlStateManager.color(1f, 1f, 1f, 1f) + GlScissorStack.push(l + 5, t + 5, w + l - 5, h + t - 5, sr) + + for (msg in history) { + drawString(mc.fontRendererObj, msg.actionKind.renderedString, 0, 0, -1) + GlStateManager.color(1f, 1f, 1f, 1f) + drawString(mc.fontRendererObj, msg.actionReason, ChatManager.ActionKind.maxLength + 5, 0, -1) + GlStateManager.color(1f, 1f, 1f, 1f) + var size = drawMultiLineText( + msg.message, + ChatManager.ActionKind.maxLength + reasonMaxLength + 10, + ) + if (msg.modified != null) { + drawString( + mc.fontRendererObj, + "§e§lNEW TEXT", + 0, 0, -1 + ) + size += drawMultiLineText( + msg.modified, + ChatManager.ActionKind.maxLength + reasonMaxLength + 10, + ) + } + if (mouseX in 0..w && mouseY in 0..(size * 10) && (isMouseButtonDown && !wasMouseButtonDown)) { + OSUtils.copyToClipboard(msg.message.formattedText) + LorenzUtils.chat("Copied to clipboard") + } + mouseY -= size * 10 + } + GlScissorStack.pop(sr) + wasMouseButtonDown = isMouseButtonDown + GlStateManager.popMatrix() + } + + fun splitLine(comp: IChatComponent): MutableList<IChatComponent> { + return GuiUtilRenderComponents.splitText( + comp, + w - (ChatManager.ActionKind.maxLength + reasonMaxLength + 10 + 10), + mc.fontRendererObj, + false, + true + ) + } + + override fun initGui() { + super.initGui() + if (this.scroll < 0) { + setScroll(1000000000.0) + } + } + + fun setScroll(newScroll: Double) { + this.scroll = newScroll.coerceAtMost(historySize - h + 10.0).coerceAtLeast(0.0) + } + + fun drawMultiLineText(comp: IChatComponent, xPos: Int): Int { + val modifiedSplitText = splitLine(comp) + for (line in modifiedSplitText) { + drawString( + mc.fontRendererObj, + line.formattedText, + xPos, + 0, + -1 + ) + GlStateManager.color(1f, 1f, 1f, 1f) + GlStateManager.translate(0F, 10F, 0F) + } + return modifiedSplitText.size + } + + + override fun handleMouseInput() { + super.handleMouseInput() + setScroll(scroll - Mouse.getEventDWheel()) + } + +}
\ No newline at end of file |