From 35bddd8b5212af1091ba52778409d3854f9186c0 Mon Sep 17 00:00:00 2001 From: Fly Date: Tue, 5 Aug 2025 18:32:50 +0800 Subject: [PATCH 01/21] First --- .../me/odinmain/features/ModuleManager.kt | 2 +- .../odinmain/features/impl/dungeon/MapInfo.kt | 3 +- .../features/impl/skyblock/ChatCommands.kt | 23 +++++++- .../features/impl/skyblock/Countdowns.kt | 53 +++++++++++++++++++ src/main/kotlin/me/odinmain/utils/Utils.kt | 5 +- .../utils/skyblock/dungeon/DungeonListener.kt | 2 +- 6 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt diff --git a/src/main/kotlin/me/odinmain/features/ModuleManager.kt b/src/main/kotlin/me/odinmain/features/ModuleManager.kt index 0f219b489..e2585f47f 100644 --- a/src/main/kotlin/me/odinmain/features/ModuleManager.kt +++ b/src/main/kotlin/me/odinmain/features/ModuleManager.kt @@ -65,7 +65,7 @@ object ModuleManager { //skyblock NoCursorReset, AutoSprint, BlazeAttunement, ChatCommands, DeployableTimer, DianaHelper, ArrowHit, Ragnarock, MobSpawn, Splits, WardrobeKeybinds, InvincibilityTimer, ItemsHighlight, PlayerDisplay, - FarmKeys, PetKeybinds, CommandKeybinds, SpringBoots, AbilityTimers, SlotBinds, + FarmKeys, PetKeybinds, CommandKeybinds, SpringBoots, AbilityTimers, SlotBinds, Countdowns, // kuudra BuildHelper, FreshTools, KuudraDisplay, NoPre, PearlWaypoints, RemovePerks, SupplyHelper, TeamHighlight, diff --git a/src/main/kotlin/me/odinmain/features/impl/dungeon/MapInfo.kt b/src/main/kotlin/me/odinmain/features/impl/dungeon/MapInfo.kt index bc5f63c0b..3bf25b3bb 100644 --- a/src/main/kotlin/me/odinmain/features/impl/dungeon/MapInfo.kt +++ b/src/main/kotlin/me/odinmain/features/impl/dungeon/MapInfo.kt @@ -115,7 +115,8 @@ object MapInfo : Module( return when { score < 270 -> "§c${score}" score < 300 -> "§e${score}" - else -> "§a${score}" + score < 305 -> "§a${score}" + else -> "§b${score}" } } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt index 812747c73..4df6357f7 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt @@ -5,6 +5,7 @@ import me.odinmain.clickgui.settings.impl.BooleanSetting import me.odinmain.clickgui.settings.impl.DropdownSetting import me.odinmain.clickgui.settings.impl.ListSetting import me.odinmain.events.impl.MessageSentEvent +import me.odinmain.events.impl.PacketEvent import me.odinmain.features.Module import me.odinmain.features.impl.dungeon.DungeonRequeue.disableRequeue import me.odinmain.utils.ServerUtils @@ -13,6 +14,7 @@ import me.odinmain.utils.noControlCodes import me.odinmain.utils.runIn import me.odinmain.utils.skyblock.* import net.minecraft.event.ClickEvent +import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.time.ZonedDateTime import java.time.format.DateTimeFormatter @@ -55,6 +57,10 @@ object ChatCommands : Module( private val location by BooleanSetting("Location", false, desc = "Sends your current location.").withDependency { showSettings } private val holding by BooleanSetting("Holding", false, desc = "Sends the item you are holding.").withDependency { showSettings } + private val showExtraStuff by DropdownSetting("Show Extra Stuff", false) + private val noMoreLocraw by BooleanSetting("No More Locraw", false, desc = "Cancel repetitive /locraw commands.").withDependency { showExtraStuff } + + private var locrawSent = false private val dtReason = mutableListOf>() val blacklist: MutableList by ListSetting("Blacklist", mutableListOf()) @@ -88,7 +94,10 @@ object ChatCommands : Module( runIn(5) { handleChatCommands(msg, ign, channel) } } - onWorldLoad { dtReason.clear() } + onWorldLoad { + locrawSent = false + dtReason.clear() + } } private fun handleChatCommands(message: String, name: String, channel: ChatChannel) { @@ -102,6 +111,7 @@ object ChatCommands : Module( ChatChannel.PRIVATE -> mapOf ("coords" to coords, "odin" to odin, "boop" to boop, "cf" to cf, "8ball" to eightball, "dice" to dice, "racism" to racism, "ping" to ping, "tps" to tps, "invite" to invite, "time" to time) } + modMessage(message) // i mean i don't understand, doesn't split sometimes result you an empty list val words = message.drop(1).split(" ").map { it.lowercase() } when (words[0]) { @@ -190,6 +200,17 @@ object ChatCommands : Module( sendChatMessage(words.joinToString(" ")) } + @SubscribeEvent + fun onPacket(event: PacketEvent.Send) { + (event.packet as? C01PacketChatMessage)?.let { + if (!noMoreLocraw || it.message != "/locraw") return + when (locrawSent) { + true -> event.isCanceled = true + else -> locrawSent = true + } + } + } + private val replacements = mapOf( "<3" to "❤", "o/" to "( ゚◡゚)/", diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt new file mode 100644 index 000000000..dd6d20f29 --- /dev/null +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -0,0 +1,53 @@ +package me.odinmain.features.impl.skyblock + +import me.odinmain.clickgui.settings.impl.ListSetting +import me.odinmain.events.impl.ServerTickEvent +import me.odinmain.features.Module +import me.odinmain.utils.render.Colors +import me.odinmain.utils.toFixed +import me.odinmain.utils.ui.drawStringWidth +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.concurrent.CopyOnWriteArrayList + +object Countdowns : Module( + name = "Countdowns", + description = "Starts a countdown in HUD when you receive certain chat messages." // "/countdowns (coming soon)" +) { + private val hud by HUD("Hud", "Displays something i can't tell.", false) { example -> + if (example) { + "Some Timer: 4.30s" + } else { + countdowns.joinToString("\n") { + "§r${it.prefix}${it.time.toFixed(divisor = 20)}" + } + }.let { + if (it.isNotEmpty()) + drawStringWidth(it, 1f, 1f, Colors.WHITE) + 2f to 10f + else + 0f to 0f + } + } + + data class CountdownTrigger(val prefix: String, val time: Int, val message: String) + val countdownTriggers by ListSetting("Countdowns", mutableListOf()) + + private data class Countdown(val prefix: String, var time: Int) + private val countdowns = CopyOnWriteArrayList() + + init { + onMessage(Regex(".*")) { result -> + countdownTriggers.firstOrNull { + it.message == result.value + }?.let { + countdowns.add(Countdown(it.prefix, it.time)) + } + } + } + + @SubscribeEvent + fun onServerTick(event: ServerTickEvent) { + countdowns.removeIf { + --it.time <= 0 + } + } +} diff --git a/src/main/kotlin/me/odinmain/utils/Utils.kt b/src/main/kotlin/me/odinmain/utils/Utils.kt index ac96c372c..01726aeeb 100644 --- a/src/main/kotlin/me/odinmain/utils/Utils.kt +++ b/src/main/kotlin/me/odinmain/utils/Utils.kt @@ -58,6 +58,9 @@ fun String.containsOneOf(options: Collection, ignoreCase: Boolean = fals fun Number.toFixed(decimals: Int = 2): String = "%.${decimals}f".format(Locale.US, this) +fun Number.toFixed(decimals: Int = 2, divisor: Int): String = + "%.${decimals}f".format(Locale.US, this / divisor) + fun String.startsWithOneOf(vararg options: String, ignoreCase: Boolean = false): Boolean = options.any { this.startsWith(it, ignoreCase) } @@ -245,7 +248,7 @@ fun EntityLivingBase?.getSBMaxHealth(): Float { return this?.getEntityAttribute(SharedMonsterAttributes.maxHealth)?.baseValue?.toFloat() ?: 0f } -fun formatNumber(unFormatNumber: Any): String { +fun formatNumber(unFormatNumber: Any): String { // todo: cleanup val number: Double = when (unFormatNumber) { is String -> unFormatNumber.replace(",", "").toDoubleOrNull() ?: 0.0 is Number -> unFormatNumber.toDouble() diff --git a/src/main/kotlin/me/odinmain/utils/skyblock/dungeon/DungeonListener.kt b/src/main/kotlin/me/odinmain/utils/skyblock/dungeon/DungeonListener.kt index fc2109326..3841ff1a7 100644 --- a/src/main/kotlin/me/odinmain/utils/skyblock/dungeon/DungeonListener.kt +++ b/src/main/kotlin/me/odinmain/utils/skyblock/dungeon/DungeonListener.kt @@ -119,7 +119,7 @@ object DungeonListener { "prince killed", "prince slain", "prince killed!", "prince dead", "prince dead!", "\$skytils-dungeon-score-prince\$", Mimic.princeMessage -> dungeonStats.princeKilled = true - "blaze done!", "blaze done", "blaze puzzle solved!" -> + "blaze done!", "blaze done", "blaze puzzle solved!", "blaze puzzle finished!", "blaze finished!" -> puzzles.find { it == Puzzle.BLAZE }.let { it?.status = PuzzleStatus.Completed } } } From e7ebb9632b8ea3601ccfff7bb71552d64515401c Mon Sep 17 00:00:00 2001 From: Fly Date: Tue, 5 Aug 2025 21:40:44 +0800 Subject: [PATCH 02/21] Second --- .../me/odinmain/commands/CommandRegistry.kt | 3 +- .../me/odinmain/commands/impl/Countdowns.kt | 40 +++++++++++++++++++ .../features/impl/dungeon/ExtraStats.kt | 1 + .../features/impl/skyblock/ChatCommands.kt | 7 ++-- .../features/impl/skyblock/Countdowns.kt | 30 +++++++++----- src/main/kotlin/me/odinmain/utils/Utils.kt | 33 +++++++-------- 6 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt diff --git a/src/main/kotlin/me/odinmain/commands/CommandRegistry.kt b/src/main/kotlin/me/odinmain/commands/CommandRegistry.kt index 0ff2a4921..0793ca84f 100644 --- a/src/main/kotlin/me/odinmain/commands/CommandRegistry.kt +++ b/src/main/kotlin/me/odinmain/commands/CommandRegistry.kt @@ -20,7 +20,8 @@ object CommandRegistry { termSimCommand, chatCommandsCommand, devCommand, highlightCommand, waypointCommand, dungeonWaypointsCommand, - petCommand, visualWordsCommand, PosMsgCommand + petCommand, visualWordsCommand, PosMsgCommand, + CountdownsCommand ) fun add(vararg commands: Commodore) { diff --git a/src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt b/src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt new file mode 100644 index 000000000..51b56052b --- /dev/null +++ b/src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt @@ -0,0 +1,40 @@ +package me.odinmain.commands.impl + +import com.github.stivais.commodore.Commodore +import com.github.stivais.commodore.utils.GreedyString +import me.odinmain.config.Config +import me.odinmain.features.impl.skyblock.Countdowns.countdownTriggers +import me.odinmain.features.impl.skyblock.Countdowns.CountdownTrigger +import me.odinmain.utils.skyblock.modMessage +import me.odinmain.utils.toFixed + + +val CountdownsCommand = Commodore("countdowns") { + literal("add").runs { prefix: String, time: Int, message: GreedyString -> + countdownTriggers.add(CountdownTrigger(prefix, time, message.string).takeUnless { it in countdownTriggers } + ?: return@runs modMessage("This message already exists!")) + modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message.string\"") + Config.save() + } + + literal("remove").runs { index: Int -> + if (countdownTriggers.size < index) return@runs modMessage("Theres no countdown trigger in position #$index") + countdownTriggers.removeAt(index - 1) + modMessage("Removed Countdown Trigger #$index") + Config.save() + } + + literal("clear").runs { + countdownTriggers.clear() + modMessage("Cleared List") + Config.save() + } + + literal("list").runs { + var i = 0 + val output = countdownTriggers.joinToString("\n") { + "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, \"${it.message}\"" + } + modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt b/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt index eef1172c5..3dcb63433 100644 --- a/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt +++ b/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt @@ -84,6 +84,7 @@ object ExtraStats : Module( onMessage(Regex("^\\s*(Ally Healing: ([\\d,.]+)\\s?(\\(NEW RECORD!\\))?)\$")) { extraStats.healPB = it.groupValues[3].isNotEmpty() + formatNumber(it.groupValues[2]) extraStats.heal = formatNumber(it.groupValues[2]) + if (extraStats.healPB) "(NEW PB!)" else "" extraStats.combatStats.add("§a${it.groupValues[1]}") } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt index 4df6357f7..845230aa0 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt @@ -204,9 +204,10 @@ object ChatCommands : Module( fun onPacket(event: PacketEvent.Send) { (event.packet as? C01PacketChatMessage)?.let { if (!noMoreLocraw || it.message != "/locraw") return - when (locrawSent) { - true -> event.isCanceled = true - else -> locrawSent = true + if (locrawSent) { + event.isCanceled = true + } else { + locrawSent = true } } } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index dd6d20f29..1fd43906b 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -6,6 +6,7 @@ import me.odinmain.features.Module import me.odinmain.utils.render.Colors import me.odinmain.utils.toFixed import me.odinmain.utils.ui.drawStringWidth +import me.odinmain.utils.ui.getMCTextHeight import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.concurrent.CopyOnWriteArrayList @@ -14,18 +15,21 @@ object Countdowns : Module( description = "Starts a countdown in HUD when you receive certain chat messages." // "/countdowns (coming soon)" ) { private val hud by HUD("Hud", "Displays something i can't tell.", false) { example -> - if (example) { - "Some Timer: 4.30s" - } else { - countdowns.joinToString("\n") { - "§r${it.prefix}${it.time.toFixed(divisor = 20)}" - } - }.let { - if (it.isNotEmpty()) - drawStringWidth(it, 1f, 1f, Colors.WHITE) + 2f to 10f - else - 0f to 0f + if (example) return@HUD drawStringWidth("Some Countdown: 3.50s", 1f, 1f, Colors.WHITE) to 10f + + var w = 1f + var h = 1f + val lineHeight = getMCTextHeight() + + countdowns.forEach { + w = maxOf(w, drawStringWidth( + "§r${it.prefix}${it.time.toFixed(divisor = 20)}", + 1f, w, Colors.WHITE + )) + h += lineHeight } + + if (h == 1f) (0f to 0f) else (w to h) } data class CountdownTrigger(val prefix: String, val time: Int, val message: String) @@ -42,6 +46,10 @@ object Countdowns : Module( countdowns.add(Countdown(it.prefix, it.time)) } } + + onWorldLoad { + countdowns.clear() + } } @SubscribeEvent diff --git a/src/main/kotlin/me/odinmain/utils/Utils.kt b/src/main/kotlin/me/odinmain/utils/Utils.kt index 01726aeeb..f46b9b531 100644 --- a/src/main/kotlin/me/odinmain/utils/Utils.kt +++ b/src/main/kotlin/me/odinmain/utils/Utils.kt @@ -248,24 +248,25 @@ fun EntityLivingBase?.getSBMaxHealth(): Float { return this?.getEntityAttribute(SharedMonsterAttributes.maxHealth)?.baseValue?.toFloat() ?: 0f } -fun formatNumber(unFormatNumber: Any): String { // todo: cleanup - val number: Double = when (unFormatNumber) { - is String -> unFormatNumber.replace(",", "").toDoubleOrNull() ?: 0.0 - is Number -> unFormatNumber.toDouble() - else -> unFormatNumber.toString().toDoubleOrNull() ?: 0.0 - } +private val oneDecimalFormat = DecimalFormat("#.#") - return when { - number.absoluteValue < 1000 -> number.formatOneOrNoDecimal() - number.absoluteValue >= 1_000_000_000 -> (number / 1_000_000_000).formatOneOrNoDecimal()+"B" - number.absoluteValue >= 1_000_000 -> (number / 1_000_000).formatOneOrNoDecimal()+"M" - number.absoluteValue >= 1000 -> (number / 1000).formatOneOrNoDecimal()+"K" - else -> number.toString() - } +fun Number.formatOneOrNoDecimal(): String { + return oneDecimalFormat.format(this) } -private val oneDecimalFormat = DecimalFormat("#.#") +fun formatNumber(number: Number): String { + val number = number.toDouble() + number.absoluteValue.let { + return when { + it >= 1_000_000_000_000 -> (number / 1_000_000_000_000).formatOneOrNoDecimal() + "T" + it >= 1_000_000_000 -> (number / 1_000_000_000).formatOneOrNoDecimal() + "B" + it >= 1_000_000 -> (number / 1_000_000).formatOneOrNoDecimal() + "M" + it >= 1_000 -> (number / 1_000).formatOneOrNoDecimal() + "K" + else -> number.formatOneOrNoDecimal() + } + } +} -fun Double.formatOneOrNoDecimal(): String { - return oneDecimalFormat.format(this) +fun formatNumber(number: String): String{ + return formatNumber(number.replace(",", "").replace(" ", "").toDoubleOrNull() ?: 0.0) } \ No newline at end of file From 0dd376326753df423bb6d19bb7da27b170184df6 Mon Sep 17 00:00:00 2001 From: Fly Date: Tue, 5 Aug 2025 22:15:17 +0800 Subject: [PATCH 03/21] Third --- .../commands/impl/{Countdowns.kt => CountdownsCommand.kt} | 8 +++----- .../me/odinmain/features/impl/skyblock/Countdowns.kt | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) rename src/main/kotlin/me/odinmain/commands/impl/{Countdowns.kt => CountdownsCommand.kt} (86%) diff --git a/src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt similarity index 86% rename from src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt rename to src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index 51b56052b..1d2d67000 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -1,19 +1,17 @@ package me.odinmain.commands.impl import com.github.stivais.commodore.Commodore -import com.github.stivais.commodore.utils.GreedyString import me.odinmain.config.Config import me.odinmain.features.impl.skyblock.Countdowns.countdownTriggers import me.odinmain.features.impl.skyblock.Countdowns.CountdownTrigger import me.odinmain.utils.skyblock.modMessage import me.odinmain.utils.toFixed - val CountdownsCommand = Commodore("countdowns") { - literal("add").runs { prefix: String, time: Int, message: GreedyString -> - countdownTriggers.add(CountdownTrigger(prefix, time, message.string).takeUnless { it in countdownTriggers } + literal("add").runs { prefix: String, time: Int, message: String -> + countdownTriggers.add(CountdownTrigger(prefix, time, message).takeUnless { it in countdownTriggers } ?: return@runs modMessage("This message already exists!")) - modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message.string\"") + modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message\"") Config.save() } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 1fd43906b..ad759bc40 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -24,7 +24,7 @@ object Countdowns : Module( countdowns.forEach { w = maxOf(w, drawStringWidth( "§r${it.prefix}${it.time.toFixed(divisor = 20)}", - 1f, w, Colors.WHITE + 1f, h, Colors.WHITE )) h += lineHeight } From 0c706c39481cdc8e9ef69b1e4cbf10fd3800eedd Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 16:44:10 +0800 Subject: [PATCH 04/21] Forth --- .../commands/impl/CountdownsCommand.kt | 11 +++++++-- .../features/impl/dungeon/ExtraStats.kt | 1 - .../features/impl/skyblock/ChatCommands.kt | 4 +++- .../features/impl/skyblock/Countdowns.kt | 24 ++++++++++++++++--- src/main/kotlin/me/odinmain/utils/Utils.kt | 9 +++++++ 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index 1d2d67000..78b0ffd0f 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -4,17 +4,24 @@ import com.github.stivais.commodore.Commodore import me.odinmain.config.Config import me.odinmain.features.impl.skyblock.Countdowns.countdownTriggers import me.odinmain.features.impl.skyblock.Countdowns.CountdownTrigger +import me.odinmain.utils.addOrNull import me.odinmain.utils.skyblock.modMessage import me.odinmain.utils.toFixed val CountdownsCommand = Commodore("countdowns") { literal("add").runs { prefix: String, time: Int, message: String -> - countdownTriggers.add(CountdownTrigger(prefix, time, message).takeUnless { it in countdownTriggers } - ?: return@runs modMessage("This message already exists!")) + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message)) ?: return@runs modMessage("This thing already exists!") modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message\"") Config.save() } + literal("addregex").runs { prefix: String, time: Int, message: String -> + if (runCatching { Regex(message) }.isFailure) return@runs modMessage("Bad regex!") + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, true, message)) ?: return@runs modMessage("This thing already exists!") + modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by regex \"$message\"") + Config.save() + } + literal("remove").runs { index: Int -> if (countdownTriggers.size < index) return@runs modMessage("Theres no countdown trigger in position #$index") countdownTriggers.removeAt(index - 1) diff --git a/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt b/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt index 3dcb63433..eef1172c5 100644 --- a/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt +++ b/src/main/kotlin/me/odinmain/features/impl/dungeon/ExtraStats.kt @@ -84,7 +84,6 @@ object ExtraStats : Module( onMessage(Regex("^\\s*(Ally Healing: ([\\d,.]+)\\s?(\\(NEW RECORD!\\))?)\$")) { extraStats.healPB = it.groupValues[3].isNotEmpty() - formatNumber(it.groupValues[2]) extraStats.heal = formatNumber(it.groupValues[2]) + if (extraStats.healPB) "(NEW PB!)" else "" extraStats.combatStats.add("§a${it.groupValues[1]}") } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt index 845230aa0..410797f28 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt @@ -111,7 +111,9 @@ object ChatCommands : Module( ChatChannel.PRIVATE -> mapOf ("coords" to coords, "odin" to odin, "boop" to boop, "cf" to cf, "8ball" to eightball, "dice" to dice, "racism" to racism, "ping" to ping, "tps" to tps, "invite" to invite, "time" to time) } - modMessage(message) // i mean i don't understand, doesn't split sometimes result you an empty list + modMessage(message.drop(1)) + modMessage(message.drop(1).length) + modMessage(message.drop(1).split(""))// i mean i don't understand, doesn't split sometimes result you an empty list val words = message.drop(1).split(" ").map { it.lowercase() } when (words[0]) { diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index ad759bc40..b978f29ed 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -1,18 +1,23 @@ package me.odinmain.features.impl.skyblock +import me.odinmain.clickgui.settings.Setting.Companion.withDependency +import me.odinmain.clickgui.settings.impl.ActionSetting +import me.odinmain.clickgui.settings.impl.DropdownSetting import me.odinmain.clickgui.settings.impl.ListSetting import me.odinmain.events.impl.ServerTickEvent import me.odinmain.features.Module +import me.odinmain.utils.addOrNull import me.odinmain.utils.render.Colors import me.odinmain.utils.toFixed import me.odinmain.utils.ui.drawStringWidth import me.odinmain.utils.ui.getMCTextHeight import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.concurrent.CopyOnWriteArrayList +import java.util.regex.PatternSyntaxException object Countdowns : Module( name = "Countdowns", - description = "Starts a countdown in HUD when you receive certain chat messages." // "/countdowns (coming soon)" + description = "Starts a countdown in HUD when you trigger certain chat message, or regex expressions." ) { private val hud by HUD("Hud", "Displays something i can't tell.", false) { example -> if (example) return@HUD drawStringWidth("Some Countdown: 3.50s", 1f, 1f, Colors.WHITE) to 10f @@ -32,16 +37,29 @@ object Countdowns : Module( if (h == 1f) (0f to 0f) else (w to h) } - data class CountdownTrigger(val prefix: String, val time: Int, val message: String) + data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { + @Transient + var realRegex: Regex? = try { + if (regex) Regex(message) else null + } catch(e: PatternSyntaxException) { // it refused to work + null + } + } val countdownTriggers by ListSetting("Countdowns", mutableListOf()) + private val presetsDropdown by DropdownSetting("Add Presets") + private val presetQuiz by ActionSetting("Quiz", desc = "wtf") { + countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 240, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) + countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 164, true, "[STATUE] Oruo the Omniscient: FlyMode answered Question #2 correctly!")) + }.withDependency { presetsDropdown } + private data class Countdown(val prefix: String, var time: Int) private val countdowns = CopyOnWriteArrayList() init { onMessage(Regex(".*")) { result -> countdownTriggers.firstOrNull { - it.message == result.value + if (it.regex) (it.realRegex?.let { regex -> result.value.matches(regex) } ?: false) else (it.message == result.value) }?.let { countdowns.add(Countdown(it.prefix, it.time)) } diff --git a/src/main/kotlin/me/odinmain/utils/Utils.kt b/src/main/kotlin/me/odinmain/utils/Utils.kt index f46b9b531..de03d94ca 100644 --- a/src/main/kotlin/me/odinmain/utils/Utils.kt +++ b/src/main/kotlin/me/odinmain/utils/Utils.kt @@ -234,6 +234,15 @@ inline fun MutableCollection.removeFirstOrNull(predicate: (T) -> Boolean) return first } +fun MutableList.addOrNull(element: T): T? { + return if (element in this) { + null + } else { + this.add(element) + element + } +} + fun Int.addRange(add: Int): IntRange = this..this+add fun runOnMCThread(run: () -> Unit) { From a7e700c8cc111a87f524b6648aca3812bb0538cd Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 17:55:19 +0800 Subject: [PATCH 05/21] Fifth --- .../me/odinmain/commands/impl/CountdownsCommand.kt | 13 +++++++------ .../odinmain/features/impl/skyblock/ChatCommands.kt | 3 --- .../odinmain/features/impl/skyblock/Countdowns.kt | 6 +++--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index 78b0ffd0f..b454b3ac1 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -1,6 +1,7 @@ package me.odinmain.commands.impl import com.github.stivais.commodore.Commodore +import com.github.stivais.commodore.utils.GreedyString import me.odinmain.config.Config import me.odinmain.features.impl.skyblock.Countdowns.countdownTriggers import me.odinmain.features.impl.skyblock.Countdowns.CountdownTrigger @@ -9,15 +10,15 @@ import me.odinmain.utils.skyblock.modMessage import me.odinmain.utils.toFixed val CountdownsCommand = Commodore("countdowns") { - literal("add").runs { prefix: String, time: Int, message: String -> - countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message)) ?: return@runs modMessage("This thing already exists!") + literal("add").runs { prefix: String, time: Int, message: GreedyString -> + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message.string)) ?: return@runs modMessage("This thing already exists!") modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message\"") Config.save() } - literal("addregex").runs { prefix: String, time: Int, message: String -> - if (runCatching { Regex(message) }.isFailure) return@runs modMessage("Bad regex!") - countdownTriggers.addOrNull(CountdownTrigger(prefix, time, true, message)) ?: return@runs modMessage("This thing already exists!") + literal("addregex").runs { prefix: String, time: Int, message: GreedyString -> + if (runCatching { Regex(message.string) }.isFailure) return@runs modMessage("Bad regex!") + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, true, message.string)) ?: return@runs modMessage("This thing already exists!") modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by regex \"$message\"") Config.save() } @@ -38,7 +39,7 @@ val CountdownsCommand = Commodore("countdowns") { literal("list").runs { var i = 0 val output = countdownTriggers.joinToString("\n") { - "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, \"${it.message}\"" + "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt index 410797f28..21a8f7a7e 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/ChatCommands.kt @@ -111,9 +111,6 @@ object ChatCommands : Module( ChatChannel.PRIVATE -> mapOf ("coords" to coords, "odin" to odin, "boop" to boop, "cf" to cf, "8ball" to eightball, "dice" to dice, "racism" to racism, "ping" to ping, "tps" to tps, "invite" to invite, "time" to time) } - modMessage(message.drop(1)) - modMessage(message.drop(1).length) - modMessage(message.drop(1).split(""))// i mean i don't understand, doesn't split sometimes result you an empty list val words = message.drop(1).split(" ").map { it.lowercase() } when (words[0]) { diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index b978f29ed..41d2d1275 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -41,7 +41,7 @@ object Countdowns : Module( @Transient var realRegex: Regex? = try { if (regex) Regex(message) else null - } catch(e: PatternSyntaxException) { // it refused to work + } catch(e: PatternSyntaxException) { // it refuses to work null } } @@ -49,8 +49,8 @@ object Countdowns : Module( private val presetsDropdown by DropdownSetting("Add Presets") private val presetQuiz by ActionSetting("Quiz", desc = "wtf") { - countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 240, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) - countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 164, true, "[STATUE] Oruo the Omniscient: FlyMode answered Question #2 correctly!")) + countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 220, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) + countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 140, true, "\\[STATUE\\] Oruo the Omniscient: \\w{1,16} answered Question #[12] correctly!")) }.withDependency { presetsDropdown } private data class Countdown(val prefix: String, var time: Int) From a5e8fd260fda2c94617d7a322b87450dd341c013 Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 19:12:11 +0800 Subject: [PATCH 06/21] thingy --- .../kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 41d2d1275..f2b7e9ee2 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -40,8 +40,10 @@ object Countdowns : Module( data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { @Transient var realRegex: Regex? = try { + print(message) if (regex) Regex(message) else null } catch(e: PatternSyntaxException) { // it refuses to work + print(false) null } } From 0e136951452898c039b22c4b80913a4db29abd92 Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 19:42:14 +0800 Subject: [PATCH 07/21] thingy --- src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index b454b3ac1..b2010266a 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -39,7 +39,7 @@ val CountdownsCommand = Commodore("countdowns") { literal("list").runs { var i = 0 val output = countdownTriggers.joinToString("\n") { - "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" + "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\", $it.realRegex" } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } From b36fcf51cfcf751c8ccda450e021019fe503290a Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 20:00:48 +0800 Subject: [PATCH 08/21] thingy --- .../features/impl/skyblock/Countdowns.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index f2b7e9ee2..049bc6bab 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -8,6 +8,7 @@ import me.odinmain.events.impl.ServerTickEvent import me.odinmain.features.Module import me.odinmain.utils.addOrNull import me.odinmain.utils.render.Colors +import me.odinmain.utils.skyblock.modMessage import me.odinmain.utils.toFixed import me.odinmain.utils.ui.drawStringWidth import me.odinmain.utils.ui.getMCTextHeight @@ -38,13 +39,20 @@ object Countdowns : Module( } data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { - @Transient - var realRegex: Regex? = try { - print(message) - if (regex) Regex(message) else null - } catch(e: PatternSyntaxException) { // it refuses to work - print(false) - null + val a = modMessage("wtf? created") + @delegate:Transient + val realRegex: Regex? by lazy { + if (regex) { + try { + modMessage("Recompiling regex for message: $message") + Regex(message) + } catch (e: PatternSyntaxException) { + modMessage("Bad regex for message: $message") + null + } + } else { + null + } } } val countdownTriggers by ListSetting("Countdowns", mutableListOf()) From 32852a13f16af8002ad0b2bd6a6a4bf3b0d6e324 Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 20:13:08 +0800 Subject: [PATCH 09/21] thingy --- .../features/impl/skyblock/Countdowns.kt | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 049bc6bab..45def1488 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -40,19 +40,17 @@ object Countdowns : Module( data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { val a = modMessage("wtf? created") - @delegate:Transient - val realRegex: Regex? by lazy { - if (regex) { - try { - modMessage("Recompiling regex for message: $message") - Regex(message) - } catch (e: PatternSyntaxException) { - modMessage("Bad regex for message: $message") - null - } - } else { + @Transient + val realRegex: Regex? = if (regex) { + try { + modMessage("Recompiling regex for message: $message") + Regex(message) + } catch (e: PatternSyntaxException) { + modMessage("Bad regex for message: $message") null } + } else { + null } } val countdownTriggers by ListSetting("Countdowns", mutableListOf()) From 53c37138998e0c1699a7aa4b9607aae07eaecbbe Mon Sep 17 00:00:00 2001 From: Fly Date: Wed, 6 Aug 2025 23:03:02 +0800 Subject: [PATCH 10/21] thingy --- .../features/impl/skyblock/Countdowns.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 45def1488..bbe8ff338 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -1,5 +1,6 @@ package me.odinmain.features.impl.skyblock + import me.odinmain.clickgui.settings.Setting.Companion.withDependency import me.odinmain.clickgui.settings.impl.ActionSetting import me.odinmain.clickgui.settings.impl.DropdownSetting @@ -8,7 +9,6 @@ import me.odinmain.events.impl.ServerTickEvent import me.odinmain.features.Module import me.odinmain.utils.addOrNull import me.odinmain.utils.render.Colors -import me.odinmain.utils.skyblock.modMessage import me.odinmain.utils.toFixed import me.odinmain.utils.ui.drawStringWidth import me.odinmain.utils.ui.getMCTextHeight @@ -39,14 +39,11 @@ object Countdowns : Module( } data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { - val a = modMessage("wtf? created") @Transient - val realRegex: Regex? = if (regex) { + var realRegex: Regex? = if (regex) { try { - modMessage("Recompiling regex for message: $message") Regex(message) } catch (e: PatternSyntaxException) { - modMessage("Bad regex for message: $message") null } } else { @@ -65,6 +62,16 @@ object Countdowns : Module( private val countdowns = CopyOnWriteArrayList() init { + countdownTriggers.forEach{ it.realRegex = if (it.regex) { + try { + Regex(it.message) + } catch (e: PatternSyntaxException) { + null + } + } else { + null + }} + onMessage(Regex(".*")) { result -> countdownTriggers.firstOrNull { if (it.regex) (it.realRegex?.let { regex -> result.value.matches(regex) } ?: false) else (it.message == result.value) From 7c70ac82f7ffa3413584d1fc39f7ab3500b3bf0f Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 01:37:33 +0800 Subject: [PATCH 11/21] thingy!! --- .../clickgui/settings/impl/ListSetting.kt | 29 +++++++++++++++++-- .../features/impl/skyblock/Countdowns.kt | 16 ++-------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt index 7ff347719..94496ecfc 100644 --- a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt +++ b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt @@ -11,10 +11,10 @@ import java.lang.reflect.Type * * @author Stivais */ -class ListSetting>( +open class ListSetting>( name: String, override val default: T, - private val type: Type + protected val type: Type, ) : Setting(name, description = ""), Saving { override var value: T = default @@ -33,4 +33,27 @@ class ListSetting>( inline fun > ListSetting( name: String, default: T, -): ListSetting = ListSetting(name, default, object : TypeToken() {}.type) \ No newline at end of file +): ListSetting = ListSetting(name, default, object : TypeToken() {}.type) + + +class ListSettingWithReload>( + name: String, + default: T, + type: Type, + private val reconstructor: (E) -> E +) : ListSetting(name, default, type) { + + override fun read(element: JsonElement?) { + element?.asJsonArray?.let { + val temp = gson.fromJson(it, type) + value.clear() + value.addAll(temp.map(reconstructor)) + } + } +} + +inline fun > ListSettingWithReload( + name: String, + default: T, + noinline reconstructor: (E) -> E +): ListSettingWithReload = ListSettingWithReload(name, default, object : TypeToken() {}.type, reconstructor) \ No newline at end of file diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index bbe8ff338..e2afc837d 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -4,7 +4,7 @@ package me.odinmain.features.impl.skyblock import me.odinmain.clickgui.settings.Setting.Companion.withDependency import me.odinmain.clickgui.settings.impl.ActionSetting import me.odinmain.clickgui.settings.impl.DropdownSetting -import me.odinmain.clickgui.settings.impl.ListSetting +import me.odinmain.clickgui.settings.impl.ListSettingWithReload import me.odinmain.events.impl.ServerTickEvent import me.odinmain.features.Module import me.odinmain.utils.addOrNull @@ -50,10 +50,10 @@ object Countdowns : Module( null } } - val countdownTriggers by ListSetting("Countdowns", mutableListOf()) + val countdownTriggers by ListSettingWithReload("Countdowns", mutableListOf()) { it.copy() } private val presetsDropdown by DropdownSetting("Add Presets") - private val presetQuiz by ActionSetting("Quiz", desc = "wtf") { + private val presetQuiz by ActionSetting("Quiz", desc = "Quiz puzzle in dungeons.") { countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 220, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 140, true, "\\[STATUE\\] Oruo the Omniscient: \\w{1,16} answered Question #[12] correctly!")) }.withDependency { presetsDropdown } @@ -62,16 +62,6 @@ object Countdowns : Module( private val countdowns = CopyOnWriteArrayList() init { - countdownTriggers.forEach{ it.realRegex = if (it.regex) { - try { - Regex(it.message) - } catch (e: PatternSyntaxException) { - null - } - } else { - null - }} - onMessage(Regex(".*")) { result -> countdownTriggers.firstOrNull { if (it.regex) (it.realRegex?.let { regex -> result.value.matches(regex) } ?: false) else (it.message == result.value) From 320a513a1b454cda0e8de6c415286f69f8ec0247 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 01:54:30 +0800 Subject: [PATCH 12/21] thingy!! --- .../clickgui/settings/impl/ListSetting.kt | 37 ++++--------------- .../commands/impl/CountdownsCommand.kt | 2 +- .../features/impl/skyblock/Countdowns.kt | 4 +- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt index 94496ecfc..7082626d9 100644 --- a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt +++ b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt @@ -11,10 +11,11 @@ import java.lang.reflect.Type * * @author Stivais */ -open class ListSetting>( +class ListSetting>( name: String, override val default: T, - protected val type: Type, + private val type: Type, + private val reloader: ((E) -> E)? = null ) : Setting(name, description = ""), Saving { override var value: T = default @@ -22,10 +23,10 @@ open class ListSetting>( override fun write(): JsonElement = gson.toJsonTree(value) override fun read(element: JsonElement?) { - element?.asJsonArray?.let { - val temp = gson.fromJson(it, type) + element?.asJsonArray?.let { ja -> + val temp = gson.fromJson(ja, type) value.clear() - value.addAll(temp) + value.addAll(reloader?.let{ temp.map(it) } ?: temp) } } } @@ -33,27 +34,5 @@ open class ListSetting>( inline fun > ListSetting( name: String, default: T, -): ListSetting = ListSetting(name, default, object : TypeToken() {}.type) - - -class ListSettingWithReload>( - name: String, - default: T, - type: Type, - private val reconstructor: (E) -> E -) : ListSetting(name, default, type) { - - override fun read(element: JsonElement?) { - element?.asJsonArray?.let { - val temp = gson.fromJson(it, type) - value.clear() - value.addAll(temp.map(reconstructor)) - } - } -} - -inline fun > ListSettingWithReload( - name: String, - default: T, - noinline reconstructor: (E) -> E -): ListSettingWithReload = ListSettingWithReload(name, default, object : TypeToken() {}.type, reconstructor) \ No newline at end of file + noinline reloader: ((E) -> E)? = null +): ListSetting = ListSetting(name, default, object : TypeToken() {}.type, reloader) \ No newline at end of file diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index b2010266a..b454b3ac1 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -39,7 +39,7 @@ val CountdownsCommand = Commodore("countdowns") { literal("list").runs { var i = 0 val output = countdownTriggers.joinToString("\n") { - "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\", $it.realRegex" + "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index e2afc837d..feaa8b33f 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -4,7 +4,7 @@ package me.odinmain.features.impl.skyblock import me.odinmain.clickgui.settings.Setting.Companion.withDependency import me.odinmain.clickgui.settings.impl.ActionSetting import me.odinmain.clickgui.settings.impl.DropdownSetting -import me.odinmain.clickgui.settings.impl.ListSettingWithReload +import me.odinmain.clickgui.settings.impl.ListSetting import me.odinmain.events.impl.ServerTickEvent import me.odinmain.features.Module import me.odinmain.utils.addOrNull @@ -50,7 +50,7 @@ object Countdowns : Module( null } } - val countdownTriggers by ListSettingWithReload("Countdowns", mutableListOf()) { it.copy() } + val countdownTriggers by ListSetting("Countdowns", mutableListOf()) { it.copy() } private val presetsDropdown by DropdownSetting("Add Presets") private val presetQuiz by ActionSetting("Quiz", desc = "Quiz puzzle in dungeons.") { From 7e9e1bdb6e2dac8901639b876dfb2fd420a62273 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 02:03:34 +0800 Subject: [PATCH 13/21] thingy!! --- .../me/odinmain/clickgui/settings/impl/ListSetting.kt | 2 +- .../kotlin/me/odinmain/commands/impl/CountdownsCommand.kt | 2 +- .../kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt | 6 +----- src/main/kotlin/me/odinmain/utils/Utils.kt | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt index 7082626d9..b2dd84591 100644 --- a/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt +++ b/src/main/kotlin/me/odinmain/clickgui/settings/impl/ListSetting.kt @@ -35,4 +35,4 @@ inline fun > ListSetting( name: String, default: T, noinline reloader: ((E) -> E)? = null -): ListSetting = ListSetting(name, default, object : TypeToken() {}.type, reloader) \ No newline at end of file +): ListSetting = ListSetting(name, default, object : TypeToken() {}.type, reloader) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index b454b3ac1..4125249d0 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -43,4 +43,4 @@ val CountdownsCommand = Commodore("countdowns") { } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } -} \ No newline at end of file +} diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index feaa8b33f..71d56aa85 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -41,11 +41,7 @@ object Countdowns : Module( data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { @Transient var realRegex: Regex? = if (regex) { - try { - Regex(message) - } catch (e: PatternSyntaxException) { - null - } + runCatching { Regex(message) }.getOrNull() } else { null } diff --git a/src/main/kotlin/me/odinmain/utils/Utils.kt b/src/main/kotlin/me/odinmain/utils/Utils.kt index de03d94ca..5a6fa860f 100644 --- a/src/main/kotlin/me/odinmain/utils/Utils.kt +++ b/src/main/kotlin/me/odinmain/utils/Utils.kt @@ -278,4 +278,4 @@ fun formatNumber(number: Number): String { fun formatNumber(number: String): String{ return formatNumber(number.replace(",", "").replace(" ", "").toDoubleOrNull() ?: 0.0) -} \ No newline at end of file +} From 0f93bf0f4b7af6324ff03cbb34714729e85cfe97 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 14:19:58 +0800 Subject: [PATCH 14/21] more thingy --- .../commands/impl/CountdownsCommand.kt | 34 ++++++++++++------- .../features/impl/skyblock/Countdowns.kt | 8 +++-- src/main/kotlin/me/odinmain/utils/Utils.kt | 14 ++++---- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index 4125249d0..87403b77f 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -11,23 +11,34 @@ import me.odinmain.utils.toFixed val CountdownsCommand = Commodore("countdowns") { literal("add").runs { prefix: String, time: Int, message: GreedyString -> - countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message.string)) ?: return@runs modMessage("This thing already exists!") + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message.string)) + ?: return@runs modMessage("This thing already exists!") modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message\"") Config.save() } literal("addregex").runs { prefix: String, time: Int, message: GreedyString -> - if (runCatching { Regex(message.string) }.isFailure) return@runs modMessage("Bad regex!") - countdownTriggers.addOrNull(CountdownTrigger(prefix, time, true, message.string)) ?: return@runs modMessage("This thing already exists!") - modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by regex \"$message\"") - Config.save() + runCatching { + Regex(message.string) + }.onSuccess { + countdownTriggers.addOrNull(CountdownTrigger(prefix, time, true, message.string)) + ?: return@runs modMessage("This thing already exists!") + modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by regex \"$message\"") + Config.save() + }.onFailure { + modMessage("Bad regex!") + } } literal("remove").runs { index: Int -> - if (countdownTriggers.size < index) return@runs modMessage("Theres no countdown trigger in position #$index") - countdownTriggers.removeAt(index - 1) - modMessage("Removed Countdown Trigger #$index") - Config.save() + runCatching { + countdownTriggers.removeAt(index) + }.onSuccess { + modMessage("Removed Countdown Trigger #$index") + Config.save() + }.onFailure { + modMessage("Theres no countdown trigger in position #$index") + } } literal("clear").runs { @@ -37,9 +48,8 @@ val CountdownsCommand = Commodore("countdowns") { } literal("list").runs { - var i = 0 - val output = countdownTriggers.joinToString("\n") { - "${++i}: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" + val output = countdownTriggers.withIndex().joinToString("\n") { (i, it) -> + "$i: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 71d56aa85..26ca2c6ae 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -14,7 +14,6 @@ import me.odinmain.utils.ui.drawStringWidth import me.odinmain.utils.ui.getMCTextHeight import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.concurrent.CopyOnWriteArrayList -import java.util.regex.PatternSyntaxException object Countdowns : Module( name = "Countdowns", @@ -22,6 +21,7 @@ object Countdowns : Module( ) { private val hud by HUD("Hud", "Displays something i can't tell.", false) { example -> if (example) return@HUD drawStringWidth("Some Countdown: 3.50s", 1f, 1f, Colors.WHITE) to 10f + if (countdowns.isEmpty()) return@HUD 0f to 0f var w = 1f var h = 1f @@ -35,7 +35,7 @@ object Countdowns : Module( h += lineHeight } - if (h == 1f) (0f to 0f) else (w to h) + w to h } data class CountdownTrigger(val prefix: String, val time: Int, val regex: Boolean, val message: String) { @@ -53,6 +53,10 @@ object Countdowns : Module( countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 220, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 140, true, "\\[STATUE\\] Oruo the Omniscient: \\w{1,16} answered Question #[12] correctly!")) }.withDependency { presetsDropdown } + private val presetEndIsland by ActionSetting("End Island", desc = "Endstone & Dragon Protector spawn.") { + countdownTriggers.addOrNull(CountdownTrigger("§eEndstone Protector: §f", 400, false, "The ground begins to shake as an Endstone Protector rises from below!")) + countdownTriggers.addOrNull(CountdownTrigger("§eDragon: §f", 174, true, "☬ \\w{1,16} placed a Summoning Eye! Brace yourselves! \\(8/8\\)")) + }.withDependency { presetsDropdown } private data class Countdown(val prefix: String, var time: Int) private val countdowns = CopyOnWriteArrayList() diff --git a/src/main/kotlin/me/odinmain/utils/Utils.kt b/src/main/kotlin/me/odinmain/utils/Utils.kt index 5a6fa860f..08707cd2d 100644 --- a/src/main/kotlin/me/odinmain/utils/Utils.kt +++ b/src/main/kotlin/me/odinmain/utils/Utils.kt @@ -265,14 +265,12 @@ fun Number.formatOneOrNoDecimal(): String { fun formatNumber(number: Number): String { val number = number.toDouble() - number.absoluteValue.let { - return when { - it >= 1_000_000_000_000 -> (number / 1_000_000_000_000).formatOneOrNoDecimal() + "T" - it >= 1_000_000_000 -> (number / 1_000_000_000).formatOneOrNoDecimal() + "B" - it >= 1_000_000 -> (number / 1_000_000).formatOneOrNoDecimal() + "M" - it >= 1_000 -> (number / 1_000).formatOneOrNoDecimal() + "K" - else -> number.formatOneOrNoDecimal() - } + return when { + number.absoluteValue >= 1_000_000_000_000 -> (number / 1_000_000_000_000).formatOneOrNoDecimal() + "T" + number.absoluteValue >= 1_000_000_000 -> (number / 1_000_000_000).formatOneOrNoDecimal() + "B" + number.absoluteValue >= 1_000_000 -> (number / 1_000_000).formatOneOrNoDecimal() + "M" + number.absoluteValue >= 1_000 -> (number / 1_000).formatOneOrNoDecimal() + "K" + else -> number.formatOneOrNoDecimal() } } From f9620189672b9c27c850b15ecfb1151e58b50c23 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 22:16:56 +0800 Subject: [PATCH 15/21] fix thingy --- .../kotlin/me/odinmain/clickgui/settings/impl/HUDSetting.kt | 4 ++-- src/main/kotlin/me/odinmain/events/EventDispatcher.kt | 2 +- src/main/kotlin/me/odinmain/features/Module.kt | 3 ++- .../kotlin/me/odinmain/features/impl/dungeon/SpiritBear.kt | 2 +- .../kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/me/odinmain/clickgui/settings/impl/HUDSetting.kt b/src/main/kotlin/me/odinmain/clickgui/settings/impl/HUDSetting.kt index cca21ddda..1c5b4809b 100644 --- a/src/main/kotlin/me/odinmain/clickgui/settings/impl/HUDSetting.kt +++ b/src/main/kotlin/me/odinmain/clickgui/settings/impl/HUDSetting.kt @@ -24,8 +24,8 @@ class HUDSetting( val module: Module, ) : RenderableSetting(name, description), Saving { - constructor(name: String, x: Float, y: Float, scale: Float, toggleable: Boolean, description: String, module: Module, draw: (Boolean) -> Pair) - : this(name, HudElement(x, y, scale, toggleable, draw), toggleable, description, module) + constructor(name: String, x: Float, y: Float, scale: Float, default: Boolean, toggleable: Boolean, description: String, module: Module, draw: (Boolean) -> Pair) + : this(name, HudElement(x, y, scale, default, draw), toggleable, description, module) override val default: HudElement = hud override var value: HudElement = default diff --git a/src/main/kotlin/me/odinmain/events/EventDispatcher.kt b/src/main/kotlin/me/odinmain/events/EventDispatcher.kt index f160bebd9..b0c84df67 100644 --- a/src/main/kotlin/me/odinmain/events/EventDispatcher.kt +++ b/src/main/kotlin/me/odinmain/events/EventDispatcher.kt @@ -48,7 +48,7 @@ object EventDispatcher { if (event.packet is S29PacketSoundEffect && inDungeons && !inBoss && (event.packet.soundName.equalsOneOf("mob.bat.hurt", "mob.bat.death") && event.packet.volume == 0.1f)) SecretPickupEvent.Bat(event.packet).postAndCatch() - if (event.packet is S02PacketChat && ChatPacketEvent(event.packet.chatComponent.unformattedText.noControlCodes).postAndCatch()) + if (event.packet is S02PacketChat && event.packet.isChat && ChatPacketEvent(event.packet.chatComponent.unformattedText.noControlCodes).postAndCatch()) event.isCanceled = true } diff --git a/src/main/kotlin/me/odinmain/features/Module.kt b/src/main/kotlin/me/odinmain/features/Module.kt index 01635f30e..7888e7d36 100644 --- a/src/main/kotlin/me/odinmain/features/Module.kt +++ b/src/main/kotlin/me/odinmain/features/Module.kt @@ -104,12 +104,13 @@ abstract class Module( fun HUD( name: String, desc: String, + default: Boolean = true, toggleable: Boolean = true, x: Float = 10f, y: Float = 10f, scale: Float = 2f, block: (example: Boolean) -> Pair - ): HUDSetting = HUDSetting(name, x, y, scale, toggleable, desc, this, block) + ): HUDSetting = HUDSetting(name, x, y, scale, default, toggleable, desc, this, block) /** * Helper function to make cleaner code, and better performance, since we don't need multiple registers for packet received events. diff --git a/src/main/kotlin/me/odinmain/features/impl/dungeon/SpiritBear.kt b/src/main/kotlin/me/odinmain/features/impl/dungeon/SpiritBear.kt index 9610f4467..c27cc4baf 100644 --- a/src/main/kotlin/me/odinmain/features/impl/dungeon/SpiritBear.kt +++ b/src/main/kotlin/me/odinmain/features/impl/dungeon/SpiritBear.kt @@ -15,7 +15,7 @@ object SpiritBear : Module( name = "Spirit Bear", description = "Displays the current state of Spirit Bear." ) { - private val hud by HUD("Hud", "Displays the current state of Spirit Bear in the HUD.", false) { example -> + private val hud by HUD("Hud", "Displays the current state of Spirit Bear in the HUD.", toggleable = false) { example -> when { example -> "§e1.45s" !DungeonUtils.isFloor(4) || !DungeonUtils.inBoss -> null diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 26ca2c6ae..93d04bcc4 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -19,7 +19,7 @@ object Countdowns : Module( name = "Countdowns", description = "Starts a countdown in HUD when you trigger certain chat message, or regex expressions." ) { - private val hud by HUD("Hud", "Displays something i can't tell.", false) { example -> + private val hud by HUD("Hud", "Displays something i can't tell.", toggleable = false) { example -> if (example) return@HUD drawStringWidth("Some Countdown: 3.50s", 1f, 1f, Colors.WHITE) to 10f if (countdowns.isEmpty()) return@HUD 0f to 0f From 09a7247620613f5d322706a2e2caa4543efda771 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 23:24:31 +0800 Subject: [PATCH 16/21] final thingy --- .../odinmain/commands/impl/CountdownsCommand.kt | 6 ++++-- .../me/odinmain/commands/impl/DevCommand.kt | 16 ++++++++++++++-- .../me/odinmain/commands/impl/OdinCommand.kt | 1 + .../features/impl/skyblock/Countdowns.kt | 7 +++++-- .../me/odinmain/utils/skyblock/PartyUtils.kt | 6 +++++- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt index 87403b77f..43477d914 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/CountdownsCommand.kt @@ -11,13 +11,15 @@ import me.odinmain.utils.toFixed val CountdownsCommand = Commodore("countdowns") { literal("add").runs { prefix: String, time: Int, message: GreedyString -> - countdownTriggers.addOrNull(CountdownTrigger(prefix, time, false, message.string)) + val prefix = prefix.replace("&", "§") + countdownTriggers.addOrNull(CountdownTrigger(prefix.replace("&", "§"), time, false, message.string)) ?: return@runs modMessage("This thing already exists!") modMessage("$prefix${time.toFixed(divisor = 20)}, Triggers by \"$message\"") Config.save() } literal("addregex").runs { prefix: String, time: Int, message: GreedyString -> + val prefix = prefix.replace("&", "§") runCatching { Regex(message.string) }.onSuccess { @@ -49,7 +51,7 @@ val CountdownsCommand = Commodore("countdowns") { literal("list").runs { val output = countdownTriggers.withIndex().joinToString("\n") { (i, it) -> - "$i: ${it.prefix}${it.time.toFixed(divisor = 20)}, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" + "$i: ${it.prefix}${it.time.toFixed(divisor = 20)}&r, ${if (it.regex) "regex" else "normal"} \"${it.message}\"" } modMessage(if (countdownTriggers.isEmpty()) "The list is empty!" else "Countdown Trigger list:\n$output") } diff --git a/src/main/kotlin/me/odinmain/commands/impl/DevCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/DevCommand.kt index 28cf61343..33dd932c2 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/DevCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/DevCommand.kt @@ -155,8 +155,20 @@ val devCommand = Commodore("oddev") { """.trimIndent(), "") } - literal("party").runs { - modMessage("${PartyUtils.isInParty}, ${PartyUtils.partyLeader}, ${PartyUtils.partyMembers}") + literal("party"){ + runs { + modMessage("${PartyUtils.isInParty}, ${PartyUtils.partyLeader}, ${PartyUtils.partyMembers}") + } + + literal("forceInParty").runs { + PartyUtils.forceInParty = !PartyUtils.forceInParty + modMessage("forceInParty is now: $PartyUtils.forceInParty") + } + + literal("forceIsLeader").runs { + PartyUtils.forceIsLeader = !PartyUtils.forceIsLeader + modMessage("forceIsLeader is now: $PartyUtils.forceIsLeader") + } } literal("simulate").runs { str: GreedyString -> diff --git a/src/main/kotlin/me/odinmain/commands/impl/OdinCommand.kt b/src/main/kotlin/me/odinmain/commands/impl/OdinCommand.kt index 659457b24..12a2a15cb 100644 --- a/src/main/kotlin/me/odinmain/commands/impl/OdinCommand.kt +++ b/src/main/kotlin/me/odinmain/commands/impl/OdinCommand.kt @@ -70,6 +70,7 @@ val mainCommand = Commodore("od", "odin") { §3- /posmsg §7» §8Position message command. §3- /chatclist §7» §8Used to configure your blacklist/whitelist. §3- /highlight §7» §8Used to configure Highlight list. + §3- /countdowns §7» §8Make custom countdowns by chat triggers. §3- /waypoint §7» §8Configure waypoints. §3- /termsim ? §7» §8Simulates terminals so you can practice them. §3- /od rq §7» §8Requeues dungeon run. diff --git a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt index 93d04bcc4..9d59e5f84 100644 --- a/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt +++ b/src/main/kotlin/me/odinmain/features/impl/skyblock/Countdowns.kt @@ -49,14 +49,17 @@ object Countdowns : Module( val countdownTriggers by ListSetting("Countdowns", mutableListOf()) { it.copy() } private val presetsDropdown by DropdownSetting("Add Presets") - private val presetQuiz by ActionSetting("Quiz", desc = "Quiz puzzle in dungeons.") { + private val presetQuiz by ActionSetting("Quiz", desc = "Quiz puzzle in dungeons. (2)") { countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 220, false, "[STATUE] Oruo the Omniscient: I am Oruo the Omniscient. I have lived many lives. I have learned all there is to know.")) countdownTriggers.addOrNull(CountdownTrigger("§eQuiz: §f", 140, true, "\\[STATUE\\] Oruo the Omniscient: \\w{1,16} answered Question #[12] correctly!")) }.withDependency { presetsDropdown } - private val presetEndIsland by ActionSetting("End Island", desc = "Endstone & Dragon Protector spawn.") { + private val presetEndIsland by ActionSetting("End Island", desc = "Endstone & Dragon Protector spawn. (2)") { countdownTriggers.addOrNull(CountdownTrigger("§eEndstone Protector: §f", 400, false, "The ground begins to shake as an Endstone Protector rises from below!")) countdownTriggers.addOrNull(CountdownTrigger("§eDragon: §f", 174, true, "☬ \\w{1,16} placed a Summoning Eye! Brace yourselves! \\(8/8\\)")) }.withDependency { presetsDropdown } + private val presetM3FireFreeze by ActionSetting("M3 Fire Freeze", desc = "The Professor. (1)") { + countdownTriggers.addOrNull(CountdownTrigger("§eFire Freeze: §f", 106, false, "[BOSS] The Professor: Oh? You found my Guardians' one weakness?")) + }.withDependency { presetsDropdown } private data class Countdown(val prefix: String, var time: Int) private val countdowns = CopyOnWriteArrayList() diff --git a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt index 5a950ed6e..f557a656d 100644 --- a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt +++ b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt @@ -35,6 +35,9 @@ object PartyUtils { Regex("^You are not currently in a party.$") ) + var forceInParty = false + var forceIsLeader = false + private val members = mutableListOf() var partyLeader: String? = null @@ -44,6 +47,7 @@ object PartyUtils { var isInParty: Boolean = false private set + get() = (forceInParty || field) @SubscribeEvent fun onChatPacket(event: ChatPacketEvent) = with(event.message) { @@ -154,5 +158,5 @@ object PartyUtils { isInParty = false } - fun isLeader(): Boolean = partyLeader == mc.thePlayer.name + fun isLeader(): Boolean = (forceIsLeader || partyLeader == mc.thePlayer.name) } \ No newline at end of file From 39be541c1c7c516f27ed581bdd204c18ee97aee0 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 23:53:36 +0800 Subject: [PATCH 17/21] re build cuz broken --- src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt index f557a656d..ec7739daf 100644 --- a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt +++ b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt @@ -159,4 +159,4 @@ object PartyUtils { } fun isLeader(): Boolean = (forceIsLeader || partyLeader == mc.thePlayer.name) -} \ No newline at end of file +} From 0e776cac4993f124202a8a1bc64dc9b0131cf532 Mon Sep 17 00:00:00 2001 From: Fly Date: Thu, 7 Aug 2025 23:58:48 +0800 Subject: [PATCH 18/21] re build cuz broken --- src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt index ec7739daf..f557a656d 100644 --- a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt +++ b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt @@ -159,4 +159,4 @@ object PartyUtils { } fun isLeader(): Boolean = (forceIsLeader || partyLeader == mc.thePlayer.name) -} +} \ No newline at end of file From 7dc9f2286485bd1d7f76e62f886973745b931e15 Mon Sep 17 00:00:00 2001 From: Fly Date: Fri, 8 Aug 2025 00:06:43 +0800 Subject: [PATCH 19/21] re build cuz broken --- src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt index f557a656d..ec7739daf 100644 --- a/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt +++ b/src/main/kotlin/me/odinmain/utils/skyblock/PartyUtils.kt @@ -159,4 +159,4 @@ object PartyUtils { } fun isLeader(): Boolean = (forceIsLeader || partyLeader == mc.thePlayer.name) -} \ No newline at end of file +} From 88605609232094a709c81d3f7c90d99e8a6478cc Mon Sep 17 00:00:00 2001 From: FlyModeZ <102896994+FlyModeZ@users.noreply.github.com> Date: Fri, 8 Aug 2025 12:26:35 +0800 Subject: [PATCH 20/21] Update EventDispatcher.kt Signed-off-by: FlyModeZ <102896994+FlyModeZ@users.noreply.github.com> --- src/main/kotlin/me/odinmain/events/EventDispatcher.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/odinmain/events/EventDispatcher.kt b/src/main/kotlin/me/odinmain/events/EventDispatcher.kt index b0c84df67..81fa10b66 100644 --- a/src/main/kotlin/me/odinmain/events/EventDispatcher.kt +++ b/src/main/kotlin/me/odinmain/events/EventDispatcher.kt @@ -48,7 +48,7 @@ object EventDispatcher { if (event.packet is S29PacketSoundEffect && inDungeons && !inBoss && (event.packet.soundName.equalsOneOf("mob.bat.hurt", "mob.bat.death") && event.packet.volume == 0.1f)) SecretPickupEvent.Bat(event.packet).postAndCatch() - if (event.packet is S02PacketChat && event.packet.isChat && ChatPacketEvent(event.packet.chatComponent.unformattedText.noControlCodes).postAndCatch()) + if (event.packet is S02PacketChat && event.packet.type != 2.toByte() && ChatPacketEvent(event.packet.chatComponent.unformattedText.noControlCodes).postAndCatch()) event.isCanceled = true } From 1b03822f9e6ef37f7d9028aacfe321f6de8f65a7 Mon Sep 17 00:00:00 2001 From: FlyModeZ <102896994+FlyModeZ@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:56:40 +0800 Subject: [PATCH 21/21] revert ping :< Signed-off-by: FlyModeZ <102896994+FlyModeZ@users.noreply.github.com> --- .../kotlin/me/odinmain/utils/ServerUtils.kt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/me/odinmain/utils/ServerUtils.kt b/src/main/kotlin/me/odinmain/utils/ServerUtils.kt index d0a17b575..4138bb5b8 100644 --- a/src/main/kotlin/me/odinmain/utils/ServerUtils.kt +++ b/src/main/kotlin/me/odinmain/utils/ServerUtils.kt @@ -4,9 +4,10 @@ import me.odinmain.OdinMain.mc import me.odinmain.events.impl.PacketEvent import me.odinmain.utils.clock.Executor import me.odinmain.utils.clock.Executor.Companion.register -import me.odinmain.utils.skyblock.sendCommand -import net.minecraft.network.play.server.S02PacketChat +import me.odinmain.utils.skyblock.LocationUtils.isOnHypixel +import net.minecraft.network.play.client.C16PacketClientStatus import net.minecraft.network.play.server.S03PacketTimeUpdate +import net.minecraft.network.play.server.S37PacketStatistics import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -17,28 +18,24 @@ object ServerUtils { var averagePing = 0f private set - private val unknownCommandRegex = Regex("^/?Unknown command\\. Type \"/?help\" for help\\. \\('odingetpingcommand-----'\\)$") private var pingStartTime = 0L private var isPinging = false private var prevTime = 0L init { Executor(2000, "ServerUtils") { - if (mc.isSingleplayer) return@Executor + if (!isOnHypixel) return@Executor pingStartTime = System.nanoTime() isPinging = true - - sendCommand("odingetpingcommand-----") + mc.netHandler?.addToSendQueue(C16PacketClientStatus(C16PacketClientStatus.EnumState.REQUEST_STATS)) }.register() } @SubscribeEvent fun onPacket(event: PacketEvent.Receive) { when (event.packet) { - is S02PacketChat -> { - if (event.packet.chatComponent?.unformattedText?.noControlCodes?.let { unknownCommandRegex.matches(it) } == false) return + is S37PacketStatistics -> { averagePing = (System.nanoTime() - pingStartTime) / 1e6f - event.isCanceled = true isPinging = false } @@ -58,4 +55,4 @@ object ServerUtils { averageTps = 20f prevTime = 0L } -} \ No newline at end of file +}