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 2e2bfccfc6cec6582a5b595e0343c27be5267b7a..77e5b55b6c1ea505c7fd11d5f9ee783c9ffa72f7 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 b0a79e335ac9dc24fc6f18010bf40716ecc724bf..e4ba278cf42c4a946ddd3e1fefd07ae3b696cdc0 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 d0daee81837fe64ac766e615d0a0bbb891de3306..dbee85771fa020295bc967b99ef8dd3fb67f4d3c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2971,7 +2971,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i if (event.isCancelled()) { 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 2c0c9019245e94a4c89c948eafa837a7d6279b7e..0d720d6d50de919a4a65278a73db7e4b639b6bc9 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -631,7 +631,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 } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index ef841a5ea1f634e87e5437faf83dc00efd590106..f7d25a63d80fed46f81f46e98e6a36bc8cfa5f88 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2113,7 +2113,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(); }