aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ChatComponentUtils.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt105
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/chat/ChatClickActionManager.kt36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/chat/Text.kt101
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt3
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) {