diff options
Diffstat (limited to 'src/main')
24 files changed, 362 insertions, 54 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 5eb0eec1b..f79a02ba6 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -59,6 +59,9 @@ import at.hannibal2.skyhanni.features.mobs.AshfangMinisNametagHider import at.hannibal2.skyhanni.features.mobs.MobHighlight import at.hannibal2.skyhanni.features.nether.ashfang.* import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper +import at.hannibal2.skyhanni.features.rift.HighlightRiftGuide +import at.hannibal2.skyhanni.features.rift.RiftAPI +import at.hannibal2.skyhanni.features.rift.RiftTimer import at.hannibal2.skyhanni.features.slayer.* import at.hannibal2.skyhanni.features.slayer.blaze.BlazeSlayerClearView import at.hannibal2.skyhanni.features.slayer.blaze.BlazeSlayerDaggerHelper @@ -94,7 +97,7 @@ import org.apache.logging.log4j.Logger clientSideOnly = true, useMetadata = true, guiFactory = "at.hannibal2.skyhanni.config.ConfigGuiForgeInterop", - version = "0.18.Beta.21", + version = "0.18", ) class SkyHanniMod { @Mod.EventHandler @@ -144,6 +147,7 @@ class SkyHanniMod { loadModule(PartyAPI()) loadModule(SlayerAPI) loadModule(PurseAPI()) + loadModule(RiftAPI) // features loadModule(BazaarOrderHelper()) @@ -301,6 +305,8 @@ class SkyHanniMod { loadModule(FrozenTreasureTracker()) loadModule(SlayerRngMeterDisplay()) loadModule(GhostCounter) + loadModule(RiftTimer()) + loadModule(HighlightRiftGuide()) init() diff --git a/src/main/java/at/hannibal2/skyhanni/config/Features.java b/src/main/java/at/hannibal2/skyhanni/config/Features.java index d80195e71..02c4f9a80 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Features.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Features.java @@ -116,6 +116,10 @@ public class Features extends Config { public Garden garden = new Garden(); @Expose + @Category(name = "The Rift", desc = "Features for The Rift dimension.") + public RiftConfig rift = new RiftConfig(); + + @Expose @Category(name = "Ghost Counter", desc = "Ghost Counter settings.") public GhostCounter ghostCounter = new GhostCounter(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index ca852e482..ccae2ce25 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -195,6 +195,9 @@ public class Storage { public long cakeExpiring = -1L; @Expose + public boolean carrotFortune = false; + + @Expose public Map<FarmingItems, ItemStack> farmingItems = new HashMap<>(); } diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index ebcb72d28..59b850784 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -125,9 +125,9 @@ object Commands { } private fun createCommand(function: (Array<String>) -> Unit) = - object : ProcessCommandRunnable() { - override fun processCommand(sender: ICommandSender?, args: Array<out String>) { - function(args.asList().toTypedArray()) - } + object : ProcessCommandRunnable() { + override fun processCommand(sender: ICommandSender?, args: Array<out String>) { + function(args.asList().toTypedArray()) } + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.java b/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.java index 25e3ba97b..fa2c310de 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.java +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.java @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.config.commands; +import at.hannibal2.skyhanni.test.command.CopyErrorCommand; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.util.BlockPos; @@ -7,7 +8,7 @@ import net.minecraft.util.BlockPos; import java.util.List; /** - @author Moulberry + * @author Moulberry **/ public class SimpleCommand extends CommandBase { @@ -50,7 +51,11 @@ public class SimpleCommand extends CommandBase { @Override public void processCommand(ICommandSender sender, String[] args) { - runnable.processCommand(sender, args); + try { + runnable.processCommand(sender, args); + } catch (Throwable e) { + CopyErrorCommand.INSTANCE.logError(e, "Error while running command /" + commandName); + } } @Override diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Bingo.java b/src/main/java/at/hannibal2/skyhanni/config/features/Bingo.java index 53ebf93e1..b9270b03c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Bingo.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Bingo.java @@ -35,7 +35,7 @@ public class Bingo { @ConfigOption( name = "Show Guide", desc = "Show tips and difficulty for bingo goals inside the bingo card inventory.\n" + - "§7(§eData from Bingo Splash Community§7)" + "§eData from Bingo Splash Community§7, made by §cMayxo" ) @ConfigEditorBoolean public boolean bingoSplashGuide = true; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java index c53508dac..84a792a09 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -1196,12 +1196,24 @@ public class Garden { public int timeout = 5; @Expose - @ConfigOption(name = "Always Shown", desc = "Always show the Yaw and Pitch overlay, ignoring the timeout.") + @ConfigOption(name = "Show Without Tool", desc = "Does not require you to hold a tool for the overlay to show.") + @ConfigEditorBoolean + public boolean showWithoutTool = false; + + @Expose + @ConfigOption(name = "Show Outside Garden", desc = "The overlay will work outside of the garden.") + @ConfigEditorBoolean + public boolean showEverywhere = false; + + @Expose + @ConfigOption(name = "Ignore Timeout", desc = "Ignore the timeout after not moving mouse.") @ConfigEditorBoolean public boolean showAlways = false; @Expose public Position pos = new Position(445, 225, false, true); + @Expose + public Position posOutside = new Position(445, 225, false, true); } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java new file mode 100644 index 000000000..0477920a2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java @@ -0,0 +1,42 @@ +package at.hannibal2.skyhanni.config.features; + +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.Accordion; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class RiftConfig { + + @ConfigOption(name = "Rift Timer", desc = "") + @Accordion + @Expose + public RiftTimerConfig timer = new RiftTimerConfig(); + + public static class RiftTimerConfig { + + @Expose + @ConfigOption(name = "Enabled", desc = "Show the remaining rift time, max time, percentage, and extra time changes.") + @ConfigEditorBoolean + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Max time", desc = "Show max time.") + @ConfigEditorBoolean + public boolean maxTime = true; + + @Expose + @ConfigOption(name = "Percentage", desc = "Show percentage.") + @ConfigEditorBoolean + public boolean percentage = true; + + @Expose + public Position timerPosition = new Position(10, 10, false, true); + + } + + @Expose + @ConfigOption(name = "Highlight Guide", desc = "Highlight things to do in the Rift Guide.") + @ConfigEditorBoolean + public boolean highlightGuide = true; +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt index 30f88f48e..b5a2d2b92 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt @@ -21,8 +21,6 @@ class EntityMovementData { } } - var tick = 0 - @SubscribeEvent fun onTick(event: TickEvent.ClientTickEvent) { if (!LorenzUtils.inSkyBlock) return diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt index 7935bf985..91f2bed9a 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt @@ -19,6 +19,7 @@ enum class IslandType(val displayName: String, val apiName: String = "null") { GARDEN_GUEST("Garden Guest"), SPIDER_DEN("Spider's Den"), WINTER("Jerry's Workshop"), //todo confirm + THE_RIFT("The Rift"), NONE(""), UNKNOWN("???"), diff --git a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt index ddd208db1..7c4cfd7c1 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt @@ -1,11 +1,10 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.jsonobjects.MayorJson -import com.google.gson.GsonBuilder -import io.github.moulberry.moulconfig.observer.PropertyTypeAdapterFactory import io.github.moulberry.notenoughupdates.util.SkyBlockTime import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -17,10 +16,6 @@ class MayorElection { private var tick = 0 private var lastUpdate = 0L - private val gson = GsonBuilder().setPrettyPrinting() - .registerTypeAdapterFactory(PropertyTypeAdapterFactory()) - .create() - companion object { var rawMayorData: MayorJson? = null var candidates = mapOf<Int, MayorJson.Candidate>() @@ -52,7 +47,7 @@ class MayorElection { SkyHanniMod.coroutineScope.launch { val url = "https://api.hypixel.net/resources/skyblock/election" val jsonObject = withContext(Dispatchers.IO) { APIUtil.getJSONResponse(url) } - rawMayorData = gson.fromJson(jsonObject, MayorJson::class.java) + rawMayorData = ConfigManager.gson.fromJson(jsonObject, MayorJson::class.java) val data = rawMayorData ?: return@launch val map = mutableMapOf<Int, MayorJson.Candidate>() map put data.mayor.election.getPairs() diff --git a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt index 2dc65f358..e1d6aa933 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt @@ -1,10 +1,9 @@ package at.hannibal2.skyhanni.data.repo import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import com.google.gson.Gson -import com.google.gson.GsonBuilder import com.google.gson.JsonObject import net.minecraft.client.Minecraft import org.apache.commons.io.FileUtils @@ -15,7 +14,7 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.atomic.AtomicBoolean class RepoManager(private val configLocation: File) { - val gson: Gson = GsonBuilder().setPrettyPrinting().create() + private val gson get() = ConfigManager.gson private var latestRepoCommit: String? = null private val repoLocation: File = File(configLocation, "repo") diff --git a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt index 3e67adcac..9719c70ff 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt @@ -79,17 +79,13 @@ object RepoUtils { fun <T> getConstant(repo: File, constant: String, gson: Gson, clazz: Class<T>?): T? { if (repo.exists()) { val jsonFile = File(repo, "constants/$constant.json") - try { - BufferedReader( - InputStreamReader( - FileInputStream(jsonFile), - StandardCharsets.UTF_8 - ) - ).use { reader -> - return gson.fromJson(reader, clazz) - } - } catch (e: Exception) { - return null + BufferedReader( + InputStreamReader( + FileInputStream(jsonFile), + StandardCharsets.UTF_8 + ) + ).use { reader -> + return gson.fromJson(reader, clazz) } } return null diff --git a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt index 5cfd59aa1..39d187326 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.events import at.hannibal2.skyhanni.data.repo.RepoUtils +import at.hannibal2.skyhanni.test.command.CopyErrorCommand import com.google.gson.Gson import com.google.gson.JsonObject import java.io.File @@ -8,6 +9,10 @@ import java.io.File class RepositoryReloadEvent(val repoLocation: File, val gson: Gson): LorenzEvent() { fun getConstant(constant: String) = getConstant<JsonObject>(constant) - inline fun <reified T : Any> getConstant(constant: String) = + inline fun <reified T : Any> getConstant(constant: String) = try { RepoUtils.getConstant(repoLocation, constant, gson, T::class.java) + } catch (e: Exception) { + CopyErrorCommand.logError(Exception("Repo parsing error while trying to read constant '$constant'", e), "Error reading repo data") + null + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt index fa11ee786..a2106bf15 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt @@ -58,7 +58,7 @@ class BazaarBestSellMethod { val result = NumberUtil.format(totalDiff.toInt()) val name = NEUItems.getItemStack(internalName).nameWithEnchantment - return "§b$name§f sell difference: §e$result coins" + return "$name§7 sell difference: §6$result coins" } catch (e: Error) { e.printStackTrace() return "" @@ -72,7 +72,5 @@ class BazaarBestSellMethod { SkyHanniMod.feature.bazaar.bestSellMethodPos.renderString(display, posLabel = "Bazaar Best Sell Method") } - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyBlock && SkyHanniMod.feature.bazaar.bestSellMethod - } + private fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.bazaar.bestSellMethod }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt index 59356f30d..f569a0f21 100755 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.round import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import net.minecraft.client.Minecraft @@ -16,8 +17,10 @@ class GardenYawAndPitch { @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { - if (!isEnabled()) return - if (GardenAPI.toolInHand == null) return + if (!LorenzUtils.inSkyBlock) return + if (!config.enabled) return + if (!GardenAPI.inGarden() && !config.showEverywhere) return + if (GardenAPI.toolInHand == null && !config.showWithoutTool) return val player = Minecraft.getMinecraft().thePlayer @@ -38,13 +41,15 @@ class GardenYawAndPitch { "§aYaw: §f${yaw.toDouble().round(config.yawPrecision)}", "§aPitch: §f${pitch.toDouble().round(config.pitchPrecision)}", ) - config.pos.renderStrings(displayList, posLabel = "Yaw and Pitch") + if (GardenAPI.inGarden()) { + config.pos.renderStrings(displayList, posLabel = "Yaw and Pitch") + } else { + config.posOutside.renderStrings(displayList, posLabel = "Yaw and Pitch") + } } @SubscribeEvent fun onGardenToolChange(event: GardenToolChangeEvent) { lastChange = System.currentTimeMillis() } - - private fun isEnabled() = GardenAPI.inGarden() && config.enabled -} +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt index 2da6f89b5..d52535f0d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt @@ -191,7 +191,6 @@ class CaptureFarmingGear { } } - //todo pet level up @SubscribeEvent fun onChat(event: LorenzChatEvent) { if (!LorenzUtils.inSkyBlock) return @@ -226,5 +225,8 @@ class CaptureFarmingGear { if (msg == "Yum! You gain +5☘ Farming Fortune for 48 hours!") { hidden.cakeExpiring = System.currentTimeMillis() + 172800000 } + if (msg == "CARROTS EXPORTATION COMPLETE!") { + hidden.carrotFortune = true + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt index 20f203bb7..d114913bb 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt @@ -108,7 +108,7 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?) } if (coins == "1") { lastKnownDisplayStrings[PURSE] = "1 Coin" - } else if (coins != "") { + } else if (coins != "" && coins != null) { lastKnownDisplayStrings[PURSE] = "$coins Coins" } lastKnownDisplayStrings[PURSE] ?: "" diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/HighlightRiftGuide.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/HighlightRiftGuide.kt new file mode 100644 index 000000000..a8bf69fba --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/HighlightRiftGuide.kt @@ -0,0 +1,63 @@ +package at.hannibal2.skyhanni.features.rift + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class HighlightRiftGuide { + private val config get() = SkyHanniMod.feature.rift + private var inInventory = false + private var highlightedItems = listOf<Int>() + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + inInventory = false + + if (!isEnabled()) return + + val inGuide = event.inventoryItems[40]?.getLore()?.let { + if (it.size == 1) { + it[0] == "§7To Rift Guide" + } else false + } ?: false + if (!inGuide) return + + val highlightedItems = mutableListOf<Int>() + for ((slot, stack) in event.inventoryItems) { + val lore = stack.getLore() + if (lore.isNotEmpty()) { + if (lore.last() == "§8✖ Not completed yet!") { + highlightedItems.add(slot) + } + } + } + inInventory = true + this.highlightedItems = highlightedItems + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inInventory = false + } + + @SubscribeEvent(priority = EventPriority.LOW) + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!isEnabled()) return + if (!inInventory) return + + for (slot in InventoryUtils.getItemsInOpenChest()) { + if (slot.slotIndex in highlightedItems) { + slot highlight LorenzColor.YELLOW + } + } + } + + fun isEnabled() = RiftAPI.inRift() && config.highlightGuide +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt new file mode 100644 index 000000000..ea2f929e6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt @@ -0,0 +1,8 @@ +package at.hannibal2.skyhanni.features.rift + +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.utils.LorenzUtils + +object RiftAPI { + fun inRift() = LorenzUtils.inIsland(IslandType.THE_RIFT) +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/RiftTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftTimer.kt new file mode 100644 index 000000000..6fe16c981 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftTimer.kt @@ -0,0 +1,98 @@ +package at.hannibal2.skyhanni.features.rift + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzActionBarEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.TimeUtils +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class RiftTimer { + private val config get() = SkyHanniMod.feature.rift.timer + private var display = listOf<String>() + private var maxTime = 0L + private var latestTime = 0L + private val changes = mutableMapOf<Long, String>() + + @SubscribeEvent + fun onJoinWorld(ignored: WorldEvent.Load) { + display = emptyList() + } + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!isEnabled()) return + + val message = event.message + " §r§7You have §r§a(?<time>.*)ф §r§7left before the rift collapses!".toPattern().matchMatcher(message) { + val time = group("time") + maxTime = formatTime(time) + } + } + + @SubscribeEvent + fun onActionBar(event: LorenzActionBarEvent) { + if (!isEnabled()) return + + val message = event.message + for (entry in message.split(" ")) { + "§(?<color>[a7])(?<time>.*)ф Left.*".toPattern().matchMatcher(entry) { + val color = group("color") + if (color == "7") { + display = emptyList() + return + } + val time = group("time") + val currentTime = formatTime(time) + update(currentTime) + } + } + } + + private fun formatTime(time: String) = TimeUtils.getMillis(time.replace("m", "m ")) + + private fun update(currentTime: Long) { + if (currentTime == latestTime) return + val diff = (currentTime - latestTime) + 1000 + latestTime = currentTime + addDiff(diff) + + val currentFormat = TimeUtils.formatDuration(currentTime) + val percentage = LorenzUtils.formatPercentage(currentTime.toDouble() / maxTime) + val percentageFormat = if (config.percentage) " §7($percentage)" else "" + val maxTimeFormat = if (config.maxTime) "§7/§b" + TimeUtils.formatDuration(maxTime) else "" + val color = if (currentTime <= 60_000) "§c" else if (currentTime <= 60_000 * 5) "§e" else "§b" + val firstLine = "§eRift Timer: $color$currentFormat$maxTimeFormat$percentageFormat" + + display = buildList { + add(firstLine) + changes.keys.removeIf { System.currentTimeMillis() > it + 4_000 } + for (entry in changes.values) { + add(entry) + } + } + } + + private fun addDiff(diff: Long) { + val diffFormat = if (diff > 0) { + "§a+${TimeUtils.formatDuration(diff)}" + } else if (diff < 0) { + "§c-${TimeUtils.formatDuration(-diff)}" + } else return + + changes[System.currentTimeMillis()] = diffFormat + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { + if (!isEnabled()) return + + config.timerPosition.renderStrings(display, posLabel = "Rift Timer") + } + + fun isEnabled() = RiftAPI.inRift() && config.enabled +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt index c04d662e2..9faa3511b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt @@ -196,7 +196,7 @@ object SlayerItemProfitTracker { val renderable = if (inventoryOpen) Renderable.clickAndHover( text, listOf( - "§7Dropped §e$timesDropped §7times.", + "§7Dropped §e${timesDropped.addSeparators()} §7times.", "§7Your drop rate: §c$perBoss", "", "§eClick to " + (if (hidden) "show" else "hide") + "!", @@ -250,8 +250,8 @@ object SlayerItemProfitTracker { val slayerCompletedCount = itemLog.slayerCompletedCount addAsSingletonList( Renderable.hoverTips( - "§7Bosses killed: §e$slayerCompletedCount", - listOf("§7You killed the $itemLogCategory boss", "§e$slayerCompletedCount §7times.") + "§7Bosses killed: §e${slayerCompletedCount.addSeparators()}", + listOf("§7You killed the $itemLogCategory boss", "§e${slayerCompletedCount.addSeparators()} §7times.") ) ) diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyErrorCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyErrorCommand.kt index a8c6660f3..ccaeee6ef 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyErrorCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/command/CopyErrorCommand.kt @@ -4,12 +4,14 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.OSUtils import com.google.common.cache.CacheBuilder +import net.minecraft.client.Minecraft import java.util.* import java.util.concurrent.TimeUnit object CopyErrorCommand { // random id -> error message private val errorMessages = mutableMapOf<String, String>() + private val fullErrorMessages = mutableMapOf<String, String>() private var cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build<Pair<String, Int>, Unit>() @@ -20,22 +22,34 @@ object CopyErrorCommand { return } - LorenzUtils.chat(errorMessages[array[0]]?.let { + val id = array[0] + val fullErrorMessage = LorenzUtils.isControlKeyDown() + val errorMessage = if (fullErrorMessage) { + fullErrorMessages[id] + } else { + errorMessages[id] + } + val name = if (fullErrorMessage) "Ful error" else "Error" + LorenzUtils.chat(errorMessage?.let { OSUtils.copyToClipboard(it) - "§e[SkyHanni] Error copied into the clipboard, please report it on the SkyHanni discord!" + "§e[SkyHanni] $name copied into the clipboard, please report it on the SkyHanni discord!" } ?: "§c[SkyHanni] Error id not found!") } fun logError(error: Throwable, message: String) { + Minecraft.getMinecraft().thePlayer ?: throw Error(message, error) + val pair = error.stackTrace[0].let { it.fileName to it.lineNumber } if (cache.getIfPresent(pair) != null) return cache.put(pair, Unit) - val stackTrace = error.stackTraceToString().removeSpam() + val fullStackTrace = error.getExactStackTrace(true).joinToString("\n") + val stackTrace = error.getExactStackTrace(false).joinToString("\n").removeSpam() val randomId = UUID.randomUUID().toString() - errorMessages[randomId] = - "```\nSkyHanni ${SkyHanniMod.version}: $message\n \n$stackTrace```" + errorMessages[randomId] = "```\nSkyHanni ${SkyHanniMod.version}: $message\n \n$stackTrace\n```" + fullErrorMessages[randomId] = + "```\nSkyHanni ${SkyHanniMod.version}: $message\n(full stack trace)\n \n$fullStackTrace\n```" LorenzUtils.clickableChat( "§c[SkyHanni ${SkyHanniMod.version}]: $message. Click here to copy the error into the clipboard.", @@ -44,12 +58,57 @@ object CopyErrorCommand { } } +private fun Throwable.getExactStackTrace(full: Boolean, parent: List<String> = emptyList()): List<String> = buildList { + add("Caused by " + javaClass.name + ": $message") + + val breakAfter = listOf( + "at net.minecraftforge.client.ClientCommandHandler.executeCommand(", + ) + val replace = mapOf( + "io.mouberry,notenoughupdates" to "NEU", + "at.hannibal2.skyhanni" to "SH", + ) + + for (traceElement in stackTrace) { + var text = "\tat $traceElement" + if (!full) { + if (text in parent) { + println("broke at: $text") + break + } + } + if (!full) { + for ((from, to) in replace) { + text = text.replace(from, to) + } + } + add(text) + if (!full) { + if (breakAfter.any { text.contains(it) }) { + println("breakAfter: $text") + break + } + } + } + + cause?.let { + addAll(it.getExactStackTrace(full, this)) + } +} + private fun String.removeSpam(): String { val ignored = listOf( "at io.netty.", "at net.minecraft.network.", "at net.minecraftforge.fml.common.network.handshake.", "at java.lang.Thread.run", + "at com.google.gson.internal.", + "at net.minecraftforge.fml.common.eventhandler.", + "at java.util.concurrent.", + "at sun.reflect.", + "at net.minecraft.client.Minecraft.addScheduledTask(", + "at java.lang.reflect.", + "at at.hannibal2.skyhanni.config.commands.Commands\$", ) - return split("\r\n\t").filter { line -> !ignored.any { line.startsWith(it) } }.joinToString("\n") + return split("\n").filter { line -> !ignored.any { line.contains(it) } }.joinToString("\n") } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 054b8509c..bc50ea0e6 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -372,4 +372,13 @@ object LorenzUtils { && tileSign.signText[2].unformattedText.removeColor() == "Set your" && tileSign.signText[3].unformattedText.removeColor() == "speed cap!") } + + fun inIsland(island: IslandType) = inSkyBlock && skyBlockIsland == island + + fun <K, N : Number> MutableMap<K, N>.addOrPut(item: K, amount: N) { + val old = this[item] ?: 0 + val d = old.toDouble() + amount.toDouble() + @Suppress("UNCHECKED_CAST") + this[item] = d as N + } }
\ No newline at end of file |