diff options
author | Linnea Gräf <nea@nea.moe> | 2024-04-10 12:37:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-10 12:37:49 +0200 |
commit | c09c456d72ef95aeddf9c3b93639af8c64552fd1 (patch) | |
tree | 319d83484ffd6b92f83b65843d0fcdae680adc2a /src/main/kotlin/io | |
parent | b04290ede8420e8ef9b56f2c8a9252224b8f1d2d (diff) | |
download | NotEnoughUpdates-c09c456d72ef95aeddf9c3b93639af8c64552fd1.tar.gz NotEnoughUpdates-c09c456d72ef95aeddf9c3b93639af8c64552fd1.tar.bz2 NotEnoughUpdates-c09c456d72ef95aeddf9c3b93639af8c64552fd1.zip |
Add tab list tutorial (#1014)
Co-authored-by: Lulonaut <lulonaut@lulonaut.tech>
Diffstat (limited to 'src/main/kotlin/io')
6 files changed, 529 insertions, 6 deletions
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt index d5b91b9d..9e9cca14 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 NotEnoughUpdates contributors + * Copyright (C) 2023-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * @@ -27,6 +27,7 @@ import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent import io.github.moulberry.notenoughupdates.util.DiscordMarkdownBuilder import io.github.moulberry.notenoughupdates.util.SBInfo +import io.github.moulberry.notenoughupdates.util.TabListUtils import io.github.moulberry.notenoughupdates.util.brigadier.reply import io.github.moulberry.notenoughupdates.util.brigadier.thenExecute import io.github.moulberry.notenoughupdates.util.brigadier.thenLiteralExecute @@ -61,6 +62,9 @@ class NEUStatsCommand { .toString() ) }.withHelp("Copy the mod list to your clipboard") + thenLiteralExecute("tablist") { + clipboardAndSendMessage("```\n${TabListUtils.getTabList()}\n```") + }.withHelp("Copy the current tab list to your clipboard") thenLiteralExecute("repo") { clipboardAndSendMessage( DiscordMarkdownBuilder() @@ -173,7 +177,6 @@ class NEUStatsCommand { Loader.instance().indexedModList[NotEnoughUpdates.MODID]!!.displayVersion ) builder.append("SB Profile", SBInfo.getInstance().currentProfile) - builder.append("Has Advanced Tab", if (SBInfo.getInstance().hasNewTab) "TRUE" else "FALSE") .also(::appendRepoStats) } diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistAPI.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistAPI.kt new file mode 100644 index 00000000..5c493108 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistAPI.kt @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2024 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial + +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.util.TabListUtils +import io.github.moulberry.notenoughupdates.util.stripControlCodes +import net.minecraft.client.Minecraft +import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.* + +@NEUAutoSubscribe +object TablistAPI { + + private var lastWorldSwitch = 0L + var lastWidgetEnabled: WidgetNames? = null + + @SubscribeEvent + fun onWorldSwitch(event: EntityJoinWorldEvent) { + if (event.entity == Minecraft.getMinecraft().thePlayer) { + lastWorldSwitch = System.nanoTime() + } + } + + @JvmStatic + fun getWidgetLinesInRegion( + widget: TablistTutorial.TabListWidget, + addToQueue: Boolean, + showNotification: Boolean + ): List<String> { + val regex = widget.widgetName.regex ?: Regex.fromLiteral("${widget.widgetName}:") + val list = mutableListOf<String>() + // If not a single reset is present, the tab list hasn't been initialized yet + var sawReset = false + + for (entry in TabListUtils.getTabList()) { + if (entry.contains("§r")) { + sawReset = true + } + + if (list.isNotEmpty()) { + // New tab section, or empty line indicate a new section + if (entry == "§r §r§3§lInfo§r" || entry == "§r") { + break + } + list.add(entry) + } else if (entry.stripControlCodes().matches(regex)) { + list.add(entry) + } + } + if (addToQueue && + list.isEmpty() && + sawReset && + (System.nanoTime() - lastWorldSwitch > 10_000_000L) && + widget.widgetName != lastWidgetEnabled + ) { + TablistTaskQueue.addToQueue(widget, showNotification) + } + return list + } + + /** + * Attempt to get the lines for this widget. + * Otherwise, add the widget to the tablist queue and show a notification to the user + */ + @JvmStatic + fun getWidgetLines(widgetName: WidgetNames): List<String> { + return getWidgetLinesInRegion( + TablistTutorial.TabListWidget("CURRENT_REGION", widgetName), + addToQueue = true, + showNotification = true + ) + } + + /** + * Attempt to get the lines for this widget. + * Otherwise, add the widget to the tablist queue without showing a notification to the user. + * + * Consider using this if there is a more optimal way of informing the user. + */ + @JvmStatic + fun getWidgetLinesWithoutNotification(widgetName: WidgetNames): List<String> { + return getWidgetLinesInRegion( + TablistTutorial.TabListWidget("CURRENT_REGION", widgetName), + addToQueue = true, + showNotification = false + ) + } + + /** + * Attempt to get the lines for this widget. + * Otherwise, do nothing. + * + * Consider using this if the result is not important, but simply a nice to have. + */ + @JvmStatic + fun getOptionalWidgetLines(widgetName: WidgetNames): List<String> { + return getWidgetLinesInRegion( + TablistTutorial.TabListWidget("CURRENT_REGION", widgetName), + addToQueue = false, + showNotification = false + ) + } + + enum class WidgetNames(val regex: Regex?) { + COMMISSIONS(null), + SKILLS(null), + TRAPPER(null), + FORGE(Regex.fromLiteral("Forges:")), + POWDER(Regex.fromLiteral("Powders:")), + PROFILE(Regex("Profile: ([A-Za-z]+)( .*)?")) + ; + + override fun toString(): String { + return this.name.lowercase().split(" ").joinToString(" ") { str -> + str.replaceFirstChar { + if (it.isLowerCase()) { + it.titlecase( + Locale.ROOT + ) + } else { + it.toString() + } + } + } + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTaskQueue.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTaskQueue.kt new file mode 100644 index 00000000..8cbd27a0 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTaskQueue.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial + +import io.github.moulberry.notenoughupdates.util.NotificationHandler + +object TablistTaskQueue { + private val queue = mutableListOf<TablistTutorial.TabListWidget>() + + fun addToQueue(task: TablistTutorial.TabListWidget, showNotification: Boolean) { + if (showNotification && !queueContainsElements()) { + NotificationHandler.displayNotification( + listOf( + "§l§4Widget missing", + "§cOne or more tab list widgets, which are required for NEU to function properly, are missing", + "§cOpen the Tablist Widgets settings using", + "§b/tab", + "§cto get some assistance in fixing this problem." + ), + false + ) + } + if (task !in queue) { + // see todo in MiningOverlay.java:377 +// Utils.addChatMessage("Adding $task") + queue.add(task) + } + } + + fun removeFromQueue(task: TablistTutorial.TabListWidget) { + queue.remove(task) + } + + fun queueContainsElements(): Boolean { + return queue.isNotEmpty() + } + + fun getNextQueueItem(): TablistTutorial.TabListWidget? { + return if (!queueContainsElements()) { + null + } else { + queue.removeLast() + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTutorial.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTutorial.kt new file mode 100644 index 00000000..e7299e12 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/tablisttutorial/TablistTutorial.kt @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2024 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial + +import com.mojang.brigadier.arguments.StringArgumentType.string +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.core.util.StringUtils +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils +import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent +import io.github.moulberry.notenoughupdates.mixins.AccessorGlStateManager +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer +import io.github.moulberry.notenoughupdates.util.ItemUtils +import io.github.moulberry.notenoughupdates.util.StateManagerUtils +import io.github.moulberry.notenoughupdates.util.brigadier.thenArgument +import io.github.moulberry.notenoughupdates.util.brigadier.thenExecute +import io.github.moulberry.notenoughupdates.util.brigadier.withHelp +import io.github.moulberry.notenoughupdates.util.stripControlCodes +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.inventory.ContainerChest +import net.minecraft.inventory.Slot +import net.minecraft.util.ResourceLocation +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@NEUAutoSubscribe +object TablistTutorial { + data class TabListWidget( + var regionName: String, + val widgetName: TablistAPI.WidgetNames, + ) + + private object Arrow { + val imageLocation = ResourceLocation("notenoughupdates:textures/gui/tablisttutorial/arrow.png") + val tipXOffset = 16 + val tipYOffset = 64 + val labelXOffset = 58 + val labelYOffset = 19 + val textureSize = 64 + val textScale = 2f + + fun drawBigRedArrow(x: Int, y: Int, label: String) { + val imgX = x - Arrow.tipXOffset + val imgY = y - Arrow.tipYOffset + val textX = imgX + Arrow.labelXOffset + val textY = imgY + Arrow.labelYOffset + + GlStateManager.pushMatrix() + GlStateManager.translate(0f, 0f, 300f) + GlStateManager.color(1f, 1f, 1f, 1f) + Minecraft.getMinecraft().textureManager.bindTexture(imageLocation) + RenderUtils.drawTexturedRect(imgX.toFloat(), imgY.toFloat(), textureSize.toFloat(), textureSize.toFloat()) + GlStateManager.translate(textX.toFloat(), textY.toFloat(), 0F) + GlStateManager.scale(textScale, textScale, 1F) + val fr = Minecraft.getMinecraft().fontRendererObj + fr.drawString(label, 0, -fr.FONT_HEIGHT / 2, -1) + GlStateManager.popMatrix() + } + + fun drawBigRedArrow(gui: GuiContainer, slot: Slot, label: String) { + gui as AccessorGuiContainer + drawBigRedArrow(gui.guiLeft + slot.xDisplayPosition + 9, gui.guiTop + slot.yDisplayPosition, label) + } + } + + var activeTask: TabListWidget? = null + + @SubscribeEvent + fun onGuiPostRender(event: GuiScreenEvent.DrawScreenEvent.Post) { + if (activeTask == null) { + activeTask = TablistTaskQueue.getNextQueueItem() + } + val task = activeTask ?: return + + val gui = event.gui as? GuiChest ?: return + val chestInventory = gui.inventorySlots as ContainerChest + + val name = chestInventory.lowerChestInventory.displayName.unformattedText + + StateManagerUtils.withSavedState(AccessorGlStateManager.getLightingState()) { + GlStateManager.disableLighting() + if (name == "Tablist Widgets") { + drawSelectAreaArrow(gui, chestInventory, task) + } + val regionName = getRegionName(name) + + // Assume the user is capable of clicking on the current region + if (task.regionName == "CURRENT_REGION") { + activeTask!!.regionName = regionName ?: return + } + if (regionName == task.regionName) { + drawEnableEffect(gui, chestInventory, task) + } else if (regionName != null) { + val backSlot = chestInventory.inventorySlots.getOrNull(5 * 9 + 3) + if (backSlot != null) { + Arrow.drawBigRedArrow(gui, backSlot, "Go back!") + } + } + } + } + + data class WidgetStatus( + val widgetName: String, + val enabled: Boolean, + val slot: Slot, + ) + + fun findWidgets(chestInventory: ContainerChest): List<WidgetStatus> { + return chestInventory.inventorySlots.mapNotNull { + val name = ItemUtils.getDisplayName(it.stack)?.let(StringUtils::cleanColour) ?: return@mapNotNull null + if (!name.endsWith(" Widget")) { + return@mapNotNull null + } + val disabled = name.startsWith("✖") + val enabled = name.startsWith("✔") + if (!(enabled || disabled)) { + return@mapNotNull null + } + return@mapNotNull WidgetStatus(name.drop(1).removeSuffix(" Widget").trim(), enabled, it) + } + } + + private fun drawEnableEffect(gui: GuiChest, chestInventory: ContainerChest, task: TabListWidget) { + val widgets = findWidgets(chestInventory) + val widget = widgets.find { it.widgetName == task.widgetName.toString() } + if (widget == null) return + if (widget.enabled) { + drawPriorityClick(gui, chestInventory, widget) + return + } + Arrow.drawBigRedArrow(gui, widget.slot, "Click here!") + } + + /*{ + id: "minecraft:skull", + Count: 1b, + tag: { + overrideMeta: 1b, + HideFlags: 254, + SkullOwner: { + Id: "474a0574-24e5-4949-bf61-f8d06120815e", + hypixelPopulated: 1b, + Properties: { + textures: [{ + Value: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzljODg4MWU0MjkxNWE5ZDI5YmI2MWExNmZiMjZkMDU5OTEzMjA0ZDI2NWRmNWI0MzliM2Q3OTJhY2Q1NiJ9fX0=" + }] + }, + Name: "§474a0574-24e5-4949-bf61-f8d06120815e" + }, + display: { + Lore: ["§7§3⬛ §3§lInfo", "§7§8⬛§f§b§lArea: §7Private Island", "§7§8⬛§f Server: §8mini4C", "§7§8⬛§f Gems: §a0", "§7§8⬛§f Crystals: §d3", "§7§8⬛§f", "§7§8⬛§f§b§lMinions§f: 27§7/§r28", "§7§8⬛§f 7x Ice VII §7[§aACTIVE§7]", "§7§8⬛§f 1x Acacia XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Cave Spider XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Cow XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Creeper X §7[§aACTIVE§7]", "§7§8⬛§f 1x Fishing X §7[§aACTIVE§7]", "§7§8⬛§f 1x Ice XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Iron XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Jungle XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Melon XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Obsidian XI §7[§aACTIVE§7]", "§7§8⬛§f 1x Pig XI §7[§aACTIVE§7]", "§7§8⬛§f ... and 10 more."], + Name: "§aPrivate Island Widgets Preview" + }, + AttributeModifiers: [] + }, + Damage: 3s + }*/ + fun drawPriorityClick(gui: GuiChest, chestInventory: ContainerChest, widget: WidgetStatus) { + val prioritySlot = chestInventory.inventorySlots.getOrNull(13) ?: return + val leftSide = chestInventory.inventory.getOrNull(3).let(ItemUtils::getLore) + val middle = chestInventory.inventory.getOrNull(4).let(ItemUtils::getLore) + val rightSide = chestInventory.inventory.getOrNull(5).let(ItemUtils::getLore) + + val priorityList = chestInventory.inventory.getOrNull(13).let(ItemUtils::getLore) + val allTabListEntries = leftSide + middle + rightSide + val regex = activeTask?.widgetName?.regex ?: Regex.fromLiteral("${widget.widgetName}:") + if (allTabListEntries.any { it.replace("⬛", "").stripControlCodes().matches(regex) }) { + TablistAPI.lastWidgetEnabled = activeTask!!.widgetName + activeTask = TablistTaskQueue.getNextQueueItem() +// Utils.addChatMessage("Success! You enabled ${widget.widgetName}!") + return + } + val editingIndex = priorityList.indexOfFirst { it.contains("EDITING") } + val widgetPriorityIndex = priorityList.indexOfFirst { it.contains("${widget.widgetName} Widget") } + if (editingIndex < 0 || widgetPriorityIndex < 0) { + return + } + if (editingIndex == widgetPriorityIndex) { + Arrow.drawBigRedArrow(gui, prioritySlot, "Shift Right Click") + } else if (editingIndex < widgetPriorityIndex) { + Arrow.drawBigRedArrow(gui, prioritySlot, "Left Click") + } else { + Arrow.drawBigRedArrow(gui, prioritySlot, "Right Click") + } + } + + fun getRegionName(label: String): String? { + if (!label.startsWith("Widgets")) return null + if (label == "Private Islands") return "Private Island" + return label.removePrefix("Widgets ").removePrefix("in ").removePrefix("on ") + .removePrefix("the ") + } + + private fun drawSelectAreaArrow(gui: GuiChest, inventory: ContainerChest, task: TabListWidget) { + var regionName = task.regionName + if (regionName == "CURRENT_REGION") { + val infoSlot = inventory.inventory.getOrNull(4).let(ItemUtils::getLore) + if (infoSlot.isEmpty()) { + return + } + val lastLine = infoSlot.last().stripControlCodes() + val pattern = Regex("Click to edit (?<area>[\\w\\s]+) settings!") + + val result = pattern.matchEntire(lastLine) ?: return + regionName = result.groups["area"]?.value!! + activeTask!!.regionName = regionName + } + + val regionSlot = inventory.inventorySlots.find { + val name = ItemUtils.getDisplayName(it.stack)?.let(StringUtils::cleanColour) ?: "" + getRegionName(name) == regionName + } ?: return + Arrow.drawBigRedArrow(gui, regionSlot, "§cClick here!") + } + + @SubscribeEvent + fun onCommands(event: RegisterBrigadierCommandEvent) { + event.command("neutesttablisttutorial") { + thenArgument("region", string()) { region -> + thenArgument("widget", string()) { widget -> + thenExecute { + TablistTaskQueue.addToQueue( + TabListWidget( + "Dwarven Mines", + TablistAPI.WidgetNames.COMMISSIONS, + ), + true + ) + NotEnoughUpdates.INSTANCE.sendChatMessage("/tab") + } + }.withHelp("Test command for showing a tab list tutorial") + } + } + + event.command("neutesttablistapi") { + thenExecute { + TablistAPI.getWidgetLinesInRegion(TabListWidget("CURRENT_REGION", TablistAPI.WidgetNames.SKILLS), + addToQueue = true, + showNotification = true + ) + .forEach { println(it) } +// println("SEP") +// TablistAPI.getWidgetLines(TabListWidget("Dwarven Mines", TablistAPI.WidgetNames.FORGE)) +// .forEach { println(it) } + } + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/StateManagerUtils.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/StateManagerUtils.kt new file mode 100644 index 00000000..a7e50fda --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/StateManagerUtils.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util + +import io.github.moulberry.notenoughupdates.mixins.AccessorBooleanState +import net.minecraft.client.renderer.GlStateManager + +object StateManagerUtils { + fun readState(state: GlStateManager.BooleanState): Boolean { + state as AccessorBooleanState + return state.currentState + } + + inline fun withSavedState(state: GlStateManager.BooleanState, block: () -> Unit) { + val savedState = readState(state) + block() + state.setState(savedState) + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt index b4bfdf28..0c3e1901 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 NotEnoughUpdates contributors + * Copyright (C) 2023-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * @@ -20,15 +20,17 @@ package io.github.moulberry.notenoughupdates.util import com.google.gson.JsonArray +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial.TablistAPI import net.minecraft.util.EnumChatFormatting import java.util.regex.Pattern import kotlin.math.abs object TabSkillInfoParser { private val skillTabPattern: Pattern = - Pattern.compile("^§r§e§lSkills: §r§a(?<type>\\w+) (?<level>\\d+): §r§3(?<progress>.+)%§r\$") + Pattern.compile("^§r (?<type>\\w+) (?<level>\\d+): §r§a(?<progress>.+)%§r\$") private val maxSkillTabPattern: Pattern = - Pattern.compile("^§r§e§lSkills: §r§a(?<type>\\w+) (?<level>\\d+): §r§c§lMAX§r\$") + Pattern.compile("^§r (?<type>\\w+) (?<level>\\d+): §r§c§lMAX§r\$") private var sentErrorOnce = false private fun calculateLevelXp(levelingArray: JsonArray, level: Int): Double { @@ -58,12 +60,18 @@ object TabSkillInfoParser { @JvmStatic fun parseSkillInfo() { + if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + return + } + if (Constants.LEVELING == null) { sendError("${EnumChatFormatting.RED}[NEU] There is an error with your repo, please report this in the discord at ${EnumChatFormatting.AQUA}discord.gg/moulberry") return } - for (s in TabListUtils.getTabList()) { + for (s in TablistAPI.getOptionalWidgetLines( + TablistAPI.WidgetNames.SKILLS + )) { val matcher = skillTabPattern.matcher(s) val maxLevelMatcher = maxSkillTabPattern.matcher(s) if (matcher.matches()) { |