@@ -22,19 +22,22 @@ import com.lambda.context.AutomationConfig
2222import com.lambda.context.AutomationConfig.avoidDesync
2323import com.lambda.context.SafeContext
2424import com.lambda.event.EventFlow.post
25- import com.lambda.event.events.PacketEvent
2625import com.lambda.event.events.TickEvent
2726import com.lambda.event.events.UpdateManagerEvent
2827import com.lambda.event.listener.SafeListener.Companion.listen
2928import com.lambda.interaction.request.Logger
3029import com.lambda.interaction.request.RequestHandler
3130import com.lambda.interaction.request.placing.PlaceManager
3231import com.lambda.module.hud.ManagerDebugLoggers.inventoryManagerLogger
33- import com.lambda.util.Communication.info
32+ import com.lambda.threading.runSafe
3433import com.lambda.util.collections.LimitedDecayQueue
3534import com.lambda.util.item.ItemStackUtils.equal
35+ import com.llamalad7.mixinextras.injector.wrapoperation.Operation
36+ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen
3637import net.minecraft.item.ItemStack
3738import net.minecraft.network.packet.s2c.play.InventoryS2CPacket
39+ import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket
40+ import net.minecraft.screen.PlayerScreenHandler
3841import net.minecraft.screen.ScreenHandler
3942import net.minecraft.screen.slot.Slot
4043
@@ -69,33 +72,8 @@ object InventoryManager : RequestHandler<InventoryRequest>(
6972 override fun load (): String {
7073 super .load()
7174
72- listen<PacketEvent .Receive .Pre >(priority = Int .MIN_VALUE ) { event ->
73- if (! avoidDesync) return @listen
74- val packet = event.packet as ? InventoryS2CPacket ? : return @listen
75- screenHandler = player.currentScreenHandler
76- val packetScreenHandler =
77- if (packet.syncId == 0 ) player.playerScreenHandler
78- else player.currentScreenHandler
79- event.cancel()
80- val alteredContents = mutableListOf<ItemStack >()
81- packet.contents.forEachIndexed { index, incomingStack ->
82- val matches = alteredSlots.removeIf { cached ->
83- incomingStack.equal(cached.second.second)
84- }
85- if (matches) alteredContents.add(packetScreenHandler.slots[index].stack)
86- else alteredContents.add(incomingStack)
87- if (matches) info(matches.toString())
88- }
89- mc.executeSync {
90- packetScreenHandler.updateSlotStacks(packet.revision(), alteredContents, packet.cursorStack())
91- }
92- }
93-
9475 listen<TickEvent .Post >(priority = Int .MIN_VALUE ) {
95- if (avoidDesync) {
96- alteredSlots.addAll(gatherInventoryChanges())
97- slots = getStacks(player.currentScreenHandler.slots)
98- }
76+ if (avoidDesync) indexInventoryChanges()
9977 if (++ secondCounter >= 20 ) {
10078 secondCounter = 0
10179 actionsThisSecond = 0
@@ -122,6 +100,7 @@ object InventoryManager : RequestHandler<InventoryRequest>(
122100 while (iterator.hasNext()) {
123101 if (actionsThisSecond + 1 > maxActionsThisSecond && ! request.mustPerform) break
124102 iterator.next()()
103+ if (avoidDesync) indexInventoryChanges()
125104 actionsThisTick++
126105 actionsThisSecond++
127106 iterator.remove()
@@ -141,14 +120,91 @@ object InventoryManager : RequestHandler<InventoryRequest>(
141120 maxActionsThisSecond = request.inventoryConfig.actionsPerSecond
142121 }
143122
144- private fun SafeContext.gatherInventoryChanges () =
145- if (player.currentScreenHandler != = screenHandler) emptyList()
146- else screenHandler?.slots
147- ?.filter { it.stack != slots[it.id] }
123+ private fun SafeContext.indexInventoryChanges () {
124+ if (player.currentScreenHandler != = screenHandler) return
125+ val changes = screenHandler?.slots
126+ ?.filter { ! it.stack.equal( slots[it.id]) }
148127 ?.map { Pair (it.id, Pair (slots[it.id], it.stack.copy())) }
149128 ? : emptyList()
129+ alteredSlots.addAll(changes)
130+ slots = getStacks(player.currentScreenHandler.slots)
131+ }
150132
151133 private fun getStacks (slots : Collection <Slot >) = slots.map { it.stack.copy() }
152134
135+ /* *
136+ * A modified version of the [net.minecraft.client.network.ClientPlayNetworkHandler.onInventory] method
137+ */
138+ @JvmStatic
139+ fun onInventoryUpdate (packet : InventoryS2CPacket , original : Operation <Void >){
140+ runSafe {
141+ if (! mc.isOnThread || ! avoidDesync) {
142+ original.call(packet)
143+ return
144+ }
145+ screenHandler = player.currentScreenHandler
146+ val packetScreenHandler =
147+ when (packet.syncId) {
148+ 0 -> player.playerScreenHandler
149+ screenHandler?.syncId -> player.currentScreenHandler
150+ else -> return @runSafe
151+ }
152+ val alteredContents = mutableListOf<ItemStack >()
153+ packet.contents.forEachIndexed { index, incomingStack ->
154+ val matches = alteredSlots.removeIf { cached ->
155+ incomingStack.equal(cached.second.second)
156+ }
157+ if (matches) alteredContents.add(packetScreenHandler.slots[index].stack)
158+ else alteredContents.add(incomingStack)
159+ }
160+ packetScreenHandler.updateSlotStacks(packet.revision(), alteredContents, packet.cursorStack())
161+ return
162+ }
163+ original.call(packet)
164+ }
165+
166+ /* *
167+ * A modified version of the vanilla [net.minecraft.client.network.ClientPlayNetworkHandler.onScreenHandlerSlotUpdate] method
168+ */
169+ @JvmStatic
170+ fun onSlotUpdate (packet : ScreenHandlerSlotUpdateS2CPacket , original : Operation <Void >) {
171+ runSafe {
172+ screenHandler = player.currentScreenHandler
173+ if (! mc.isOnThread || ! avoidDesync) {
174+ original.call(packet)
175+ return
176+ }
177+ val itemStack = packet.stack
178+ mc.tutorialManager.onSlotUpdate(itemStack)
179+
180+ val bl = (mc.currentScreen as ? CreativeInventoryScreen )?.let {
181+ ! it.isInventoryTabSelected
182+ } ? : false
183+
184+ val matches = alteredSlots.removeIf {
185+ it.first == packet.slot && it.second.second.equal(itemStack)
186+ }
187+
188+ if (packet.syncId == 0 ) {
189+ if (PlayerScreenHandler .isInHotbar(packet.slot) && ! itemStack.isEmpty) {
190+ val itemStack2 = screenHandler?.getSlot(packet.slot)?.stack ? : return
191+ if (itemStack2.isEmpty || itemStack2.count < itemStack.count) {
192+ itemStack.bobbingAnimationTime = 5
193+ }
194+ }
195+
196+ if (! matches) player.playerScreenHandler.setStackInSlot(packet.slot, packet.revision, itemStack)
197+ } else if (packet.syncId == player.currentScreenHandler.syncId && (packet.syncId != 0 || ! bl))
198+ if (! matches) player.currentScreenHandler.setStackInSlot(packet.slot, packet.revision, itemStack)
199+
200+ if (mc.currentScreen is CreativeInventoryScreen ) {
201+ player.playerScreenHandler.setReceivedStack(packet.slot, itemStack)
202+ player.playerScreenHandler.sendContentUpdates()
203+ }
204+ return
205+ }
206+ original.call(packet)
207+ }
208+
153209 override fun preEvent () = UpdateManagerEvent .Inventory .post()
154210}
0 commit comments