Readd fixes for SpawnReason API patch

This commit is contained in:
Nassim Jahnke 2022-12-08 17:51:06 +01:00
parent 5256716ffb
commit 93ee9e63c9
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
2 changed files with 13 additions and 160 deletions

View File

@ -1,147 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 22 Mar 2019 22:24:03 -0700
Subject: [PATCH] Properly resend entities
This resolves some issues which caused entities to not be resent correctly.
Entities that are interacted with need to be resent to the client, so we resend all the entity
data to the player whilst making sure not to clear dirty entries from the tracker. This makes
sure that values will be correctly updated to other players.
See: https://github.com/PaperMC/Paper/pull/1896
Co-authored-by: AgentTroll <woodyc40@gmail.com>m
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
index 3e17f6131bf590d7c4a16b79c1c145cb4f565bc9..bf838c097aeb79fbe82c0b6cdf3315acf03474cd 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
@@ -12,10 +12,15 @@ public class ClientboundSetEntityDataPacket implements Packet<ClientGamePacketLi
private final List<SynchedEntityData.DataItem<?>> packedItems;
public ClientboundSetEntityDataPacket(int id, SynchedEntityData tracker, boolean forceUpdateAll) {
+ // Paper start
+ this(id, tracker, forceUpdateAll, true);
+ }
+ public ClientboundSetEntityDataPacket(int id, SynchedEntityData tracker, boolean forceUpdateAll, boolean clearDirty) {
+ // Paper end
this.id = id;
if (forceUpdateAll) {
this.packedItems = tracker.getAll();
- tracker.clearDirty();
+ if (clearDirty) tracker.clearDirty(); // Paper
} else {
this.packedItems = tracker.packDirty();
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 2b14841c23c9d9f4a6fe82fb2779cd5ff79a96f6..6089512fbae4254f8c8c5266373e2539f479918b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1194,5 +1194,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
+ // Paper start
+ // This method should only be used if the data of an entity could have became desynced
+ // due to interactions on the client.
+ public void resendPossiblyDesyncedEntity(ServerPlayer player) {
+ if (player.getBukkitEntity().canSee(entity.getBukkitEntity())) {
+ // This will prevent the entity data from being cleared, so that ONLY this player
+ // will have its entity data updated and it won't dirty the datatracker for other players.
+ this.serverEntity.clearDirtyEntityData = false;
+ this.serverEntity.sendPairingData(player.connection::send, player);
+ this.serverEntity.clearDirtyEntityData = true;
+ }
+ }
+
+ public void resendPossiblyDesyncedEntityData(ServerPlayer player) {
+ if (player.getBukkitEntity().canSee(entity.getBukkitEntity())) {
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true, false));
+ }
+ }
+ // Paper end
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index d6f34adbdf45bbef4a39e629dd7cb6d7fcb5db0f..286a14aafe2e8b4662515165ede8a74833897f33 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -66,6 +66,7 @@ public class ServerEntity {
private boolean wasOnGround;
// CraftBukkit start
final Set<ServerPlayerConnection> trackedPlayers; // Paper - private -> package
+ public boolean clearDirtyEntityData = true; // Paper
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
this.trackedPlayers = trackedPlayers;
@@ -265,7 +266,7 @@ public class ServerEntity {
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0F / 360.0F);
consumer.accept(packet);
if (!this.entity.getEntityData().isEmpty()) {
- consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true));
+ consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true, this.clearDirtyEntityData)); // Paper
}
boolean flag = this.trackDelta;
@@ -371,6 +372,13 @@ public class ServerEntity {
}
+ // Paper start - Add broadcast method
+ @Deprecated(forRemoval = true)
+ void broadcast(Packet<?> packet) {
+ this.broadcast.accept(packet);
+ }
+ // Paper end
+
private void broadcastAndSend(Packet<?> packet) {
this.broadcast.accept(packet);
if (this.entity instanceof ServerPlayer) {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 20f67746bd0ab2008a7d433abe6b312cd9b13932..48c2451c1a5ffe3ff8eb6748693b2743a9aad4da 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2721,7 +2721,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
// Entity in bucket - SPIGOT-4048 and SPIGOT-6859
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) {
- ServerGamePacketListenerImpl.this.send(new ClientboundAddEntityPacket(entity));
+ // Paper start
+ if (entity.tracker != null) {
+ entity.tracker.resendPossiblyDesyncedEntity(((ServerPlayer) player)); // The entire mob gets deleted, so resend it.
+ }
+ // Paper end
player.containerMenu.sendAllDataToRemote();
}
@@ -2732,7 +2736,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
if (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem) {
// Refresh the current entity metadata
- ServerGamePacketListenerImpl.this.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true));
+ // Paper start
+ if (entity.tracker != null) {
+ entity.tracker.resendPossiblyDesyncedEntityData(((ServerPlayer) player));
+ }
+ // Paper end
// SPIGOT-7136 - Allays
if (entity instanceof Allay) {
ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
index 87b9c3cd91f91df58e5175aaf3e8d32914b062d4..974ced175bf2bcd1b4529e6d14f0931df5cbde26 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
@@ -110,8 +110,11 @@ public interface Bucketable {
itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket());
if (playerBucketFishEvent.isCancelled()) {
((ServerPlayer) player).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket
- ((ServerPlayer) player).connection.send(new ClientboundAddEntityPacket(entity)); // We need to play out these packets as the client assumes the fish is gone
- ((ServerPlayer) player).connection.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true)); // Need to send data such as the display name to client
+ // Paper start
+ if (entity.tracker != null) {
+ entity.tracker.resendPossiblyDesyncedEntity(((ServerPlayer) player));
+ }
+ // Paper end
return Optional.of(InteractionResult.FAIL);
}
entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F);

