diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
42 files changed, 746 insertions, 223 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt index c0116f57c..1801e7802 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt @@ -41,9 +41,13 @@ object APIUtil { .useSystemProperties() fun getJSONResponse(urlString: String, silentError: Boolean = false) = - getJSONResponseAsElement(urlString, silentError) as JsonObject + getJSONResponseAsElement(urlString, silentError) as JsonObject - fun getJSONResponseAsElement(urlString: String, silentError: Boolean = false, apiName: String = "Hypixel API"): JsonElement { + fun getJSONResponseAsElement( + urlString: String, + silentError: Boolean = false, + apiName: String = "Hypixel API" + ): JsonElement { val client = builder.build() try { client.execute(HttpGet(urlString)).use { response -> @@ -60,7 +64,7 @@ object APIUtil { } else if (retSrc.contains("<center><h1>502 Bad Gateway</h1></center>")) { if (showApiErrors && apiName == "Hypixel API") { LorenzUtils.clickableChat( - "[SkyHanni] Problems with detecting the Hypixel API. §eClick here to hide this message for now.", + "Problems with detecting the Hypixel API. §eClick here to hide this message for now.", "shtogglehypixelapierrors" ) } @@ -128,6 +132,6 @@ object APIUtil { fun toggleApiErrorMessages() { showApiErrors = !showApiErrors - LorenzUtils.chat("§e[SkyHanni] Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown") + LorenzUtils.chat("Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt index 5a14cadf7..9bc353820 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt @@ -53,4 +53,4 @@ object BlockUtils { Minecraft.getMinecraft().thePlayer.lookVec.toLorenzVec(), duration ) -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt index 8f05d64ec..9d00958f2 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt @@ -1,11 +1,24 @@ package at.hannibal2.skyhanni.utils data class CachedItemData( - /** -1 = not loaded */ var petCandies: Int? = -1, - /** "" = not loaded */ var heldItem: String? = "", - /** -1 = not loaded */ var sackInASack: Int? = -1, - /** null = not loaded */ var riftTransferable: Boolean? = null, - /** null = not loaded */ var riftExportable: Boolean? = null, - /** null = not loaded */ var itemRarityLastCheck: Long = 0L, // Cant use SimpleTimeMark here - /** null = not loaded */ var itemRarity: LorenzRarity? = null, -)
\ No newline at end of file + // -1 = not loaded + var petCandies: Int? = -1, + + // "" = not loaded + var heldItem: String? = "", + + // -1 = not loaded + var sackInASack: Int? = -1, + + // null = not loaded + var riftTransferable: Boolean? = null, + + // null = not loaded + var riftExportable: Boolean? = null, + + // null = not loaded + var itemRarityLastCheck: Long = 0L, // Cant use SimpleTimeMark here + + // null = not loaded + var itemRarity: LorenzRarity? = null, +) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt index cbd39849d..b0af1d93e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt @@ -72,8 +72,8 @@ object CombatUtils { lastKillUpdate = System.currentTimeMillis() killGainHourLast = killGainHour - GhostCounter.hidden?.bestiaryNextLevel?.toInt()?.let { nextLevel -> - GhostCounter.hidden?.bestiaryCurrentKill?.toInt()?.let { kill -> + GhostCounter.storage?.bestiaryNextLevel?.toInt()?.let { nextLevel -> + GhostCounter.storage?.bestiaryCurrentKill?.toInt()?.let { kill -> val sum = GhostData.bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum() val cKill = sum + kill val totalKill = if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill else cKill @@ -112,4 +112,4 @@ object CombatUtils { return interp } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt index fbe2f1e96..28fc08807 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt @@ -104,13 +104,13 @@ object EntityOutlineRenderer { mc.renderManager.setRenderOutlines(true) // Enable outline mode - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_REPLACE); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL13.GL_CONSTANT); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_REPLACE); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_ALPHA, GL11.GL_TEXTURE); - GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA); + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_REPLACE) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL13.GL_CONSTANT) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_REPLACE) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_ALPHA, GL11.GL_TEXTURE) + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA) // Render x-ray outlines first, ignoring the depth buffer bit if (!isXrayCacheEmpty()) { @@ -293,7 +293,7 @@ object EntityOutlineRenderer { // Only render the view entity when sleeping or in 3rd person mode if (entity === mc.renderViewEntity && !(mc.renderViewEntity is EntityLivingBase && (mc.renderViewEntity as EntityLivingBase).isPlayerSleeping || - mc.gameSettings.thirdPersonView != 0) + mc.gameSettings.thirdPersonView != 0) ) { false } else mc.theWorld.isBlockLoaded(BlockPos(entity)) && (mc.renderManager.shouldRender( @@ -339,7 +339,7 @@ object EntityOutlineRenderer { } } - fun isCacheEmpty() = isXrayCacheEmpty() && isNoXrayCacheEmpty() + private fun isCacheEmpty() = isXrayCacheEmpty() && isNoXrayCacheEmpty() private fun isXrayCacheEmpty() = entityRenderCache.xrayCache?.isEmpty() ?: true private fun isNoXrayCacheEmpty() = entityRenderCache.noXrayCache?.isEmpty() ?: true @@ -361,12 +361,12 @@ object EntityOutlineRenderer { */ @SubscribeEvent fun onTick(event: LorenzTickEvent) { - if (!(event.phase == EventPriority.NORMAL && isEnabled())) return; + if (!(event.phase == EventPriority.NORMAL && isEnabled())) return val renderGlobal = try { mc.renderGlobal as CustomRenderGlobal } catch (e: NoClassDefFoundError) { - ErrorManager.logError(e, "Unable to enable entity outlines, the required mixin is not loaded") + ErrorManager.logErrorWithData(e, "Unable to enable entity outlines, the required mixin is not loaded") isMissingMixin = true return } @@ -406,4 +406,4 @@ object EntityOutlineRenderer { var noXrayCache: HashMap<Entity, Int>?, var noOutlineCache: HashSet<Entity>? ) -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt index 1269ec005..5e4a63452 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt @@ -164,9 +164,8 @@ object GuiRenderUtils { drawTooltip(textLines, mouseX, mouseY, screenHeight, Minecraft.getMinecraft().fontRendererObj) } - fun isPointInRect(x: Int, y: Int, left: Int, top: Int, width: Int, height: Int): Boolean { - return left <= x && x < left + width && top <= y && y < top + height - } + fun isPointInRect(x: Int, y: Int, left: Int, top: Int, width: Int, height: Int) = + left <= x && x < left + width && top <= y && y < top + height fun drawProgressBar(x: Int, y: Int, barWidth: Int, progress: Float) { GuiScreen.drawRect(x, y, x + barWidth, y + 6, 0xFF43464B.toInt()) @@ -181,7 +180,15 @@ object GuiRenderUtils { ) } - fun renderItemAndTip(list: MutableList<String>, item: ItemStack?, x: Int, y: Int, mouseX: Int, mouseY: Int, color: Int = 0xFF43464B.toInt()) { + fun renderItemAndTip( + list: MutableList<String>, + item: ItemStack?, + x: Int, + y: Int, + mouseX: Int, + mouseY: Int, + color: Int = 0xFF43464B.toInt() + ) { GuiScreen.drawRect(x, y, x + 16, y + 16, color) if (item != null) { renderItemStack(item, x, y) @@ -277,12 +284,14 @@ object GuiRenderUtils { } fun drawScaledRec(left: Int, top: Int, right: Int, bottom: Int, colour: Int, inverseScale: Float) { - GuiScreen.drawRect((left * inverseScale).toInt(), (top * inverseScale).toInt(), - (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour) + GuiScreen.drawRect( + (left * inverseScale).toInt(), (top * inverseScale).toInt(), + (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour + ) } fun renderItemAndBackground(item: ItemStack, x: Int, y: Int, colour: Int) { renderItemStack(item, x, y) GuiScreen.drawRect(x, y, x + 16, y + 16, colour) } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index 4c60444c1..be29569a5 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -1,14 +1,12 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.config.ConfigManager -import at.hannibal2.skyhanni.data.OtherMod import at.hannibal2.skyhanni.test.command.ErrorManager +import io.github.moulberry.notenoughupdates.NotEnoughUpdates import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.inventory.ContainerChest import net.minecraft.inventory.Slot import net.minecraft.item.ItemStack -import java.io.File import kotlin.time.Duration.Companion.seconds object InventoryUtils { @@ -40,13 +38,14 @@ object InventoryUtils { fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() fun getItemsInOwnInventory() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory.filterNotNull() + fun getItemsInOwnInventoryWithNull() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory fun countItemsInLowerInventory(predicate: (ItemStack) -> Boolean) = getItemsInOwnInventory().filter { predicate(it) }.sumOf { it.stackSize } 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 @@ -55,17 +54,16 @@ object InventoryUtils { val isNeuStorageEnabled = RecalculatingValue(10.seconds) { try { - val configPath = OtherMod.NEU.configPath - if (File(configPath).exists()) { - val json = ConfigManager.gson.fromJson( - APIUtil.readFile(File(configPath)), - com.google.gson.JsonObject::class.java - ) - json["storageGUI"].asJsonObject["enableStorageGUI3"].asBoolean - } else false - } catch (e: Exception) { + val config = NotEnoughUpdates.INSTANCE.config + + val storageField = config.javaClass.getDeclaredField("storageGUI") + val storage = storageField.get(config) + + val booleanField = storage.javaClass.getDeclaredField("enableStorageGUI3") + booleanField.get(storage) as Boolean + } catch (e: Throwable) { ErrorManager.logError(e, "Could not read NEU config to determine if the neu storage is emabled.") false } } -}
\ 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 2c5ab63d3..a1b7ed09f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -65,7 +65,7 @@ object ItemUtils { val list: LinkedList<ItemStack> = LinkedList() val player = Minecraft.getMinecraft().thePlayer if (player == null) { - LorenzUtils.warning("getItemsInInventoryWithSlots: player is null!") + LorenzUtils.error("getItemsInInventoryWithSlots: player is null!") return list } for (slot in player.openContainer.inventorySlots) { @@ -75,7 +75,7 @@ object ItemUtils { } if (withCursorItem && player.inventory != null && player.inventory.itemStack != null) { - list.add(player.inventory.itemStack) + list.add(player.inventory.itemStack) } return list } @@ -84,7 +84,7 @@ object ItemUtils { val map: LinkedHashMap<ItemStack, Int> = LinkedHashMap() val player = Minecraft.getMinecraft().thePlayer if (player == null) { - LorenzUtils.warning("getItemsInInventoryWithSlots: player is null!") + LorenzUtils.error("getItemsInInventoryWithSlots: player is null!") return map } for (slot in player.openContainer.inventorySlots) { @@ -220,9 +220,13 @@ object ItemUtils { val rarity = LorenzRarity.readItemRarity(this) data.itemRarity = rarity if (rarity == null && logError) { - ErrorManager.logErrorState( + ErrorManager.logErrorStateWithData( "Could not read rarity for item $name", - "getItemRarityOrNull not found for: $internalName, name:'$name''" + "Failed to read rarity from item rarity via item lore", + "internal name" to internalName, + "item name" to name, + "inventory name" to InventoryUtils.openInventoryName(), + "lore" to getLore(), ) } return rarity @@ -302,15 +306,18 @@ object ItemUtils { return getItemStack().nameWithEnchantment ?: error("Could not find item name for $this") } - private fun getPetRarity(pet: ItemStack): LorenzRarity? { val rarityId = pet.getInternalName().asString().split(";").last().toInt() val rarity = LorenzRarity.getById(rarityId) val name = pet.name if (rarity == null) { - ErrorManager.logErrorState( + ErrorManager.logErrorStateWithData( "Could not read rarity for pet $name", - "getPetRarity not found for: ${pet.getInternalName()}, name:'$name'" + "Failed to read rarity from pet item via internal name", + "internal name" to pet.getInternalName(), + "item name" to name, + "rarity id" to rarityId, + "inventory name" to InventoryUtils.openInventoryName() ) } return rarity diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt index fafb41c96..e6929d737 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt @@ -6,9 +6,8 @@ import net.minecraft.util.AxisAlignedBB object LocationUtils { - fun canSee(a: LorenzVec, b: LorenzVec): Boolean { - return Minecraft.getMinecraft().theWorld.rayTraceBlocks(a.toVec3(), b.toVec3(), false, true, false) == null - } + fun canSee(a: LorenzVec, b: LorenzVec) = + Minecraft.getMinecraft().theWorld.rayTraceBlocks(a.toVec3(), b.toVec3(), false, true, false) == null fun playerLocation() = Minecraft.getMinecraft().thePlayer.getLorenzVec() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt index a382a5149..e949742cd 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt @@ -1,20 +1,27 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.utils.LorenzUtils.formatCurrentTime +import kotlinx.coroutines.launch import java.io.File import java.io.IOException +import java.nio.file.Files +import java.nio.file.attribute.BasicFileAttributes import java.text.SimpleDateFormat import java.util.logging.FileHandler import java.util.logging.Formatter import java.util.logging.LogRecord 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 init { val format = SimpleDateFormat("yyyy_MM_dd/HH_mm_ss").formatCurrentTime() @@ -53,6 +60,37 @@ class LorenzLogger(filePath: String) { } catch (e: IOException) { e.printStackTrace() } + + if (!hasDone && LorenzUtils.onHypixel) { + hasDone = true + val directoryFiles = LOG_DIRECTORY.listFiles() ?: run { + println("log directory has no files") + return logger + } + SkyHanniMod.coroutineScope.launch { + val timeToDelete = SkyHanniMod.feature.dev.logExpiryTime.days + + for (file in directoryFiles) { + val path = file.toPath() + try { + val attributes = Files.readAttributes(path, BasicFileAttributes::class.java) + val creationTime = attributes.creationTime().toMillis() + val timeSinceCreation = SimpleTimeMark(creationTime).passedSince() + if (timeSinceCreation > timeToDelete) { + if (!file.deleteRecursively()) { + println("failed to delete directory: ${file.name}") + } + } + } catch (e: SecurityException) { + e.printStackTrace() + } catch (e: IOException) { + e.printStackTrace() + println("Error: Unable to get creation date.") + } + } + } + } + return logger } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt index d589df3ac..35868027f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt @@ -29,9 +29,10 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) { fun oneBelow(logError: Boolean = true): LorenzRarity? {
val rarityBelow = getById(ordinal - 1)
if (rarityBelow == null && logError) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Problem with item rarity detected.",
- "Trying to get an item rarity below common"
+ "Trying to get an item rarity below common",
+ "ordinal" to ordinal
)
}
return rarityBelow
@@ -40,9 +41,10 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) { fun oneAbove(logError: Boolean = true): LorenzRarity? {
val rarityBelow = getById(ordinal + 1)
if (rarityBelow == null && logError) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Problem with item rarity detected.",
- "Trying to get an item rarity above special"
+ "Trying to get an item rarity above special",
+ "ordinal" to ordinal
)
}
return rarityBelow
@@ -65,4 +67,4 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) { }
}
-}
\ No newline at end of file +}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 28afe3b4e..90970a315 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -64,28 +64,78 @@ object LorenzUtils { val lastWorldSwitch get() = HypixelData.joinedWorld - const val DEBUG_PREFIX = "[SkyHanni Debug] §7" + // 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") } } - // TODO remove ig? - fun warning(message: String) { - internalChat("§cWarning! $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("§c$message") - } - - fun chat(message: String) { - internalChat(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 { @@ -133,12 +183,13 @@ object LorenzUtils { var multiplier = 1.0 repeat(decimals) { multiplier *= 10 } val result = kotlin.math.round(this * multiplier) / multiplier - val a = result.toString() - val b = toString() - return if (a.length > b.length) this else result.toFloat() + val a = result.toString().length + val b = toString().length + return if (a > b) this else result.toFloat() } // TODO replace all calls with regex + @Deprecated("Do not use complicated string operations", ReplaceWith("Regex")) fun String.between(start: String, end: String): String = this.split(start, end)[1] // TODO use derpy() on every use case @@ -203,7 +254,7 @@ object LorenzUtils { fun getRawPlayerUuid() = Minecraft.getMinecraft().thePlayer.uniqueID - fun getPlayerName() = Minecraft.getMinecraft().thePlayer.name + fun getPlayerName(): String = Minecraft.getMinecraft().thePlayer.name fun <E> MutableList<List<E>>.addAsSingletonList(text: E) { add(Collections.singletonList(text)) @@ -243,8 +294,18 @@ object LorenzUtils { lines[index] = ChatComponentText(text.capAtMinecraftLength(90)) } - fun clickableChat(message: String, command: String) { - val text = ChatComponentText(message) + /** + * 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 = @@ -252,13 +313,30 @@ object LorenzUtils { Minecraft.getMinecraft().thePlayer.addChatMessage(text) } - fun hoverableChat(message: String, hover: List<String>, command: String? = null) { - val text = ChatComponentText(message) + /** + * 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<String>, + 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"))) - if (command != null) { - text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${command.removePrefix("/")}") + command?.let { + text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${it.removePrefix("/")}") } Minecraft.getMinecraft().thePlayer.addChatMessage(text) @@ -333,22 +411,29 @@ object LorenzUtils { isCurrent: (T) -> Boolean, crossinline onChange: (T) -> Unit, ) { - add(buildList { - add(prefix) - for (entry in enumValues<T>()) { - val display = getName(entry) - if (isCurrent(entry)) { - add("§a[$display]") - } else { - add("§e[") - add(Renderable.link("§e$display") { - onChange(entry) - }) - add("§e]") - } - add(" ") + add(buildSelector<T>(prefix, getName, isCurrent, onChange)) + } + + inline fun <reified T : Enum<T>> buildSelector( + prefix: String, + getName: (T) -> String, + isCurrent: (T) -> Boolean, + crossinline onChange: (T) -> Unit + ) = buildList { + add(prefix) + for (entry in enumValues<T>()) { + val display = getName(entry) + if (isCurrent(entry)) { + add("§a[$display]") + } else { + add("§e[") + add(Renderable.link("§e$display") { + onChange(entry) + }) + add("§e]") } - }) + add(" ") + } } inline fun MutableList<List<Any>>.addButton( @@ -404,10 +489,12 @@ object LorenzUtils { } } - fun List<String>.nextAfter(after: String, skip: Int = 1): String? { + fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after}, skip) + + fun List<String>.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? { var missing = -1 for (line in this) { - if (line == after) { + if (after(line)) { missing = skip - 1 continue } @@ -426,13 +513,11 @@ object LorenzUtils { val tileSign = (this as AccessorGuiEditSign).tileSign return (tileSign.signText[1].unformattedText.removeColor() == "^^^^^^" - && tileSign.signText[2].unformattedText.removeColor() == "Set your" - && tileSign.signText[3].unformattedText.removeColor() == "speed cap!") + && tileSign.signText[2].unformattedText.removeColor() == "Set your" + && tileSign.signText[3].unformattedText.removeColor() == "speed cap!") } - fun inIsland(island: IslandType) = inSkyBlock && (skyBlockIsland == island || island == IslandType.CATACOMBS && inDungeons) - - fun IslandType.isInIsland() = inIsland(this) + fun IslandType.isInIsland() = inSkyBlock && (skyBlockIsland == this || this == IslandType.CATACOMBS && inDungeons) fun <K> MutableMap<K, Int>.addOrPut(key: K, number: Int): Int { val currentValue = this[key] ?: 0 @@ -529,5 +614,15 @@ object LorenzUtils { TitleManager.sendTitle(text, duration, height) } + @Deprecated("Dont use this approach at all. check with regex or equals instead.", ReplaceWith("Regex or equals")) fun Iterable<String>.anyContains(element: String) = any { it.contains(element) } + + inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? { + val enums = enumValues<T>() + return enums.firstOrNull { it.name == name } + } + + inline fun <reified T : Enum<T>> enumValueOf(name: String) = + enumValueOfOrNull<T>(name) + ?: kotlin.error("Unknown enum constant for ${enumValues<T>().first().name.javaClass.simpleName}: '$name'") } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index 339a16efc..fd38fd441 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -130,6 +130,8 @@ data class LorenzVec( return LorenzVec(scalar * x, scalar * y, scalar * z) } + fun axisAlignedTo(other: LorenzVec) = AxisAlignedBB(x, y, z, other.x, other.y, other.z) + companion object { fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec { val yaw: Double = (yaw + 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 ee373d6b1..3aa432cde 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt @@ -73,9 +73,9 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter { } } if (loggerName == "AsmHelper" && filterConfig.filterAmsHelperTransformer) { - if (formattedMessage.startsWith("Transforming class ")) { - filterConsole("AsmHelper Transforming") - return Filter.Result.DENY + if (formattedMessage.startsWith("Transforming class ")) { + filterConsole("AsmHelper Transforming") + return Filter.Result.DENY } if (filterConfig.filterAsmHelperApplying && formattedMessage.startsWith("Applying AsmWriter ModifyWriter")) { filterConsole("AsmHelper Applying AsmWriter") @@ -118,7 +118,7 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter { } } - if (thrown != null && filterConfig.filterScoreboardErrors) { + if (thrown != null && filterConfig.filterScoreboardErrors) { val cause = thrown.cause if (cause != null && cause.stackTrace.isNotEmpty()) { val first = cause.stackTrace[0] @@ -241,13 +241,25 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter { fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(3, "dev.printUnfilteredDebugs", "dev.minecraftConsoles.printUnfilteredDebugs") event.move(3, "dev.logUnfilteredFile", "dev.minecraftConsoles.logUnfilteredFile") - event.move(3, "dev.printUnfilteredDebugsOutsideSkyBlock", "dev.minecraftConsoles.printUnfilteredDebugsOutsideSkyBlock") + event.move( + 3, + "dev.printUnfilteredDebugsOutsideSkyBlock", + "dev.minecraftConsoles.printUnfilteredDebugsOutsideSkyBlock" + ) event.move(3, "dev.printFilteredReason", "dev.minecraftConsoles.printFilteredReason") event.move(3, "dev.filterChat", "dev.minecraftConsoles.consoleFilter.filterChat") event.move(3, "dev.filterGrowBuffer", "dev.minecraftConsoles.consoleFilter.filterGrowBuffer") event.move(3, "dev.filterUnknownSound", "dev.minecraftConsoles.consoleFilter.filterUnknownSound") - event.move(3, "dev.filterParticleVillagerHappy", "dev.minecraftConsoles.consoleFilter.filterParticleVillagerHappy") - event.move(3, "dev.filterAmsHelperTransformer", "dev.minecraftConsoles.consoleFilter.filterAmsHelperTransformer") + event.move( + 3, + "dev.filterParticleVillagerHappy", + "dev.minecraftConsoles.consoleFilter.filterParticleVillagerHappy" + ) + event.move( + 3, + "dev.filterAmsHelperTransformer", + "dev.minecraftConsoles.consoleFilter.filterAmsHelperTransformer" + ) event.move(3, "dev.filterAsmHelperApplying", "dev.minecraftConsoles.consoleFilter.filterAsmHelperApplying") event.move(3, "dev.filterBiomeIdBounds", "dev.minecraftConsoles.consoleFilter.filterBiomeIdBounds") event.move(3, "dev.filterScoreboardErrors", "dev.minecraftConsoles.consoleFilter.filterScoreboardErrors") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index 3fa8a09ad..007d9f1d5 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -185,8 +185,8 @@ object NEUItems { ErrorManager.logError( IllegalStateException("Something went wrong!"), "Encountered an error getting the item for §7$this§c. " + - "This may be because your NEU repo is outdated. Please ask in the SkyHanni " + - "Discord if this is the case" + "This may be because your NEU repo is outdated. Please ask in the SkyHanni " + + "Discord if this is the case" ) fallbackItem } @@ -233,9 +233,11 @@ object NEUItems { return multiplierCache[internalName]!! } if (tryCount == 10) { - val message = "Error reading getMultiplier for item '$internalName'" - Error(message).printStackTrace() - LorenzUtils.error(message) + ErrorManager.logErrorStateWithData( + "Cound not load recipe data.", + "Failed to find item multiplier", + "internalName" to internalName + ) return Pair(internalName, 1) } for (recipe in getRecipes(internalName)) { @@ -310,8 +312,8 @@ object NEUItems { val name = group("name").trim { it <= ' ' } val ultimate = group("format").lowercase().contains("§l") ((if (ultimate && name != "Ultimate Wise") "ULTIMATE_" else "") - + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase() - + ";" + group("level").romanToDecimal()) + + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase() + + ";" + group("level").romanToDecimal()) } //Uses NEU diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt index a1a35b9d8..f05f4bd0b 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt @@ -19,12 +19,10 @@ object NEUVersionCheck { } catch (e: Throwable) { neuWarning( "NotEnoughUpdates is missing!\n" + - "SkyHanni requires the latest version of NotEnoughUpdates to work.\n" + - "You currently need NEU version 2.1.1-Alpha-19 or later.\n" + - "NEU 2.1 is NOT the latest version.\n" + - "It is ONLY in the #neu-alphas channel in the NEU discord\n" + - "Or in the #neu-updates channel in the SkyHanni discord\n" + - "Use these links to download the latest version:" + "SkyHanni requires the latest version of NotEnoughUpdates to work.\n" + + "You currently need NEU version 2.1.1-Pre-4 or later.\n" + + "NEU 2.1 is NOT the latest version.\n" + + "Use these links to download the latest version:" ) return } @@ -39,12 +37,9 @@ object NEUVersionCheck { } neuWarning( "NotEnoughUpdates is outdated!\n" + - "You currently need NEU version 2.1.1-Alpha-19 or later.\n\n" + - "NEU 2.1 is NOT the latest version.\n\n" + - "NEU 2.1.1 is NOT on the NEU GitHub.\n\n" + - "It is ONLY in the #neu-alphas channel in the NEU discord\n" + - "Or in the #neu-updates channel in the SkyHanni discord\n" + - "Use these links to download the latest version:" + "You currently need NEU version 2.1.1-Pre-4 or later.\n" + + "NEU 2.1 is NOT the latest version.\n" + + "Use these links to download the latest version:" ) } @@ -54,6 +49,7 @@ object NEUVersionCheck { Pair("Join SkyHanni Discord", "https://discord.com/invite/skyhanni-997079228510117908"), Pair("Open SkyHanni GitHub", "https://github.com/hannibal002/SkyHanni"), Pair("Join NEU Discord", "https://discord.gg/moulberry"), + Pair("Download Pre-4", "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/v2.1.1-pre4"), ) closeMinecraft() } @@ -117,4 +113,4 @@ object NEUVersionCheck { FMLCommonHandler.instance().handleExit(-1) FMLCommonHandler.instance().expectServerStopped() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt index 3ad9e2da7..41e5f4923 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt @@ -163,12 +163,10 @@ object NumberUtil { } else romanSymbols[l] + (this - l).toRoman() } - private fun processDecimal(decimal: Int, lastNumber: Int, lastDecimal: Int): Int { - return if (lastNumber > decimal) { - lastDecimal - decimal - } else { - lastDecimal + decimal - } + private fun processDecimal(decimal: Int, lastNumber: Int, lastDecimal: Int) = if (lastNumber > decimal) { + lastDecimal - decimal + } else { + lastDecimal + decimal } val pattern = "^[0-9]*$".toPattern() @@ -189,16 +187,23 @@ object NumberUtil { } fun String.formatNumber(): Long { - var text = replace(",", "") + var text = lowercase().replace(",", "") val multiplier = if (text.endsWith("k")) { text = text.substring(0, text.length - 1) - 1_000 + 1_000.0 } else if (text.endsWith("m")) { text = text.substring(0, text.length - 1) - 1_000_000 - } else 1 + 1.milion + } else if (text.endsWith("b")) { + text = text.substring(0, text.length - 1) + 1.bilion + } else 1.0 val d = text.toDouble() return (d * multiplier).toLong() } -}
\ No newline at end of file + + val Int.milion get() = this * 1_000_000.0 + private val Int.bilion get() = this * 1_000_000_000.0 + val Double.milion get() = (this * 1_000_000.0).toLong() +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt index b083b2d3b..1f28effae 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.test.command.ErrorManager import java.awt.Desktop import java.io.IOException import java.net.URI @@ -12,12 +13,11 @@ object OSUtils { try { Desktop.getDesktop().browse(URI(url)) } catch (e: IOException) { - e.printStackTrace() - LorenzUtils.error("[SkyHanni] Error opening website: $url!") + ErrorManager.logError(e, "Error opening website: $url") } } else { copyToClipboard(url) - LorenzUtils.warning("[SkyHanni] Web browser is not supported! Copied url to clipboard.") + LorenzUtils.error("Web browser is not supported! Copied url to clipboard.") } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt index c9903ffc2..68f7a0d49 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt @@ -53,7 +53,9 @@ class ParkourHelper( if (visible) { for ((index, location) in locations.withIndex()) { - if (location.offsetCenter().distanceToPlayer() < detectionRange && Minecraft.getMinecraft().thePlayer.onGround) { + val onGround = Minecraft.getMinecraft().thePlayer.onGround + val closeEnough = location.offsetCenter().distanceToPlayer() < detectionRange + if (closeEnough && onGround) { current = index } } @@ -146,4 +148,4 @@ class ParkourHelper( private fun colorForIndex(index: Int) = if (rainbowColor) { RenderUtils.chromaColor(4.seconds, offset = -index / 12f, brightness = 0.7f) } else monochromeColor -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 4a5754b6c..03f552e7a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -303,7 +303,6 @@ object RenderUtils { val z = pos.z - player.lastTickPosZ + (pos.z - player.posZ - (pos.z - player.lastTickPosZ)) * partialTicks - //7 – 25 val translate = LorenzVec(x, y, z) @@ -353,7 +352,6 @@ object RenderUtils { return lastValue + (currentValue - lastValue) * multiplier } - fun Position.transform(): Pair<Int, Int> { GlStateManager.translate(getAbsX().toFloat(), getAbsY().toFloat(), 0F) GlStateManager.scale(effectiveScale, effectiveScale, 1F) @@ -365,22 +363,28 @@ object RenderUtils { fun Position.renderString(string: String?, offsetX: Int = 0, offsetY: Int = 0, posLabel: String) { if (string == null) return if (string == "") return - val x = renderString0(string, offsetX, offsetY) + val x = renderString0(string, offsetX, offsetY, isCenter) GuiEditManager.add(this, posLabel, x, 10) } - private fun Position.renderString0(string: String?, offsetX: Int = 0, offsetY: Int = 0): Int { + private fun Position.renderString0(string: String?, offsetX: Int = 0, offsetY: Int = 0, centered: Boolean): Int { val display = "§f$string" GlStateManager.pushMatrix() transform() val minecraft = Minecraft.getMinecraft() val renderer = minecraft.renderManager.fontRenderer - val x = offsetX - val y = offsetY + GlStateManager.translate(offsetX + 1.0, offsetY + 1.0, 0.0) - GlStateManager.translate(x + 1.0, y + 1.0, 0.0) - renderer.drawStringWithShadow(display, 0f, 0f, 0) + if (centered) { + val strLen: Int = renderer.getStringWidth(string) + val x2 = offsetX - strLen / 2f + GL11.glTranslatef(x2, 0f, 0f) + renderer.drawStringWithShadow(display, 0f, 0f, 0) + GL11.glTranslatef(-x2, 0f, 0f) + } else { + renderer.drawStringWithShadow(display, 0f, 0f, 0) + } GlStateManager.popMatrix() @@ -394,7 +398,7 @@ object RenderUtils { var offsetY = 0 var longestX = 0 for (s in list) { - val x = renderString0(s, offsetY = offsetY) + val x = renderString0(s, offsetY = offsetY, centered = false) if (x > longestX) { longestX = x } @@ -756,7 +760,6 @@ object RenderUtils { return LorenzVec(x, y, z) } - fun drawFilledBoundingBox(aabb: AxisAlignedBB, c: Color, alphaMultiplier: Float = 1f) { GlStateManager.enableBlend() GlStateManager.disableLighting() @@ -927,7 +930,12 @@ object RenderUtils { GlStateManager.disableBlend() } - fun LorenzRenderWorldEvent.outlineTopFace(boundingBox: AxisAlignedBB, lineWidth: Int, colour: Color, depth: Boolean) { + fun LorenzRenderWorldEvent.outlineTopFace( + boundingBox: AxisAlignedBB, + lineWidth: Int, + colour: Color, + depth: Boolean + ) { val cornerOne = LorenzVec(boundingBox.minX, boundingBox.maxY, boundingBox.minZ) val cornerTwo = LorenzVec(boundingBox.minX, boundingBox.maxY, boundingBox.maxZ) val cornerThree = LorenzVec(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ) @@ -1021,4 +1029,4 @@ object RenderUtils { GlStateManager.enableLighting() GlStateManager.enableDepth() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt index e79599cae..3e30f300c 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt @@ -7,18 +7,23 @@ import kotlin.time.Duration.Companion.milliseconds @JvmInline value class SimpleTimeMark(private val millis: Long) { + operator fun minus(other: SimpleTimeMark) = (millis - other.millis).milliseconds operator fun plus(other: Duration) = SimpleTimeMark(millis + other.inWholeMilliseconds) - fun passedSince() = if (millis == 0L) Duration.INFINITE else now() - this + operator fun minus(other: Duration) = plus(-other) + + fun passedSince() = now() - this fun timeUntil() = -passedSince() fun isInPast() = timeUntil().isNegative() + fun isFarPast() = millis == 0L + override fun toString(): String { if (millis == 0L) return "The Far Past" return Instant.ofEpochMilli(millis).toString() @@ -33,4 +38,4 @@ value class SimpleTimeMark(private val millis: Long) { fun Long.asTimeMark() = SimpleTimeMark(this) fun SkyBlockTime.asTimeMark() = SimpleTimeMark(toMillis()) } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt index 7f6cc7623..9f65a71f1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt @@ -26,6 +26,8 @@ object SkyBlockItemModifierUtils { fun ItemStack.getPolarvoidBookCount() = getAttributeInt("polarvoid") + fun ItemStack.getBookwormBookCount() = getAttributeInt("bookworm_books") + fun ItemStack.getCultivatingCounter() = getAttributeLong("farmed_cultivating") fun ItemStack.getHoeCounter() = getAttributeLong("mined_crops") @@ -117,6 +119,8 @@ object SkyBlockItemModifierUtils { fun ItemStack.getArmorDye() = getAttributeString("dye_item")?.asInternalName() + fun ItemStack.getFungiCutterMode() = getAttributeString("fungi_cutter_mode") + fun ItemStack.getRune(): NEUInternalName? { val runesMap = getExtraAttributes()?.getCompoundTag("runes") ?: return null val runesList = runesMap.keySet.associateWith { runesMap.getInteger(it) }.toList() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt index d2403d4c6..c9892a9bf 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt @@ -9,7 +9,7 @@ import net.minecraft.util.ResourceLocation object SoundUtils { private val beepSound by lazy { createSound("random.orb", 1f) } private val clickSound by lazy { createSound("gui.button.press", 1f) } - private val errorSound by lazy {createSound("mob.endermen.portal", 0f)} + private val errorSound by lazy { createSound("mob.endermen.portal", 0f) } val centuryActiveTimerAlert by lazy { createSound("skyhanni:centurytimer.active", 1f) } fun ISound.playSound() { @@ -58,7 +58,7 @@ object SoundUtils { fun command(args: Array<String>) { if (args.isEmpty()) { - LorenzUtils.chat("§c[SkyHanni] Specify a sound effect to test") + LorenzUtils.userError("Specify a sound effect to test") return } @@ -72,4 +72,4 @@ object SoundUtils { fun playErrorSound() { errorSound.playSound() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index 66eb0faad..dd114d8fd 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.mixins.transformers.AccessorChatComponentText import at.hannibal2.skyhanni.utils.GuiRenderUtils.darkenColor +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiUtilRenderComponents import net.minecraft.util.ChatComponentText @@ -17,7 +18,8 @@ import java.util.regex.Pattern object StringUtils { // TODO USE SH-REPO private val playerChatPattern = "(?<important>.*?)(?:§[f7r])*: .*".toPattern() - private val chatUsernamePattern = "^(?:§\\w\\[§\\w\\d+§\\w] )?(?:(?:§\\w)+\\S )?(?<rankedName>(?:§\\w\\[\\w.+] )?(?:§\\w)?(?<username>\\w+))(?: (?:§\\w)?\\[.+?])?".toPattern() + private val chatUsernamePattern = + "^(?:§\\w\\[§\\w\\d+§\\w] )?(?:(?:§\\w)+\\S )?(?<rankedName>(?:§\\w\\[\\w.+] )?(?:§\\w)?(?<username>\\w+))(?: (?:§\\w)?\\[.+?])?".toPattern() private val whiteSpaceResetPattern = "^(?:\\s|§r)*|(?:\\s|§r)*$".toPattern() private val whiteSpacePattern = "^\\s*|\\s*$".toPattern() private val resetPattern = "(?i)§R".toPattern() @@ -71,6 +73,7 @@ object StringUtils { return toString().replace("-", "") } + @Deprecated("Do not create a regex pattern each time.", ReplaceWith("toPattern()")) fun String.matchRegex(@Language("RegExp") regex: String): Boolean = regex.toRegex().matches(this) private fun String.removeAtBeginning(text: String): String = @@ -89,6 +92,15 @@ object StringUtils { } } + inline fun <T> List<Pattern>.matchMatchers(text: String, consumer: Matcher.() -> T): T? { + for (pattern in iterator()) { + pattern.matchMatcher<T>(text) { + return consumer() + } + } + return null + } + fun getColor(string: String, default: Int, darker: Boolean = true): Int { val stringPattern = "§[0123456789abcdef].*".toPattern() @@ -138,7 +150,7 @@ object StringUtils { } fun optionalPlural(number: Int, singular: String, plural: String) = - "$number " + if (number == 1) singular else plural + "${number.addSeparators()} " + if (number == 1) singular else plural fun progressBar(percentage: Double, steps: Int = 24): Any { //'§5§o§2§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §f§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §r §e348,144.3§6/§e936k' @@ -235,4 +247,6 @@ object StringUtils { fun String.convertToFormatted(): String { return this.replace("&&", "§") } -}
\ No newline at end of file + + fun Pattern.matches(string: String) = matcher(string).matches() +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt index 252d974ca..fe07509be 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt @@ -1,10 +1,16 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.TabListUpdateEvent import at.hannibal2.skyhanni.mixins.hooks.tabListGuard +import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiPlayerTabOverlay +import at.hannibal2.skyhanni.utils.LorenzUtils.conditionalTransform +import at.hannibal2.skyhanni.utils.LorenzUtils.transformIf +import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.common.collect.ComparisonChain import com.google.common.collect.Ordering +import kotlinx.coroutines.launch import net.minecraft.client.Minecraft import net.minecraft.client.network.NetworkPlayerInfo import net.minecraft.world.WorldSettings @@ -16,9 +22,43 @@ class TabListData { companion object { private var cache = emptyList<String>() + private var debugCache: List<String>? = null // TODO replace with TabListUpdateEvent - fun getTabList() = cache + fun getTabList() = debugCache ?: cache + + fun toggleDebugCommand() { + if (debugCache != null) { + LorenzUtils.chat("Disabled tab list debug.") + debugCache = null + return + } + SkyHanniMod.coroutineScope.launch { + val clipboard = OSUtils.readFromClipboard() ?: return@launch + debugCache = clipboard.lines() + LorenzUtils.chat("Enabled tab list debug with your clipboard.") + } + } + + fun copyCommand(args: Array<String>) { + if (debugCache != null) { + LorenzUtils.clickableChat("Tab list debug is enabled!", "shdebugtablist") + return + } + + val resultList = mutableListOf<String>() + val noColor = args.size == 1 && args[0] == "true" + for (line in getTabList()) { + val tabListLine = line.transformIf({ noColor }) { removeColor() } + if (tabListLine != "") resultList.add("'$tabListLine'") + } + val tabList = Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay + val tabHeader = tabList.header_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText }) + val tabFooter = tabList.footer_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText }) + val string = "Header:\n\n$tabHeader\n\nBody:\n\n${resultList.joinToString("\n")}\n\nFooter:\n\n$tabFooter" + OSUtils.copyToClipboard(string) + LorenzUtils.chat("Tab list copied into the clipboard!") + } } private val playerOrdering = Ordering.from(PlayerComparator()) @@ -60,7 +100,7 @@ class TabListData { val tabList = readTabList() ?: return if (cache != tabList) { cache = tabList - TabListUpdateEvent(cache).postAndCatch() + TabListUpdateEvent(getTabList()).postAndCatch() } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt index 3a32b3de6..5bf6bfcf0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt @@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import io.github.moulberry.notenoughupdates.util.SkyBlockTime import kotlin.time.Duration +import kotlin.time.DurationUnit +import kotlin.time.toDuration object TimeUtils { private val pattern = @@ -73,8 +75,10 @@ object TimeUtils { return builder.toString().trim() } - // TODO: use kotlin Duration - fun getMillis(string: String) = getMillis_(string.replace("m", "m ").replace(" ", " ").trim()) + @Deprecated("Do no longer use long for time", ReplaceWith("getDuration()")) + fun getMillis(string: String) = getDuration(string).inWholeMilliseconds + + fun getDuration(string: String) = getMillis_(string.replace("m", "m ").replace(" ", " ").trim()) private fun getMillis_(string: String) = pattern.matchMatcher(string.lowercase().trim()) { val years = group("y")?.toLong() ?: 0L @@ -90,10 +94,10 @@ object TimeUtils { millis += days * 24 * 60 * 60 * 1000 millis += (years * 365.25 * 24 * 60 * 60 * 1000).toLong() - millis + millis.toDuration(DurationUnit.MILLISECONDS) } ?: tryAlternativeFormat(string) - private fun tryAlternativeFormat(string: String): Long { + private fun tryAlternativeFormat(string: String): Duration { val split = string.split(":") return when (split.size) { 3 -> { @@ -116,7 +120,7 @@ object TimeUtils { else -> { throw RuntimeException("Invalid format: '$string'") } - }.toLong() + }.toLong().toDuration(DurationUnit.MILLISECONDS) } fun SkyBlockTime.formatted(): String { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt index 55ea90b52..2a6d1f5ab 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt @@ -11,7 +11,7 @@ class Timer( private var started: SimpleTimeMark = SimpleTimeMark.now(), startPaused: Boolean = false -): Comparable<Timer> { +) : Comparable<Timer> { @Expose private var paused: SimpleTimeMark? = null @@ -40,4 +40,4 @@ class Timer( override fun compareTo(other: Timer): Int = remaining.compareTo(other.remaining) -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java index 6ab663941..8e5648f5e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java @@ -1,4 +1,5 @@ package at.hannibal2.skyhanni.utils.jsonobjects; + import com.google.gson.annotations.Expose; import java.util.List; @@ -6,4 +7,4 @@ import java.util.List; public class ContributorListJson { @Expose public List<String> usernames; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java index 87a80d391..7bc9cf7fa 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java @@ -1,7 +1,10 @@ package at.hannibal2.skyhanni.utils.jsonobjects; import at.hannibal2.skyhanni.features.garden.CropType; +import at.hannibal2.skyhanni.utils.LorenzRarity; +import at.hannibal2.skyhanni.utils.LorenzVec; import com.google.gson.annotations.Expose; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -14,6 +17,9 @@ public class GardenJson { public Map<CropType, List<Integer>> crop_milestones; @Expose + public Map<String, Boolean> crop_milestone_community_help; + + @Expose public Map<String, GardenVisitor> visitors; @Expose @@ -24,9 +30,29 @@ public class GardenJson { public static class GardenVisitor { @Expose - public String rarity; + public LorenzRarity rarity; + + @Expose + public LorenzRarity new_rarity; + + @Nullable + @Expose + public LorenzVec position; + + /** + * Formatted as follows: + * - If this visitor is a player, get the encoded skin value + * - If this visitor is a mob, get their mob class name + */ + @Nullable + @Expose + public String skinOrType; + + @Nullable + @Expose + public String mode; @Expose public List<String> need_items; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java new file mode 100644 index 000000000..87d1e9a22 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java @@ -0,0 +1,13 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +import at.hannibal2.skyhanni.features.garden.CropType; +import com.google.gson.annotations.Expose; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class JacobContestsJson { + @Expose + public Map<Long, List<CropType>> contestTimes = new HashMap<>(); +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java new file mode 100644 index 000000000..bd5048cfb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +import com.google.gson.annotations.Expose; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class KnownFeaturesJson { + @Expose + public Map<String, List<String>> knownFeatures = new HashMap<>(); +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java new file mode 100644 index 000000000..802627e7a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java @@ -0,0 +1,27 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +import at.hannibal2.skyhanni.utils.LorenzVec; +import com.google.gson.annotations.Expose; + +import java.util.Map; + +public class LocationFixJson { + + @Expose + public Map<String, LocationFix> locationFixes; + + public static class LocationFix { + @Expose + public LorenzVec a; + + @Expose + public LorenzVec b; + + @Expose + public String island_name; + + @Expose + public String real_location; + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java index bc877658a..d2173c74b 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java @@ -27,11 +27,11 @@ public class MayorJson { @Override public String toString() { return "Candidate{" + - "key='" + key + '\'' + - ", name='" + name + '\'' + - ", perks=" + perks + - ", votes=" + votes + - '}'; + "key='" + key + '\'' + + ", name='" + name + '\'' + + ", perks=" + perks + + ", votes=" + votes + + '}'; } } @@ -62,9 +62,9 @@ public class MayorJson { @Override public String toString() { return "Perk{" + - "name='" + name + '\'' + - ", description='" + description + '\'' + - '}'; + "name='" + name + '\'' + + ", description='" + description + '\'' + + '}'; } } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java index 52ed7f636..8053e87cb 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java @@ -9,7 +9,8 @@ import java.util.Map; public class SeaCreatureJson {
- public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>(){}.getType();
+ public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() {
+ }.getType();
public static class Variant {
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java new file mode 100644 index 000000000..03c256256 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java @@ -0,0 +1,11 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +import com.google.gson.annotations.Expose; + +import java.util.List; + +public class TabListJson { + + @Expose + public List<String> sun_moon_symbols; +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index 2a3321abc..9367e5ee1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -21,7 +21,7 @@ interface Renderable { val height: Int fun isHovered(posX: Int, posY: Int) = currentRenderPassMousePosition?.let { (x, y) -> x in (posX..posX + width) - && y in (posY..posY + height) // TODO: adjust for variable height? + && y in (posY..posY + height) // TODO: adjust for variable height? } ?: false /** @@ -35,7 +35,7 @@ interface Renderable { val list = mutableMapOf<Pair<Int, Int>, List<Int>>() var currentRenderPassMousePosition: Pair<Int, Int>? = null - private set + set fun <T> withMousePosition(posX: Int, posY: Int, block: () -> T): T { val last = currentRenderPassMousePosition diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt index f198f7e7a..7fb13ab86 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt @@ -30,7 +30,7 @@ abstract class Shader(vertex: String, fragment: String) { if (linkStatus == GL11.GL_FALSE) { LorenzUtils.consoleLog( "Error occurred when linking program with Vertex Shader: $vertex and Fragment Shader: $fragment : " + - StringUtils.trim(ShaderHelper.glGetProgramInfoLog(shaderProgram, 1024)) + StringUtils.trim(ShaderHelper.glGetProgramInfoLog(shaderProgram, 1024)) ) } @@ -52,4 +52,4 @@ abstract class Shader(vertex: String, fragment: String) { fun <T> registerUniform(uniformType: Uniform.UniformType<T>, name: String, uniformValuesSupplier: Supplier<T>) { uniforms.add(Uniform(this, uniformType, name, uniformValuesSupplier)) } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt index e554a4098..2576b4248 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt @@ -1,7 +1,13 @@ package at.hannibal2.skyhanni.utils.shader import at.hannibal2.skyhanni.utils.LorenzUtils -import org.lwjgl.opengl.* +import org.lwjgl.opengl.ARBFragmentShader +import org.lwjgl.opengl.ARBShaderObjects +import org.lwjgl.opengl.ARBVertexShader +import org.lwjgl.opengl.ContextCapabilities +import org.lwjgl.opengl.GL11 +import org.lwjgl.opengl.GL20 +import org.lwjgl.opengl.GLContext /** * Class to check shaders support, OpenGL capabilities, and shader helper functions @@ -27,9 +33,9 @@ class ShaderHelper { // Check OpenGL 2.0 Capabilities val openGL20supported = capabilities.OpenGL20 SHADERS_SUPPORTED = openGL20supported || - capabilities.GL_ARB_vertex_shader && - capabilities.GL_ARB_fragment_shader && - capabilities.GL_ARB_shader_objects + capabilities.GL_ARB_vertex_shader && + capabilities.GL_ARB_fragment_shader && + capabilities.GL_ARB_shader_objects var log = "Shaders are" if (!SHADERS_SUPPORTED) log += " not" @@ -67,12 +73,18 @@ class ShaderHelper { if (USING_ARB_SHADERS) ARBShaderObjects.glLinkProgramARB(program) else GL20.glLinkProgram(program) } - fun glGetProgramInfoLog(program: Int, maxLength: Int) : String { - return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(program, maxLength) else GL20.glGetProgramInfoLog(program, maxLength) + fun glGetProgramInfoLog(program: Int, maxLength: Int): String { + return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB( + program, + maxLength + ) else GL20.glGetProgramInfoLog(program, maxLength) } - fun glGetProgrami(program: Int, pname: Int) : Int { - return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(program, pname) else GL20.glGetProgrami(program, pname) + fun glGetProgrami(program: Int, pname: Int): Int { + return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB( + program, + pname + ) else GL20.glGetProgrami(program, pname) } fun glUseProgram(program: Int) { @@ -80,27 +92,39 @@ class ShaderHelper { } fun glAttachShader(program: Int, shaderIn: Int) { - if (USING_ARB_SHADERS) ARBShaderObjects.glAttachObjectARB(program, shaderIn) else GL20.glAttachShader(program, shaderIn) + if (USING_ARB_SHADERS) ARBShaderObjects.glAttachObjectARB(program, shaderIn) else GL20.glAttachShader( + program, + shaderIn + ) } - fun glCreateShader(type: Int) : Int { + fun glCreateShader(type: Int): Int { return if (USING_ARB_SHADERS) ARBShaderObjects.glCreateShaderObjectARB(type) else GL20.glCreateShader(type) } fun glShaderSource(shader: Int, source: CharSequence) { - if (USING_ARB_SHADERS) ARBShaderObjects.glShaderSourceARB(shader, source) else GL20.glShaderSource(shader, source) + if (USING_ARB_SHADERS) ARBShaderObjects.glShaderSourceARB(shader, source) else GL20.glShaderSource( + shader, + source + ) } fun glCompileShader(shader: Int) { if (USING_ARB_SHADERS) ARBShaderObjects.glCompileShaderARB(shader) else GL20.glCompileShader(shader) } - fun glGetShaderi(shader: Int, pname: Int) : Int { - return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(shader, pname) else GL20.glGetShaderi(shader, pname) + fun glGetShaderi(shader: Int, pname: Int): Int { + return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB( + shader, + pname + ) else GL20.glGetShaderi(shader, pname) } - fun glGetShaderInfoLog(shader: Int, maxLength: Int) : String { - return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(shader, maxLength) else GL20.glGetShaderInfoLog(shader, maxLength) + fun glGetShaderInfoLog(shader: Int, maxLength: Int): String { + return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB( + shader, + maxLength + ) else GL20.glGetShaderInfoLog(shader, maxLength) } fun glDeleteShader(shader: Int) { @@ -112,13 +136,21 @@ class ShaderHelper { } fun glUniform3f(location: Int, v0: Float, v1: Float, v2: Float) { - if (USING_ARB_SHADERS) ARBShaderObjects.glUniform3fARB(location, v0, v1, v2) else GL20.glUniform3f(location, v0, v1, v2) + if (USING_ARB_SHADERS) ARBShaderObjects.glUniform3fARB(location, v0, v1, v2) else GL20.glUniform3f( + location, + v0, + v1, + v2 + ) } - fun glGetUniformLocation(program: Int, name: CharSequence) : Int { - return if (USING_ARB_SHADERS) ARBShaderObjects.glGetUniformLocationARB(program, name) else GL20.glGetUniformLocation(program, name) + fun glGetUniformLocation(program: Int, name: CharSequence): Int { + return if (USING_ARB_SHADERS) ARBShaderObjects.glGetUniformLocationARB( + program, + name + ) else GL20.glGetUniformLocation(program, name) } fun areShadersSupported() = SHADERS_SUPPORTED } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt index e7eb48f11..3dbec3c6e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt @@ -21,7 +21,7 @@ object ShaderManager { CHROMA(ChromaShader.INSTANCE); companion object { - fun getShaderInstance(shaderName: String) : Shader? = when (shaderName) { + fun getShaderInstance(shaderName: String): Shader? = when (shaderName) { "chroma" -> CHROMA.shader else -> { null @@ -58,7 +58,7 @@ object ShaderManager { activeShader = null } - fun loadShader(type: ShaderType, fileName: String) : Int { + fun loadShader(type: ShaderType, fileName: String): Int { val resourceLocation = ResourceLocation("skyhanni:shaders/$fileName${type.extension}") val source = StringBuilder() @@ -73,8 +73,10 @@ object ShaderManager { ShaderHelper.glCompileShader(shaderID) if (ShaderHelper.glGetShaderi(shaderID, ShaderHelper.GL_COMPILE_STATUS) == 0) { - LorenzUtils.consoleLog("Error occurred when compiling shader $fileName${type.extension} : " + - StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderID, 1024))) + LorenzUtils.consoleLog( + "Error occurred when compiling shader $fileName${type.extension} : " + + StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderID, 1024)) + ) } return shaderID @@ -84,4 +86,4 @@ object ShaderManager { enum class ShaderType(val extension: String, val shaderType: Int) { VERTEX(".vsh", ShaderHelper.GL_VERTEX_SHADER), FRAGMENT(".fsh", ShaderHelper.GL_FRAGMENT_SHADER) -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt index e87ea3b22..d57398ea4 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt @@ -37,9 +37,10 @@ class Uniform<T>( val values = newUniformValue as FloatArray ShaderHelper.glUniform3f(uniformID, values[0], values[1], values[2]) } + UniformType.BOOL -> ShaderHelper.glUniform1f(uniformID, if (newUniformValue as Boolean) 1f else 0f) } previousUniformValue = newUniformValue } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt new file mode 100644 index 000000000..f882a268e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -0,0 +1,133 @@ +package at.hannibal2.skyhanni.utils.tracker + +import at.hannibal2.skyhanni.config.Storage +import at.hannibal2.skyhanni.config.core.config.Position +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.renderables.Renderable +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiInventory +import kotlin.time.Duration.Companion.seconds + +class SkyHanniTracker<Data : TrackerData>( + private val name: String, + private val createNewSession: () -> Data, + private val getStorage: (Storage.ProfileSpecific) -> Data, + private val drawDisplay: (Data) -> List<List<Any>>, +) { + private var inventoryOpen = false + private var displayMode = DisplayMode.TOTAL + private val currentSessions = mutableMapOf<Storage.ProfileSpecific, Data>() + private var display = emptyList<List<Any>>() + private var sessionResetTime = SimpleTimeMark.farPast() + private var dirty = false + + fun isInventoryOpen() = inventoryOpen + + fun resetCommand(args: Array<String>, command: String) { + if (args.size == 1 && args[0].lowercase() == "confirm") { + reset(DisplayMode.TOTAL, "Reset total $name!") + return + } + + LorenzUtils.clickableChat( + "Are you sure you want to reset your total $name? Click here to confirm.", + "$command confirm" + ) + } + + fun modify(modifyFunction: (Data) -> Unit) { + getSharedTracker()?.let { + it.modify(modifyFunction) + update() + } + } + + fun renderDisplay(position: Position) { + val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory + if (inventoryOpen != currentlyOpen) { + inventoryOpen = currentlyOpen + update() + } + + if (dirty) { + display = getSharedTracker()?.let { + buildFinalDisplay(drawDisplay(it.get(displayMode))) + } ?: emptyList() + dirty = false + } + + position.renderStringsAndItems(display, posLabel = name) + } + + fun update() { + dirty = true + } + + private fun buildFinalDisplay(rawList: List<List<Any>>) = rawList.toMutableList().also { + if (it.isEmpty()) return@also + if (inventoryOpen) { + it.add(1, buildDisplayModeView()) + } + if (inventoryOpen && displayMode == DisplayMode.SESSION) { + it.addAsSingletonList(buildSessionResetButton()) + } + } + + private fun buildSessionResetButton() = Renderable.clickAndHover( + "§cReset session!", + listOf( + "§cThis will reset your", + "§ccurrent session of", + "§c$name" + ), + ) { + if (sessionResetTime.passedSince() > 3.seconds) { + reset(DisplayMode.SESSION, "Reset this session of $name!") + sessionResetTime = SimpleTimeMark.now() + } + } + + private fun buildDisplayModeView() = LorenzUtils.buildSelector<DisplayMode>( + "§7Display Mode: ", + getName = { type -> type.displayName }, + isCurrent = { it == displayMode }, + onChange = { + displayMode = it + update() + } + ) + + private fun getSharedTracker() = ProfileStorageData.profileSpecific?.let { + SharedTracker(getStorage(it), currentSessions.getOrPut(it) { createNewSession() }) + } + + private fun reset(displayMode: DisplayMode, message: String) { + getSharedTracker()?.let { + it.get(displayMode).reset() + LorenzUtils.chat(message) + update() + } + } + + class SharedTracker<Data : TrackerData>(private val total: Data, private val currentSession: Data) { + fun modify(modifyFunction: (Data) -> Unit) { + modifyFunction(total) + modifyFunction(currentSession) + } + + fun get(displayMode: DisplayMode) = when (displayMode) { + DisplayMode.TOTAL -> total + DisplayMode.SESSION -> currentSession + } + } + + enum class DisplayMode(val displayName: String) { + TOTAL("Total"), + SESSION("This Session"), + ; + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt new file mode 100644 index 000000000..3c4a8bbd0 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt @@ -0,0 +1,5 @@ +package at.hannibal2.skyhanni.utils.tracker + +abstract class TrackerData { + abstract fun reset() +} |