From f9ce2fa19a1178fd9f2e2728d09ac5acd299d69f Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 8 May 2024 08:30:59 -0230 Subject: Backend: Text API (#1718) Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../hannibal2/skyhanni/config/commands/Commands.kt | 15 ++- .../skyhanni/data/ChatClickActionManager.kt | 49 ---------- .../data/hypixel/chat/PlayerNameFormatter.kt | 12 +-- .../features/combat/ghostcounter/GhostCounter.kt | 1 + .../features/commands/PartyChatCommands.kt | 7 +- .../features/dungeon/DungeonArchitectFeatures.kt | 6 +- .../event/diana/InquisitorWaypointShare.kt | 12 ++- .../features/event/hoppity/HoppityEggsManager.kt | 3 +- .../features/fame/AccountUpgradeReminder.kt | 4 +- .../skyhanni/features/fame/CityProjectFeatures.kt | 3 +- .../features/fishing/trophy/TrophyFishManager.kt | 9 +- .../features/garden/GardenNextJacobContest.kt | 6 +- .../skyhanni/test/SkyHanniDebugsAndTests.kt | 3 +- .../skyhanni/test/command/TestChatCommand.kt | 2 +- .../hannibal2/skyhanni/utils/ChatComponentUtils.kt | 8 -- .../java/at/hannibal2/skyhanni/utils/ChatUtils.kt | 105 +++++---------------- .../skyhanni/utils/chat/ChatClickActionManager.kt | 36 +++++++ .../java/at/hannibal2/skyhanni/utils/chat/Text.kt | 101 ++++++++++++++++++++ .../skyhanni/utils/tracker/SkyHanniTracker.kt | 3 +- 19 files changed, 216 insertions(+), 169 deletions(-) delete mode 100644 src/main/java/at/hannibal2/skyhanni/data/ChatClickActionManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ChatComponentUtils.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/chat/ChatClickActionManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt (limited to 'src/main') diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index d3ab8daff..24c85e80c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.api.SkillAPI import at.hannibal2.skyhanni.config.ConfigFileType import at.hannibal2.skyhanni.config.ConfigGuiManager import at.hannibal2.skyhanni.config.features.About.UpdateStream -import at.hannibal2.skyhanni.data.ChatClickActionManager +import at.hannibal2.skyhanni.utils.chat.ChatClickActionManager import at.hannibal2.skyhanni.data.ChatManager import at.hannibal2.skyhanni.data.GardenCropMilestonesCommunityFix import at.hannibal2.skyhanni.data.GuiEditManager @@ -82,6 +82,9 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.StringUtils.splitLines import at.hannibal2.skyhanni.utils.TabListData +import at.hannibal2.skyhanni.utils.chat.Text +import at.hannibal2.skyhanni.utils.chat.Text.hover +import at.hannibal2.skyhanni.utils.chat.Text.suggest import at.hannibal2.skyhanni.utils.repopatterns.RepoPatternGui import net.minecraft.command.ICommandSender import net.minecraft.util.BlockPos @@ -565,9 +568,10 @@ object Commands { addDescription(category.description) } - val commandInfo = ChatUtils.createHoverableChat("$color/$name", hoverText, "/$name", false) - - components.add(commandInfo) + components.add(Text.text("$color/$name") { + this.hover = Text.multiline(hoverText) + this.suggest = "/$name" + }) components.add(ChatComponentText("§7, ")) } components.add(ChatComponentText("\n ")) @@ -629,7 +633,8 @@ object Commands { "Are you sure you want to switch to beta? These versions may be less stable.", onClick = { UpdateManager.checkUpdate(true, updateStream) - } + }, + oneTimeClick = true ) } else { UpdateManager.checkUpdate(true, updateStream) diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatClickActionManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatClickActionManager.kt deleted file mode 100644 index 140615e08..000000000 --- a/src/main/java/at/hannibal2/skyhanni/data/ChatClickActionManager.kt +++ /dev/null @@ -1,49 +0,0 @@ -package at.hannibal2.skyhanni.data - -import at.hannibal2.skyhanni.utils.ChatUtils -import at.hannibal2.skyhanni.utils.SimpleTimeMark -import at.hannibal2.skyhanni.utils.StringUtils - -object ChatClickActionManager { - - private val actions = mutableListOf() - - fun oneTimeClick(message: String, onClick: () -> Any, expiresAt: SimpleTimeMark) { - val action = ClickableAction(StringUtils.generateRandomId(), message, onClick, expiresAt = expiresAt) - actions.add(action) - action.sendToChat() - } - - private fun ClickableAction.sendToChat() { - @Suppress("DEPRECATION") - // TODO rename function - ChatUtils.clickableChat(message, "shaction $token", prefix = false) - } - - fun onCommand(args: Array) { - if (args.size == 1) { - getActionByToken(args[0])?.runAction() - } - } - - private fun ClickableAction.runAction() { - if (expiresAt.isInPast()) { - actions.remove(this) - return - } - onClick() - if (oneTime) { - actions.remove(this) - } - } - - private fun getActionByToken(token: String) = actions.find { it.token == token } - - class ClickableAction( - val token: String, - val message: String, - val onClick: () -> Any, - val oneTime: Boolean = true, - val expiresAt: SimpleTimeMark = SimpleTimeMark.farFuture(), - ) -} diff --git a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt index 35c1e8cd1..4190b2e9d 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/hypixel/chat/PlayerNameFormatter.kt @@ -13,7 +13,6 @@ import at.hannibal2.skyhanni.features.bingo.BingoAPI import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatFilter import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager import at.hannibal2.skyhanni.features.misc.compacttablist.AdvancedPlayerList -import at.hannibal2.skyhanni.utils.ChatComponentUtils import at.hannibal2.skyhanni.utils.ComponentMatcherUtils.matchStyledMatcher import at.hannibal2.skyhanni.utils.ComponentSpan import at.hannibal2.skyhanni.utils.LorenzUtils @@ -21,6 +20,7 @@ import at.hannibal2.skyhanni.utils.StringUtils import at.hannibal2.skyhanni.utils.StringUtils.applyFormattingFrom import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName import at.hannibal2.skyhanni.utils.StringUtils.toCleanChatComponent +import at.hannibal2.skyhanni.utils.chat.Text import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import com.google.gson.JsonArray import com.google.gson.JsonNull @@ -85,7 +85,7 @@ class PlayerNameFormatter { if (!isEnabled()) return event.chatComponent = StringUtils.replaceIfNeeded( event.chatComponent, - ChatComponentUtils.text("§bCo-Op > ") { + Text.text("§bCo-Op > ") { appendSibling(nameFormat(event.authorComponent)) appendText("§f: ") appendSibling(event.messageComponent.intoComponent()) @@ -98,7 +98,7 @@ class PlayerNameFormatter { if (!isEnabled()) return event.chatComponent = StringUtils.replaceIfNeeded( event.chatComponent, - ChatComponentUtils.text("§2Guild > ") { + Text.text("§2Guild > ") { appendSibling(nameFormat(event.authorComponent, guildRank = event.guildRank)) appendText("§f: ") appendSibling(event.messageComponent.intoComponent()) @@ -111,7 +111,7 @@ class PlayerNameFormatter { if (!isEnabled()) return event.chatComponent = StringUtils.replaceIfNeeded( event.chatComponent, - ChatComponentUtils.text("§9Party §8> ") { + Text.text("§9Party §8> ") { appendSibling(nameFormat(event.authorComponent)) appendText("§f: ") appendSibling(event.messageComponent.intoComponent()) @@ -123,7 +123,7 @@ class PlayerNameFormatter { fun onPrivateChat(event: PrivateMessageChatEvent) { if (!isEnabled()) return event.chatComponent = - StringUtils.replaceIfNeeded(event.chatComponent, ChatComponentUtils.text("§d${event.direction}") { + StringUtils.replaceIfNeeded(event.chatComponent, Text.text("§d${event.direction}") { appendText(" ") appendSibling(nameFormat(event.authorComponent)) appendText("§f: ") @@ -135,7 +135,7 @@ class PlayerNameFormatter { @SubscribeEvent fun onPlayerShowItemChat(event: PlayerShowItemChatEvent) { if (!isEnabled()) return - event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, ChatComponentUtils.text("") { + event.chatComponent = StringUtils.replaceIfNeeded(event.chatComponent, Text.text("") { appendSibling( nameFormat( event.authorComponent, diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt index dcac24f63..4d9b94d31 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt @@ -324,6 +324,7 @@ object GhostCounter { GhostUtil.importCTGhostCounterData() }, prefixColor = "§6", + oneTimeClick = true ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/PartyChatCommands.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/PartyChatCommands.kt index be986e01d..fca11b45a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/PartyChatCommands.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/PartyChatCommands.kt @@ -162,11 +162,14 @@ object PartyChatCommands { } "clear" -> { - ChatUtils.clickableChat("Are you sure you want to do this? Click here to confirm.", + ChatUtils.clickableChat( + "Are you sure you want to do this? Click here to confirm.", onClick = { storage.blacklistedUsers.clear() ChatUtils.chat("Cleared your ignored players list!") - }) + }, + oneTimeClick = true + ) } else -> blacklistModify(firstArg) diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonArchitectFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonArchitectFeatures.kt index d23d5dda9..29d3f8d11 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonArchitectFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonArchitectFeatures.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.SackAPI.getAmountInSacks import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.HypixelCommands import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher @@ -43,12 +44,11 @@ class DungeonArchitectFeatures { val architectItemAmount = architectsFirstDraftItem.getAmountInSacks() if (architectItemAmount <= 0) return - // TODO use hypxel command class (once the pr is merged ChatUtils.clickableChat( "§c§lPUZZLE FAILED! §r§b$name §r§efailed a puzzle. \n" + "§eClick here to get §5Architect's First Draft §7(§e${architectItemAmount}x left§7)", - "/gfs ARCHITECT_FIRST_DRAFT 1", - false + { HypixelCommands.getFromSacks("ARCHITECT_FIRST_DRAFT", 1) }, + prefix = false ) LorenzUtils.sendTitle("§c§lPUZZLE FAILED!", 3.seconds) event.blockedReason = "puzzle_fail" diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt index 25fba4ceb..ef1a58c55 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt @@ -170,11 +170,13 @@ object InquisitorWaypointShare { sendInquisitor() } else { val keyName = KeyboardManager.getKeyName(config.keyBindShare) - val message = - "§l§bYou found a Inquisitor! Press §l§chere §l§bor §c$keyName to share the location!" - ChatUtils.clickableChat(message, onClick = { - sendInquisitor() - }) + val message = "§l§bYou found a Inquisitor! Press §l§chere §l§bor §c$keyName to share the location!" + ChatUtils.clickableChat( + message, onClick = { + sendInquisitor() + }, + oneTimeClick = true + ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt index 608f241cc..c382e227e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt @@ -135,7 +135,8 @@ object HoppityEggsManager { ChatUtils.clickableChat( "Click here to share the location of this chocolate egg with the server!", onClick = { HoppityEggsShared.shareNearbyEggLocation(currentLocation, meal, note) }, - expireAt = 30.seconds.fromNow() + expireAt = 30.seconds.fromNow(), + oneTimeClick = true ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt b/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt index 74645000a..b26a05094 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt @@ -52,7 +52,8 @@ class AccountUpgradeReminder { "The §a$upgrade §eupgrade has completed! §c(Click to disable these reminders)", onClick = { disable() - } + }, + oneTimeClick = true ) } @@ -113,6 +114,7 @@ class AccountUpgradeReminder { fun disable() { SkyHanniMod.feature.misc.accountUpgradeReminder = false + ChatUtils.chat("Disabled account upgrade reminder.") } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt index d9631f55d..2fd91bdf5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt @@ -82,7 +82,8 @@ class CityProjectFeatures { "Daily City Project Reminder! (Click here to disable this reminder)", onClick = { disable() - } + }, + oneTimeClick = true ) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt index 9bff45019..564e56edf 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt @@ -54,9 +54,12 @@ object TrophyFishManager { } } if (changed) { - ChatUtils.clickableChat("Click here to load data from NEU PV!", onClick = { - updateFromNeuPv(savedFishes, neuData) - }) + ChatUtils.clickableChat( + "Click here to load data from NEU PV!", onClick = { + updateFromNeuPv(savedFishes, neuData) + }, + oneTimeClick = true + ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt index 8c41a5137..c175c219f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -249,7 +249,8 @@ object GardenNextJacobContest { "§2Click here to submit this year's farming contests. Thank you for helping everyone out!", onClick = { shareContests() - } + }, + oneTimeClick = true ) } } @@ -303,7 +304,8 @@ object GardenNextJacobContest { config.shareAutomatically = ShareContestsEntry.AUTO SkyHanniMod.feature.storage.contestSendingAsked = true ChatUtils.chat("§2Enabled automatic sharing of future contests!") - } + }, + oneTimeClick = true ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt index 0ae712f9d..4916d770f 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt @@ -206,7 +206,8 @@ class SkyHanniDebugsAndTests { onClick = { resetConfig() }, - prefix = false + prefix = false, + oneTimeClick = true ) } diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt index 4c23f5ed1..2007e5b99 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt @@ -51,7 +51,7 @@ object TestChatCommand { if (finalMessage.formattedText.stripHypixelMessage() != message) { ChatUtils.chat("§eChat modified!") } - ChatUtils.chatComponent(finalMessage) + ChatUtils.chat(finalMessage) } } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ChatComponentUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ChatComponentUtils.kt deleted file mode 100644 index 4a0d8ce76..000000000 --- a/src/main/java/at/hannibal2/skyhanni/utils/ChatComponentUtils.kt +++ /dev/null @@ -1,8 +0,0 @@ -package at.hannibal2.skyhanni.utils - -import net.minecraft.util.ChatComponentText - -object ChatComponentUtils { - fun text(text: String, init: ChatComponentText.() -> Unit = {}): ChatComponentText = - ChatComponentText(text).also(init) -} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt index c2292845c..d1dce7fe3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt @@ -1,14 +1,18 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.ChatClickActionManager import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.utils.ConfigUtils.jumpToEditor import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.chat.Text +import at.hannibal2.skyhanni.utils.chat.Text.asComponent +import at.hannibal2.skyhanni.utils.chat.Text.command +import at.hannibal2.skyhanni.utils.chat.Text.hover +import at.hannibal2.skyhanni.utils.chat.Text.onClick +import at.hannibal2.skyhanni.utils.chat.Text.prefix +import at.hannibal2.skyhanni.utils.chat.Text.url import net.minecraft.client.Minecraft -import net.minecraft.event.ClickEvent -import net.minecraft.event.HoverEvent import net.minecraft.util.ChatComponentText import net.minecraft.util.IChatComponent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -55,19 +59,6 @@ object ChatUtils { internalChat(USER_ERROR_PREFIX + message) } - /** - * Sends a message to the user that they did something incorrectly. - * Runs a command when clicked to fix the issue. - * - * @param message The message to be sent - * @param command The command to be executed when the message is clicked - * - * @see USER_ERROR_PREFIX - */ - fun clickableUserError(message: String, command: String) { - internalChat(createClickableChat(USER_ERROR_PREFIX + message, command)) - } - /** * Sends a message to the user that an error occurred caused by something in the code. * This should be used for errors that are not caused by the user. @@ -106,15 +97,11 @@ object ChatUtils { } } - fun chatComponent(message: IChatComponent) { - internalChat(message) - } - private fun internalChat(message: String): Boolean { - return internalChat(ChatComponentText(message)) + return chat(ChatComponentText(message)) } - private fun internalChat(message: IChatComponent): Boolean { + fun chat(message: IChatComponent): Boolean { val formattedMessage = message.formattedText log.log(formattedMessage) @@ -134,34 +121,6 @@ object ChatUtils { return true } - /** - * Sends a message to the user that they can click and run a command - * @param message The message to be sent - * @param command The command to be executed when the message is clicked - * @param prefix Whether to prefix the message with the chat prefix, default true - * @param prefixColor Color that the prefix should be, default yellow (§e) - * - * @see CHAT_PREFIX - */ - //TODO rename to runHypixelCommand - @Deprecated("Use clickableChat with onClick or use HypixelCommands", ReplaceWith("")) - fun clickableChat(message: String, command: String, prefix: Boolean = true, prefixColor: String = "§e") { - val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" - val fullMessage = msgPrefix + message - - internalChat(createClickableChat(fullMessage, command)) - } - - private fun createClickableChat(message: String, command: String): ChatComponentText { - val text = ChatComponentText(message) - val fullCommand = "/" + command.removePrefix("/") - text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand) - text.chatStyle.chatHoverEvent = - HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText("§eClick here!")) - - return text - } - /** * Sends a message to the user that they can click and run an action * @param message The message to be sent @@ -178,9 +137,13 @@ object ChatUtils { expireAt: SimpleTimeMark = SimpleTimeMark.farFuture(), prefix: Boolean = true, prefixColor: String = "§e", + oneTimeClick: Boolean = false, ) { val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" - ChatClickActionManager.oneTimeClick(msgPrefix + message, onClick, expireAt) + chat(Text.text(msgPrefix + message) { + this.onClick(expireAt, oneTimeClick, onClick) + this.hover = "§eClick here!".asComponent() + }) } /** @@ -201,27 +164,13 @@ object ChatUtils { prefixColor: String = "§e", ) { val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" - val fullMessage = msgPrefix + message - - internalChat(createHoverableChat(fullMessage, hover, command)) - } - fun createHoverableChat( - message: String, - hover: List, - command: String? = null, - runCommand: Boolean = true, - ): ChatComponentText { - val text = ChatComponentText(message) - text.chatStyle.chatHoverEvent = - HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText(hover.joinToString("\n"))) - - command?.let { - val eventType = if (runCommand) ClickEvent.Action.RUN_COMMAND else ClickEvent.Action.SUGGEST_COMMAND - text.chatStyle.chatClickEvent = ClickEvent(eventType, "/${it.removePrefix("/")}") - } - - return text + chat(Text.text(msgPrefix + message) { + this.hover = Text.multiline(hover) + if (command != null) { + this.command = command + } + }) } /** @@ -244,10 +193,10 @@ object ChatUtils { prefixColor: String = "§e", ) { val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" - val text = ChatComponentText(msgPrefix + message) - text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.OPEN_URL, url) - text.chatStyle.chatHoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText("$prefixColor$hover")) - internalChat(text) + chat(Text.text(msgPrefix + message) { + this.url = url + this.hover = "$prefixColor$hover".asComponent() + }) if (autoOpen) OSUtils.openBrowser(url) } @@ -265,11 +214,7 @@ object ChatUtils { prefixColor: String = "§e", ) { val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else "" - val baseMessage = ChatComponentText(msgPrefix) - - for (component in components) baseMessage.appendSibling(component) - - internalChat(baseMessage) + chat(Text.join(components).prefix(msgPrefix)) } private var lastMessageSent = SimpleTimeMark.farPast() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/chat/ChatClickActionManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/chat/ChatClickActionManager.kt new file mode 100644 index 000000000..17264a020 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/chat/ChatClickActionManager.kt @@ -0,0 +1,36 @@ +package at.hannibal2.skyhanni.utils.chat + +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils + +object ChatClickActionManager { + + private val actions = mutableMapOf() + + fun createAction(onClick: () -> Any, expiresAt: SimpleTimeMark, oneTime: Boolean = true): String { + val token = StringUtils.generateRandomId() + actions[token] = ClickableAction(onClick, oneTime, expiresAt) + return token + } + + fun onCommand(args: Array) { + if (args.size == 1) { + actions[args.first()]?.apply { + if (expiresAt.isInPast()) { + actions.remove(args.first()) + return + } + onClick() + if (oneTime) { + actions.remove(args.first()) + } + } + } + } + + class ClickableAction( + val onClick: () -> Any, + val oneTime: Boolean = true, + val expiresAt: SimpleTimeMark = SimpleTimeMark.farFuture(), + ) +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt b/src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt new file mode 100644 index 000000000..5bec46867 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt @@ -0,0 +1,101 @@ +package at.hannibal2.skyhanni.utils.chat + +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import net.minecraft.client.Minecraft +import net.minecraft.event.ClickEvent +import net.minecraft.event.HoverEvent +import net.minecraft.util.ChatComponentText +import net.minecraft.util.ChatStyle +import net.minecraft.util.IChatComponent + +object Text { + + val NEWLINE = "\n".asComponent() + val HYPHEN = "-".asComponent() + val SPACE = " ".asComponent() + val EMPTY = "".asComponent() + + fun text(text: String, init: IChatComponent.() -> Unit = {}) = text.asComponent(init) + fun String.asComponent(init: IChatComponent.() -> Unit = {}) = ChatComponentText(this).also(init) + + fun multiline(vararg lines: Any?) = join(*lines, separator = NEWLINE) + fun join(vararg components: Any?, separator: IChatComponent? = null): IChatComponent { + val result = ChatComponentText("") + components.forEachIndexed { index, it -> + when (it) { + is IChatComponent -> result.appendSibling(it) + is String -> result.appendText(it) + is List<*> -> result.appendSibling(join(*it.toTypedArray(), separator = separator)) + null -> return@forEachIndexed + else -> error("Unsupported type: ${it::class.simpleName}") + } + + if (index < components.size - 1 && separator != null) { + result.appendSibling(separator) + } + } + return result + } + + fun IChatComponent.style(init: ChatStyle.() -> Unit): IChatComponent { + this.chatStyle.init() + return this + } + + fun IChatComponent.prefix(prefix: String): IChatComponent = join(prefix, this) + fun IChatComponent.suffix(suffix: String): IChatComponent = join(this, suffix) + fun IChatComponent.wrap(prefix: String, suffix: String) = this.prefix(prefix).suffix(suffix) + + fun IChatComponent.width(): Int = Minecraft.getMinecraft().fontRendererObj.getStringWidth(this.formattedText) + + fun IChatComponent.fitToChat(): IChatComponent { + val width = this.width() + val maxWidth = Minecraft.getMinecraft().ingameGUI.chatGUI.chatWidth + if (width < maxWidth) { + val repeat = maxWidth / width + val component = ChatComponentText("") + repeat(repeat) { component.appendSibling(this) } + return component + } + return this + } + fun IChatComponent.center(width: Int = Minecraft.getMinecraft().ingameGUI.chatGUI.chatWidth): IChatComponent { + val textWidth = this.width() + val spaceWidth = SPACE.width() + val padding = (width - textWidth) / 2 + return join(" ".repeat(padding / spaceWidth), this) + } + + fun IChatComponent.send(id: Int = 0) = + Minecraft.getMinecraft().ingameGUI.chatGUI.printChatMessageWithOptionalDeletion(this, id) + + var IChatComponent.hover: IChatComponent? + get() = this.chatStyle.chatHoverEvent?.value + set(value) { + this.chatStyle.chatHoverEvent = value?.let { HoverEvent(HoverEvent.Action.SHOW_TEXT, it) } + } + + var IChatComponent.command: String? + get() = this.chatStyle.chatClickEvent?.let { if (it.action == ClickEvent.Action.RUN_COMMAND) it.value else null } + set(value) { + this.chatStyle.chatClickEvent = value?.let { ClickEvent(ClickEvent.Action.RUN_COMMAND, it) } + } + + var IChatComponent.suggest: String? + get() = this.chatStyle.chatClickEvent?.let { if (it.action == ClickEvent.Action.SUGGEST_COMMAND) it.value else null } + set(value) { + this.chatStyle.chatClickEvent = value?.let { ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, it) } + } + + var IChatComponent.url: String? + get() = this.chatStyle.chatClickEvent?.let { if (it.action == ClickEvent.Action.OPEN_URL) it.value else null } + set(value) { + this.chatStyle.chatClickEvent = value?.let { ClickEvent(ClickEvent.Action.OPEN_URL, it) } + } + + fun IChatComponent.onClick(expiresAt: SimpleTimeMark = SimpleTimeMark.farFuture(), oneTime: Boolean = true, onClick: () -> Any) { + val token = ChatClickActionManager.createAction(onClick, expiresAt, oneTime) + this.command = "/shaction $token" + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt index 5f7265120..51a0e4f65 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -54,7 +54,8 @@ open class SkyHanniTracker( "Are you sure you want to reset your total $name? Click here to confirm.", onClick = { reset(DisplayMode.TOTAL, "Reset total $name!") - } + }, + oneTimeClick = true ) fun modify(modifyFunction: (Data) -> Unit) { -- cgit