mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-16 06:30:46 +01:00
Properly resend entities (#7041)
This commit is contained in:
parent
d8be0e795b
commit
0ea0d39edf
2 changed files with 147 additions and 43 deletions
147
patches/server/Properly-resend-entities.patch
Normal file
147
patches/server/Properly-resend-entities.patch
Normal file
|
@ -0,0 +1,147 @@
|
|||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AgentTroll <woodyc40@gmail.com>
|
||||
Date: Fri, 22 Mar 2019 22:24:03 -0700
|
||||
Subject: [PATCH] Update entity Metadata for all tracked players
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ServerEntity {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Add broadcast method
|
||||
+ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ 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 - update entity for all players
|
||||
+ ClientboundSetEntityDataPacket entityDataPacket = new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true);
|
||||
+ if (entity.tracker != null) {
|
||||
+ entity.tracker.broadcast(entityDataPacket);
|
||||
+ } else {
|
||||
+ ServerGamePacketListenerImpl.this.send(entityDataPacket);
|
||||
+ }
|
||||
+ // 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())));
|
Loading…
Reference in a new issue