blob: ad5d01d3c24fa32fa31a0512cfb2a5f13bc60a1f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.features.garden.CropAccessory
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import com.google.gson.JsonElement
import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompressedStreamTools
import net.minecraftforge.client.event.GuiScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.io.ByteArrayInputStream
import java.util.Base64
class CropAccessoryData {
// TODO USE SH-REPO
private val accessoryBagNamePattern = "Accessory Bag \\((?<current>\\d)/(?<total>\\d)\\)".toPattern()
private var loadedAccessoryThisProfile = false
private var ticks = 0
private var accessoryInBag: CropAccessory? = null
private var accessoryInInventory = CropAccessory.NONE
private var accessoryBagPageNumber = 0
// Handle API detection
@SubscribeEvent
fun onProfileJoin(event: ProfileJoinEvent) {
loadedAccessoryThisProfile = false
accessoryPage.clear()
}
// Handle accessory bag detection
@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
// handling accessory bags with only one page
if (event.inventoryName == "Accessory Bag") {
isLoadingAccessories = true
accessoryBagPageCount = 1
accessoryBagPageNumber = 1
return
}
accessoryBagNamePattern.matchMatcher(event.inventoryName) {
isLoadingAccessories = true
accessoryBagPageNumber = group("current").toInt()
accessoryBagPageCount = group("total").toInt()
} ?: return
}
@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
isLoadingAccessories = false
}
@SubscribeEvent
fun onGuiDraw(event: GuiScreenEvent.DrawScreenEvent) {
if (!isLoadingAccessories) return
val items = runCatching {
InventoryUtils.getItemsInOpenChest()
}.getOrNull() ?: return
val bestCropAccessoryPage = bestCropAccessory(items.map { it.stack })
accessoryPage[accessoryBagPageNumber] = bestCropAccessoryPage
if (accessoryBagPageCount == accessoryPage.size) {
accessoryInBag = accessoryPage.values.max().also {
cropAccessory = maxOf(it, accessoryInInventory)
}
loadedAccessoryThisProfile = true
}
}
// Handle inventory detection
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!event.repeatSeconds(1)) return
if (!LorenzUtils.inSkyBlock) return
accessoryInInventory = bestCropAccessory(InventoryUtils.getItemsInOwnInventory())
if (accessoryInInventory == CropAccessory.NONE) return
if (accessoryInInventory > (accessoryInBag ?: CropAccessory.NONE)) {
cropAccessory = accessoryInInventory
}
}
private fun bestCropAccessory(items: Iterable<ItemStack>) =
items.mapNotNull { item -> CropAccessory.getByName(item.getInternalName()) }
.maxOrNull() ?: CropAccessory.NONE
companion object {
var accessoryBagPageCount = 0
private set
private var accessoryPage = mutableMapOf<Int, CropAccessory>()
var isLoadingAccessories = false
private set
val pagesLoaded get() = accessoryPage.size
var cropAccessory: CropAccessory?
get() = GardenAPI.storage?.savedCropAccessory
private set(accessory) {
GardenAPI.storage?.savedCropAccessory = accessory
}
// Derived partially from NotEnoughUpdates/NotEnoughUpdates, ProfileViewer.Profile#getInventoryInfo
private fun getCropAccessories(inventory: JsonElement?): MutableList<CropAccessory> {
if (inventory == null) return mutableListOf()
val cropAccessories = mutableListOf<CropAccessory>()
val data = inventory.asJsonObject["data"]?.asString
val accessoryBagItems = CompressedStreamTools.readCompressed(
ByteArrayInputStream(Base64.getDecoder().decode(data))
).getTagList("i", 10)
for (j in 0 until accessoryBagItems.tagCount()) {
val itemStackTag = accessoryBagItems.getCompoundTagAt(j)
if (!itemStackTag.hasKey("tag")) continue
val itemTag = itemStackTag.getCompoundTag("tag")
val itemName = NEUItems.getInternalNameOrNull(itemTag) ?: continue
val itemAsCropAccessory = CropAccessory.getByName(itemName) ?: continue
cropAccessories.add(itemAsCropAccessory)
}
return cropAccessories
}
}
}
|