View File

@ -8,15 +8,15 @@ Fixes some wrong reasons, and adds missing spawn reasons for entities.
Co-authored-by: Doc <nachito94@msn.com>
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 215050f514fdc64b21018924376df9830aaaa6c4..72516335570d7137a62ec8667a6e8f06f024692f 100644
index ac681ad0d8a55dc216c737bff22a9db8114e7b2d..a8e8cb8686a34ddd13c71261ffc40204ce6fefe3 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -342,7 +342,7 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
@@ -341,7 +341,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
@Nullable
public T spawn(ServerLevel world, @Nullable CompoundTag itemNbt, @Nullable Component name, @Nullable Player player, BlockPos pos, MobSpawnType spawnReason, boolean alignPosition, boolean invertY) {
public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, MobSpawnType spawnReason, boolean alignPosition, boolean invertY) {
// CraftBukkit start
- return this.spawn(world, itemNbt, name, player, pos, spawnReason, alignPosition, invertY, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
+ return this.spawn(world, itemNbt, name, player, pos, spawnReason, alignPosition, invertY, spawnReason == MobSpawnType.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs
- return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
+ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, spawnReason == MobSpawnType.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs
}
@Nullable
@ -34,15 +34,15 @@ index 6afe37e42d88701af38df5793a9ea9d7d2cda5c5..c72ab3c9f7cb20f22b051981fe1fc419
this.discard();
}
diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
index af7f77fb9fdf27509499f9d35fd42a6a50bf9cb0..e1d8ababdb992821cc0ac383c13f1f4d10b09107 100644
index 2974f64d5a931a08e450aacbfd1281c4d3f15303..5ac75fbb994b4436fa3d6b723a9e0f58650236ed 100644
--- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
@@ -103,7 +103,7 @@ public class FrogspawnBlock extends Block {
int k = random.nextInt(1, 361);
tadpole.moveTo(d, (double)pos.getY() - 0.5D, e, (float)k, 0.0F);
tadpole.setPersistenceRequired();
- world.addFreshEntity(tadpole);
+ world.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper
@@ -109,7 +109,7 @@ public class FrogspawnBlock extends Block {
int k = random.nextInt(1, 361);
tadpole.moveTo(d, (double)pos.getY() - 0.5D, e, (float)k, 0.0F);
tadpole.setPersistenceRequired();
- world.addFreshEntity(tadpole);
+ world.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper
}
}
}