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
|
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.itemName
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 }
}
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
sackToInventoryChatPattern.matchMatcher(event.message) {
val name = group("name")
ignoreItem(500.milliseconds) { it.itemName.contains(name) }
}
}
private 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()
}
}
|