diff options
author | CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> | 2023-09-10 18:40:56 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-10 10:40:56 +0200 |
commit | 593c01992afe4e8d5d4cd8aa61abbfb1d82e2a30 (patch) | |
tree | 5e9941862992f014b68dea6420d169be352c6295 /src/main/java/at/hannibal2/skyhanni/data | |
parent | 7e6a2296142e811f77049c0b4080bbd00cd29692 (diff) | |
download | skyhanni-593c01992afe4e8d5d4cd8aa61abbfb1d82e2a30.tar.gz skyhanni-593c01992afe4e8d5d4cd8aa61abbfb1d82e2a30.tar.bz2 skyhanni-593c01992afe4e8d5d4cd8aa61abbfb1d82e2a30.zip |
SackAPI event and storing data #410
* implement SackChangeEvent
* move SackAPI
* handling events
* fixed small errors
* fetching item data
* moved over sack display
* it should work
* saving gemstones
* saving gemstones
* new config file for sacks
* saving last change amount
* fix conflicts fully
* implement SackChangeEvent
* move SackAPI
* handle 'other items' correctly
* move sackAPI again
* handling events
* fixed small errors
* fetching item data
* moved over sack display
* it should work
* saving gemstones
* saving gemstones
* new config file for sacks
* saving last change amount
* Merge branch 'beta' into sack_storage
* fix conflicts fully
* Merge remote-tracking branch 'origin/sack_storage' into sack_storage
* Merge branch 'hannibal002:beta' into sack_storage
* Merge remote-tracking branch 'origin/sack_storage' into sack_storage
* remove unnecessary thing
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/data')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt | 26 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt | 291 |
2 files changed, 311 insertions, 6 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt b/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt index 36940104b..3524f03db 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.SackData import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.LorenzUtils @@ -17,6 +18,10 @@ object ProfileStorageData { private var nextProfile: String? = null + + private var sackPlayers: SackData.PlayerSpecific? = null + var sackProfiles: SackData.ProfileSpecific? = null + @SubscribeEvent(priority = EventPriority.HIGHEST) fun onChat(event: LorenzChatEvent) { "§7Switching to profile (?<name>.*)\\.\\.\\.".toPattern().matchMatcher(event.message) { @@ -32,25 +37,35 @@ object ProfileStorageData { nextProfile = null val playerSpecific = playerSpecific + val sackPlayers = sackPlayers if (playerSpecific == null) { LorenzUtils.error("profileSpecific after profile swap can not be set: playerSpecific is null!") return } - loadProfileSpecific(playerSpecific, profileName, "profile swap (chat message)") + if (sackPlayers == null) { + LorenzUtils.error("sackPlayers after profile swap can not be set: sackPlayers is null!") + return + } + loadProfileSpecific(playerSpecific, sackPlayers, profileName, "profile swap (chat message)") ConfigLoadEvent().postAndCatch() } @SubscribeEvent(priority = EventPriority.HIGHEST) fun onProfileJoin(event: ProfileJoinEvent) { val playerSpecific = playerSpecific + val sackPlayers = sackPlayers if (playerSpecific == null) { LorenzUtils.error("playerSpecific is null in ProfileJoinEvent!") return } + if (sackPlayers == null) { + LorenzUtils.error("sackPlayers is null in sackPlayers!") + return + } if (profileSpecific == null) { val profileName = event.name - loadProfileSpecific(playerSpecific, profileName, "first join (chat message)") + loadProfileSpecific(playerSpecific, sackPlayers, profileName, "first join (chat message)") } } @@ -58,11 +73,12 @@ object ProfileStorageData { fun onTabListUpdate(event: TabListUpdateEvent) { if (profileSpecific != null) return val playerSpecific = playerSpecific ?: return + val sackPlayers = sackPlayers ?: return for (line in event.tabList) { val pattern = "§e§lProfile: §r§a(?<name>.*)".toPattern() pattern.matchMatcher(line) { val profileName = group("name").lowercase() - loadProfileSpecific(playerSpecific, profileName, "tab list") + loadProfileSpecific(playerSpecific, sackPlayers, profileName, "tab list") nextProfile = null return } @@ -87,9 +103,10 @@ object ProfileStorageData { } } - private fun loadProfileSpecific(playerSpecific: Storage.PlayerSpecific, profileName: String, reason: String) { + private fun loadProfileSpecific(playerSpecific: Storage.PlayerSpecific, sackProfile: SackData.PlayerSpecific, profileName: String, reason: String) { noTabListTime = -1 profileSpecific = playerSpecific.profiles.getOrPut(profileName) { Storage.ProfileSpecific() } + sackProfiles = sackProfile.profiles.getOrPut(profileName) { SackData.ProfileSpecific() } tryMigrateProfileSpecific() loaded = true ConfigLoadEvent().postAndCatch() @@ -99,6 +116,7 @@ object ProfileStorageData { fun onHypixelJoin(event: HypixelJoinEvent) { val playerUuid = LorenzUtils.getRawPlayerUuid() playerSpecific = SkyHanniMod.feature.storage.players.getOrPut(playerUuid) { Storage.PlayerSpecific() } + sackPlayers = SkyHanniMod.sackData.players.getOrPut(playerUuid) { SackData.PlayerSpecific() } migratePlayerSpecific() ConfigLoadEvent().postAndCatch() } diff --git a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt index 3990e13d6..4534e49a5 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt @@ -1,13 +1,192 @@ package at.hannibal2.skyhanni.data +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.SackChangeEvent +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity +import at.hannibal2.skyhanni.features.inventory.SackDisplay +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull +import at.hannibal2.skyhanni.utils.NEUItems.getPrice +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import com.google.gson.annotations.Expose +import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -class SackAPI { +object SackAPI { + private val sackDisplayConfig get() = SkyHanniMod.feature.inventory.sackDisplay + private var lastOpenedInventory = "" + + var inSackInventory = false + private val sackPattern = "^(.* Sack|Enchanted .* Sack)$".toPattern() + private val numPattern = + "(?:(?:§[0-9a-f](?<level>I{1,3})§7:)?|(?:§7Stored:)?) (?<color>§[0-9a-f])(?<stored>[0-9.,kKmMbB]+)§7/(?<total>\\d+(?:[0-9.,]+)?[kKmMbB]?)".toPattern() + private val gemstonePattern = + " §[0-9a-f](?<gemrarity>[A-z]*): §[0-9a-f](?<stored>\\d+(?:\\.\\d+)?(?:(?:,\\d+)?)+[kKmM]?)(?: §[0-9a-f]\\(\\d+(?:\\.\\d+)?(?:(?:,\\d+)?)+[kKmM]?\\))?".toPattern() + + private var isRuneSack = false + private var isGemstoneSack = false + var isTrophySack = false + private var sackRarity: TrophyRarity? = null + + val sackItem = mutableMapOf<String, SackOtherItem>() + val runeItem = mutableMapOf<String, SackRune>() + val gemstoneItem = mutableMapOf<String, SackGemstone>() + private val stackList = mutableMapOf<Int, ItemStack>() + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inSackInventory = false + isRuneSack = false + isGemstoneSack = false + isTrophySack = false + runeItem.clear() + gemstoneItem.clear() + sackItem.clear() + stackList.clear() + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + val inventoryName = event.inventoryName + val isNewInventory = inventoryName != lastOpenedInventory + lastOpenedInventory = inventoryName + val match = sackPattern.matcher(inventoryName).matches() + if (!match) return + val stacks = event.inventoryItems + isRuneSack = inventoryName == "Runes Sack" + isGemstoneSack = inventoryName == "Gemstones Sack" + isTrophySack = inventoryName.contains("Trophy Fishing Sack") + sackRarity = inventoryName.getTrophyRarity() + inSackInventory = true + stackList.putAll(stacks) + SackDisplay.update(isNewInventory) + } + + private fun String.getTrophyRarity(): TrophyRarity? { + return if (this.startsWith("Bronze")) + TrophyRarity.BRONZE + else + if (this.startsWith("Silver")) + TrophyRarity.SILVER + else null + } + + private fun NEUInternalName.sackPrice(stored: String) = when (sackDisplayConfig.priceFrom) { + 0 -> (getPrice(true) * stored.formatNumber()).toInt().let { if (it < 0) 0 else it } + + 1 -> try { + val npcPrice = getNpcPriceOrNull() ?: 0.0 + (npcPrice * stored.formatNumber()).toInt() + } catch (e: Exception) { + 0 + } + + else -> 0 + } + + fun getSacksData(savingSacks: Boolean) { + if (savingSacks) sackData = ProfileStorageData.sackProfiles?.sackContents ?: return + for ((_, stack) in stackList) { + val name = stack.name ?: continue + val lore = stack.getLore() + val gem = SackGemstone() + val rune = SackRune() + val item = SackOtherItem() + loop@ for (line in lore) { + if (isGemstoneSack) { + gemstonePattern.matchMatcher(line) { + val rarity = group("gemrarity") + val stored = group("stored") + gem.internalName = gemstoneMap[name.removeColor()] ?: NEUInternalName.NONE + if (gemstoneMap.containsKey(name.removeColor())) { + val internalName = "${rarity.uppercase()}_${ + name.uppercase().split(" ")[0].removeColor() + }_GEM".asInternalName() + + when (rarity) { + "Rough" -> { + gem.rough = stored + gem.roughPrice = internalName.sackPrice(stored) + if (savingSacks) setSackItem(internalName, stored.formatNumber().toInt()) + } + + "Flawed" -> { + gem.flawed = stored + gem.flawedPrice = internalName.sackPrice(stored) + if (savingSacks) setSackItem(internalName, stored.formatNumber().toInt()) + } + + "Fine" -> { + gem.fine = stored + gem.finePrice = internalName.sackPrice(stored) + if (savingSacks) setSackItem(internalName, stored.formatNumber().toInt()) + } + + "Flawless" -> { + gem.flawless = stored + gem.flawlessPrice = internalName.sackPrice(stored) + if (savingSacks) setSackItem(internalName, stored.formatNumber().toInt()) + } + } + gemstoneItem[name] = gem + } + } + } else { + numPattern.matchMatcher(line) { + val stored = group("stored") + val internalName = stack.getInternalName() + item.internalName = internalName + item.colorCode = group("color") + item.stored = stored + item.total = group("total") + if (savingSacks) setSackItem(item.internalName, item.stored.formatNumber().toInt()) + item.price = if (isTrophySack) { + val trophyName = + internalName.asString().lowercase().substringBeforeLast("_").replace("_", "") + val filletValue = + TrophyFishManager.getInfoByName(trophyName)?.getFilletValue(sackRarity!!) ?: 0 + val storedNumber = stored.formatNumber().toInt() + "MAGMA_FISH".asInternalName().sackPrice((filletValue * storedNumber).toString()) + } else internalName.sackPrice(stored).coerceAtLeast(0) + + if (isRuneSack) { + val level = group("level") + rune.stack = stack + if (level == "I") { + rune.lvl1 = stored + continue@loop + } + if (level == "II") { + rune.lvl2 = stored + continue@loop + } + if (level == "III") { + rune.lvl3 = stored + } + runeItem.put(name, rune) + } else { + sackItem.put(name, item) + } + } + } + } + } + if (savingSacks) saveSackData() + } + + private var sackData = mapOf<NEUInternalName, SackItem>() data class SackChange(val delta: Int, val internalName: NEUInternalName, val sacks: List<String>) @@ -16,7 +195,7 @@ class SackAPI { @SubscribeEvent fun onChat(event: LorenzChatEvent) { if (!event.message.removeColor().startsWith("[Sacks]")) return - + val sackAddText = event.chatComponent.siblings.firstNotNullOfOrNull { sibling -> sibling.chatStyle?.chatHoverEvent?.value?.formattedText?.removeColor()?.takeIf { it.startsWith("Added") @@ -45,4 +224,112 @@ class SackAPI { } SackChangeEvent(sackChanges, otherItemsAdded, otherItemsRemoved).postAndCatch() } + + @SubscribeEvent + fun sackChange(event: SackChangeEvent) { + sackData = ProfileStorageData.sackProfiles?.sackContents ?: return + + // if it gets added and subtracted but only 1 shows it will be outdated + val justChanged = mutableMapOf<NEUInternalName, Int>() + + for (change in event.sackChanges) { + if (change.internalName in justChanged) { + justChanged[change.internalName] = (justChanged[change.internalName] ?: 0) + change.delta + } else { + justChanged[change.internalName] = change.delta + } + } + + for (item in justChanged) { + if (sackData.containsKey(item.key)) { + val oldData = sackData[item.key] + var newAmount = oldData!!.amount + item.value + var changed = newAmount - oldData.amount + if (newAmount < 0) { + newAmount = 0 + changed = 0 + } + sackData = sackData.editCopy { this[item.key] = SackItem(newAmount, changed, oldData.outdatedStatus) } + } else { + val newAmount = if (item.value > 0) item.value else 0 + sackData = sackData.editCopy { this[item.key] = SackItem(newAmount, newAmount, 2) } + } + } + + if (event.otherItemsAdded || event.otherItemsRemoved) { + for (item in sackData) { + if (item.key in justChanged) continue + val oldData = sackData[item.key] + sackData = sackData.editCopy { this[item.key] = SackItem(oldData!!.amount, 0, 1) } + } + } + saveSackData() + } + + private fun setSackItem(item: NEUInternalName, amount: Int) { + sackData = sackData.editCopy { this[item] = SackItem(amount, 0, 0) } + } + + fun fetchSackItem(item: NEUInternalName): SackItem? { + sackData = ProfileStorageData.sackProfiles?.sackContents ?: return SackItem(0, 0, -1) + + if (sackData.containsKey(item)) { + return sackData[item] + } + + sackData = sackData.editCopy { this[item] = SackItem(0, 0, 2) } + return sackData[item] + } + + private fun saveSackData() { + ProfileStorageData.sackProfiles?.sackContents = sackData + SkyHanniMod.configManager.saveSackData("shutdown-hook") + } + + data class SackGemstone( + var internalName: NEUInternalName = NEUInternalName.NONE, + var rough: String = "0", + var flawed: String = "0", + var fine: String = "0", + var flawless: String = "0", + var roughPrice: Int = 0, + var flawedPrice: Int = 0, + var finePrice: Int = 0, + var flawlessPrice: Int = 0, + ) + + data class SackRune( + var stack: ItemStack? = null, + var lvl1: String = "0", + var lvl2: String = "0", + var lvl3: String = "0", + ) + + data class SackOtherItem( + var internalName: NEUInternalName = NEUInternalName.NONE, + var colorCode: String = "", + var stored: String = "0", + var total: String = "0", + var price: Int = 0, + ) } + +// status -1 = fetching data failed, 0 = < 1% of being wrong, 1 = 10% of being wrong, 2 = is 100% wrong +// lastChange is set to 0 when value is refreshed in the sacks gui and when being set initially +// if it didn't change in an update the lastChange value will stay the same and not be set to 0 +data class SackItem( + @Expose val amount: Int, + @Expose val lastChange: Int, + @Expose val outdatedStatus: Int +) + +private val gemstoneMap = mapOf( + "Jade Gemstones" to "ROUGH_JADE_GEM".asInternalName(), + "Amber Gemstones" to "ROUGH_AMBER_GEM".asInternalName(), + "Topaz Gemstones" to "ROUGH_TOPAZ_GEM".asInternalName(), + "Sapphire Gemstones" to "ROUGH_SAPPHIRE_GEM".asInternalName(), + "Amethyst Gemstones" to "ROUGH_AMETHYST_GEM".asInternalName(), + "Jasper Gemstones" to "ROUGH_JASPER_GEM".asInternalName(), + "Ruby Gemstones" to "ROUGH_RUBY_GEM".asInternalName(), + "Opal Gemstones" to "ROUGH_OPAL_GEM".asInternalName(), +) |