From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cryptite Date: Mon, 28 Feb 2022 09:01:45 -0600 Subject: [PATCH] Packet obfuscation and reduction 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..e1233fa58d068448d0accef7a7f6725fcb902848 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java @@ -22,6 +22,13 @@ public class ClientboundSetEntityDataPacket implements Packet> packedItems) { + this.id = id; + this.packedItems = packedItems; + } + // Slice end + public ClientboundSetEntityDataPacket(FriendlyByteBuf buf) { this.id = buf.readVarInt(); this.packedItems = SynchedEntityData.unpack(buf); diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java index 1d88edfd09a909044f6e3175af652914b4d06311..e4f8403c6544e1a00571f28954458a1412a6de58 100644 --- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java +++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java @@ -136,6 +136,11 @@ public class SynchedEntityData { } public void set(EntityDataAccessor key, T value) { + //Slice start + set(key, value, null); + } + + public void set(EntityDataAccessor key, T value, @Nullable T foreignValue) { // Slice end SynchedEntityData.DataItem datawatcher_item = this.getItem(key); if (ObjectUtils.notEqual(value, datawatcher_item.getValue())) { @@ -145,6 +150,11 @@ public class SynchedEntityData { this.isDirty = true; } + // Slice start + if (foreignValue != null && ObjectUtils.notEqual(foreignValue, datawatcher_item.getForeignValue())) { + datawatcher_item.setForeignValue(foreignValue); + } + // Slice end } // CraftBukkit start - add method from above @@ -200,6 +210,28 @@ public class SynchedEntityData { return list; } + // Slice start + @Nullable + public List> packForeignDirty(List> unpackedData) { + List> list = null; + + for (DataItem dataItem : unpackedData) { + DataItem item = itemsById.get(dataItem.accessor.getId()); + if (item.isDirty(true)) { + item.setForeignDirty(false); + + if (list == null) { + list = Lists.newArrayList(); + } + + list.add(item.copy(true)); + } + } + + return list; + } + // Slice end + @Nullable public List> getAll() { List> list = null; @@ -313,11 +345,14 @@ public class SynchedEntityData { final EntityDataAccessor accessor; T value; private boolean dirty; + @Nullable T foreignValue = null; // Slice + private boolean foreignDirty; // Slice public DataItem(EntityDataAccessor data, T value) { this.accessor = data; this.value = value; this.dirty = true; + this.foreignDirty = true; // Slice } public EntityDataAccessor getAccessor() { @@ -343,5 +378,34 @@ public class SynchedEntityData { public SynchedEntityData.DataItem copy() { return new SynchedEntityData.DataItem<>(this.accessor, this.accessor.getSerializer().copy(this.value)); } + + // Slice start + public void setForeignValue(T foreignValue) { + this.foreignValue = foreignValue; + this.foreignDirty = true; + } + + public @Nullable T getForeignValue() { + return foreignValue; + } + + public boolean isDirty(boolean foreign) { + if (foreign) { + //There must be a foreign value in order for this to be dirty, otherwise we consider this a normal + //value and check the normal dirty flag. + return foreignValue == null || this.foreignDirty; + } + + return this.dirty; + } + + public void setForeignDirty(boolean dirty) { + this.foreignDirty = dirty; + } + + public SynchedEntityData.DataItem copy(boolean foreign) { + return new SynchedEntityData.DataItem<>(this.accessor, this.accessor.getSerializer().copy((foreign && this.foreignValue != null ? this.foreignValue : this.value))); + } + // Slice end } } diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java index f91e1a876ad4c46a7c92cead18947a941b4d9e68..13973b8803afefd491dc05e1df6e9b10174e0108 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -371,7 +371,19 @@ public class ServerEntity { SynchedEntityData datawatcher = this.entity.getEntityData(); if (datawatcher.isDirty()) { - this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false)); + // Slice start + ClientboundSetEntityDataPacket dataPacket = new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false); + if (this.entity instanceof ServerPlayer serverPlayer) { + serverPlayer.connection.send(dataPacket); + } + + //Get the packedData that the original packet has, and then determine if any of those are changed in + //the foreign version. If null, nothing to notify foreign trackers about. + List> dirtyItems = datawatcher.packForeignDirty(dataPacket.getUnpackedData()); + if (dirtyItems != null) { + this.broadcast(new ClientboundSetEntityDataPacket(this.entity.getId(), dirtyItems)); + } + // Slice end } if (this.entity instanceof LivingEntity) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 7fcb2ecae7ec9a457e00a6a3ea1fb7b589360e02..75afbe3722d3e3ba7fe33f959ca40679c40b95dc 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2987,7 +2987,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.entityData.markDirty(Entity.DATA_AIR_SUPPLY_ID); return; } - this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, event.getAmount()); + this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, event.getAmount(), getMaxAirSupply()); // Slice // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java index 0156525637f8aa2e4e639bc493d8617b5af4cc32..1c598a97ed78a744907ae310f3568c447aad0949 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -632,7 +632,7 @@ public abstract class Player extends LivingEntity { public void increaseScore(int score) { int j = this.getScore(); - this.entityData.set(Player.DATA_SCORE_ID, j + score); + this.entityData.set(Player.DATA_SCORE_ID, j + score, 0); // Slice } public void startAutoSpinAttack(int riptideTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index ce78e024244c14530270b8276e5b0fd853f0a110..df22a1407f3d1e93f0f1d50b5dbec3df12b106d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2196,7 +2196,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.sendHealthUpdate(); } } - this.getHandle().getEntityData().set(net.minecraft.world.entity.LivingEntity.DATA_HEALTH_ID, (float) this.getScaledHealth()); + this.getHandle().getEntityData().set(net.minecraft.world.entity.LivingEntity.DATA_HEALTH_ID, (float) this.getScaledHealth(), isDead() ? 0f : 20f); // Slice this.getHandle().maxHealthCache = getMaxHealth(); }