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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
import at.hannibal2.skyhanni.events.minecraft.packet.PacketReceivedEvent
import at.hannibal2.skyhanni.events.minecraft.packet.PacketSentEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraft.client.Minecraft
import net.minecraft.network.play.client.C0EPacketClickWindow
import net.minecraft.network.play.server.S0DPacketCollectItem
import net.minecraft.network.play.server.S2FPacketSetSlot
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
@SkyHanniModule
object OwnInventoryData {
private var itemAmounts = mapOf<NEUInternalName, Int>()
private var dirty = false
private val sackToInventoryChatPattern by RepoPattern.pattern(
"data.owninventory.chat.movedsacktoinventory",
"§aMoved §r§e\\d* (?<name>.*)§r§a from your Sacks to your inventory.",
)
@HandleEvent(priority = HandleEvent.LOW, receiveCancelled = true, onlyOnSkyblock = true)
fun onItemPickupReceivePacket(event: PacketReceivedEvent) {
val packet = event.packet
if (packet is S2FPacketSetSlot || packet is S0DPacketCollectItem) {
dirty = true
}
if (packet is S2FPacketSetSlot) {
val windowId = packet.func_149175_c()
if (windowId == 0) {
val slot = packet.func_149173_d()
val item = packet.func_149174_e() ?: return
DelayedRun.runNextTick {
OwnInventoryItemUpdateEvent(item, slot).postAndCatch()
}
}
}
}
@HandleEvent(onlyOnSkyblock = true)
fun onClickEntity(event: PacketSentEvent) {
val packet = event.packet
if (packet is C0EPacketClickWindow) {
dirty = true
}
}
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!LorenzUtils.inSkyBlock) return
if (itemAmounts.isEmpty()) {
itemAmounts = getCurrentItems()
}
if (!dirty) return
dirty = false
val map = getCurrentItems()
for ((internalName, amount) in map) {
calculateDifference(internalName, amount)
}
itemAmounts = map
}
private fun getCurrentItems(): MutableMap<NEUInternalName, Int> {
val map = mutableMapOf<NEUInternalName, Int>()
for (itemStack in InventoryUtils.getItemsInOwnInventory()) {
val internalName = itemStack.getInternalNameOrNull() ?: continue
map.addOrPut(internalName, itemStack.stackSize)
}
return map
}
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
itemAmounts = emptyMap()
}
private fun calculateDifference(internalName: NEUInternalName, newAmount: Int) {
val oldAmount = itemAmounts[internalName] ?: 0
val diff = newAmount - oldAmount
if (diff > 0) {
addItem(internalName, diff)
}
}
@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
val item = Minecraft.getMinecraft().thePlayer.inventory.itemStack ?: return
val internalNameOrNull = item.getInternalNameOrNull() ?: return
ignoreItem(500.milliseconds) { it == internalNameOrNull }
}
@SubscribeEvent
fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) {
ignoreItem(500.milliseconds) { true }
val itemName = event.item?.name ?: return
checkAHMovements(itemName)
}
private fun checkAHMovements(itemName: String) {
val inventoryName = InventoryUtils.openInventoryName()
// cancel own auction
if (inventoryName.let { it == "BIN Auction View" || it == "Auction View" }) {
if (itemName == "§cCancel Auction") {
val item = InventoryUtils.getItemAtSlotIndex(13)
val internalName = item?.getInternalNameOrNull() ?: return
OwnInventoryData.ignoreItem(5.seconds, { it == internalName })
}
}
// bought item from bin ah
if (inventoryName == "Confirm Purchase" && itemName == "§aConfirm") {
val item = InventoryUtils.getItemAtSlotIndex(13)
val internalName = item?.getInternalNameOrNull() ?: return
OwnInventoryData.ignoreItem(5.seconds, { it == internalName })
}
// bought item from normal ah
if (inventoryName == "Auction View" && itemName == "§6Collect Auction") {
val item = InventoryUtils.getItemAtSlotIndex(13)
val internalName = item?.getInternalNameOrNull() ?: return
OwnInventoryData.ignoreItem(5.seconds, { it == internalName })
}
// collected all items in "own bins"
if (inventoryName == "Your Bids" && itemName == "§aClaim All") {
for (stack in InventoryUtils.getItemsInOpenChest().map { it.stack }) {
if (stack.getLore().any { it == "§7Status: §aSold!" || it == "7Status: §aEnded!" }) {
val internalName = stack.getInternalNameOrNull() ?: return
OwnInventoryData.ignoreItem(5.seconds, { it == internalName })
}
}
}
}
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
sackToInventoryChatPattern.matchMatcher(event.message) {
val name = group("name")
ignoreItem(500.milliseconds) { it.itemName.contains(name) }
}
}
fun ignoreItem(duration: Duration, condition: (NEUInternalName) -> Boolean) {
ignoredItemsUntil.add(IgnoredItem(condition, SimpleTimeMark.now() + duration))
}
private val ignoredItemsUntil = mutableListOf<IgnoredItem>()
class IgnoredItem(val condition: (NEUInternalName) -> Boolean, val blockedUntil: SimpleTimeMark)
private fun addItem(internalName: NEUInternalName, add: Int) {
if (LorenzUtils.lastWorldSwitch.passedSince() < 3.seconds) return
ignoredItemsUntil.removeIf { it.blockedUntil.isInPast() }
if (ignoredItemsUntil.any { it.condition(internalName) }) {
return
}
if (internalName.startsWith("MAP-")) return
ItemAddInInventoryEvent(internalName, add).postAndCatch()
}
}
|