diff --git a/pull_request_template.md b/pull_request_template.md index f7bfe3c3fe43..2dd04bcec865 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,5 +1,11 @@ +## PR Reviews + +When your PR is marked as ready for review, some of our maintainers will look through your code to make sure everything is good to go. In order to do this, they may request some changes you will need to do, **or fix smaller stuff (like merge conflicts) for you**. If a maintainer has reviewed your PR, make sure to **pull any of their changes** into your local project before doing more work on your code. Having maintainers fix small stuff for you helps us speed up the process of merging your PR, so if some of your systems warrant further care, be sure to let us know (preferably with a code comment). + +Make sure to only mark your PR as "Ready to review" when it is. If you still want to do major changes, you can keep a draft PR open until then. + ## Dependencies - pr_number_or_link_here diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 126a6652ffdd..380cb0b7fdb0 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -133,6 +133,7 @@ import at.hannibal2.skyhanni.features.dungeon.TerracottaPhase import at.hannibal2.skyhanni.features.event.UniqueGiftingOpportunitiesFeatures import at.hannibal2.skyhanni.features.event.diana.AllBurrowsList import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper +import at.hannibal2.skyhanni.features.event.diana.DianaFixChat import at.hannibal2.skyhanni.features.event.diana.DianaProfitTracker import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowHelper import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowParticleFinder @@ -508,7 +509,7 @@ class SkyHanniMod { loadModule(ScoreboardData()) loadModule(SeaCreatureFeatures()) loadModule(SeaCreatureManager()) - loadModule(EntityData()) + loadModule(EntityData) loadModule(MobData()) loadModule(MobDetection()) loadModule(EntityMovementData) @@ -705,6 +706,7 @@ class SkyHanniMod { loadModule(NonGodPotEffectDisplay()) loadModule(SoopyGuessBurrow()) loadModule(DianaProfitTracker) + loadModule(DianaFixChat()) loadModule(MythologicalCreatureTracker) loadModule(ShiftClickNPCSell) loadModule(HighlightJerries()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java index 950aa2169bf2..e904dd7aba49 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java @@ -14,15 +14,9 @@ public class DevConfig { @Expose - @ConfigOption(name = "Repo Auto Update", desc = "Update the repository on every startup.\n" + - "§cOnly disable this if you know what you are doing!") - @ConfigEditorBoolean - public boolean repoAutoUpdate = true; - - @Expose - @ConfigOption(name = "Log Expiry Time", desc = "Deletes your SkyHanni logs after this time period in days.") - @ConfigEditorSlider(minValue = 1, maxValue = 30, minStep = 1) - public int logExpiryTime = 14; + @ConfigOption(name = "Repository", desc = "") + @Accordion + public RepositoryConfig repo = new RepositoryConfig(); @Expose @ConfigOption(name = "Debug", desc = "") @@ -34,6 +28,11 @@ public class DevConfig { @Accordion public RepoPatternConfig repoPattern = new RepoPatternConfig(); + @Expose + @ConfigOption(name = "Log Expiry Time", desc = "Deletes your SkyHanni logs after this time period in days.") + @ConfigEditorSlider(minValue = 1, maxValue = 30, minStep = 1) + public int logExpiryTime = 14; + @Expose @ConfigOption(name = "Slot Number", desc = "Show slot number in inventory while pressing this key.") @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) @@ -64,12 +63,20 @@ public class DevConfig { @Expose @ConfigOption( name = "Fancy Contributors", - desc = "Marks §cSkyHanni's contributors §7fancy in the tab list. " + + desc = "Marks §cSkyHanni's contributors §7fancy in the tab list and nametags. " + "§eThose are the folks that coded the mod for you for free :)" ) @ConfigEditorBoolean public boolean fancyContributors = true; + @Expose + @ConfigOption( + name = "Contributor Nametags", + desc = "Makes SkyHanni contributors' nametags fancy too. " + ) + @ConfigEditorBoolean + public boolean contributorNametags = false; + @Expose @ConfigOption( name = "Flip Contributors", diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/RepositoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/RepositoryConfig.java new file mode 100644 index 000000000000..697cb3c91857 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/RepositoryConfig.java @@ -0,0 +1,50 @@ +package at.hannibal2.skyhanni.config.features.dev; + +import at.hannibal2.skyhanni.data.repo.RepoUtils; +import com.google.gson.annotations.Expose; +import io.github.notenoughupdates.moulconfig.annotations.Accordion; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorButton; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorText; +import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; + +public class RepositoryConfig { + + @Expose + @ConfigOption(name = "Repo Auto Update", desc = "Update the repository on every startup.\n" + + "§cOnly disable this if you know what you are doing!") + @ConfigEditorBoolean + public boolean repoAutoUpdate = true; + + @ConfigOption(name = "Update Repo Now", desc = "Update your repository to the latest version") + @ConfigEditorButton(buttonText = "Update") + public Runnable updateRepo = RepoUtils::updateRepo; + + @Expose + @ConfigOption(name = "Repository Location", desc = "") + @Accordion + public RepositoryLocation location = new RepositoryLocation(); + + public static class RepositoryLocation { + + @ConfigOption(name = "Reset Repository Location", desc = "Reset your repository location to the default.") + @ConfigEditorButton(buttonText = "Reset") + public Runnable resetRepoLocation = RepoUtils::resetRepoLocation; + + @Expose + @ConfigOption(name = "Repository User", desc = "The Repository Branch, default: hannibal002") + @ConfigEditorText + public String user = "hannibal002"; + + @Expose + @ConfigOption(name = "Repository Name", desc = "The Repository Name, default: SkyHanni-Repo") + @ConfigEditorText + public String name = "SkyHanni-REPO"; + + @Expose + @ConfigOption(name = "Repository Branch", desc = "The Repository Branch, default: main") + @ConfigEditorText + public String branch = "main"; + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java index 04c915ff0bdb..2bfe65a49638 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java @@ -92,4 +92,10 @@ public class HoppityEggsConfig { @ConfigEditorBoolean @FeatureToggle public boolean timeInChat = true; + + @Expose + @ConfigOption(name = "Compact Chat", desc = "Compact chat events when finding a Hoppity Egg.") + @ConfigEditorBoolean + @FeatureToggle + public boolean compactChat = false; } diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt index 4cc5f840da3e..cf2d260f4874 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt @@ -6,11 +6,14 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.SecondPassedEvent +import at.hannibal2.skyhanni.events.entity.EntityDisplayNameEvent import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth import at.hannibal2.skyhanni.utils.LorenzUtils.derpy +import at.hannibal2.skyhanni.utils.TimeLimitedCache import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.client.entity.EntityPlayerSP +import net.minecraft.entity.Entity import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.boss.EntityWither import net.minecraft.entity.item.EntityArmorStand @@ -18,11 +21,14 @@ import net.minecraft.entity.item.EntityItem import net.minecraft.entity.item.EntityItemFrame import net.minecraft.entity.item.EntityXPOrb import net.minecraft.network.play.server.S1CPacketEntityMetadata +import net.minecraft.util.IChatComponent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds -class EntityData { +object EntityData { private val maxHealthMap = mutableMapOf() + private val nametagCache = TimeLimitedCache(50.milliseconds) @SubscribeEvent fun onTick(event: LorenzTickEvent) { @@ -83,4 +89,12 @@ class EntityData { } } } + + fun postRenderNametag(entity: Entity, chatComponent: IChatComponent): IChatComponent { + return nametagCache.getOrPut(entity) { + val event = EntityDisplayNameEvent(entity, chatComponent) + event.postAndCatch() + event.chatComponent + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt index 55ab2dd35df1..024733446be5 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt @@ -283,6 +283,7 @@ class HypixelData { } @SubscribeEvent + // TODO rewrite everything in here fun onTick(event: LorenzTickEvent) { if (!LorenzUtils.inSkyBlock) { // Modified from NEU. @@ -302,17 +303,19 @@ class HypixelData { } } - if (LorenzUtils.inSkyBlock) { - loop@ for (line in ScoreboardData.sidebarLinesFormatted) { - skyblockAreaPattern.matchMatcher(line) { - val originalLocation = group("area") - skyBlockArea = LocationFixData.fixLocation(skyBlockIsland) ?: originalLocation - skyBlockAreaWithSymbol = line.trim() - break@loop + if (LorenzUtils.onHypixel) { + if (LorenzUtils.inSkyBlock) { + loop@ for (line in ScoreboardData.sidebarLinesFormatted) { + skyblockAreaPattern.matchMatcher(line) { + val originalLocation = group("area") + skyBlockArea = LocationFixData.fixLocation(skyBlockIsland) ?: originalLocation + skyBlockAreaWithSymbol = line.trim() + break@loop + } } - } - checkProfileName() + checkProfileName() + } } if (!event.isMod(5)) return diff --git a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt index ec62adda023e..f4235cb73945 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt @@ -38,27 +38,21 @@ object SlayerAPI { System.currentTimeMillis() } else latestProgressChangeTime - fun getItemNameAndPrice(internalName: NEUInternalName, amount: Int): Pair { - val key = internalName to amount - nameCache.getOrNull(key)?.let { - return it - } - - val amountFormat = if (amount != 1) "§7${amount}x §r" else "" - val displayName = internalName.itemName + fun getItemNameAndPrice(internalName: NEUInternalName, amount: Int): Pair = + nameCache.getOrPut(internalName to amount) { + val amountFormat = if (amount != 1) "§7${amount}x §r" else "" + val displayName = internalName.itemName - val price = internalName.getPrice() - val npcPrice = internalName.getNpcPriceOrNull() ?: 0.0 - val maxPrice = npcPrice.coerceAtLeast(price) - val totalPrice = maxPrice * amount + val price = internalName.getPrice() + val npcPrice = internalName.getNpcPriceOrNull() ?: 0.0 + val maxPrice = npcPrice.coerceAtLeast(price) + val totalPrice = maxPrice * amount - val format = NumberUtil.format(totalPrice) - val priceFormat = " §7(§6$format coins§7)" + val format = NumberUtil.format(totalPrice) + val priceFormat = " §7(§6$format coins§7)" - val result = "$amountFormat$displayName$priceFormat" to totalPrice - nameCache.put(key, result) - return result - } + "$amountFormat$displayName$priceFormat" to totalPrice + } @SubscribeEvent fun onDebugDataCollect(event: DebugDataCollectEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/data/mob/MobFilter.kt b/src/main/java/at/hannibal2/skyhanni/data/mob/MobFilter.kt index c539ccb31964..f752fac46eec 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/mob/MobFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/mob/MobFilter.kt @@ -63,10 +63,11 @@ object MobFilter { * REGEX-TEST: ﴾ [Lv500] Arachne 100k/100k❤ ﴿ * REGEX-TEST: ﴾ [Lv200] Barbarian Duke X 70M/70M❤ ﴿ * REGEX-TEST: ﴾ [Lv100] Endstone Protector 4.6M/5M❤ ﴿ + * REGEX-TEST: ﴾ [Lv400] Thunder 29M/35M❤ ﴿ * */ val bossMobNameFilter by repoGroup.pattern( "filter.boss", - "^. (?:\\[Lv(?\\d+)\\] )?(?[^ᛤ\n]*)(?: ᛤ)?(?: [\\d\\/BMk.,❤]+|█+)? .$" + "^. (?:\\[Lv(?\\d+)\\] )?(?[^ᛤ\n]*?)(?: ᛤ)?(?: [\\d\\/BMk.,❤]+| █+)? .$" ) val dungeonNameFilter by repoGroup.pattern( "filter.dungeon", 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 29a22138dbaf..358b00c9c047 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt @@ -36,22 +36,28 @@ class RepoManager(private val configLocation: File) { companion object { + private val config get() = SkyHanniMod.feature.dev.repo + val successfulConstants = mutableListOf() val unsuccessfulConstants = mutableListOf() private var lastConstant: String? = null - fun setlastConstant(constant: String) { + fun setLastConstant(constant: String) { lastConstant?.let { successfulConstants.add(it) } lastConstant = constant } + + fun getRepoLocation(): String { + return "${config.location.user}/${config.location.name}/${config.location.branch}" + } } fun loadRepoInformation() { atomicShouldManuallyReload.set(true) - if (SkyHanniMod.feature.dev.repoAutoUpdate) { + if (config.repoAutoUpdate) { fetchRepository(false).thenRun(this::reloadRepository) } else { reloadRepository() @@ -62,6 +68,7 @@ class RepoManager(private val configLocation: File) { fun updateRepo() { atomicShouldManuallyReload.set(true) + checkRepoLocation() fetchRepository(true).thenRun { this.reloadRepository("Repo updated successfully.") } } @@ -219,7 +226,7 @@ class RepoManager(private val configLocation: File) { if (unsuccessfulConstants.isNotEmpty()) { ChatUtils.error( "§7Repo Issue! Some features may not work. Please report this error on the Discord!\n" - + "§7Repo Auto Update Value: §c${SkyHanniMod.feature.dev.repoAutoUpdate}\n" + + "§7Repo Auto Update Value: §c${config.repoAutoUpdate}\n" + "§7If you have Repo Auto Update turned off, please try turning that on.\n" + "§cUnsuccessful Constants §7(${unsuccessfulConstants.size}):" ) @@ -266,15 +273,15 @@ class RepoManager(private val configLocation: File) { } private fun getCommitApiUrl(): String { - val repoUser = "hannibal002" - val repoName = "SkyHanni-REPO" - val repoBranch = "main" + val repoUser = config.location.user + val repoName = config.location.name + val repoBranch = config.location.branch return String.format("https://api.github.com/repos/%s/%s/commits/%s", repoUser, repoName, repoBranch) } private fun getDownloadUrl(commitId: String?): String { - val repoUser = "hannibal002" - val repoName = "SkyHanni-REPO" + val repoUser = config.location.user + val repoName = config.location.name return String.format("https://github.com/%s/%s/archive/%s.zip", repoUser, repoName, commitId) } @@ -293,4 +300,37 @@ class RepoManager(private val configLocation: File) { fun onNeuRepoReload(event: io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent) { NeuRepositoryReloadEvent().postAndCatch() } + + fun resetRepositoryLocation(manual: Boolean = false) { + val defaultUser = "hannibal002" + val defaultName = "SkyHanni-Repo" + val defaultBranch = "main" + + with(config.location) { + if (user == defaultUser && name == defaultName && branch == defaultBranch) { + if (manual) { + ChatUtils.chat("Repo settings are already on default!") + } + return + } + + user = defaultUser + name = defaultName + branch = defaultBranch + if (manual) { + ChatUtils.clickableChat("Reset Repo settings to default. " + + "Click §aUpdate Repo Now §ein config or run /shupdaterepo to update!", + onClick = { + updateRepo() + }) + } + } + } + + private fun checkRepoLocation() { + if (config.location.user.isEmpty() || config.location.name.isEmpty() || config.location.branch.isEmpty()) { + ChatUtils.userError("Invalid Repo settings detected, resetting default settings.") + resetRepositoryLocation() + } + } } 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 861e17c827f9..1e9af5d69e2b 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.data.repo +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.test.command.ErrorManager import com.google.gson.Gson import java.io.BufferedReader @@ -103,4 +104,14 @@ object RepoUtils { } } } + + @JvmStatic + fun updateRepo() { + SkyHanniMod.repo.updateRepo() + } + + @JvmStatic + fun resetRepoLocation() { + SkyHanniMod.repo.resetRepositoryLocation(manual = true) + } } diff --git a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt index fc006b04989a..ec5b0a8ec95e 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt @@ -10,7 +10,7 @@ import java.lang.reflect.Type class RepositoryReloadEvent(val repoLocation: File, val gson: Gson) : LorenzEvent() { inline fun getConstant(constant: String, type: Type? = null, gson: Gson = this.gson): T = try { - RepoManager.setlastConstant(constant) + RepoManager.setLastConstant(constant) if (!repoLocation.exists()) throw RepoError("Repo folder does not exist!") RepoUtils.getConstant(repoLocation, constant, gson, T::class.java, type) } catch (e: Exception) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt index fcc647809ed8..d67e9550abbc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt @@ -35,6 +35,7 @@ enum class HoppityEggType( fun isClaimed() = claimed val formattedName get() = "${if (isClaimed()) "§7§m" else mealColour}$mealName:$mealColour" + val coloredName get() = "$mealColour$mealName" companion object { fun allFound() = entries.forEach { it.markClaimed() } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt new file mode 100644 index 000000000000..21a2e4f7af5a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt @@ -0,0 +1,101 @@ +package at.hannibal2.skyhanni.features.event.hoppity + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsManager.getEggType +import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.DelayedRun +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.fromNow +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +object HoppityEggsCompactChat { + + private var hoppityEggChat = mutableListOf() + private var duplicate = false + private var lastRarity = "" + private var lastName = "" + private var lastProfit = "" + private var newRabbit = false + private var lastChatMeal: HoppityEggType? = null + private var lastDuplicateAmount: Long? = null + + fun compactChat(event: LorenzChatEvent, lastDuplicateAmount: Long? = null) { + lastDuplicateAmount?.let { + this.lastDuplicateAmount = it + } + if (!HoppityEggsManager.config.compactChat) return + event.blockedReason = "compact_hoppity" + hoppityEggChat.add(event.message) + if (lastDuplicateAmount != null) { + this.duplicate = true + } + if (hoppityEggChat.size == 3) { + DelayedRun.runDelayed(200.milliseconds) { + sendCompact() + } + } + } + + private fun sendCompact() { + if (hoppityEggChat.isNotEmpty()) { + ChatUtils.hoverableChat(createCompactMessage(), hover = hoppityEggChat, prefix = false) + } + + this.duplicate = false + this.newRabbit = false + lastRarity = "" + lastName = "" + lastProfit = "" + lastChatMeal = null + lastDuplicateAmount = null + } + + private fun createCompactMessage(): String { + val mealName = lastChatMeal?.coloredName ?: "" + + return if (duplicate) { + val format = lastDuplicateAmount?.let { NumberUtil.format(it) } ?: "?" + "$mealName Egg! §7Duplicate $lastName §7(§6+$format Chocolate§7)" + } else if (newRabbit) { + "$mealName Egg! §d§lNEW $lastName §7(${lastProfit}§7)" + } else "?" + } + + fun handleChat(event: LorenzChatEvent) { + HoppityEggsManager.eggFoundPattern.matchMatcher(event.message) { + hoppityEggChat = mutableListOf() + lastChatMeal = getEggType(event) + compactChat(event) + } + + HoppityEggsManager.rabbitFoundPatttern.matchMatcher(event.message) { + lastName = group("name") + lastRarity = group("rarity") + compactChat(event) + } + HoppityEggsManager.newRabbitFound.matchMatcher(event.message) { + val chocolate = group("chocolate") + val perSecond = group("perSecond") + newRabbit = true + lastProfit = "§6+$chocolate §7and §6+${perSecond}x c/s!" + compactChat(event) + } + } + + fun clickableCompact(onClick: () -> Unit): Boolean = if (hoppityEggChat.size > 0) { + val hover = hoppityEggChat.joinToString("\n") + + " \n§eClick here to share the location of this chocolate egg with the server!" + hoppityEggChat.clear() + ChatUtils.clickableChat( + createCompactMessage(), + hover = hover, + onClick = onClick, + expireAt = 30.seconds.fromNow(), + oneTimeClick = true, + prefix = false + ) + true + } else false +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt index 8ee19dda846a..e96b2a829d0d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt @@ -37,10 +37,27 @@ object HoppityEggsManager { * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§aChocolate Dinner Egg §r§dbehind Emissary Sisko§r§d! * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§9Chocolate Lunch Egg §r§dnear the Diamond Essence Shop§r§d! */ - private val eggFoundPattern by ChocolateFactoryAPI.patternGroup.pattern( + val eggFoundPattern by ChocolateFactoryAPI.patternGroup.pattern( "egg.found", "§d§lHOPPITY'S HUNT §r§dYou found a §r§.Chocolate (?\\w+) Egg §r§d(?.*)§r§d!" ) + + /** + * REGEX-TEST: §D§LHOPPITY'S HUNT §7You found §fArnie §7(§F§LCOMMON§7)! + * REGEX-TEST: §D§LHOPPITY'S HUNT §7You found §aPenelope §7(§A§LUNCOMMON§7)! + */ + val rabbitFoundPatttern by ChocolateFactoryAPI.patternGroup.pattern( + "rabbit.found", + "§D§LHOPPITY'S HUNT §7You found (?.*) §7\\((?.*)§7\\)!" + ) + + /** + * REGEX-TEST: §d§lNEW RABBIT! §6+2 Chocolate §7and §6+0.003x Chocolate §7per second! + */ + val newRabbitFound by ChocolateFactoryAPI.patternGroup.pattern( + "rabbit.found.new", + "§d§lNEW RABBIT! §6\\+(?.*) Chocolate §7and §6\\+(?.*)x Chocolate §7per second!" + ) private val noEggsLeftPattern by ChocolateFactoryAPI.patternGroup.pattern( "egg.noneleft", "§cThere are no hidden Chocolate Rabbit Eggs nearby! Try again later!" @@ -88,6 +105,8 @@ object HoppityEggsManager { if (!ChocolateFactoryAPI.isHoppityEvent()) return + HoppityEggsCompactChat.handleChat(event) + eggFoundPattern.matchMatcher(event.message) { HoppityEggLocator.eggFound() val meal = getEggType(event) @@ -142,12 +161,15 @@ object HoppityEggsManager { val currentLocation = LocationUtils.playerLocation() DelayedRun.runNextTick { - ChatUtils.clickableChat( - "Click here to share the location of this chocolate egg with the server!", - onClick = { HoppityEggsShared.shareNearbyEggLocation(currentLocation, meal, note) }, - expireAt = 30.seconds.fromNow(), - oneTimeClick = true - ) + val onClick = { HoppityEggsShared.shareNearbyEggLocation(currentLocation, meal, note) } + if (!HoppityEggsCompactChat.clickableCompact(onClick)) { + ChatUtils.clickableChat( + "Click here to share the location of this chocolate egg with the server!", + onClick = onClick, + expireAt = 30.seconds.fromNow(), + oneTimeClick = true + ) + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt index 28c2aa27f201..2ce023100482 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt @@ -4,12 +4,11 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.features.fishing.FishingAPI.isBait +import at.hannibal2.skyhanni.utils.ConditionalUtils.transformIf import at.hannibal2.skyhanni.utils.EntityUtils -import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.LocationUtils import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.exactLocation import at.hannibal2.skyhanni.utils.StringUtils.removeColor @@ -21,8 +20,7 @@ import kotlin.time.Duration.Companion.milliseconds class ShowFishingItemName { private val config get() = SkyHanniMod.feature.fishing.fishedItemName - private var hasRodInHand = false - private var cache = TimeLimitedCache>(750.milliseconds) + private var itemsOnGround = TimeLimitedCache(750.milliseconds) // Taken from Skytils private val cheapCoins = setOf( @@ -33,53 +31,39 @@ class ShowFishingItemName { @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!isEnabled()) return + for (entityItem in EntityUtils.getEntitiesNextToPlayer(15.0)) { + val itemStack = entityItem.entityItem + // Hypixel sometimes replaces the bait item mid air with a stone + if (itemStack.name.removeColor() == "Stone") continue + var text = "" - if (event.isMod(10)) { - hasRodInHand = isFishingRod() + val isBait = itemStack.isBait() + if (isBait && !config.showBaits) continue + + if (itemStack.getSkullTexture() in cheapCoins) { + text = "§6Coins" + } else { + val name = itemStack.name.transformIf({isBait}) { "§7" + this.removeColor() } + text += if (isBait) "§c§l- §r" else "§a§l+ §r" + + val size = itemStack.stackSize + if (size != 1) text += "§7x$size §r" + text += name + } + + itemsOnGround.put(entityItem, text) } } - private fun isFishingRod() = InventoryUtils.getItemInHand()?.name?.contains("Rod") ?: false - @SubscribeEvent fun onRenderWorld(event: LorenzRenderWorldEvent) { if (!isEnabled()) return - if (hasRodInHand) { - for (entityItem in EntityUtils.getEntities()) { - val location = event.exactLocation(entityItem).add(y = 0.8) - if (location.distance(LocationUtils.playerLocation()) > 15) continue - val itemStack = entityItem.entityItem - var name = itemStack.name - - // Hypixel sometimes replaces the bait item mid air with a stone - if (name.removeColor() == "Stone") continue - - val size = itemStack.stackSize - val prefix = if (!itemStack.isBait()) { - "§a§l+" - } else { - if (!config.showBaits) continue - name = "§7" + name.removeColor() - "§c§l-" - } - - itemStack?.tagCompound?.getTag("SkullOwner")?.toString()?.let { - for (coin in cheapCoins) { - if (it.contains(coin)) { - name = "§6Coins" - } - } - } - - val sizeText = if (size != 1) "§7x$size §r" else "" - cache.put(entityItem, location to "$prefix §r$sizeText$name") - } - } - for ((location, text) in cache.values()) { + for ((item, text) in itemsOnGround) { + val location = event.exactLocation(item).add(y = 0.8) event.drawString(location, text) } } - fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && FishingAPI.holdingRod } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt index 05668871fa4a..0bfc9c87bd29 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -28,7 +28,6 @@ import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TabListData import at.hannibal2.skyhanni.utils.TimeUtils.format @@ -67,9 +66,16 @@ object GardenNextJacobContest { "day", "§aDay (?.*)" ) + + /** + * REGEX-TEST: Early Spring, Year 351 + * REGEX-TEST: Late Summer, Year 351 + * REGEX-TEST: Autumn, Year 351 + */ + val monthPattern by patternGroup.pattern( "month", - "(?.*), Year (?.*)" + "(?(?:\\w+ )?(?:Summer|Spring|Winter|Autumn)), Year (?\\d+)" ) private val cropPattern by patternGroup.pattern( "crop", @@ -187,11 +193,8 @@ object GardenNextJacobContest { @SubscribeEvent fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (!config.display) return - if (!monthPattern.matches(event.inventoryName)) return - - inCalendar = true - monthPattern.matchMatcher(event.inventoryName) { + inCalendar = true val month = LorenzUtils.getSBMonthByName(group("month")) val year = group("year").toInt() diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt index be5bde924e0e..8bd3a1decf40 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt @@ -144,11 +144,6 @@ class ToolTooltipTweaks { } } } - - // Fixing a hypixel bug. TODO remove once hypixel fixes it. use disabled features repo maybe? - if (internalName.contains("LOTUS")) { - event.toolTip.replaceAll { it.replace("Kills:", "Visitors:") } - } } private fun Number.formatStat() = statFormatter.format(this) diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt index 72d3c697580c..8cdde229f53b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt @@ -82,6 +82,7 @@ class JacobFarmingContestsInventory { @SubscribeEvent fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + // TODO add tooltip line "click + press to open on elite website if (!config.openOnElite.isKeyHeld()) return if (!LorenzUtils.inSkyBlock) return diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt index 3525b5e44265..26156fcaae64 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt @@ -83,7 +83,7 @@ enum class PestType( SprayType.TASTY_CHEESE, VinylType.RODENT_REVOLUTION, "PEST_RAT_MONSTER".asInternalName(), - CropType.COCOA_BEANS, + CropType.PUMPKIN, ), SLUG( "Slug", diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt index 445c72974533..1a82440f672e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt @@ -1,8 +1,10 @@ package at.hannibal2.skyhanni.features.inventory.chocolatefactory import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsCompactChat import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsManager import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.HypixelCommands import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.formatLong @@ -54,10 +56,12 @@ object ChocolateFactoryBarnManager { val amount = group("amount").formatLong() if (config.showDuplicateTime) { val format = ChocolateFactoryAPI.timeUntilNeed(amount).format(maxUnits = 2) - event.chatComponent.appendText("\n§7(§a+§b$format §aof production§7)") - ChocolateAmount.averageChocPerSecond() + DelayedRun.runNextTick { + ChatUtils.chat("§7(§a+§b$format §aof production§7)") + } } ChocolateAmount.addToAll(amount) + HoppityEggsCompactChat.compactChat(event, lastDuplicateAmount = amount) } rabbitCrashedPattern.matchMatcher(event.message) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt index 9da53010e88d..a0c382d718bb 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt @@ -32,7 +32,7 @@ class HighlightMiningCommissionMobs { // Dwarven Mines DWARVEN_GOBLIN_SLAYER("Goblin Slayer", { it.name == "Goblin " }), STAR_PUNCHER("Star Sentry Puncher", { it.name == "Crystal Sentry" }), - ICE_WALKER("Ice Walker Slayer", { it.name == "Ice Walker" }), + ICE_WALKER("Glacite Walker Slayer", { it.name == "Ice Walker" }), GOLDEN_GOBLIN("Golden Goblin Slayer", { it.name.contains("Golden Goblin") }), // Crystal Hollows diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ContributorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ContributorManager.kt index 2ad7d6446e40..10153cca38b6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/ContributorManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ContributorManager.kt @@ -3,7 +3,11 @@ package at.hannibal2.skyhanni.features.misc import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.jsonobjects.repo.ContributorJsonEntry import at.hannibal2.skyhanni.data.jsonobjects.repo.ContributorsJson +import at.hannibal2.skyhanni.data.mob.MobFilter.isRealPlayer import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.events.entity.EntityDisplayNameEvent +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.util.ChatComponentText import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object ContributorManager { @@ -16,7 +20,17 @@ object ContributorManager { contributors = event.getConstant("Contributors").contributors.mapKeys { it.key.lowercase() } } - fun getTabListSuffix(username: String): String? = getContributor(username)?.suffix + @SubscribeEvent + fun onRenderNametag(event: EntityDisplayNameEvent) { + if (!config.contributorNametags) return + (event.entity as? EntityPlayer)?.let { player -> + if (player.isRealPlayer()) getSuffix(event.entity.name)?.let { + event.chatComponent.appendSibling(ChatComponentText(" $it")) + } + } + } + + fun getSuffix(username: String): String? = getContributor(username)?.suffix fun shouldSpin(username: String): Boolean = getContributor(username)?.spinny ?: false fun shouldBeUpsideDown(username: String): Boolean = getContributor(username)?.upsideDown ?: false diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt index 70571b5cc768..3402f8d8e475 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt @@ -197,7 +197,7 @@ object AdvancedPlayerList { if (config.markSpecialPersons) { suffix += " ${getSocialIcon(data.name).icon()}" } - ContributorManager.getTabListSuffix(data.name)?.let { + ContributorManager.getSuffix(data.name)?.let { suffix += " $it" } @@ -210,14 +210,8 @@ object AdvancedPlayerList { private var randomOrderCache = TimeLimitedCache(20.minutes) - private fun getRandomOrder(name: String): Int { - val saved = randomOrderCache.getOrNull(name) - if (saved != null) { - return saved - } - val r = (Random.nextDouble() * 500).toInt() - randomOrderCache.put(name, r) - return r + private fun getRandomOrder(name: String) = randomOrderCache.getOrPut(name) { + (Random.nextDouble() * 500).toInt() } private fun getSocialIcon(name: String) = when { diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt index 2c31f078c643..b0a9d651e1d7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt @@ -29,35 +29,32 @@ object ModifyVisualWords { modifiedWords.addAll(SkyHanniMod.visualWordsData.modifiedWords) } - val cachedResult = textCache.getOrNull(originalText) - if (cachedResult != null) { - return cachedResult - } + return textCache.getOrPut(originalText) { + if (originalText.startsWith("§§")) { + modifiedText = modifiedText.removePrefix("§§") + } else { + for (modifiedWord in modifiedWords) { + if (!modifiedWord.enabled) continue + val phrase = modifiedWord.phrase.convertToFormatted() - if (originalText.startsWith("§§")) { - modifiedText = modifiedText.removePrefix("§§") - } else { - for (modifiedWord in modifiedWords) { - if (!modifiedWord.enabled) continue - val phrase = modifiedWord.phrase.convertToFormatted() + if (phrase.isEmpty()) continue - if (phrase.isEmpty()) continue + modifiedText = modifiedText.replace( + phrase, modifiedWord.replacement.convertToFormatted(), modifiedWord.isCaseSensitive() + ) + } + } - modifiedText = modifiedText.replace( - phrase, modifiedWord.replacement.convertToFormatted(), modifiedWord.isCaseSensitive() - ) + // Disabled, as its only a novelty for 30 seconds and will annoy after that everyone. + /* + if (LorenzUtils.isAprilFoolsDay && !FontRendererHook.cameFromChat && Random.nextDouble() < 0.02) { + modifiedText = modifiedText.replace(reverseRegex) { + it.groupValues[1] + it.groupValues[2].reversed() + } } + */ + modifiedText } - - // Disabled, as its only a novelty for 30 seconds and will annoy after that everyone. - -// if (LorenzUtils.isAprilFoolsDay && !FontRendererHook.cameFromChat && Random.nextDouble() < 0.02) { -// modifiedText = modifiedText.replace(reverseRegex) { -// it.groupValues[1] + it.groupValues[2].reversed() -// } -// } - textCache.put(originalText, modifiedText) - return modifiedText } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt index 0864bf658527..7474b10886c1 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt @@ -3,11 +3,10 @@ package at.hannibal2.skyhanni.features.slayer import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.SlayerAPI import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName -import at.hannibal2.skyhanni.utils.LocationUtils import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.exactLocation @@ -21,33 +20,31 @@ class SlayerItemsOnGround { private val config get() = SkyHanniMod.feature.slayer.itemsOnGround - private var itemsOnGround = TimeLimitedCache>(2.seconds) + private var itemsOnGround = TimeLimitedCache(2.seconds) @SubscribeEvent - fun onRenderWorld(event: LorenzRenderWorldEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.enabled) return - if (!SlayerAPI.isInCorrectArea) return - if (!SlayerAPI.hasActiveSlayerQuest()) return - - for (entityItem in EntityUtils.getEntities()) { - val location = event.exactLocation(entityItem).add(y = 0.8) - if (location.distance(LocationUtils.playerLocation()) > 15) continue - + fun onTick(event: LorenzTickEvent) { + if (!isEnabled()) return + for (entityItem in EntityUtils.getEntitiesNextToPlayer(15.0)) { val itemStack = entityItem.entityItem - // happens in spiders den sometimes if (itemStack.item == Items.spawn_egg) continue - if (itemStack.getInternalName().equals("")) continue // TODO remove, should never happen if (itemStack.getInternalName() == NEUInternalName.NONE) continue - - val (itemName, price) = SlayerAPI.getItemNameAndPrice(itemStack.getInternalName(), itemStack.stackSize) + val (name, price) = SlayerAPI.getItemNameAndPrice(itemStack.getInternalName(), itemStack.stackSize) if (config.minimumPrice > price) continue - - itemsOnGround.put(entityItem, location to itemName) + itemsOnGround.put(entityItem, name) } + } - for ((location, text) in itemsOnGround.values()) { + @SubscribeEvent + fun onRenderWorld(event: LorenzRenderWorldEvent) { + if (!isEnabled()) return + + for ((item, text) in itemsOnGround) { + val location = event.exactLocation(item).add(y = 0.8) event.drawString(location, text) } } + + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && + SlayerAPI.isInCorrectArea && SlayerAPI.hasActiveSlayerQuest() } diff --git a/src/main/java/at/hannibal2/skyhanni/test/DebugCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/DebugCommand.kt index 699239c9edf8..e5ea5ab83049 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/DebugCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/DebugCommand.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.test import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.HypixelData import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.repo.RepoManager import at.hannibal2.skyhanni.events.DebugDataCollectEvent import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.LorenzUtils @@ -36,6 +37,7 @@ object DebugCommand { // calling default debug stuff player(event) repoAutoUpdate(event) + repoLocation(event) globalRender(event) skyblockStatus(event) profileName(event) @@ -127,13 +129,18 @@ object DebugCommand { private fun repoAutoUpdate(event: DebugDataCollectEvent) { event.title("Repo Auto Update") - if (SkyHanniMod.feature.dev.repoAutoUpdate) { + if (SkyHanniMod.feature.dev.repo.repoAutoUpdate) { event.addIrrelevant("normal enabled") } else { event.addData("The repo does not auto update because auto update is disabled!") } } + private fun repoLocation(event: DebugDataCollectEvent) { + event.title("Repo Location") + event.addIrrelevant("repo location: '${RepoManager.getRepoLocation()}'") + } + private fun player(event: DebugDataCollectEvent) { event.title("Player") event.addIrrelevant { diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt index 6d67a9ad0394..e5ed69064411 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt @@ -47,20 +47,24 @@ object TestChatCommand { } else ChatComponentText(text.replace("&", "§")) if (!isHidden) ChatUtils.chat("Testing message: §7${component.formattedText}", prefixColor = "§a") - test(component) + test(component, isHidden) } - private fun test(componentText: IChatComponent) { + private fun test(componentText: IChatComponent, isHidden: Boolean) { val message = componentText.formattedText.stripHypixelMessage() val event = LorenzChatEvent(message, componentText) event.postAndCatch() if (event.blockedReason != "") { - ChatUtils.chat("§cChat blocked: ${event.blockedReason}") + if (!isHidden) { + ChatUtils.chat("§cChat blocked: ${event.blockedReason}") + } } else { val finalMessage = event.chatComponent if (finalMessage.formattedText.stripHypixelMessage() != message) { - ChatUtils.chat("§eChat modified!") + if (!isHidden) { + ChatUtils.chat("§eChat modified!") + } } ChatUtils.chat(finalMessage) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt index 0c55b894ccda..ddd072c2864d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt @@ -2,8 +2,8 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.test.command.ErrorManager -import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.awt.Toolkit @@ -26,20 +26,18 @@ object ClipboardUtils { return result } - private suspend fun getClipboard(): Clipboard? { - val deferred = CompletableDeferred() - if (canAccessClipboard()) { - deferred.complete(Toolkit.getDefaultToolkit().systemClipboard) - } else { - LorenzUtils.runDelayed(5.milliseconds) { - SkyHanniMod.coroutineScope.launch { - deferred.complete(getClipboard()) - } - } - } - return deferred.await() + private suspend fun getClipboard(retries: Int = 20): Clipboard? = if (canAccessClipboard()) { + Toolkit.getDefaultToolkit().systemClipboard + } else if (retries > 0) { + delay(11) + getClipboard(retries - 1) + } else { + ErrorManager.logErrorStateWithData("can not read clipboard", + "clipboard can not be accessed after 20 retries") + null } + fun copyToClipboard(text: String, step: Int = 0) { SkyHanniMod.coroutineScope.launch { try { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 20bf02bb7dac..3aa530c22590 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -1040,6 +1040,7 @@ object RenderUtils { } fun exactLocation(entity: Entity, partialTicks: Float): LorenzVec { + if (entity.isDead) return entity.getLorenzVec() val x = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks val y = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks val z = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt index 8b4b0c3724be..182b1381bfa7 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt @@ -4,10 +4,10 @@ import com.google.common.cache.CacheBuilder import java.util.concurrent.TimeUnit import kotlin.time.Duration -class TimeLimitedCache( +class TimeLimitedCache( expireAfterWrite: Duration, private val removalListener: (K?, V?) -> Unit = { _, _ -> }, -) { +): Iterable> { private val cache = CacheBuilder.newBuilder() .expireAfterWrite(expireAfterWrite.inWholeMilliseconds, TimeUnit.MILLISECONDS) @@ -18,11 +18,17 @@ class TimeLimitedCache( fun getOrNull(key: K): V? = cache.getIfPresent(key) + fun getOrPut(key: K, defaultValue: () -> V) = getOrNull(key) ?: defaultValue().also { put(key, it) } + fun clear() = cache.invalidateAll() + fun entries(): Set> = cache.asMap().entries + fun values(): Collection = cache.asMap().values fun keys(): Set = cache.asMap().keys fun containsKey(key: K): Boolean = cache.getIfPresent(key) != null + + override fun iterator(): Iterator> = entries().iterator() } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedSet.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedSet.kt index 5f0ccd4040aa..fae86fac57cf 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedSet.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedSet.kt @@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.utils import kotlin.time.Duration -class TimeLimitedSet( +class TimeLimitedSet( expireAfterWrite: Duration, private val removalListener: (T) -> Unit = {}, ) {