@@ -158,13 +158,6 @@ public Integer apply(TypedDataComponent<?> tdc) {
158158 protected final Queue <Packet <? super ServerGamePacketListener >> incoming = new ConcurrentLinkedQueue <>();
159159 private final Map <Integer , PingData > pendingPongs = new ConcurrentHashMap <>();
160160
161- // Only items marked as dirty via the fields below will be compared with their remote counterparts.
162- // Then, only if they differ, an update packet will be created for them.
163- // The intention of these dirty fields is to avoid expensive comparisons between the remote and server items.
164- private final BitSet dirtyItems ;
165- private boolean dirtyCarried ;
166- private boolean dirtyOffHand ;
167-
168161 /**
169162 * Creates a new {@link CustomContainerMenu} for the specified player.
170163 *
@@ -181,7 +174,6 @@ protected CustomContainerMenu(MenuType<?> menuType, org.bukkit.entity.Player pla
181174 this .items = ArrayUtils .newArray (ItemStack []::new , size , ItemStack .EMPTY );
182175 this .remoteSlots = ArrayUtils .newArrayBy (RemoteSlot .Synchronized []::new , size , _ -> remoteSlot (ItemStack .EMPTY ));
183176 this .remoteOffHand = remoteSlot (serverPlayer .getOffhandItem ());
184- this .dirtyItems = new BitSet (size );
185177
186178 int dataSize = InventoryUtils .getDataSlotCountOf (menuType );
187179 this .dataSlots = new int [dataSize ];
@@ -201,7 +193,6 @@ public void setItem(int slot, org.bukkit.inventory.@Nullable ItemStack item) {
201193 throw new IllegalArgumentException ("Slot out of bounds: " + slot );
202194
203195 items [slot ] = item == null ? ItemStack .EMPTY : CraftItemStack .unwrap (item );
204- dirtyItems .set (slot );
205196 }
206197
207198 public ItemStack getItem (int slot ) {
@@ -218,7 +209,6 @@ public ItemStack getItem(int slot) {
218209 */
219210 public void setCursor (org .bukkit .inventory .@ Nullable ItemStack item ) {
220211 carried = item == null ? ItemStack .EMPTY : CraftItemStack .unwrap (item );
221- dirtyCarried = true ;
222212 }
223213
224214 /**
@@ -232,29 +222,13 @@ public org.bukkit.inventory.ItemStack getCursor() {
232222
233223 //<editor-fold desc="synchronization">
234224 private RemoteSlot .Synchronized remoteSlot (ItemStack initial ) {
235- var slot = new RemoteSlot .Synchronized ( hashGenerator );
225+ var slot = new RemoteSlot .Synchronized (hashGenerator );
236226 slot .force (initial );
237227 return slot ;
238228 }
239229
240230 protected void forceRemoteItem (int slot , ItemStack item ) {
241231 remoteSlots [slot ].force (item );
242- dirtyItems .set (slot );
243- }
244-
245- protected void receiveRemoteItem (int slot , HashedStack item ) {
246- remoteSlots [slot ].receive (item );
247- dirtyItems .set (slot );
248- }
249-
250- protected void forceRemoteCarried (ItemStack item ) {
251- remoteCarried .force (item );
252- dirtyCarried = true ;
253- }
254-
255- protected void forceRemoteOffHand (ItemStack item ) {
256- remoteOffHand .force (item );
257- dirtyOffHand = true ;
258232 }
259233
260234 /**
@@ -265,38 +239,30 @@ protected void forceRemoteOffHand(ItemStack item) {
265239 public void sendChangesToRemote (int pingId ) {
266240 var packets = new ArrayList <Packet <? super ClientGamePacketListener >>();
267241
268- int itemSlot = -1 ;
269- while ((itemSlot = dirtyItems .nextSetBit (itemSlot + 1 )) != -1 ) {
270- var item = items [itemSlot ];
271- var remoteSlot = remoteSlots [itemSlot ];
242+ for (int i = 0 ; i < items .length ; i ++) {
243+ var item = items [i ];
244+ var remoteSlot = remoteSlots [i ];
272245 if (!remoteSlot .matches (item )) {
273- packets .add (new ClientboundContainerSetSlotPacket (containerId , incrementStateId (), itemSlot , item .copy ()));
246+ packets .add (new ClientboundContainerSetSlotPacket (containerId , incrementStateId (), i , item .copy ()));
274247 remoteSlot .force (item );
275248 }
276249 }
277- dirtyItems .clear ();
278250
279- if (dirtyOffHand ) {
280- var offHand = serverPlayer .getOffhandItem ();
281- if (!remoteOffHand .matches (offHand )) {
282- packets .add (new ClientboundContainerSetSlotPacket (serverPlayer .inventoryMenu .containerId , incrementStateId (), OFF_HAND_SLOT , offHand .copy ()));
283- remoteOffHand .force (offHand );
284- }
285- dirtyOffHand = false ;
251+ var offHand = serverPlayer .getOffhandItem ();
252+ if (!remoteOffHand .matches (offHand )) {
253+ packets .add (new ClientboundContainerSetSlotPacket (serverPlayer .inventoryMenu .containerId , incrementStateId (), OFF_HAND_SLOT , offHand .copy ()));
254+ remoteOffHand .force (offHand );
286255 }
287256
288- if (dirtyCarried ) {
289- if (!remoteCarried .matches (carried )) {
290- packets .add (new ClientboundSetCursorItemPacket (carried .copy ()));
291- remoteCarried .force (carried );
292- }
293- dirtyCarried = false ;
257+ if (!remoteCarried .matches (carried )) {
258+ packets .add (new ClientboundSetCursorItemPacket (carried .copy ()));
259+ remoteCarried .force (carried );
294260 }
295261
296- for (int dataSlot = 0 ; dataSlot < dataSlots .length ; dataSlot ++) {
297- if (dataSlots [dataSlot ] != remoteDataSlots [dataSlot ]) {
298- packets .add (new ClientboundContainerSetDataPacket (containerId , dataSlot , dataSlots [dataSlot ]));
299- remoteDataSlots [dataSlot ] = dataSlots [dataSlot ];
262+ for (int i = 0 ; i < dataSlots .length ; i ++) {
263+ if (dataSlots [i ] != remoteDataSlots [i ]) {
264+ packets .add (new ClientboundContainerSetDataPacket (containerId , i , dataSlots [i ]));
265+ remoteDataSlots [i ] = dataSlots [i ];
300266 }
301267 }
302268
@@ -314,7 +280,6 @@ public void sendCarriedToRemote() {
314280 var content = new ClientboundSetCursorItemPacket (carried .copy ());
315281 PacketListener .getInstance ().injectOutgoing (player , content );
316282 remoteCarried .force (carried );
317- dirtyCarried = false ;
318283 }
319284
320285 /**
@@ -373,10 +338,6 @@ private void markRemoteSynced() {
373338 }
374339 remoteCarried .force (carried );
375340 System .arraycopy (dataSlots , 0 , remoteDataSlots , 0 , dataSlots .length );
376-
377- dirtyItems .clear ();
378- dirtyCarried = false ;
379- dirtyOffHand = false ;
380341 }
381342 //</editor-fold>
382343
@@ -532,9 +493,9 @@ protected UpdateType handleClick(ServerboundContainerClickPacket packet) {
532493 HashedStack stack = entry .getValue ();
533494 if (slot < 0 || slot > remoteSlots .length )
534495 continue ;
535- receiveRemoteItem ( slot , stack );
496+ remoteSlots [ slot ]. receive ( stack );
536497 }
537- forceRemoteCarried (DIRTY_MARKER );
498+ remoteCarried . force (DIRTY_MARKER );
538499
539500 if (packet .clickType () == net .minecraft .world .inventory .ClickType .QUICK_CRAFT ) {
540501 if (!handleDragClick (packet ))
@@ -572,7 +533,7 @@ private void handleNormalClick(ServerboundContainerClickPacket packet) {
572533 yield ClickType .NUMBER_KEY ;
573534 }
574535 case 40 -> {
575- forceRemoteOffHand (DIRTY_MARKER );
536+ remoteOffHand . force (DIRTY_MARKER );
576537 yield ClickType .SWAP_OFFHAND ;
577538 }
578539 default -> ClickType .UNKNOWN ;
@@ -758,12 +719,21 @@ public ItemStack getCarried() {
758719 @ Override
759720 public void setCarried (ItemStack stack ) {
760721 carried = stack ;
761- dirtyCarried = true ;
762722 }
763723
764724 @ Override
765725 public void broadcastCarriedItem () {
766- dirtyCarried = true ;
726+ // handled through window tick
727+ }
728+
729+ @ Override
730+ public void broadcastChanges () {
731+ // handled through window tick
732+ }
733+
734+ @ Override
735+ public void broadcastFullState () {
736+ // handled through window tick
767737 }
768738
769739 @ Override
0 commit comments