From 8b373f577d9c6dde26357ef3fc86691f1efef9b4 Mon Sep 17 00:00:00 2001 From: Wyvest Date: Wed, 22 Nov 2023 08:18:19 +0900 Subject: update PGT and relocate to org.polyfrost --- src/main/kotlin/cc/woverflow/chatting/Chatting.kt | 272 ---------------- .../cc/woverflow/chatting/chat/ChatRegexes.kt | 11 - .../woverflow/chatting/chat/ChatScrollingHook.kt | 5 - .../chatting/chat/ChatSearchingManager.kt | 42 --- .../cc/woverflow/chatting/chat/ChatShortcuts.kt | 79 ----- .../cc/woverflow/chatting/chat/ChatSpamBlock.kt | 124 -------- .../kotlin/cc/woverflow/chatting/chat/ChatTab.kt | 112 ------- .../kotlin/cc/woverflow/chatting/chat/ChatTabs.kt | 354 --------------------- .../cc/woverflow/chatting/chat/ChatTabsJson.kt | 15 - .../woverflow/chatting/command/ChattingCommand.kt | 14 - .../cc/woverflow/chatting/config/ChattingConfig.kt | 313 ------------------ .../chatting/gui/components/CleanButton.kt | 103 ------ .../chatting/gui/components/ClearButton.kt | 42 --- .../chatting/gui/components/RenderType.kt | 7 - .../chatting/gui/components/ScreenshotButton.kt | 36 --- .../chatting/gui/components/SearchButton.kt | 70 ---- .../woverflow/chatting/gui/components/TabButton.kt | 46 --- .../cc/woverflow/chatting/utils/EaseOutQuart.kt | 7 - .../cc/woverflow/chatting/utils/ModCompatHooks.kt | 100 ------ .../cc/woverflow/chatting/utils/RenderUtils.kt | 259 --------------- src/main/kotlin/org/polyfrost/chatting/Chatting.kt | 272 ++++++++++++++++ .../org/polyfrost/chatting/chat/ChatRegexes.kt | 11 + .../polyfrost/chatting/chat/ChatScrollingHook.kt | 5 + .../chatting/chat/ChatSearchingManager.kt | 42 +++ .../org/polyfrost/chatting/chat/ChatShortcuts.kt | 79 +++++ .../org/polyfrost/chatting/chat/ChatSpamBlock.kt | 124 ++++++++ .../kotlin/org/polyfrost/chatting/chat/ChatTab.kt | 112 +++++++ .../kotlin/org/polyfrost/chatting/chat/ChatTabs.kt | 354 +++++++++++++++++++++ .../org/polyfrost/chatting/chat/ChatTabsJson.kt | 15 + .../polyfrost/chatting/command/ChattingCommand.kt | 14 + .../polyfrost/chatting/config/ChattingConfig.kt | 313 ++++++++++++++++++ .../chatting/gui/components/CleanButton.kt | 103 ++++++ .../chatting/gui/components/ClearButton.kt | 42 +++ .../chatting/gui/components/RenderType.kt | 7 + .../chatting/gui/components/ScreenshotButton.kt | 36 +++ .../chatting/gui/components/SearchButton.kt | 70 ++++ .../polyfrost/chatting/gui/components/TabButton.kt | 46 +++ .../org/polyfrost/chatting/utils/EaseOutQuart.kt | 7 + .../org/polyfrost/chatting/utils/ModCompatHooks.kt | 100 ++++++ .../org/polyfrost/chatting/utils/RenderUtils.kt | 259 +++++++++++++++ 40 files changed, 2011 insertions(+), 2011 deletions(-) delete mode 100644 src/main/kotlin/cc/woverflow/chatting/Chatting.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatRegexes.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatScrollingHook.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatSearchingManager.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatShortcuts.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatSpamBlock.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatTab.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatTabs.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/chat/ChatTabsJson.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/command/ChattingCommand.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/CleanButton.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/ClearButton.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/RenderType.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/ScreenshotButton.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/SearchButton.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/gui/components/TabButton.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/utils/EaseOutQuart.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/utils/ModCompatHooks.kt delete mode 100644 src/main/kotlin/cc/woverflow/chatting/utils/RenderUtils.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/Chatting.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatRegexes.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatScrollingHook.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatSearchingManager.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatShortcuts.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatSpamBlock.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatTab.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatTabs.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/chat/ChatTabsJson.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/command/ChattingCommand.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/config/ChattingConfig.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/CleanButton.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/ClearButton.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/RenderType.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/ScreenshotButton.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/SearchButton.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/gui/components/TabButton.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/utils/EaseOutQuart.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/utils/ModCompatHooks.kt create mode 100644 src/main/kotlin/org/polyfrost/chatting/utils/RenderUtils.kt (limited to 'src/main/kotlin') diff --git a/src/main/kotlin/cc/woverflow/chatting/Chatting.kt b/src/main/kotlin/cc/woverflow/chatting/Chatting.kt deleted file mode 100644 index 9452dcf..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/Chatting.kt +++ /dev/null @@ -1,272 +0,0 @@ -package cc.woverflow.chatting - -import cc.polyfrost.oneconfig.libs.universal.UDesktop -import cc.polyfrost.oneconfig.libs.universal.UMinecraft -import cc.polyfrost.oneconfig.libs.universal.UResolution -import cc.polyfrost.oneconfig.utils.Notifications -import cc.polyfrost.oneconfig.utils.commands.CommandManager -import cc.polyfrost.oneconfig.utils.dsl.browseLink -import cc.woverflow.chatting.chat.ChatSearchingManager -import cc.woverflow.chatting.chat.ChatShortcuts -import cc.woverflow.chatting.chat.ChatSpamBlock -import cc.woverflow.chatting.chat.ChatTabs -import cc.woverflow.chatting.command.ChattingCommand -import cc.woverflow.chatting.config.ChattingConfig -import cc.woverflow.chatting.hook.ChatLineHook -import cc.woverflow.chatting.mixin.GuiNewChatAccessor -import cc.woverflow.chatting.utils.ModCompatHooks -import cc.woverflow.chatting.utils.copyToClipboard -import cc.woverflow.chatting.utils.createBindFramebuffer -import cc.woverflow.chatting.utils.screenshot -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.* -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper -import net.minecraft.client.settings.KeyBinding -import net.minecraft.client.shader.Framebuffer -import net.minecraft.util.MathHelper -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.common.MinecraftForge.EVENT_BUS -import net.minecraftforge.fml.client.registry.ClientRegistry -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.Mod -import net.minecraftforge.fml.common.event.FMLInitializationEvent -import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import org.lwjgl.input.Keyboard -import java.awt.image.BufferedImage -import java.io.File -import java.text.SimpleDateFormat -import java.util.* - - -@Mod( - modid = Chatting.ID, - name = Chatting.NAME, - version = Chatting.VER, - modLanguageAdapter = "cc.polyfrost.oneconfig.utils.KotlinLanguageAdapter" -) -object Chatting { - - val keybind = KeyBinding("Screenshot Chat", Keyboard.KEY_NONE, "Chatting") - const val NAME = "@NAME@" - const val VER = "@VER@" - const val ID = "@ID@" - var doTheThing = false - var isPatcher = false - private set - var isBetterChat = false - private set - var isSkytils = false - private set - var isHychat = false - private set - - private var time = -1L - var deltaTime = 17L - - private val fileFormatter: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd_HH.mm.ss'.png'") - - val oldModDir = File(File(Minecraft.getMinecraft().mcDataDir, "W-OVERFLOW"), NAME) - - @Mod.EventHandler - fun onInitialization(event: FMLInitializationEvent) { - ChattingConfig - CommandManager.INSTANCE.registerCommand(ChattingCommand()) - ClientRegistry.registerKeyBinding(keybind) - EVENT_BUS.register(this) - EVENT_BUS.register(ChatSpamBlock) - ChatTabs.initialize() - ChatShortcuts.initialize() - } - - @Mod.EventHandler - fun onPostInitialization(event: FMLPostInitializationEvent) { - isPatcher = Loader.isModLoaded("patcher") - isBetterChat = Loader.isModLoaded("betterchat") - isSkytils = Loader.isModLoaded("skytils") - isHychat = Loader.isModLoaded("hychat") - } - - @Mod.EventHandler - fun onForgeLoad(event: FMLLoadCompleteEvent) { - if (ChattingConfig.informForAlternatives) { - if (isHychat) { - Notifications.INSTANCE.send( - NAME, - "Hychat can be removed as it is replaced by Chatting. Click here for more information.", - Runnable { - UDesktop.browseLink("https://microcontrollersdev.github.io/Alternatives/1.8.9/hychat") - }) - } - if (isSkytils) { - try { - skytilsCompat(Class.forName("gg.skytils.skytilsmod.core.Config")) - } catch (e: Exception) { - e.printStackTrace() - try { - skytilsCompat(Class.forName("skytils.skytilsmod.core.Config")) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - if (isBetterChat) { - Notifications.INSTANCE.send( - NAME, - "BetterChat can be removed as it is replaced by Chatting. Click here to open your mods folder to delete the BetterChat file.", - Runnable { - UDesktop.open(File("./mods")) - }) - } - } - } - - private fun skytilsCompat(skytilsClass: Class<*>) { - val instance = skytilsClass.getDeclaredField("INSTANCE") - val chatTabs = skytilsClass.getDeclaredField("chatTabs") - chatTabs.isAccessible = true - if (chatTabs.getBoolean(instance)) { - Notifications.INSTANCE.send( - NAME, - "Skytils' chat tabs can be disabled as it is replace by Chatting.\nClick here to automatically do this.", - Runnable { - chatTabs.setBoolean(instance, false) - ChattingConfig.chatTabs = true - ChattingConfig.hypixelOnlyChatTabs = true - ChattingConfig.save() - skytilsClass.getMethod("markDirty").invoke(instance) - skytilsClass.getMethod("writeData").invoke(instance) - }) - } - val copyChat = skytilsClass.getDeclaredField("copyChat") - copyChat.isAccessible = true - if (copyChat.getBoolean(instance)) { - Notifications.INSTANCE.send( - NAME, - "Skytils' copy chat messages can be disabled as it is replace by Chatting.\nClick here to automatically do this.", - Runnable { - copyChat.setBoolean(instance, false) - skytilsClass.getMethod("markDirty").invoke(instance) - skytilsClass.getMethod("writeData").invoke(instance) - }) - } - } - - @SubscribeEvent - fun onRenderTick(event: RenderGameOverlayEvent.Pre) { - if (event.type == RenderGameOverlayEvent.ElementType.ALL) { - if (time == -1L) { - time = UMinecraft.getTime() - } else { - val currentTime = UMinecraft.getTime() - deltaTime = currentTime - time - time = currentTime - } - } - } - - @SubscribeEvent - fun onTickEvent(event: TickEvent.ClientTickEvent) { - if (event.phase == TickEvent.Phase.START && Minecraft.getMinecraft().theWorld != null && Minecraft.getMinecraft().thePlayer != null && (Minecraft.getMinecraft().currentScreen == null || Minecraft.getMinecraft().currentScreen is GuiChat)) { - if (doTheThing) { - screenshotChat() - doTheThing = false - } - } - } - - fun getChatHeight(opened: Boolean): Int { - var height = if (opened) ChattingConfig.focusedHeight else ChattingConfig.unfocusedHeight - height = (height * Minecraft.getMinecraft().gameSettings.chatScale).toInt() - val chatY = ModCompatHooks.yOffset + ModCompatHooks.chatPosition - if (height + chatY + 27 > (UResolution.scaledHeight / Minecraft.getMinecraft().gameSettings.chatScale).toInt() - 27 - chatY) { - height = (UResolution.scaledHeight / Minecraft.getMinecraft().gameSettings.chatScale).toInt() - 27 - chatY - } - return height - } - - fun screenshotLine(line: ChatLine): BufferedImage? { - val hud = Minecraft.getMinecraft().ingameGUI - val chat = hud.chatGUI - val i = MathHelper.floor_float(chat.chatWidth / chat.chatScale) - return screenshot( - hashMapOf().also { - GuiUtilRenderComponents.splitText( - line.chatComponent, - i, - Minecraft.getMinecraft().fontRendererObj, - false, - false - ).map { it.formattedText }.reversed().forEach { string -> - it[line] = string - } - } - ) - } - - private fun screenshotChat() { - screenshotChat(0) - } - - fun screenshotChat(scrollPos: Int) { - val hud = Minecraft.getMinecraft().ingameGUI - val chat = hud.chatGUI - val chatLines = LinkedHashMap() - ChatSearchingManager.filterMessages( - ChatSearchingManager.lastSearch, - (chat as GuiNewChatAccessor).drawnChatLines - )?.let { drawnLines -> - val chatHeight = - if (ChattingConfig.customChatHeight) getChatHeight(true) / 9 else GuiNewChat.calculateChatboxHeight( - Minecraft.getMinecraft().gameSettings.chatHeightFocused / 9 - ) - for (i in scrollPos until drawnLines.size.coerceAtMost(scrollPos + chatHeight)) { - chatLines[drawnLines[i]] = drawnLines[i].chatComponent.formattedText - } - - screenshot(chatLines)?.copyToClipboard() - } - } - - private fun screenshot(messages: HashMap): BufferedImage? { - if (messages.isEmpty()) { - Notifications.INSTANCE.send("Chatting", "Chat window is empty.") - return null - } - if (!OpenGlHelper.isFramebufferEnabled()) { - Notifications.INSTANCE.send( - "Chatting", - "Screenshot failed, please disable “Fast Render” in OptiFine’s “Performance” tab." - ) - return null - } - - val fr: FontRenderer = ModCompatHooks.fontRenderer - val width = messages.maxOf { fr.getStringWidth(it.value) + (if (ChattingConfig.showChatHeads && ((it.key as ChatLineHook).hasDetected() || ChattingConfig.offsetNonPlayerMessages)) 10 else 0) } + 4 - val fb: Framebuffer = createBindFramebuffer(width * 2, (messages.size * 9) * 2) - val file = File(Minecraft.getMinecraft().mcDataDir, "screenshots/chat/" + fileFormatter.format(Date())) - - GlStateManager.scale(2f, 2f, 1f) - val scale = Minecraft.getMinecraft().gameSettings.chatScale - GlStateManager.scale(scale, scale, 1f) - messages.entries.forEachIndexed { i: Int, entry: MutableMap.MutableEntry -> - ModCompatHooks.redirectDrawString(entry.value, 0f, (messages.size - 1 - i) * 9f, 0xffffff, entry.key, true) - } - - val image = fb.screenshot(file) - Minecraft.getMinecraft().entityRenderer.setupOverlayRendering() - Minecraft.getMinecraft().framebuffer.bindFramebuffer(true) - Notifications.INSTANCE.send( - "Chatting", - "Chat screenshotted successfully." + (if (ChattingConfig.copyMode != 1) "\nClick to open." else ""), - Runnable { - if (!UDesktop.open(file)) { - Notifications.INSTANCE.send("Chatting", "Could not browse!") - } - }) - return image - } -} diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatRegexes.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatRegexes.kt deleted file mode 100644 index a0a8e86..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatRegexes.kt +++ /dev/null @@ -1,11 +0,0 @@ -package cc.woverflow.chatting.chat - -data class ChatRegexes(val regexList: List?) { - val compiledRegexList: MutableList = arrayListOf() - - init { - regexList?.forEach { - compiledRegexList.add(Regex(it)) - } - } -} diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatScrollingHook.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatScrollingHook.kt deleted file mode 100644 index b81de94..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatScrollingHook.kt +++ /dev/null @@ -1,5 +0,0 @@ -package cc.woverflow.chatting.chat - -object ChatScrollingHook { - var shouldSmooth = false -} \ No newline at end of file diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatSearchingManager.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatSearchingManager.kt deleted file mode 100644 index 33a2642..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatSearchingManager.kt +++ /dev/null @@ -1,42 +0,0 @@ -package cc.woverflow.chatting.chat - -import cc.polyfrost.oneconfig.libs.caffeine.cache.Cache -import cc.polyfrost.oneconfig.libs.caffeine.cache.Caffeine -import cc.polyfrost.oneconfig.libs.universal.wrappers.message.UTextComponent -import net.minecraft.client.gui.ChatLine -import java.util.concurrent.LinkedBlockingQueue -import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger - -object ChatSearchingManager { - private var counter: AtomicInteger = AtomicInteger(0) - private var POOL: ThreadPoolExecutor = ThreadPoolExecutor( - 50, 50, - 0L, TimeUnit.SECONDS, - LinkedBlockingQueue() - ) { r -> - Thread( - r, - "Chat Filter Cache Thread ${counter.incrementAndGet()}" - ) - } - - @JvmStatic - val cache: Cache> = Caffeine.newBuilder().executor(POOL).maximumSize(5000).build() - - var lastSearch = "" - - @JvmStatic - fun filterMessages(text: String, list: List): List? { - if (text.isBlank()) return list - val cached = cache.getIfPresent(text) - return cached ?: run { - cache.put(text, list.filter { - UTextComponent.stripFormatting(it.chatComponent.unformattedText).lowercase() - .contains(text.lowercase()) - }) - cache.getIfPresent(text) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatShortcuts.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatShortcuts.kt deleted file mode 100644 index ef1881d..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatShortcuts.kt +++ /dev/null @@ -1,79 +0,0 @@ -package cc.woverflow.chatting.chat - -import cc.polyfrost.oneconfig.config.core.ConfigUtils -import cc.woverflow.chatting.Chatting -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import java.io.File - -object ChatShortcuts { - private val oldShortcutsFile = File(Chatting.oldModDir, "chatshortcuts.json") - private val shortcutsFile = ConfigUtils.getProfileFile("chatshortcuts.json") - private val PARSER = JsonParser() - - private var initialized = false - - val shortcuts = object : ArrayList>() { - private val comparator = Comparator> { o1, o2 -> - return@Comparator o2.first.length.compareTo(o1.first.length) - } - - override fun add(element: Pair): Boolean { - val value = super.add(element) - sortWith(comparator) - return value - } - } - - fun initialize() { - if (initialized) { - return - } else { - initialized = true - } - if (shortcutsFile.exists()) { - try { - val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject - for (shortcut in jsonObj.entrySet()) { - shortcuts.add(shortcut.key to shortcut.value.asString) - } - return - } catch (_: Throwable) { - shortcutsFile.renameTo(File(shortcutsFile.parentFile, "chatshortcuts.json.bak")) - } - } - shortcutsFile.createNewFile() - if (oldShortcutsFile.exists()) { - shortcutsFile.writeText( - oldShortcutsFile.readText() - ) - } else { - shortcutsFile.writeText(JsonObject().toString()) - } - } - - fun removeShortcut(key: String) { - shortcuts.removeIf { it.first == key } - val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject - jsonObj.remove(key) - shortcutsFile.writeText(jsonObj.toString()) - } - - fun writeShortcut(key: String, value: String) { - shortcuts.add(key to value) - val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject - jsonObj.addProperty(key, value) - shortcutsFile.writeText(jsonObj.toString()) - } - - fun handleSentCommand(command: String): String { - shortcuts.forEach { - if (command == it.first || (command.startsWith(it.first) && command.substringAfter(it.first) - .startsWith(" ")) - ) { - return command.replaceFirst(it.first, it.second) - } - } - return command - } -} \ No newline at end of file diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatSpamBlock.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatSpamBlock.kt deleted file mode 100644 index 471eec8..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatSpamBlock.kt +++ /dev/null @@ -1,124 +0,0 @@ -package cc.woverflow.chatting.chat - -import cc.woverflow.chatting.config.ChattingConfig -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import java.text.Normalizer -import net.minecraft.util.ChatComponentText -import net.minecraft.util.EnumChatFormatting -import net.minecraftforge.client.event.ClientChatReceivedEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -object ChatSpamBlock { - /* - Made by @KTibow - Based off of Unspam (also by @KTibow) - Algorithm based off of https://paulgraham.com/spam.html - */ - private val PLAYER_MESSAGE = Regex("^(\\[VIP\\+?\\] |\\[MVP\\+?\\+?\\] |)(\\w{2,16}): (.*)$") - - @SubscribeEvent - fun onChat(event: ClientChatReceivedEvent) { - val message = event.message.unformattedText.replace(Regex("\u00A7."), "") - if (!PLAYER_MESSAGE.matches(message)) return - - val (rank, player, content) = PLAYER_MESSAGE.matchEntire(message)!!.destructured - - if (ChattingConfig.spamThreshold != 100) { - val tokens = tokenize(content) - val spamProb = findSpamProbability(tokens) - if (spamProb * 100 > ChattingConfig.spamThreshold) { - if (ChattingConfig.hideSpam) { - event.isCanceled = true - } else { - var newMessage = - EnumChatFormatting.DARK_GRAY.toString() + - EnumChatFormatting.STRIKETHROUGH.toString() - if (!ChattingConfig.customChatFormatting) { - newMessage += rank - } - newMessage += "$player${EnumChatFormatting.DARK_GRAY}: $content" - event.message = ChatComponentText(newMessage) - } - return - } - } - if (ChattingConfig.customChatFormatting) { - val coloredPlayer = findRankColor(rank) + player + EnumChatFormatting.RESET.toString() - event.message = ChatComponentText("$coloredPlayer: $content") - } - } - - private fun tokenize(message: String): MutableList { - val strippedMessage = - Normalizer.normalize(message, Normalizer.Form.NFKC) - .replace(Regex("[^\\w\\s/]"), " ") - .lowercase() - .trim() - val tokens = strippedMessage.split(Regex("\\s+")).toMutableList() - if (tokens.size <= 2) { - tokens.add("TINY_LENGTH") - } else if (tokens.size <= 4) { - tokens.add("SMALL_LENGTH") - } else if (tokens.size <= 7) { - tokens.add("MEDIUM_LENGTH") - } else { - tokens.add("LONG_LENGTH") - } - if (message.replace(Regex("[\\w\\s]"), "").length > 2) { - tokens.add("SPECIAL_CHARS") - } else if (message.replace(Regex("[\\w\\s]"), "").isNotEmpty()) { - tokens.add("SPECIAL_CHAR") - } else { - tokens.add("LOW_SPECIAL_CHARS") - } - if (message.replace(Regex("[^A-Z]"), "").length >= message.length / 4) { - tokens.add("HIGH_CAPS") - } else { - tokens.add("LOW_CAPS") - } - return tokens - } - - private fun findSpamProbability(tokens: MutableList): Double { - val tokenProbs = mutableMapOf() - for (token in tokens) { - if (!spamInfoJson.has(token)) continue - val spamInToken = spamInfoJson.get(token).asJsonObject.get("spam").asDouble - val fineInToken = spamInfoJson.get(token).asJsonObject.get("fine").asDouble - tokenProbs[token] = - ((spamInToken / messageCountsJson.get("spam").asInt) / - (fineInToken / messageCountsJson.get("fine").asInt + - spamInToken / messageCountsJson.get("spam").asInt)) - } - val spamProbs = tokenProbs.values.toMutableList() - val fineProbs = tokenProbs.values.map { 1 - it }.toMutableList() - val spamProbability = spamProbs.reduce { a, b -> a * b } - val fineProbability = fineProbs.reduce { a, b -> a * b } - return spamProbability / (spamProbability + fineProbability) - } - - private fun findRankColor(rank: String): String { - println(rank) - return when (rank) { - "[VIP] ", - "[VIP+] " -> EnumChatFormatting.GREEN.toString() - "[MVP] ", - "[MVP+] " -> EnumChatFormatting.AQUA.toString() - "[MVP++] " -> EnumChatFormatting.GOLD.toString() - else -> EnumChatFormatting.GRAY.toString() - } - } - - private fun getResourceAsText(path: String): String? = - object {}.javaClass.getResource(path)?.readText() - private val spamInfoJson: JsonObject - private val messageCountsJson: JsonObject - - init { - // Load the file spamInfo.json from resources/ - val spamInfo = getResourceAsText("/spamInfo.json") - spamInfoJson = JsonParser().parse(spamInfo).asJsonObject - messageCountsJson = JsonParser().parse(" { \"fine\": 668, \"spam\": 230 }").asJsonObject - } -} diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTab.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatTab.kt deleted file mode 100644 index 50de1f4..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTab.kt +++ /dev/null @@ -1,112 +0,0 @@ -package cc.woverflow.chatting.chat - -import cc.woverflow.chatting.gui.components.TabButton -import com.google.gson.annotations.SerializedName -import net.minecraft.client.Minecraft -import net.minecraft.util.EnumChatFormatting -import net.minecraft.util.IChatComponent -import java.util.* - -data class ChatTab( - val enabled: Boolean, - val name: String, - val unformatted: Boolean, - val lowercase: Boolean?, - @SerializedName("starts") val startsWith: List?, - val contains: List?, - @SerializedName("ends") val endsWith: List?, - val equals: List?, - @SerializedName("regex") val uncompiledRegex: List?, - @SerializedName("ignore_starts") val ignoreStartsWith: List?, - @SerializedName("ignore_contains") val ignoreContains: List?, - @SerializedName("ignore_ends") val ignoreEndsWith: List?, - @SerializedName("ignore_equals") val ignoreEquals: List?, - @SerializedName("ignore_regex") val uncompiledIgnoreRegex: List?, - val color: Int?, - @SerializedName("hovered_color") val hoveredColor: Int?, - @SerializedName("selected_color") val selectedColor: Int?, - val prefix: String?, -) { - lateinit var button: TabButton - lateinit var compiledRegex: ChatRegexes - lateinit var compiledIgnoreRegex: ChatRegexes - - //Ugly hack to make GSON not make button / regex null - fun initialize() { - compiledRegex = ChatRegexes(uncompiledRegex) - compiledIgnoreRegex = ChatRegexes(uncompiledIgnoreRegex) - val width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(name) - button = TabButton(653452, run { - val returnValue = x - 2 - x += 6 + width - return@run returnValue - }, width + 4, 12, this) - } - - fun shouldRender(chatComponent: IChatComponent): Boolean { - val message = - (if (unformatted) EnumChatFormatting.getTextWithoutFormattingCodes(chatComponent.unformattedText) else chatComponent.formattedText).let { - if (lowercase == true) it.lowercase( - Locale.ENGLISH - ) else it - } - ignoreStartsWith?.forEach { - if (message.startsWith(it)) { - return false - } - } - ignoreEquals?.forEach { - if (message == it) { - return false - } - } - ignoreEndsWith?.forEach { - if (message.endsWith(it)) { - return false - } - } - ignoreContains?.forEach { - if (message.contains(it)) { - return false - } - } - compiledIgnoreRegex.compiledRegexList.forEach { - if (it.matches(message)) { - return false - } - } - if (startsWith.isNullOrEmpty() && equals.isNullOrEmpty() && endsWith.isNullOrEmpty() && contains.isNullOrEmpty() && uncompiledRegex.isNullOrEmpty()) { - return true - } - equals?.forEach { - if (message == it) { - return true - } - } - startsWith?.forEach { - if (message.startsWith(it)) { - return true - } - } - endsWith?.forEach { - if (message.endsWith(it)) { - return true - } - } - contains?.forEach { - if (message.contains(it)) { - return true - } - } - compiledRegex.compiledRegexList.forEach { - if (it.matches(message)) { - return true - } - } - return false - } - - companion object { - private var x = 4 - } -} diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabs.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabs.kt deleted file mode 100644 index 08423e5..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabs.kt +++ /dev/null @@ -1,354 +0,0 @@ -package cc.woverflow.chatting.chat - -import cc.polyfrost.oneconfig.config.core.ConfigUtils -import cc.woverflow.chatting.Chatting -import cc.woverflow.chatting.gui.components.TabButton -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import com.google.gson.JsonPrimitive -import net.minecraft.client.Minecraft -import net.minecraft.util.IChatComponent -import java.io.File - -object ChatTabs { - private val GSON = GsonBuilder().setPrettyPrinting().create() - private val PARSER = JsonParser() - val tabs = arrayListOf() - var currentTabs: ArrayList = object : ArrayList() { - override fun add(element: ChatTab?): Boolean { - if (element == null) return false - val returnValue = super.add(element) - if (Minecraft.getMinecraft().theWorld != null && returnValue) { - Minecraft.getMinecraft().ingameGUI.chatGUI.refreshChat() - } - return returnValue - } - } - var hasCancelledAnimation = false - private var initialized = false - - private val tabFile = ConfigUtils.getProfileFile("chattabs.json") - private val oldTabFile = File(Chatting.oldModDir, "chattabs.json") - - fun initialize() { - if (initialized) { - return - } else { - initialized = true - } - if (!tabFile.exists()) { - if (oldTabFile.exists()) { - tabFile.writeText(oldTabFile.readText()) - handleFile() - } else { - generateNewFile() - } - } else { - handleFile() - } - tabs.forEach { - it.initialize() - } - currentTabs.clear() - currentTabs.add(tabs[0]) - } - - private fun handleFile() { - try { - val chatTabJson = GSON.fromJson(tabFile.readText(), ChatTabsJson::class.java) - when (chatTabJson.version) { - 1 -> { - // ver 2 adds `enabled` - chatTabJson.tabs.forEach { - applyVersion2Changes(it.asJsonObject) - applyVersion3Changes(it.asJsonObject) - applyVersion4Changes(it.asJsonObject) - applyVersion5Changes(it.asJsonObject) - applyVersion6Changes(it.asJsonObject) - } - chatTabJson.version = ChatTabsJson.VERSION - tabFile.writeText(GSON.toJson(chatTabJson)) - } - 2 -> { - // ver 3 adds ignore_ - chatTabJson.tabs.forEach { - applyVersion3Changes(it.asJsonObject) - applyVersion4Changes(it.asJsonObject) - applyVersion5Changes(it.asJsonObject) - applyVersion6Changes(it.asJsonObject) - } - chatTabJson.version = ChatTabsJson.VERSION - tabFile.writeText(GSON.toJson(chatTabJson)) - } - 3 -> { - // ver 4 adds color options - chatTabJson.tabs.forEach { - applyVersion4Changes(it.asJsonObject) - applyVersion5Changes(it.asJsonObject) - applyVersion6Changes(it.asJsonObject) - } - chatTabJson.version = ChatTabsJson.VERSION - tabFile.writeText(GSON.toJson(chatTabJson)) - } - 4 -> { - // ver 5 adds lowercase - chatTabJson.tabs.forEach { - applyVersion5Changes(it.asJsonObject) - applyVersion6Changes(it.asJsonObject) - } - chatTabJson.version = ChatTabsJson.VERSION - tabFile.writeText(GSON.toJson(chatTabJson)) - } - 5 -> { - // ver 6 changes pm regex - chatTabJson.tabs.forEach { - applyVersion6Changes(it.asJsonObject) - } - chatTabJson.version = ChatTabsJson.VERSION - tabFile.writeText(GSON.toJson(chatTabJson)) - } - } - chatTabJson.tabs.forEach { - val chatTab = GSON.fromJson(it.toString(), ChatTab::class.java) - if (chatTab.enabled) { - tabs.add(chatTab) - } - } - } catch (e: Throwable) { - e.printStackTrace() - tabFile.delete() - generateNewFile() - } - } - - private fun applyVersion2Changes(json: JsonObject) { - json.addProperty("enabled", true) - } - - private fun applyVersion3Changes(json: JsonObject) { - json.add("ignore_starts", JsonArray()) - json.add("ignore_contains", JsonArray()) - json.add("ignore_ends", JsonArray()) - json.add("ignore_equals", JsonArray()) - json.add("ignore_regex", JsonArray()) - } - - private fun applyVersion4Changes(json: JsonObject) { - json.addProperty("color", TabButton.color) - json.addProperty("hovered_color", TabButton.hoveredColor) - json.addProperty("selected_color", TabButton.selectedColor) - } - - private fun applyVersion5Changes(json: JsonObject) { - json.addProperty("lowercase", false) - } - - private fun applyVersion6Changes(json: JsonObject) { - if (json.has("starts")) { - val starts = json["starts"].asJsonArray - var detected = false - starts.iterator().let { - while (it.hasNext()) { - when (it.next().asString) { - "To " -> { - detected = true - it.remove() - } - "From " -> { - detected = true - it.remove() - } - } - } - } - if (detected) { - json.add("regex", JsonArray().apply { - add(JsonPrimitive("^(?§dTo|§dFrom) (?.+): §r(?.*)(?:§r)?\$")) - }) - json.remove("unformatted") - json.addProperty("unformatted", false) - } - } - if (json.has("ends")) { - val ends = json["ends"].asJsonArray - var detected = false - ends.iterator().let { - while (it.hasNext()) { - when (it.next().asString) { - "§r§ehas invited you to join their party!", -> { - detected = true - it.remove() - } - } - } - } - if (detected) { - json.add("contains", JsonArray().apply { - add(JsonPrimitive("§r§ehas invited you to join their party!")) - }) - } - } - } - - fun shouldRender(message: IChatComponent): Boolean { - if (currentTabs.isEmpty()) return true - for (tab in currentTabs) { - if (tab?.shouldRender(message) == true) { - return true - } - } - return false - } - - private fun generateNewFile() { - tabFile.createNewFile() - val jsonObject = JsonObject() - val defaultTabs = generateDefaultTabs() - jsonObject.add("tabs", defaultTabs) - jsonObject.addProperty("version", ChatTabsJson.VERSION) - tabFile.writeText(GSON.toJson(jsonObject)) - } - - private fun generateDefaultTabs(): JsonArray { - val all = ChatTab( - true, - "ALL", - unformatted = false, - lowercase = false, - startsWith = null, - contains = null, - endsWith = null, - equals = null, - uncompiledRegex = null, - ignoreStartsWith = null, - ignoreContains = null, - ignoreEndsWith = null, - ignoreEquals = null, - uncompiledIgnoreRegex = null, - color = TabButton.color, - hoveredColor = TabButton.hoveredColor, - selectedColor = TabButton.selectedColor, - prefix = "" - ) - val party = ChatTab( - true, - "PARTY", - unformatted = false, - lowercase = false, - startsWith = listOf("§r§9Party §8> ", "§r§9P §8> ", "§eThe party was transferred to §r", "§eKicked §r"), - contains = listOf("§r§ehas invited you to join their party!"), - endsWith = listOf( - "§r§eto the party! They have §r§c60 §r§eseconds to accept.§r", - "§r§ehas disbanded the party!§r", - "§r§ehas disconnected, they have §r§c5 §r§eminutes to rejoin before they are removed from the party.§r", - " §r§ejoined the party.§r", - " §r§ehas left the party.§r", - " §r§ehas been removed from the party.§r", - "§r§e because they were offline.§r" - ), - equals = listOf("§cThe party was disbanded because all invites expired and the party was empty§r"), - uncompiledRegex = listOf( //regexes from https://github.com/kwevin/Hychat-Tabs/blob/main/tabs/re-add%20prefixes%20%26%20fix%20shortened%20tags/chat.json cause i cant write regex - "(§r)*(§9Party §8\u003e)+(.*)", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§einvited §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eto the party! They have §r§c60 §r§eseconds to accept\\.§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ehas left the party\\.§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ejoined the party\\.§r", - "§eYou left the party\\.§r", - "§eYou have joined §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)\u0027s §r§eparty!§r", - "§cThe party was disbanded because all invites expired and the party was empty§r", - "§cYou cannot invite that player since they\u0027re not online\\.§r", - "§eThe party leader, §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e, warped you to §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e\u0027s house\\.§r", - "§eSkyBlock Party Warp §r§7\\([0-9]+ players?\\)§r", - "§a. §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§f §r§awarped to your server§r", - "§eYou summoned §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§f §r§eto your server\\.§r", - "§eThe party leader, §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e, warped you to their house\\.§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§aenabled Private Game§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§cdisabled Private Game§r", - "§cThe party is now muted\\. §r", - "§aThe party is no longer muted\\.§r", - "§cThere are no offline players to remove\\.§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ehas been removed from the party\\.§r", - "§eThe party was transferred to §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eby §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e has promoted §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eto Party Leader§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e has promoted §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eto Party Moderator§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eis now a Party Moderator§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r§e has demoted §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§eto Party Member§r", - "§cYou can\u0027t demote yourself!§r", - "§6Party Members \\([0-9]+\\)§r", - "§eParty Leader: §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) ?§r(?:§[a-zA-Z0-9]).§r", - "§eParty Members: §r(?:(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r(?:§[a-zA-Z0-9]) . §r)+", - "§eParty Moderators: §r(?:(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+)§r(?:§[a-zA-Z0-9]) . §r)+", - "§eThe party invite to §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ehas expired§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§cdisabled All Invite§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§aenabled All Invite§r", - "§cYou cannot invite that player\\.§r", - "§cYou are not allowed to invite players\\.§r", - "§eThe party leader, §r(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ehas disconnected, they have §r§c5 §r§eminutes to rejoin before the party is disbanded\\.§r", - "(?:(?:§[a-zA-Z0-9])*\\[(?:(?:VIP)|(?:VIP§r§6\\+)|(?:MVP)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+)|(?:MVP(?:§r)?(?:§[a-zA-Z0-9])\\+\\+)|(?:(?:§r)?§fYOUTUBE))(?:§r)?(?:(?:§[a-zA-Z0-9]))?\\] [a-zA-Z0-9_]+|§7[a-zA-Z0-9_]+) §r§ehas disconnected, they have §r§c5 §r§eminutes to rejoin before they are removed from the party.§r", - "§cYou are not in a party right now\\.§r", - "§cThis party is currently muted\\.§r", - "(§r)*(§9P §8\u003e)+(.*)" - ), - ignoreStartsWith = null, - ignoreContains = null, - ignoreEndsWith = null, - ignoreEquals = null, - uncompiledIgnoreRegex = null, - color = TabButton.color, - hoveredColor = TabButton.hoveredColor, - selectedColor = TabButton.selectedColor, - prefix = "/pc " - ) - val guild = ChatTab( - true, - "GUILD", - unformatted = true, - lowercase = false, - startsWith = listOf("Guild >", "G >"), - contains = null, - endsWith = null, - equals = null, - uncompiledRegex = null, - ignoreStartsWith = null, - ignoreContains = null, - ignoreEndsWith = null, - ignoreEquals = null, - uncompiledIgnoreRegex = null, - color = TabButton.color, - hoveredColor = TabButton.hoveredColor, - selectedColor = TabButton.selectedColor, - prefix = "/gc " - ) - val pm = ChatTab( - true, - "PM", - unformatted = false, - lowercase = false, - startsWith = null, - contains = null, - endsWith = null, - equals = null, - uncompiledRegex = listOf("^(?§dTo|§dFrom) (?.+): §r(?.*)(?:§r)?\$"), - ignoreStartsWith = null, - ignoreContains = null, - ignoreEndsWith = null, - ignoreEquals = null, - uncompiledIgnoreRegex = null, - color = TabButton.color, - hoveredColor = TabButton.hoveredColor, - selectedColor = TabButton.selectedColor, - prefix = "/r " - ) - tabs.add(all) - tabs.add(party) - tabs.add(guild) - tabs.add(pm) - val jsonArray = JsonArray() - jsonArray.add(PARSER.parse(GSON.toJson(all)).asJsonObject) - jsonArray.add(PARSER.parse(GSON.toJson(party)).asJsonObject) - jsonArray.add(PARSER.parse(GSON.toJson(guild)).asJsonObject) - jsonArray.add(PARSER.parse(GSON.toJson(pm)).asJsonObject) - return jsonArray - } -} diff --git a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabsJson.kt b/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabsJson.kt deleted file mode 100644 index c632561..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/chat/ChatTabsJson.kt +++ /dev/null @@ -1,15 +0,0 @@ -package cc.woverflow.chatting.chat - -import com.google.gson.JsonArray -import com.google.gson.annotations.SerializedName - -data class ChatTabsJson(@SerializedName("tabs") val tabs: JsonArray, var version: Int) { - - override fun toString(): String { - return "{\"tabs\": $tabs, \"version\": $version}" - } - - companion object { - const val VERSION = 6 - } -} \ No newline at end of file diff --git a/src/main/kotlin/cc/woverflow/chatting/command/ChattingCommand.kt b/src/main/kotlin/cc/woverflow/chatting/command/ChattingCommand.kt deleted file mode 100644 index 7fcd4a8..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/command/ChattingCommand.kt +++ /dev/null @@ -1,14 +0,0 @@ -package cc.woverflow.chatting.command - -import cc.polyfrost.oneconfig.utils.commands.annotations.Command -import cc.polyfrost.oneconfig.utils.commands.annotations.Main -import cc.woverflow.chatting.Chatting -import cc.woverflow.chatting.config.ChattingConfig - -@Command(value = Chatting.ID, description = "Access the " + Chatting.NAME + " GUI.") -class ChattingCommand { - @Main - fun main() { - ChattingConfig.openGui() - } -} \ No newline at end of file diff --git a/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt b/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt deleted file mode 100644 index 711250f..0000000 --- a/src/main/kotlin/cc/woverflow/chatting/config/ChattingConfig.kt +++ /dev/null @@ -1,313 +0,0 @@ -package cc.woverflow.chatting.config - -import cc.polyfrost.oneconfig.config.Config -import cc.polyfrost.oneconfig.config.annotations.* -import cc.polyfrost.oneconfig.config.core.OneColor -import cc.polyfrost.oneconfig.config.data.InfoType -import cc.polyfrost.oneconfig.config.data.Mod -import cc.polyfrost.oneconfig.config.data.ModType -import cc.polyfrost.oneconfig.config.migration.VigilanceMigrator -import cc.polyfrost.oneconfig.utils.hypixel.HypixelUtils -import cc.woverflow.chatting.Chatting -import cc.woverflow.chatting.chat.ChatShortcuts -import cc.woverflow.chatting.chat.ChatTab -import cc.woverflow.chatting.chat.ChatTabs -import cc.woverflow.chatting.gui.components.TabButton -import cc.woverflow.chatting.hook.ChatLineHook -import cc.woverflow.chatting.utils.ModCompatHooks -import java.io.File - -object ChattingConfig : Config( - Mod( - Chatting.NAME, - ModType.UTIL_QOL, - "/chatting_dark.svg", - VigilanceMigrator(File(Chatting.oldModDir, Chatting.ID + ".toml").toPath().toString()) - ), "chatting.json" -) { - - @Dropdown( - name = "Text Render Type", category = "General", options = ["No Shadow", "Shadow", "Full Shadow"], - description = "Specifies how text should be rendered in the chat. Full Shadow displays a shadow on all sides of the text, while Shadow only displays a shadow on the right and bottom sides of the text." - ) - var textRenderType = 1 - - @Color( - name = "Chat Background Color", category = "General", - description = "The color of the chat background." - ) - var chatBackgroundColor = OneColor(0, 0, 0, 128) - - @Color( - name = "Copy Chat Message Background Color", category = "General", - description = "The color of the chat background when hovering over a message." - ) - var hoveredChatBackgroundColor = OneColor(80, 80, 80, 128) - - @Switch( - name = "Right Click to Copy Chat Message", category = "General", - description = "Enable right clicking on a chat message to copy it." - ) - var rightClickCopy = false - - @Switch( - name = "Compact Input Box", category = "General", - description = "Make the chat input box the same width as the chat box." - ) - var compactInputBox = false - - @Color( - name = "Input Box Background Color", category = "General", - description = "The color of the chat input box background." - ) - var inputBoxBackgroundColor = OneColor(0, 0, 0, 128) - - @Color( - name = "Chat Button Background Color", category = "General", - description = "The color of the chat button background." - ) - var chatButtonBackgroundColor = OneColor(0, 0, 0, 128) - - @Color( - name = "Chat Button Hovered Background Color", category = "General", - description = "The color of the chat button background when hovered." - ) - var chatButtonHoveredBackgroundColor = OneColor(255, 255, 255, 128) - - @Switch( - name = "Inform Outdated Mods", category = "General", - description = "Inform the user when a mod can be replaced by Chatting." - ) - var informForAlternatives = true - - @Switch( - name = "Smooth Chat Messages", - category = "Animations", subcategory = "Messages", - description = "Smoothly animate chat messages when they appear." - ) - var smoothChat = true - - @Slider( - name = "Message Animation Speed", - category = "Animations", subcategory = "Messages", - min = 0.0f, max = 1.0f, - description = "The speed at which chat messages animate." - ) - var messageSpeed = 0.5f - - @Switch( - name = "Smooth Chat Scrolling", - category = "Animations", subcategory = "Scrolling", - description = "Smoothly animate scrolling when scrolling through the chat." - ) - var smoothScrolling = true - - @Slider( - name = "Scrolling Animation Speed", - category = "Animations", subcategory = "Scrolling", - min = 0.0f, max = 1.0f, - description = "The speed at which scrolling animates." - ) - var scrollingSpeed = 0.15f - - @Switch( - name = "Remove Scroll Bar", - category = "Animations", subcategory = "Scrolling", - description = "Removes the vanilla scroll bar from the chat." - ) - var removeScrollBar = true - - @Switch( - name = "Show Chat Heads", description = "Show the chat heads of players in chat", category = "Chat Heads", - ) - var showChatHeads = true - - @Switch( - name = "Offset Non-Player Messages", - description = "Offset all messages, even if a player has not been detected.", - category = "Chat Heads" - ) - var offsetNonPlayerMessages = false - - @Switch( - name = "Hide Chat Head on Consecutive Messages", - description = "Hide the chat head if the previous message was from the same player.", - category = "Chat Heads" - ) - var hideChatHeadOnConsecutiveMessages = true - - /*/ - @Property( - type = PropertyType.SWITCH, - name = "Show Timestamp", - description = "Show message timestamp.", - category = "General" - ) - var showTimestamp = false - - @Property( - type = PropertyType.SWITCH, - name = "Timestamp Only On Hover", - description = "Show timestamp only on mouse hover.", - category = "General" - ) - var showTimestampHover = true - - */ - - @Info( - text = "If Chatting detects a public chat message that seems like spam, and the probability is higher than this, it will hide it.\n" + "Made for Hypixel Skyblock. Set to 100% to disable. 95% is a reasonable threshold to use it at.\n" + "Note that this is not and never will be 100% accurate; however, it's pretty much guaranteed to block most spam.", - size = 2, - category = "Player Chats", - type = InfoType.INFO - ) - var ignored = false - - @Slider( - min = 80F, max = 100F, name = "Spam Blocker Threshold", category = "Player Chats" - ) - var spamThreshold = 100 - - @Switch( - name = "Custom SkyBlock Chat Formatting (remove ranks)", category = "Player Chats" - ) - var customChatFormatting = false - - @Switch( - name = "Completely Hide Spam", category = "Player Chats" - ) - var hideSpam = false - - @Switch( - name = "Custom Chat Height", category = "Chat Window", - description = "Set a custom height for the chat window. Allows for more customization than the vanilla chat height options." - ) - var customChatHeight = false - - @Slider( - min = 180F, max = 2160F, name = "Focused Height (px)", category = "Chat Window", - description = "The height of the chat window when focused." - ) - var focusedHeight = 180 - - @Slider( - min = 180F, max = 2160F, name = "Unfocused Height (px)", category = "Chat Window", - description = "The height of the chat window when unfocused." - ) - var unfocusedHeight = 180 - - @Dropdown( - name = "Screenshot Mode", category = "Screenshotting", options = ["Save To System", "Add To Clipboard", "Both"], - description = "What to do when taking a screenshot." - ) - var copyMode = 0 - - @Checkbox( - name = "Chat Searching", category = "Searching", - description = "Enable searching through chat messages." - ) - var chatSearch = true - - @Switch( - name = "Chat Tabs", category = "Tabs", - description = "Allow filtering chat messages by a tab." - ) - var chatTabs = true - get() { - if (!field) return false - return if (hypixelOnlyChatTabs) { - HypixelUtils.INSTANCE.isHypixel - } else { - true - } - } - - @Checkbox( - name = "Enable Tabs Only on Hypixel", category = "Tabs", - description = "Only enable chat tabs on Hypixel" - ) - var hypixelOnlyChatTabs = true - - @Switch( - name = "Chat Shortcuts", category = "Shortcuts" - ) - var chatShortcuts = false - get() { - if (!field) return false - return if (hypixelOnlyChatShortcuts) { - HypixelUtils.INSTANCE.isHypixel - } else { -