From 4559e5ff05e19817a21ae49f1c0d8a97d273f6a1 Mon Sep 17 00:00:00 2001
From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com>
Date: Sat, 10 Feb 2024 00:24:52 +0100
Subject: Splitting many utils functions from LorenzUtils up into other
classes: ChatUtils, CollectionUtils, ConditionalUtils. And code cleanup #978
---
.../java/at/hannibal2/skyhanni/utils/APIUtil.kt | 27 +-
.../java/at/hannibal2/skyhanni/utils/ChatUtils.kt | 203 ++++++++++
.../at/hannibal2/skyhanni/utils/ClipboardUtils.kt | 3 +-
.../at/hannibal2/skyhanni/utils/CollectionUtils.kt | 115 ++++++
.../java/at/hannibal2/skyhanni/utils/ColorUtils.kt | 7 +-
.../at/hannibal2/skyhanni/utils/CombatUtils.kt | 1 -
.../hannibal2/skyhanni/utils/ConditionalUtils.kt | 33 ++
.../at/hannibal2/skyhanni/utils/ConfigUtils.kt | 2 +-
.../java/at/hannibal2/skyhanni/utils/DelayedRun.kt | 3 +-
.../skyhanni/utils/EntityOutlineRenderer.kt | 3 +-
.../at/hannibal2/skyhanni/utils/EntityUtils.kt | 4 +-
.../at/hannibal2/skyhanni/utils/GuiRenderUtils.kt | 8 +-
.../skyhanni/utils/IdentityCharacteristics.kt | 1 +
.../at/hannibal2/skyhanni/utils/InventoryUtils.kt | 4 +-
.../java/at/hannibal2/skyhanni/utils/ItemBlink.kt | 3 +-
.../skyhanni/utils/ItemStackTypeAdapter.kt | 4 +-
.../java/at/hannibal2/skyhanni/utils/ItemUtils.kt | 4 +-
.../at/hannibal2/skyhanni/utils/KSerializable.kt | 6 +-
.../at/hannibal2/skyhanni/utils/KeyboardManager.kt | 1 +
.../at/hannibal2/skyhanni/utils/LorenzColor.kt | 1 +
.../at/hannibal2/skyhanni/utils/LorenzDebug.kt | 4 +-
.../at/hannibal2/skyhanni/utils/LorenzLogger.kt | 2 +
.../at/hannibal2/skyhanni/utils/LorenzUtils.kt | 435 ++-------------------
.../java/at/hannibal2/skyhanni/utils/LorenzVec.kt | 1 +
.../skyhanni/utils/MinecraftConsoleFilter.kt | 5 +-
.../skyhanni/utils/MinecraftDispatcher.kt | 3 +-
.../at/hannibal2/skyhanni/utils/MultiFilter.kt | 2 +-
.../at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt | 3 +-
.../at/hannibal2/skyhanni/utils/NEUInternalName.kt | 3 +-
.../java/at/hannibal2/skyhanni/utils/NEUItems.kt | 3 +-
.../java/at/hannibal2/skyhanni/utils/NumberUtil.kt | 7 +-
.../java/at/hannibal2/skyhanni/utils/OSUtils.kt | 2 +-
.../at/hannibal2/skyhanni/utils/ParkourHelper.kt | 6 +-
.../hannibal2/skyhanni/utils/RecalculatingValue.kt | 3 +-
.../at/hannibal2/skyhanni/utils/ReflectionUtils.kt | 62 +++
.../at/hannibal2/skyhanni/utils/RenderUtils.kt | 28 +-
.../java/at/hannibal2/skyhanni/utils/Season.kt | 4 +-
.../at/hannibal2/skyhanni/utils/SimpleTimeMark.kt | 1 +
.../skyhanni/utils/SkyBlockItemModifierUtils.kt | 9 +-
.../java/at/hannibal2/skyhanni/utils/SoundUtils.kt | 3 +-
.../at/hannibal2/skyhanni/utils/StringUtils.kt | 1 +
.../at/hannibal2/skyhanni/utils/TabListData.kt | 20 +-
.../java/at/hannibal2/skyhanni/utils/TimeMark.kt | 4 +-
.../java/at/hannibal2/skyhanni/utils/TimeUtils.kt | 9 +-
src/main/java/at/hannibal2/skyhanni/utils/Timer.kt | 3 +-
.../at/hannibal2/skyhanni/utils/UtilsPatterns.kt | 4 +-
.../utils/renderables/RenderLineTooltips.kt | 4 +-
.../skyhanni/utils/renderables/Renderable.kt | 2 +
.../skyhanni/utils/repopatterns/RepoPattern.kt | 3 +-
.../utils/repopatterns/RepoPatternGroup.kt | 1 +
.../skyhanni/utils/repopatterns/RepoPatternGui.kt | 6 +-
.../skyhanni/utils/repopatterns/RepoPatternImpl.kt | 2 +-
.../utils/repopatterns/RepoPatternManager.kt | 4 +-
.../skyhanni/utils/shader/ShaderHelper.kt | 2 +
.../skyhanni/utils/shader/ShaderManager.kt | 2 +
.../at/hannibal2/skyhanni/utils/shader/Uniform.kt | 5 +-
.../skyhanni/utils/tracker/ItemTrackerData.kt | 1 +
.../skyhanni/utils/tracker/SkyHanniItemTracker.kt | 15 +-
.../skyhanni/utils/tracker/SkyHanniTracker.kt | 10 +-
.../skyhanni/utils/tracker/TrackerData.kt | 1 +
60 files changed, 605 insertions(+), 513 deletions(-)
create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ConditionalUtils.kt
create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ReflectionUtils.kt
(limited to 'src/main/java/at/hannibal2/skyhanni/utils')
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
index 2fd634d26..0f561fdff 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
@@ -22,8 +22,8 @@ import java.io.FileInputStream
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
-
object APIUtil {
+
private val parser = JsonParser()
private var showApiErrors = false
@@ -49,7 +49,7 @@ object APIUtil {
fun getJSONResponseAsElement(
urlString: String,
silentError: Boolean = false,
- apiName: String = "Hypixel API"
+ apiName: String = "Hypixel API",
): JsonElement {
val client = builder.build()
try {
@@ -63,16 +63,15 @@ object APIUtil {
if (e.message?.contains("Use JsonReader.setLenient(true)") == true) {
println("MalformedJsonException: Use JsonReader.setLenient(true)")
println(" - getJSONResponse: '$urlString'")
- LorenzUtils.debug("MalformedJsonException: Use JsonReader.setLenient(true)")
+ ChatUtils.debug("MalformedJsonException: Use JsonReader.setLenient(true)")
} else if (retSrc.contains("
502 Bad Gateway
")) {
if (showApiErrors && apiName == "Hypixel API") {
- LorenzUtils.clickableChat(
+ ChatUtils.clickableChat(
"Problems with detecting the Hypixel API. §eClick here to hide this message for now.",
"shtogglehypixelapierrors"
)
}
e.printStackTrace()
-
} else {
ErrorManager.logErrorWithData(
e, "$apiName error for url: '$urlString'",
@@ -118,7 +117,7 @@ object APIUtil {
val message = "POST request to '$urlString' returned status ${status.statusCode}"
println(message)
- LorenzUtils.error("SkyHanni ran into an error. Status: ${status.statusCode}")
+ ChatUtils.error("SkyHanni ran into an error. Status: ${status.statusCode}")
return ApiResponse(false, message, JsonObject())
}
} catch (throwable: Throwable) {
@@ -126,7 +125,7 @@ object APIUtil {
throw throwable
} else {
throwable.printStackTrace()
- LorenzUtils.error("SkyHanni ran into an ${throwable::class.simpleName ?: "error"} whilst sending a resource. See logs for more details.")
+ ChatUtils.error("SkyHanni ran into an ${throwable::class.simpleName ?: "error"} whilst sending a resource. See logs for more details.")
}
return ApiResponse(false, throwable.message, JsonObject())
} finally {
@@ -139,15 +138,21 @@ object APIUtil {
return parser.parse(retSrc) as JsonObject
}
- fun postJSONIsSuccessful(urlString: String, body: String, silentError: Boolean = false): Boolean {
- val response = postJSON(urlString, body, silentError)
+ fun postJSONIsSuccessful(url: String, body: String, silentError: Boolean = false): Boolean {
+ val response = postJSON(url, body, silentError)
if (response.success) {
return true
}
println(response.message)
- LorenzUtils.error(response.message ?: "An error occurred during the API request")
+ ErrorManager.logErrorStateWithData(
+ "An error occurred during the API request",
+ "unsuccessful API response",
+ "url" to url,
+ "body" to body,
+ "response" to response,
+ )
return false
}
@@ -158,6 +163,6 @@ object APIUtil {
fun toggleApiErrorMessages() {
showApiErrors = !showApiErrors
- LorenzUtils.chat("Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown")
+ ChatUtils.chat("Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
new file mode 100644
index 000000000..34f42e629
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
@@ -0,0 +1,203 @@
+package at.hannibal2.skyhanni.utils
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import net.minecraft.client.Minecraft
+import net.minecraft.event.ClickEvent
+import net.minecraft.event.HoverEvent
+import net.minecraft.util.ChatComponentText
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.LinkedList
+import java.util.Queue
+import kotlin.time.Duration.Companion.milliseconds
+
+object ChatUtils {
+
+ // TODO log based on chat category (error, warning, debug, user error, normal)
+ private val log = LorenzLogger("chat/mod_sent")
+ var lastButtonClicked = 0L
+
+ private const val DEBUG_PREFIX = "[SkyHanni Debug] §7"
+ private const val USER_ERROR_PREFIX = "§c[SkyHanni] "
+ private val ERROR_PREFIX by lazy { "§c[SkyHanni-${SkyHanniMod.version}] " }
+ private const val CHAT_PREFIX = "[SkyHanni] "
+
+ /**
+ * Sends a debug message to the chat and the console.
+ * This is only sent if the debug feature is enabled.
+ *
+ * @param message The message to be sent
+ *
+ * @see DEBUG_PREFIX
+ */
+ fun debug(message: String) {
+ if (SkyHanniMod.feature.dev.debug.enabled && internalChat(DEBUG_PREFIX + message)) {
+ LorenzUtils.consoleLog("[Debug] $message")
+ }
+ }
+
+ /**
+ * Sends a message to the user that they did something incorrectly.
+ * We should tell them what to do instead as well.
+ *
+ * @param message The message to be sent
+ *
+ * @see USER_ERROR_PREFIX
+ */
+ fun userError(message: String) {
+ internalChat(USER_ERROR_PREFIX + message)
+ }
+
+ /**
+ * 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.
+ *
+ * Why deprecate this? Even if this message is descriptive for the user and the developer,
+ * we don't want inconsitencies in errors, and we would need to search
+ * for the code line where this error gets printed any way.
+ * so it's better to use the stack trace still.
+ *
+ * @param message The message to be sent
+ * @param prefix Whether to prefix the message with the error prefix, default true
+ *
+ * @see ERROR_PREFIX
+ */
+ @Deprecated(
+ "Do not send the user a non clickable non stacktrace containing error message.",
+ ReplaceWith("ErrorManager.logErrorStateWithData")
+ )
+ fun error(message: String) {
+ println("error: '$message'")
+ internalChat(ERROR_PREFIX + message)
+ }
+
+ /**
+ * Sends a message to the user
+ * @param message The message to be sent
+ * @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
+ */
+ fun chat(message: String, prefix: Boolean = true, prefixColor: String = "§e") {
+ if (prefix) {
+ internalChat(prefixColor + CHAT_PREFIX + message)
+ } else {
+ internalChat(message)
+ }
+ }
+
+ private fun internalChat(message: String): Boolean {
+ log.log(message)
+ val minecraft = Minecraft.getMinecraft()
+ if (minecraft == null) {
+ LorenzUtils.consoleLog(message.removeColor())
+ return false
+ }
+
+ val thePlayer = minecraft.thePlayer
+ if (thePlayer == null) {
+ LorenzUtils.consoleLog(message.removeColor())
+ return false
+ }
+
+ thePlayer.addChatMessage(ChatComponentText(message))
+ 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
+ */
+ fun clickableChat(message: String, command: String, prefix: Boolean = true, prefixColor: String = "§e") {
+ val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
+ val text = ChatComponentText(msgPrefix + message)
+ val fullCommand = "/" + command.removePrefix("/")
+ text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand)
+ text.chatStyle.chatHoverEvent =
+ HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText("§eExecute $fullCommand"))
+ Minecraft.getMinecraft().thePlayer.addChatMessage(text)
+ }
+
+ /**
+ * Sends a message to the user that they can click and run a command
+ * @param message The message to be sent
+ * @param hover The message to be shown when the message is hovered
+ * @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
+ */
+ fun hoverableChat(
+ message: String,
+ hover: List,
+ command: String? = null,
+ prefix: Boolean = true,
+ prefixColor: String = "§e",
+ ) {
+ val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
+ val text = ChatComponentText(msgPrefix + message)
+ text.chatStyle.chatHoverEvent =
+ HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText(hover.joinToString("\n")))
+
+ command?.let {
+ text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${it.removePrefix("/")}")
+ }
+
+ Minecraft.getMinecraft().thePlayer.addChatMessage(text)
+ }
+
+ /**
+ * Sends a message to the user that they can click and run a command
+ * @param message The message to be sent
+ * @param url The url to be opened
+ * @param autoOpen Automatically opens the url as well as sending the clickable link message
+ * @param hover The message to be shown when the message is hovered
+ * @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
+ */
+ fun clickableLinkChat(
+ message: String,
+ url: String,
+ hover: String = "§eOpen $url",
+ autoOpen: Boolean = false,
+ prefix: Boolean = true,
+ 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"))
+ Minecraft.getMinecraft().thePlayer.addChatMessage(text)
+ if (autoOpen) OSUtils.openBrowser(url)
+ }
+
+ private var lastMessageSent = SimpleTimeMark.farPast()
+ private val sendQueue: Queue = LinkedList()
+
+ @SubscribeEvent
+ fun sendQueuedChatMessages(event: LorenzTickEvent) {
+ val player = Minecraft.getMinecraft().thePlayer
+ if (player == null) {
+ sendQueue.clear()
+ return
+ }
+ if (lastMessageSent.passedSince() > 300.milliseconds) {
+ player.sendChatMessage(sendQueue.poll() ?: return)
+ lastMessageSent = SimpleTimeMark.now()
+ }
+ }
+
+ fun sendMessageToServer(message: String) {
+ sendQueue.add(message)
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt
index 31008d9b4..b1d8eb68b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt
@@ -14,6 +14,7 @@ import java.awt.datatransfer.UnsupportedFlavorException
import kotlin.time.Duration.Companion.milliseconds
object ClipboardUtils {
+
private var dispatcher = Dispatchers.IO
private var lastClipboardAccessTime = SimpleTimeMark.farPast()
@@ -71,4 +72,4 @@ object ClipboardUtils {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
new file mode 100644
index 000000000..b93f17fa4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
@@ -0,0 +1,115 @@
+package at.hannibal2.skyhanni.utils
+
+import java.util.Collections
+import java.util.WeakHashMap
+import java.util.concurrent.ConcurrentLinkedQueue
+
+object CollectionUtils {
+
+ fun ConcurrentLinkedQueue.drainTo(list: MutableCollection) {
+ while (true)
+ list.add(this.poll() ?: break)
+ }
+
+ // Let garbage collector handle the removal of entries in this list
+ fun weakReferenceList(): MutableSet = Collections.newSetFromMap(WeakHashMap())
+
+ fun MutableCollection.filterToMutable(predicate: (T) -> Boolean) = filterTo(mutableListOf(), predicate)
+
+ fun List.indexOfFirst(vararg args: T) = args.map { indexOf(it) }.firstOrNull { it != -1 }
+
+ infix fun MutableMap.put(pairs: Pair) {
+ this[pairs.first] = pairs.second
+ }
+
+ // Taken and modified from Skytils
+ @JvmStatic
+ fun T.equalsOneOf(vararg other: T): Boolean {
+ for (obj in other) {
+ if (this == obj) return true
+ }
+ return false
+ }
+
+ fun List.getOrNull(index: Int): E? {
+ return if (index in indices) {
+ get(index)
+ } else null
+ }
+
+ fun T?.toSingletonListOrEmpty(): List {
+ if (this == null) return emptyList()
+ return listOf(this)
+ }
+
+ fun MutableMap.addOrPut(key: K, number: Int): Int =
+ this.merge(key, number, Int::plus)!! // Never returns null since "plus" can't return null
+
+ fun MutableMap.addOrPut(key: K, number: Long): Long =
+ this.merge(key, number, Long::plus)!! // Never returns null since "plus" can't return null
+
+ fun MutableMap.addOrPut(key: K, number: Double): Double =
+ this.merge(key, number, Double::plus)!! // Never returns null since "plus" can't return null
+
+ fun Map.sumAllValues(): Double {
+ if (values.isEmpty()) return 0.0
+
+ return when (values.first()) {
+ is Double -> values.sumOf { it.toDouble() }
+ is Float -> values.sumOf { it.toDouble() }
+ is Long -> values.sumOf { it.toLong() }.toDouble()
+ else -> values.sumOf { it.toInt() }.toDouble()
+ }
+ }
+
+ fun List.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after }, skip)
+
+ fun List.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? {
+ var missing = -1
+ for (line in this) {
+ if (after(line)) {
+ missing = skip - 1
+ continue
+ }
+ if (missing == 0) {
+ return line
+ }
+ if (missing != -1) {
+ missing--
+ }
+ }
+ return null
+ }
+
+ fun Map.editCopy(function: MutableMap.() -> Unit) =
+ toMutableMap().also { function(it) }.toMap()
+
+ fun List.editCopy(function: MutableList.() -> Unit) =
+ toMutableList().also { function(it) }.toList()
+
+ fun Map.moveEntryToTop(matcher: (Map.Entry) -> Boolean): Map {
+ val entry = entries.find(matcher)
+ if (entry != null) {
+ val newMap = linkedMapOf(entry.key to entry.value)
+ newMap.putAll(this)
+ return newMap
+ }
+ return this
+ }
+
+ fun MutableList>.addAsSingletonList(text: E) {
+ add(Collections.singletonList(text))
+ }
+
+ fun > List>.sorted(): List> {
+ return sortedBy { (_, value) -> value }
+ }
+
+ fun > Map.sorted(): Map {
+ return toList().sorted().toMap()
+ }
+
+ fun > Map.sortedDesc(): Map {
+ return toList().sorted().reversed().toMap()
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
index 076afc0c4..8eab43636 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
@@ -1,6 +1,11 @@
package at.hannibal2.skyhanni.utils
+import java.awt.Color
+
object ColorUtils {
+
+ /** transfer string colors from the config to java.awt.Color */
+ fun String.toChromaColor() = Color(SpecialColour.specialToChromaRGB(this), true)
fun getRed(colour: Int) = colour shr 16 and 0xFF
fun getGreen(colour: Int) = colour shr 8 and 0xFF
@@ -8,4 +13,4 @@ object ColorUtils {
fun getBlue(colour: Int) = colour and 0xFF
fun getAlpha(colour: Int) = colour shr 24 and 0xFF
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
index b0af1d93e..31bfe4416 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
@@ -111,5 +111,4 @@ object CombatUtils {
}
return interp
}
-
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ConditionalUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ConditionalUtils.kt
new file mode 100644
index 000000000..83a8d03f1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ConditionalUtils.kt
@@ -0,0 +1,33 @@
+package at.hannibal2.skyhanni.utils
+
+import io.github.moulberry.moulconfig.observer.Observer
+import io.github.moulberry.moulconfig.observer.Property
+
+object ConditionalUtils {
+
+ fun T.transformIf(condition: T.() -> Boolean, transofmration: T.() -> T) =
+ if (condition()) transofmration(this) else this
+
+ fun T.conditionalTransform(condition: Boolean, ifTrue: T.() -> Any, ifFalse: T.() -> Any) =
+ if (condition) ifTrue(this) else ifFalse(this)
+
+ // MoulConfig is in Java, I don't want to downgrade this logic
+ fun onChange(vararg properties: Property, observer: Observer) {
+ for (property in properties) {
+ property.whenChanged { a, b -> observer.observeChange(a, b) }
+ }
+ }
+
+ fun onToggle(vararg properties: Property, observer: Runnable) {
+ onChange(*properties) { _, _ -> observer.run() }
+ }
+
+ fun Property.onToggle(observer: Runnable) {
+ whenChanged { _, _ -> observer.run() }
+ }
+
+ fun Property.afterChange(observer: T.() -> Unit) {
+ whenChanged { _, new -> observer(new) }
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
index 3d8fd5449..55773a9c7 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
@@ -39,7 +39,7 @@ object ConfigUtils {
*/
private fun getEnumConstantFromLegacyId(
legacyId: Int,
- enumClass: Class
+ enumClass: Class,
): T? where T : Enum, T : HasLegacyId = enumClass.getEnumConstants().firstOrNull { it.legacyId == legacyId }
/**
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
index 284946072..3c6491ac3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
@@ -1,10 +1,11 @@
package at.hannibal2.skyhanni.utils
-import at.hannibal2.skyhanni.utils.LorenzUtils.drainTo
+import at.hannibal2.skyhanni.utils.CollectionUtils.drainTo
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.time.Duration
object DelayedRun {
+
private val tasks = mutableListOf Any, SimpleTimeMark>>()
private val futureTasks = ConcurrentLinkedQueue Any, SimpleTimeMark>>()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
index ca4827291..fea82caf7 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
@@ -32,6 +32,7 @@ import java.lang.reflect.Method
*
*/
object EntityOutlineRenderer {
+
private val entityRenderCache: CachedInfo = CachedInfo(null, null, null)
private var stopLookingForOptifine = false
private var isMissingMixin = false
@@ -400,6 +401,6 @@ object EntityOutlineRenderer {
private class CachedInfo(
var xrayCache: HashMap?,
var noXrayCache: HashMap?,
- var noOutlineCache: HashSet?
+ var noOutlineCache: HashSet?,
)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
index 36c01c64d..12a2129bf 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
@@ -99,13 +99,13 @@ object EntityUtils {
fun EntityLivingBase.hasBossHealth(health: Int): Boolean = this.hasMaxHealth(health, true)
- //TODO remove baseMaxHealth
+ // TODO remove baseMaxHealth
fun EntityLivingBase.hasMaxHealth(health: Int, boss: Boolean = false, maxHealth: Int = baseMaxHealth): Boolean {
val derpyMultiplier = if (LorenzUtils.isDerpy) 2 else 1
if (maxHealth == health * derpyMultiplier) return true
if (!boss && !LorenzUtils.inDungeons) {
- //Corrupted
+ // Corrupted
if (maxHealth == health * 3 * derpyMultiplier) return true
// Runic
if (maxHealth == health * 4 * derpyMultiplier) return true
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
index 5e4a63452..1d0b42b92 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
@@ -91,7 +91,7 @@ object GuiRenderUtils {
mouseX: Int,
mouseY: Int,
screenHeight: Int,
- fr: FontRenderer
+ fr: FontRenderer,
) {
if (textLines.isNotEmpty()) {
val borderColor = StringUtils.getColor(textLines[0], 0x505000FF)
@@ -187,7 +187,7 @@ object GuiRenderUtils {
y: Int,
mouseX: Int,
mouseY: Int,
- color: Int = 0xFF43464B.toInt()
+ color: Int = 0xFF43464B.toInt(),
) {
GuiScreen.drawRect(x, y, x + 16, y + 16, color)
if (item != null) {
@@ -206,7 +206,7 @@ object GuiRenderUtils {
y: Float,
mouseX: Float,
mouseY: Float,
- color: Int = 0xFF43464B.toInt()
+ color: Int = 0xFF43464B.toInt(),
) {
renderItemAndTip(list, item, x.toInt(), y.toInt(), mouseX.toInt(), mouseY.toInt(), color)
}
@@ -223,7 +223,7 @@ object GuiRenderUtils {
mouseX: Int,
mouseY: Int,
output: MutableList,
- textScale: Float = .7f
+ textScale: Float = .7f,
) {
var currentVal = currentValue.toDouble()
currentVal = if (currentVal < 0) 0.0 else currentVal
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/IdentityCharacteristics.kt b/src/main/java/at/hannibal2/skyhanni/utils/IdentityCharacteristics.kt
index 5b1399f73..64d059bd3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/IdentityCharacteristics.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/IdentityCharacteristics.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.utils
class IdentityCharacteristics(val value: T) {
+
override fun equals(other: Any?): Boolean {
if (other !is IdentityCharacteristics<*>) return false
return this.value === other.value
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
index 827b87854..1da7170ac 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
@@ -12,6 +12,7 @@ import net.minecraft.item.ItemStack
import kotlin.time.Duration.Companion.seconds
object InventoryUtils {
+
var itemInHandId = NEUInternalName.NONE
var recentItemsInHand = mutableMapOf()
var latestItemInHand: ItemStack? = null
@@ -42,7 +43,7 @@ object InventoryUtils {
fun inStorage() = openInventoryName().let {
(it.contains("Storage") && !it.contains("Rift Storage"))
- || it.contains("Ender Chest") || it.contains("Backpack")
+ || it.contains("Ender Chest") || it.contains("Backpack")
}
fun getItemInHand(): ItemStack? = Minecraft.getMinecraft().thePlayer.heldItem
@@ -54,7 +55,6 @@ object InventoryUtils {
fun getLeggings(): ItemStack? = getArmor()[1]
fun getBoots(): ItemStack? = getArmor()[0]
-
val isNeuStorageEnabled = RecalculatingValue(10.seconds) {
try {
val config = NotEnoughUpdates.INSTANCE.config
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemBlink.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemBlink.kt
index 8afc2a2b7..baa9a8c40 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemBlink.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemBlink.kt
@@ -4,6 +4,7 @@ import net.minecraft.item.Item
import net.minecraft.item.ItemStack
object ItemBlink {
+
private val offsets = mutableMapOf- ()
private var lastOffset = 0L
private var endOfBlink = 0L
@@ -28,4 +29,4 @@ object ItemBlink {
}
return if ((offset + System.currentTimeMillis()) % 1000 > 500) stack else this
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt
index 38002990f..602bffa2d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemStackTypeAdapter.kt
@@ -10,6 +10,7 @@ import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
object ItemStackTypeAdapterFactory : TypeAdapterFactory {
+
override fun create(gson: Gson?, type: TypeToken): TypeAdapter? {
if (type.rawType == ItemStack::class.java) {
val nbtCompoundTypeAdapter = gson!!.getAdapter(NBTTagCompound::class.java)
@@ -25,5 +26,4 @@ object ItemStackTypeAdapterFactory : TypeAdapterFactory {
}
return null
}
-
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
index d2c9776b7..0f506bacc 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
@@ -74,7 +74,7 @@ object ItemUtils {
val list: LinkedList = LinkedList()
val player = Minecraft.getMinecraft().thePlayer
if (player == null) {
- LorenzUtils.error("getItemsInInventoryWithSlots: player is null!")
+ ChatUtils.error("getItemsInInventoryWithSlots: player is null!")
return list
}
for (slot in player.openContainer.inventorySlots) {
@@ -93,7 +93,7 @@ object ItemUtils {
val map: LinkedHashMap = LinkedHashMap()
val player = Minecraft.getMinecraft().thePlayer
if (player == null) {
- LorenzUtils.error("getItemsInInventoryWithSlots: player is null!")
+ ChatUtils.error("getItemsInInventoryWithSlots: player is null!")
return map
}
for (slot in player.openContainer.inventorySlots) {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/KSerializable.kt b/src/main/java/at/hannibal2/skyhanni/utils/KSerializable.kt
index d075f35f7..5b80dc8b3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/KSerializable.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/KSerializable.kt
@@ -24,19 +24,17 @@ import com.google.gson.internal.`$Gson$Types` as InternalGsonTypes
@Target(AnnotationTarget.CLASS)
annotation class KSerializable
-
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class ExtraData
-
class KotlinTypeAdapterFactory : TypeAdapterFactory {
internal data class ParameterInfo(
val param: KParameter,
val adapter: TypeAdapter,
val name: String,
- val field: KProperty1
+ val field: KProperty1,
)
@OptIn(ExperimentalStdlibApi::class)
@@ -110,4 +108,4 @@ class KotlinTypeAdapterFactory : TypeAdapterFactory {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/KeyboardManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/KeyboardManager.kt
index 335ac1202..1050c5c98 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/KeyboardManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/KeyboardManager.kt
@@ -13,6 +13,7 @@ import org.lwjgl.input.Keyboard
import org.lwjgl.input.Mouse
object KeyboardManager {
+
private var lastClickedMouseButton = -1
// A mac-only key, represents Windows key on windows (but different key code)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt
index e8b0d76bc..39c877db0 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzColor.kt
@@ -39,6 +39,7 @@ enum class LorenzColor(private val chatColorCode: Char, private val color: Color
override fun toString(): String = coloredLabel
companion object {
+
fun EnumDyeColor.toLorenzColor() = when (this) {
EnumDyeColor.WHITE -> WHITE
EnumDyeColor.MAGENTA -> LIGHT_PURPLE
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzDebug.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzDebug.kt
index 93bd8419e..664ef5fd6 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzDebug.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzDebug.kt
@@ -10,7 +10,7 @@ object LorenzDebug {
}
fun chatAndLog(text: String) {
- LorenzUtils.debug(text)
+ ChatUtils.debug(text)
log(text)
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
index e949742cd..26f56fcca 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
@@ -15,10 +15,12 @@ import java.util.logging.Logger
import kotlin.time.Duration.Companion.days
class LorenzLogger(filePath: String) {
+
private val format = SimpleDateFormat("HH:mm:ss")
private val fileName = "$PREFIX_PATH$filePath.log"
companion object {
+
private var LOG_DIRECTORY = File("config/skyhanni/logs")
private var PREFIX_PATH: String
var hasDone = false
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
index 9c4116da4..33731505f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
@@ -6,10 +6,11 @@ import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.MayorElection
import at.hannibal2.skyhanni.data.TitleManager
import at.hannibal2.skyhanni.events.GuiContainerEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiEditSign
import at.hannibal2.skyhanni.test.TestBingo
+import at.hannibal2.skyhanni.utils.ChatUtils.lastButtonClicked
+import at.hannibal2.skyhanni.utils.CollectionUtils.sortedDesc
import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.StringUtils.capAtMinecraftLength
@@ -17,44 +18,20 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.toDashlessUUID
import at.hannibal2.skyhanni.utils.renderables.Renderable
import com.google.gson.JsonPrimitive
-import io.github.moulberry.moulconfig.observer.Observer
-import io.github.moulberry.moulconfig.observer.Property
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiEditSign
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.SharedMonsterAttributes
-import net.minecraft.event.ClickEvent
-import net.minecraft.event.HoverEvent
import net.minecraft.launchwrapper.Launch
import net.minecraft.util.ChatComponentText
import net.minecraftforge.fml.common.FMLCommonHandler
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.awt.Color
-import java.lang.reflect.Constructor
-import java.lang.reflect.Field
-import java.lang.reflect.Modifier
import java.text.DecimalFormat
import java.text.SimpleDateFormat
-import java.util.Collections
-import java.util.LinkedList
-import java.util.Queue
import java.util.Timer
import java.util.TimerTask
-import java.util.WeakHashMap
-import java.util.concurrent.ConcurrentLinkedQueue
import java.util.regex.Matcher
-import kotlin.properties.ReadWriteProperty
-import kotlin.reflect.KMutableProperty1
-import kotlin.reflect.KProperty
-import kotlin.reflect.KProperty0
-import kotlin.reflect.KProperty1
-import kotlin.reflect.full.isSubtypeOf
-import kotlin.reflect.full.memberProperties
-import kotlin.reflect.full.starProjectedType
-import kotlin.reflect.jvm.isAccessible
import kotlin.time.Duration
-import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
object LorenzUtils {
@@ -90,98 +67,6 @@ object LorenzUtils {
val lastWorldSwitch get() = HypixelData.joinedWorld
- // TODO log based on chat category (error, warning, debug, user error, normal)
- private val log = LorenzLogger("chat/mod_sent")
- var lastButtonClicked = 0L
-
- private const val DEBUG_PREFIX = "[SkyHanni Debug] §7"
- private const val USER_ERROR_PREFIX = "§c[SkyHanni] "
- private val ERROR_PREFIX by lazy { "§c[SkyHanni-${SkyHanniMod.version}] " }
- private const val CHAT_PREFIX = "[SkyHanni] "
-
- /**
- * Sends a debug message to the chat and the console.
- * This is only sent if the debug feature is enabled.
- *
- * @param message The message to be sent
- *
- * @see DEBUG_PREFIX
- */
- fun debug(message: String) {
- if (SkyHanniMod.feature.dev.debug.enabled && internalChat(DEBUG_PREFIX + message)) {
- consoleLog("[Debug] $message")
- }
- }
-
- /**
- * Sends a message to the user that they did something incorrectly.
- * We should tell them what to do instead as well.
- *
- * @param message The message to be sent
- *
- * @see USER_ERROR_PREFIX
- */
- fun userError(message: String) {
- internalChat(USER_ERROR_PREFIX + message)
- }
-
- /**
- * 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.
- *
- * Why deprecate this? Even if this message is descriptive for the user and the developer,
- * we don't want inconsitencies in errors, and we would need to search
- * for the code line where this error gets printed any way.
- * so it's better to use the stack trace still.
- *
- * @param message The message to be sent
- * @param prefix Whether to prefix the message with the error prefix, default true
- *
- * @see ERROR_PREFIX
- */
- @Deprecated(
- "Do not send the user a non clickable non stacktrace containing error message.",
- ReplaceWith("ErrorManager")
- )
- fun error(message: String) {
- println("error: '$message'")
- internalChat(ERROR_PREFIX + message)
- }
-
- /**
- * Sends a message to the user
- * @param message The message to be sent
- * @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
- */
- fun chat(message: String, prefix: Boolean = true, prefixColor: String = "§e") {
- if (prefix) {
- internalChat(prefixColor + CHAT_PREFIX + message)
- } else {
- internalChat(message)
- }
- }
-
- private fun internalChat(message: String): Boolean {
- log.log(message)
- val minecraft = Minecraft.getMinecraft()
- if (minecraft == null) {
- consoleLog(message.removeColor())
- return false
- }
-
- val thePlayer = minecraft.thePlayer
- if (thePlayer == null) {
- consoleLog(message.removeColor())
- return false
- }
-
- thePlayer.addChatMessage(ChatComponentText(message))
- return true
- }
-
fun SimpleDateFormat.formatCurrentTime(): String = this.format(System.currentTimeMillis())
fun stripVanillaMessage(originalMessage: String): String {
@@ -254,18 +139,6 @@ object LorenzUtils {
}
}
- fun > List>.sorted(): List> {
- return sortedBy { (_, value) -> value }
- }
-
- fun > Map.sorted(): Map {
- return toList().sorted().toMap()
- }
-
- fun > Map.sortedDesc(): Map {
- return toList().sorted().reversed().toMap()
- }
-
fun getSBMonthByName(month: String): Int {
var monthNr = 0
for (i in 1..12) {
@@ -283,10 +156,6 @@ object LorenzUtils {
fun getPlayerName(): String = Minecraft.getMinecraft().thePlayer.name
- fun MutableList
>.addAsSingletonList(text: E) {
- add(Collections.singletonList(text))
- }
-
// (key -> value) -> (sorting value -> key item icon)
fun fillTable(list: MutableList>, data: MutableMap, Pair>) {
val keys = data.mapValues { (_, v) -> v.first }.sortedDesc().keys
@@ -321,140 +190,6 @@ object LorenzUtils {
lines[index] = ChatComponentText(text.capAtMinecraftLength(91))
}
- /**
- * 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
- */
- fun clickableChat(message: String, command: String, prefix: Boolean = true, prefixColor: String = "§e") {
- val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
- val text = ChatComponentText(msgPrefix + message)
- val fullCommand = "/" + command.removePrefix("/")
- text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand)
- text.chatStyle.chatHoverEvent =
- HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText("§eExecute $fullCommand"))
- Minecraft.getMinecraft().thePlayer.addChatMessage(text)
- }
-
- /**
- * Sends a message to the user that they can click and run a command
- * @param message The message to be sent
- * @param hover The message to be shown when the message is hovered
- * @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
- */
- fun hoverableChat(
- message: String,
- hover: List,
- command: String? = null,
- prefix: Boolean = true,
- prefixColor: String = "§e",
- ) {
- val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
- val text = ChatComponentText(msgPrefix + message)
- text.chatStyle.chatHoverEvent =
- HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText(hover.joinToString("\n")))
-
- command?.let {
- text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${it.removePrefix("/")}")
- }
-
- Minecraft.getMinecraft().thePlayer.addChatMessage(text)
- }
-
- /**
- * Sends a message to the user that they can click and run a command
- * @param message The message to be sent
- * @param url The url to be opened
- * @param autoOpen Automatically opens the url as well as sending the clickable link message
- * @param hover The message to be shown when the message is hovered
- * @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
- */
- fun clickableLinkChat(
- message: String,
- url: String,
- hover: String = "§eOpen $url",
- autoOpen: Boolean = false,
- prefix: Boolean = true,
- 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"))
- Minecraft.getMinecraft().thePlayer.addChatMessage(text)
- if (autoOpen) OSUtils.openBrowser(url)
- }
-
- fun Map.moveEntryToTop(matcher: (Map.Entry) -> Boolean): Map {
- val entry = entries.find(matcher)
- if (entry != null) {
- val newMap = linkedMapOf(entry.key to entry.value)
- newMap.putAll(this)
- return newMap
- }
- return this
- }
-
- private var lastMessageSent = SimpleTimeMark.farPast()
- private val sendQueue: Queue = LinkedList()
-
- @SubscribeEvent
- fun sendQueuedChatMessages(event: LorenzTickEvent) {
- val player = Minecraft.getMinecraft().thePlayer
- if (player == null) {
- sendQueue.clear()
- return
- }
- if (lastMessageSent.passedSince() > 300.milliseconds) {
- player.sendChatMessage(sendQueue.poll() ?: return)
- lastMessageSent = SimpleTimeMark.now()
- }
- }
-
- fun sendCommandToServer(command: String) {
- sendMessageToServer("/$command")
- }
-
- fun sendMessageToServer(message: String) {
- sendQueue.add(message)
- }
-
- // MoulConfig is in Java, I don't want to downgrade this logic
- fun onChange(vararg properties: Property, observer: Observer) {
- for (property in properties) {
- property.whenChanged { a, b -> observer.observeChange(a, b) }
- }
- }
-
- fun onToggle(vararg properties: Property, observer: Runnable) {
- onChange(*properties) { _, _ -> observer.run() }
- }
-
- fun Property.onToggle(observer: Runnable) {
- whenChanged { _, _ -> observer.run() }
- }
-
- fun Property.afterChange(observer: T.() -> Unit) {
- whenChanged { _, new -> observer(new) }
- }
-
- fun Map.editCopy(function: MutableMap.() -> Unit) =
- toMutableMap().also { function(it) }.toMap()
-
- fun List.editCopy(function: MutableList.() -> Unit) =
- toMutableList().also { function(it) }.toList()
-
fun colorCodeToRarity(colorCode: Char): String {
return when (colorCode) {
'f' -> "Common"
@@ -525,61 +260,6 @@ object LorenzUtils {
})
}
- // TODO nea?
-// fun dynamic(block: () -> KMutableProperty0?): ReadWriteProperty {
-// return object : ReadWriteProperty {
-// override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
-// return block()?.get()
-// }
-//
-// override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
-// if (value != null)
-// block()?.set(value)
-// }
-// }
-// }
-
- fun dynamic(root: KProperty0, child: KMutableProperty1) =
- object : ReadWriteProperty {
- override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
- val rootObj = root.get() ?: return null
- return child.get(rootObj)
- }
-
- override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
- if (value == null) return
- val rootObj = root.get() ?: return
- child.set(rootObj, value)
- }
- }
-
- inline fun Any.getPropertiesWithType() =
- this::class.memberProperties
- .filter { it.returnType.isSubtypeOf(T::class.starProjectedType) }
- .map {
- it.isAccessible = true
- (it as KProperty1).get(this)
- }
-
- fun List.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after }, skip)
-
- fun List.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? {
- var missing = -1
- for (line in this) {
- if (after(line)) {
- missing = skip - 1
- continue
- }
- if (missing == 0) {
- return line
- }
- if (missing != -1) {
- missing--
- }
- }
- return null
- }
-
fun GuiEditSign.isRancherSign(): Boolean {
if (this !is AccessorGuiEditSign) return false
@@ -591,74 +271,6 @@ object LorenzUtils {
fun IslandType.isInIsland() = inSkyBlock && skyBlockIsland == this
- fun MutableMap.addOrPut(key: K, number: Int): Int {
- val currentValue = this[key] ?: 0
- val newValue = currentValue + number
- this[key] = newValue
- return newValue
- }
-
- fun MutableMap.addOrPut(key: K, number: Long): Long {
- val currentValue = this[key] ?: 0L
- val newValue = currentValue + number
- this[key] = newValue
- return newValue
- }
-
- fun MutableMap.addOrPut(key: K, number: Double): Double {
- val currentValue = this[key] ?: 0.0
- val newValue = currentValue + number
- this[key] = newValue
- return newValue
- }
-
- fun Map.sumAllValues(): Double {
- if (values.isEmpty()) return 0.0
-
- return when (values.first()) {
- is Double -> values.sumOf { it.toDouble() }
- is Float -> values.sumOf { it.toDouble() }
- is Long -> values.sumOf { it.toLong() }.toDouble()
- else -> values.sumOf { it.toInt() }.toDouble()
- }
- }
-
- /** transfer string colors from the config to java.awt.Color */
- fun String.toChromaColor() = Color(SpecialColour.specialToChromaRGB(this), true)
-
- fun List.getOrNull(index: Int): E? {
- return if (index in indices) {
- get(index)
- } else null
- }
-
- fun T?.toSingletonListOrEmpty(): List {
- if (this == null) return emptyList()
- return listOf(this)
- }
-
- fun Field.makeAccessible() = also { isAccessible = true }
-
- fun Constructor.makeAccessible() = also { isAccessible = true }
-
- // Taken and modified from Skytils
- @JvmStatic
- fun T.equalsOneOf(vararg other: T): Boolean {
- for (obj in other) {
- if (this == obj) return true
- }
- return false
- }
-
- infix fun MutableMap.put(pairs: Pair) {
- this[pairs.first] = pairs.second
- }
-
- fun Field.removeFinal(): Field {
- javaClass.getDeclaredField("modifiers").makeAccessible().set(this, modifiers and (Modifier.FINAL.inv()))
- return this
- }
-
fun GuiContainerEvent.SlotClickEvent.makeShiftClick() =
slot?.slotNumber?.let { slotNumber ->
Minecraft.getMinecraft().playerController.windowClick(
@@ -666,8 +278,6 @@ object LorenzUtils {
)?.also { isCanceled = true }
}
- fun List.indexOfFirst(vararg args: T) = args.map { indexOf(it) }.firstOrNull { it != -1 }
-
private val recalculateDerpy =
RecalculatingValue(1.seconds) { MayorElection.isPerkActive("Derpy", "DOUBLE MOBS HP!!!") }
@@ -687,12 +297,6 @@ object LorenzUtils {
val JsonPrimitive.asIntOrNull get() = takeIf { it.isNumber }?.asInt
- fun T.transformIf(condition: T.() -> Boolean, transofmration: T.() -> T) =
- if (condition()) transofmration(this) else this
-
- fun T.conditionalTransform(condition: Boolean, ifTrue: T.() -> Any, ifFalse: T.() -> Any) =
- if (condition) ifTrue(this) else ifFalse(this)
-
fun sendTitle(text: String, duration: Duration, height: Double = 1.8, fontSize: Float = 4f) {
TitleManager.sendTitle(text, duration, height, fontSize)
}
@@ -722,6 +326,10 @@ object LorenzUtils {
FMLCommonHandler.instance().handleExit(-1)
}
+ fun sendCommandToServer(command: String) {
+ ChatUtils.sendMessageToServer("/$command")
+ }
+
/**
* Get the group, otherwise, return null
* @param groupName The group name in the pattern
@@ -730,16 +338,29 @@ object LorenzUtils {
return runCatching { this.group(groupName) }.getOrNull()
}
- fun ConcurrentLinkedQueue.drainTo(list: MutableCollection) {
- while (true)
- list.add(this.poll() ?: break)
- }
+ @Deprecated("moved", ReplaceWith("ChatUtils.debug"))
+ fun debug(message: String) = ChatUtils.debug(message)
- // Let garbage collector handle the removal of entries in this list
- fun weakReferenceList(): MutableSet = Collections.newSetFromMap(WeakHashMap())
+ @Deprecated("moved", ReplaceWith("ChatUtils.userError"))
+ fun userError(message: String) = ChatUtils.userError(message)
- fun MutableCollection.filterToMutable(predicate: (T) -> Boolean) = filterTo(mutableListOf(), predicate)
+ @Deprecated("moved", ReplaceWith("ChatUtils.chat"))
+ fun chat(message: String, prefix: Boolean = true, prefixColor: String = "§e") =
+ ChatUtils.chat(message, prefix, prefixColor)
+
+ @Deprecated("moved", ReplaceWith("ChatUtils.clickableChat"))
+ fun clickableChat(message: String, command: String, prefix: Boolean = true, prefixColor: String = "§e") =
+ ChatUtils.clickableChat(message, command, prefix, prefixColor)
+
+ @Deprecated("moved", ReplaceWith("ChatUtils.hoverableChat"))
+ fun hoverableChat(
+ message: String,
+ hover: List,
+ command: String? = null,
+ prefix: Boolean = true,
+ prefixColor: String = "§e",
+ ) = ChatUtils.hoverableChat(message, hover, command, prefix, prefixColor)
- val Long.ticks get() = (this * 50).milliseconds
- val Int.ticks get() = (this * 50).milliseconds
+ @Deprecated("moved", ReplaceWith("ChatUtils.sendMessageToServer"))
+ fun sendMessageToServer(message: String) = ChatUtils.sendMessageToServer(message)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
index ba337b620..03f623f70 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
@@ -144,6 +144,7 @@ data class LorenzVec(
}
companion object {
+
fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec {
val yaw: Double = (yaw + 90) * Math.PI / 180
val pitch: Double = (pitch + 90) * Math.PI / 180
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
index 3e1919d8b..c6ebdd836 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
@@ -24,6 +24,7 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
private val patternBiomeIdBounds = "Biome ID is out of bounds: (\\d+), defaulting to 0 \\(Ocean\\)".toPattern()
companion object {
+
fun initLogging() {
val ctx: LoggerContext = LogManager.getContext(false) as LoggerContext
@@ -56,7 +57,7 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
filterConsole("Unknown soundEvent (minecraft:)")
return Filter.Result.DENY
}
- //TODO testing
+ // TODO testing
if (filterConfig.filterParticleVillagerHappy && formattedMessage == "Could not spawn particle effect VILLAGER_HAPPY") {
filterConsole("particle VILLAGER_HAPPY")
return Filter.Result.DENY
@@ -83,7 +84,7 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
}
}
- //TODO find a way to load the filter earlier to filter these messages too
+ // TODO find a way to load the filter earlier to filter these messages too
// if (loggerName == "LaunchWrapper") {
// //The jar file C:\Users\Lorenz\AppData\Roaming\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar has a security seal for path org.lwjgl.opengl, but that path is defined and not secure
// if (formattedMessage.startsWith("The jar file ")) {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftDispatcher.kt b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftDispatcher.kt
index 8771de215..7cbfffe37 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftDispatcher.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftDispatcher.kt
@@ -5,6 +5,7 @@ import net.minecraft.client.Minecraft
import kotlin.coroutines.CoroutineContext
object MinecraftDispatcher : MainCoroutineDispatcher() {
+
override val immediate: MainCoroutineDispatcher
get() = this
@@ -15,4 +16,4 @@ object MinecraftDispatcher : MainCoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
Minecraft.getMinecraft().addScheduledTask(block)
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
index bc3b1789e..f50a5e1dd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
@@ -1,7 +1,7 @@
package at.hannibal2.skyhanni.utils
-import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpace
import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson
+import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpace
class MultiFilter {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt
index dd798d7bf..4e0762895 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NBTTypeAdapter.kt
@@ -10,6 +10,7 @@ import java.io.ByteArrayOutputStream
import java.util.Base64
object NBTTypeAdapter : TypeAdapter() {
+
override fun write(out: JsonWriter, value: NBTTagCompound) {
val baos = ByteArrayOutputStream()
CompressedStreamTools.writeCompressed(value, baos)
@@ -20,4 +21,4 @@ object NBTTypeAdapter : TypeAdapter() {
val bais = ByteArrayInputStream(Base64.getDecoder().decode(reader.nextString()))
return CompressedStreamTools.readCompressed(bais)
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUInternalName.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUInternalName.kt
index d4499ab12..26bfcc799 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUInternalName.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUInternalName.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.utils
class NEUInternalName private constructor(private val internalName: String) {
companion object {
+
private val map = mutableMapOf()
val NONE = "NONE".asInternalName()
@@ -39,4 +40,4 @@ class NEUInternalName private constructor(private val internalName: String) {
fun replace(oldValue: String, newValue: String) =
internalName.replace(oldValue.uppercase(), newValue.uppercase()).asInternalName()
-}
\ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index cd1838bdc..06901f239 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -35,6 +35,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.opengl.GL11
object NEUItems {
+
val manager: NEUManager get() = NotEnoughUpdates.INSTANCE.manager
private val itemNameCache = mutableMapOf() // item name -> internal name
private val multiplierCache = mutableMapOf>()
@@ -213,7 +214,6 @@ object NEUItems {
fun isVanillaItem(item: ItemStack): Boolean =
manager.auctionManager.isVanillaItem(item.getInternalName().asString())
-
fun ItemStack.renderOnScreen(x: Float, y: Float, scaleMultiplier: Double = 1.0) {
val item = checkBlinkItem()
val isSkull = item.item === Items.skull
@@ -327,7 +327,6 @@ object NEUItems {
val result = Pair(internalName, 1)
multiplierCache[internalName] = result
return result
-
}
@Deprecated("Do not use strings as id", ReplaceWith("getMultiplier with NEUInternalName"))
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
index 31062b559..639d57bd0 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
@@ -7,6 +7,7 @@ import kotlin.math.pow
import kotlin.math.roundToInt
object NumberUtil {
+
@JvmField
val nf: NumberFormat = NumberFormat.getInstance(Locale.US)
private val