Skip to content

Commit 6a154f1

Browse files
committed
fix some client desync
Closes #13729
1 parent fd98513 commit 6a154f1

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
}
66

77
+ // CraftBukkit start - add method from above
8-
+ public <T> void markDirty(final EntityDataAccessor<T> entityDataAccessor) {
9-
+ this.getItem(entityDataAccessor).setDirty(true);
8+
+ public <T> void markDirty(final EntityDataAccessor<T> accessor) {
9+
+ this.getItem(accessor).setDirty(true);
1010
+ this.isDirty = true;
1111
+ }
1212
+ // CraftBukkit end
@@ -23,12 +23,12 @@
2323
+ // We need to pack all as we cannot rely on "non default values" or "dirty" ones.
2424
+ // Because these values can possibly be desynced on the client.
2525
+ public List<SynchedEntityData.DataValue<?>> packAll() {
26-
+ final List<SynchedEntityData.DataValue<?>> list = new ArrayList<>(this.itemsById.length);
27-
+ for (final DataItem<?> dataItem : this.itemsById) {
28-
+ list.add(dataItem.value());
26+
+ final List<SynchedEntityData.DataValue<?>> items = new ArrayList<>(this.itemsById.length);
27+
+ for (final DataItem<?> item : this.itemsById) {
28+
+ items.add(item.value());
2929
+ }
3030
+
31-
+ return list;
31+
+ return items;
3232
+ }
3333
+ // Paper end
3434

paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@
240240
+ // Paper start
241241
+ // This method should only be used if the data of an entity could have become desynced
242242
+ // due to interactions on the client.
243-
+ public void resendPossiblyDesyncedEntityData(net.minecraft.server.level.ServerPlayer player) {
243+
+ public void resendPossiblyDesyncedEntityData(ServerPlayer player) {
244244
+ if (player.getBukkitEntity().canSee(this.getBukkitEntity())) {
245-
+ ServerLevel world = (net.minecraft.server.level.ServerLevel)this.level();
246-
+ net.minecraft.server.level.ChunkMap.TrackedEntity tracker = world == null ? null : world.getChunkSource().chunkMap.entityMap.get(this.getId());
245+
+ ServerLevel level = (net.minecraft.server.level.ServerLevel) this.level();
246+
+ net.minecraft.server.level.ChunkMap.TrackedEntity tracker = level == null ? null : level.getChunkSource().chunkMap.entityMap.get(this.getId());
247247
+ if (tracker == null) {
248248
+ return;
249249
+ }
@@ -254,16 +254,16 @@
254254
+ }
255255
+ }
256256
+
257-
+ // This method allows you to specifically resend certain data accessor keys to the client
258-
+ public void resendPossiblyDesyncedDataValues(List<EntityDataAccessor<?>> keys, ServerPlayer to) {
257+
+ // This method allows you to specifically resend certain data accessors to the client
258+
+ public void resendPossiblyDesyncedDataValues(List<EntityDataAccessor<?>> accessors, ServerPlayer to) {
259259
+ if (!to.getBukkitEntity().canSee(this.getBukkitEntity())) {
260260
+ return;
261261
+ }
262262
+
263-
+ final List<SynchedEntityData.DataValue<?>> values = new java.util.ArrayList<>(keys.size());
264-
+ for (final EntityDataAccessor<?> key : keys) {
265-
+ final SynchedEntityData.DataItem<?> synchedValue = this.entityData.getItem(key);
266-
+ values.add(synchedValue.value());
263+
+ final List<SynchedEntityData.DataValue<?>> values = new ArrayList<>(accessors.size());
264+
+ for (final EntityDataAccessor<?> accessor : accessors) {
265+
+ final SynchedEntityData.DataItem<?> item = this.entityData.getItem(accessor);
266+
+ values.add(item.value());
267267
+ }
268268
+
269269
+ to.connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket(this.id, values));
@@ -1329,7 +1329,7 @@
13291329
}
13301330

13311331
public int getAirSupply() {
1332-
@@ -2732,10 +_,22 @@
1332+
@@ -2732,10 +_,24 @@
13331333
}
13341334

13351335
public void setAirSupply(final int supply) {
@@ -1341,7 +1341,9 @@
13411341
+ event.getEntity().getServer().getPluginManager().callEvent(event);
13421342
+ }
13431343
+ if (event.isCancelled() && this.getAirSupply() != supply) {
1344-
+ this.entityData.markDirty(DATA_AIR_SUPPLY_ID);
1344+
+ if (this instanceof ServerPlayer player) {
1345+
+ this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_AIR_SUPPLY_ID), player); // todo is that even needed?
1346+
+ }
13451347
+ return;
13461348
+ }
13471349
+ this.entityData.set(DATA_AIR_SUPPLY_ID, event.getAmount());

paper-server/patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,19 @@
4848
return InteractionResult.SUCCESS.withoutItem();
4949
}
5050

51-
@@ -486,6 +_,13 @@
51+
@@ -486,6 +_,19 @@
5252

5353
DyeColor color = itemStack.get(DataComponents.DYE);
5454
if (color != null && color != this.getCollarColor()) {
5555
+ // Paper start - Add EntityDyeEvent and CollarColorable interface
5656
+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) color.getId()), (org.bukkit.entity.Player) player.getBukkitEntity());
5757
+ if (!event.callEvent()) {
58+
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
59+
+ this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_COLLAR_COLOR), serverPlayer);
60+
+ }
61+
+ if (!player.hasInfiniteMaterials()) {
62+
+ player.containerMenu.forceHeldSlot(hand);
63+
+ }
5864
+ return InteractionResult.FAIL;
5965
+ }
6066
+ color = DyeColor.byId(event.getColor().getWoolData());

0 commit comments

Comments
 (0)