diff options
author | Linnea Gräf <nea@nea.moe> | 2025-01-25 00:40:58 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2025-01-25 00:40:58 +0100 |
commit | af991c28062e405a02c139d3d67c4f86a9043e35 (patch) | |
tree | 29bd1d1568b707be04915f47a1bf558e923cd3fe /src/main/kotlin | |
parent | e4f585c173ca0a5d09130ab97c18c48f91fe5ad7 (diff) | |
download | ultra-notifier-af991c28062e405a02c139d3d67c4f86a9043e35.tar.gz ultra-notifier-af991c28062e405a02c139d3d67c4f86a9043e35.tar.bz2 ultra-notifier-af991c28062e405a02c139d3d67c4f86a9043e35.zip |
.
Diffstat (limited to 'src/main/kotlin')
-rw-r--r-- | src/main/kotlin/datamodel/ChatType.kt | 100 | ||||
-rw-r--r-- | src/main/kotlin/gui/ChatUi.kt | 89 | ||||
-rw-r--r-- | src/main/kotlin/util/minecrat/MC.kt | 11 | ||||
-rw-r--r-- | src/main/kotlin/util/minecrat/TextUtil.kt | 1 | ||||
-rw-r--r-- | src/main/kotlin/util/minecrat/infer.kt | 15 | ||||
-rw-r--r-- | src/main/kotlin/util/render/ScreenRenderUtils.kt | 33 |
6 files changed, 248 insertions, 1 deletions
diff --git a/src/main/kotlin/datamodel/ChatType.kt b/src/main/kotlin/datamodel/ChatType.kt new file mode 100644 index 0000000..1fcc522 --- /dev/null +++ b/src/main/kotlin/datamodel/ChatType.kt @@ -0,0 +1,100 @@ +package moe.nea.ultranotifier.datamodel + +import net.minecraft.text.Text +import java.util.regex.Pattern + +data class ChatTypeId( + val id: String +) + +data class ChatType( + val id: ChatTypeId, + val name: String, + val patterns: List<ChatPattern>, +) + +data class ChatPattern( + val text: String +) { + val pattern = Pattern.compile(text) + val predicate = pattern.asMatchPredicate() +} + +data class ChatCategory( + val label: String, + val chatTypes: Set<ChatTypeId>, +) + +data class ChatUniverse( + val name: String, + val types: List<ChatType>, + val categories: List<ChatCategory>, +) { + fun categorize( + text: String + ): CategorizedChatLine { + val types = this.types + .asSequence() + .filter { + it.patterns.any { + it.predicate.test(text) + } + } + .map { + it.id + } + .toSet() + // TODO: potentially allow recalculating categories on the fly + val categories = categories.filterTo(mutableSetOf()) { it.chatTypes.any { it in types } } + return CategorizedChatLine( + text, types, categories + ) + } +} + +data class CategorizedChatLine( + val text: String, + val types: Set<ChatTypeId>, + val categories: Set<ChatCategory>, +) + +interface HasCategorizedChatLine { + val categorizedChatLine_ultraNotifier: CategorizedChatLine +} + +object ChatCategoryArbiter { + val universe = ChatUniverse( + "Hypixel SkyBlock", + listOf( + ChatType( + ChatTypeId("bazaar"), + "Bazaar", + listOf( + ChatPattern("(?i).*Bazaar.*") + ) + ), + ChatType( + ChatTypeId("auction-house"), + "Auction House", + listOf( + ChatPattern("(?i).*Auction House.*") + ) + ), + ), + listOf( + ChatCategory( + "Economy", + setOf(ChatTypeId("bazaar"), ChatTypeId("auction-house")) + ) + ) + ) + + fun categorize(content: Text): CategorizedChatLine { + universe.categorize(content.lit) + } +} + + + + + diff --git a/src/main/kotlin/gui/ChatUi.kt b/src/main/kotlin/gui/ChatUi.kt new file mode 100644 index 0000000..0ec3063 --- /dev/null +++ b/src/main/kotlin/gui/ChatUi.kt @@ -0,0 +1,89 @@ +package moe.nea.ultranotifier.gui + +import gg.essential.universal.UGraphics +import gg.essential.universal.UMatrixStack +import moe.nea.ultranotifier.util.minecrat.MC +import moe.nea.ultranotifier.util.minecrat.accessor +import moe.nea.ultranotifier.util.render.ScreenRenderUtils +import net.minecraft.client.gui.screen.ChatScreen +import java.awt.Color + +class ChatUi(val chatScreen: ChatScreen) { + + fun getChatBgOpacity(opacityMultiplier: Double = 1.0): Color { + return Color((MC.instance.options.textBackgroundOpacity.value * opacityMultiplier * 255).toInt() shl 24, true) + } + + fun calculateChatTop(): Double { + val ch = MC.chatHud + ch.accessor() + val chatOffset = + 40 + val chatTop = + (chatScreen.height - chatOffset) / ch.chatScale - ch.visibleLineCount * ch.lineHeight_ultranotifier + return chatTop + } + + var selectedTab = "Bazaar" + fun iterateButtons( + onEach: ( + label: String, + isSelected: Boolean, + pos: Rect, + ) -> Unit + ) { + val chatTop = calculateChatTop() + var xOffset = 5 + val top = chatTop - 16.0 + for (button in listOf("Socials", "Bazaar", "Slayer", "Guild", "Party", "Dungeon", "Fishing","Socials", "Bazaar", "Slayer", "Guild", "Party", "Dungeon", "Fishing")) { + val w = ScreenRenderUtils.getTextWidth(button) + 3 + val isSelected = button == selectedTab + onEach(button, isSelected, Rect(xOffset.toDouble(), top, w.toDouble(), 16.0)) + xOffset += w + 5 + } + } + + data class Rect( + val x: Double, val y: Double, + val w: Double, val h: Double, + ) { + fun contains(mouseX: Double, mouseY: Double): Boolean { + return mouseX in (l..<r) && mouseY in (t..<b) + } + + val l get() = x + val t get() = y + val r get() = x + w + val b get() = y + h + val cy get() = y + h / 2 + val cx get() = x + w / 2 + } + + fun renderButtons( + matrixStack: UMatrixStack, + mouseX: Double, mouseY: Double, + ) { + iterateButtons { text, isSelected, pos -> + val w = ScreenRenderUtils.getTextWidth(text) + UGraphics.enableBlend() + ScreenRenderUtils.fillRect(matrixStack, + pos.l, pos.t, pos.r, pos.b, + if (isSelected) getChatBgOpacity() else getChatBgOpacity(0.75)) + UGraphics.disableBlend() + ScreenRenderUtils.renderText(matrixStack, + pos.l + 2, pos.cy - 9 / 2, + if (isSelected) "§a$text" else "§f$text") + } + } + + fun clickMouse(mouseX: Double, mouseY: Double, button: Int) { + iterateButtons { label, isSelected, pos -> + if (pos.contains(mouseX, mouseY)) { + if (button == 0) { + selectedTab = label + } + // TODO: right click options or something + } + } + } +} diff --git a/src/main/kotlin/util/minecrat/MC.kt b/src/main/kotlin/util/minecrat/MC.kt new file mode 100644 index 0000000..d942982 --- /dev/null +++ b/src/main/kotlin/util/minecrat/MC.kt @@ -0,0 +1,11 @@ +package moe.nea.ultranotifier.util.minecrat + +import net.minecraft.client.MinecraftClient + +object MC { + val font get() = instance.textRenderer + val instance get() = MinecraftClient.getInstance() + val inGameHud get() = instance.inGameHud!! + val chatHud get() = inGameHud.chatHud!! + +} diff --git a/src/main/kotlin/util/minecrat/TextUtil.kt b/src/main/kotlin/util/minecrat/TextUtil.kt new file mode 100644 index 0000000..2a09e13 --- /dev/null +++ b/src/main/kotlin/util/minecrat/TextUtil.kt @@ -0,0 +1 @@ +package moe.nea.ultranotifier.util.minecrat diff --git a/src/main/kotlin/util/minecrat/infer.kt b/src/main/kotlin/util/minecrat/infer.kt new file mode 100644 index 0000000..a109bbd --- /dev/null +++ b/src/main/kotlin/util/minecrat/infer.kt @@ -0,0 +1,15 @@ +@file:OptIn(ExperimentalContracts::class) + +package moe.nea.ultranotifier.util.minecrat + +import moe.nea.ultranotifier.mixin.AccessorChatHud +import net.minecraft.client.gui.hud.ChatHud +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +fun ChatHud.accessor(): AccessorChatHud { + contract { + returns() implies (this@accessor is AccessorChatHud) + } + return this as AccessorChatHud +} diff --git a/src/main/kotlin/util/render/ScreenRenderUtils.kt b/src/main/kotlin/util/render/ScreenRenderUtils.kt index 224ccb4..af8424a 100644 --- a/src/main/kotlin/util/render/ScreenRenderUtils.kt +++ b/src/main/kotlin/util/render/ScreenRenderUtils.kt @@ -1,13 +1,36 @@ package moe.nea.ultranotifier.util.render +//#if MC > 1.16 import gg.essential.universal.UGraphics import gg.essential.universal.UMatrixStack import juuxel.libninepatch.NinePatch import juuxel.libninepatch.TextureRenderer +import moe.nea.ultranotifier.util.minecrat.MC +import net.minecraft.client.gui.DrawContext +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier import java.awt.Color +//#endif + object ScreenRenderUtils { + //#if MC > 1.16 + @JvmStatic + fun umatrix( + matrixStack: MatrixStack + ) = UMatrixStack(matrixStack) + + //#endif + //#if MC >= 1.20 + @JvmStatic + fun umatrix( + context: DrawContext + ) = UMatrixStack(context.matrices) + //#endif + + @JvmStatic + fun umatrix() = UMatrixStack() + fun fillRect( matrixStack: UMatrixStack, left: Double, top: Double, @@ -82,7 +105,7 @@ object ScreenRenderUtils { ) { val x1 = left + x.toDouble() val y1 = top + y.toDouble() - val x2 = x1+ width + val x2 = x1 + width val y2 = y1 + height graphics.pos(matrixStack, x1, y1, 0.0) .tex(u1.toDouble(), v1.toDouble()) @@ -101,4 +124,12 @@ object ScreenRenderUtils { graphics.drawDirect() } + fun getTextWidth(text: String): Int { + return MC.font.getWidth(text) + } + + fun renderText(matrixStack: UMatrixStack, x: Double, y: Double, text: String) { + UGraphics.drawString(matrixStack, text, x.toFloat(), y.toFloat(), -1, false) + } + } |