diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
5 files changed, 164 insertions, 89 deletions
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 @@ -56,19 +60,6 @@ object ChatUtils { } /** - * 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) @@ -135,34 +122,6 @@ object ChatUtils { } /** - * 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 * @param onClick The runnable to be executed when the message is clicked @@ -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<String>, - 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<String, ClickableAction>() + + 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<String>) { + 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<Data : TrackerData>( "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) { |