aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt181
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/Timer.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt70
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt133
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt5
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()
+}