Files
MiraiMC/patches/server/0056-Packet-obfuscation-and-reduction.patch
2022-06-13 16:14:55 +02:00

199 lines
8.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cryptite <cryptite@gmail.com>
Date: Wed, 6 Oct 2021 11:03:01 -0500
Subject: [PATCH] Packet obfuscation and reduction
Original code by Cryptite, licensed under MIT
You can find the original code on https://github.com/Cryptite/Slice
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 019ccd50ac87557bd971c0fde3113cc0e2e301ff..bb116272d84908649ef0f80618a66094422ecfca 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<ClientGamePacketLi
}
+ // Slice start
+ public ClientboundSetEntityDataPacket(int id, List<SynchedEntityData.DataItem<?>> 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..9031fb0e8c589b759549f4197772b6c9929736a0 100644
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
@@ -136,6 +136,12 @@ public class SynchedEntityData {
}
public <T> void set(EntityDataAccessor<T> key, T value) {
+ // Slice start
+ set(key, value, null);
+ }
+
+ public <T> void set(EntityDataAccessor<T> key, T value, @Nullable T foreignValue) {
+ // Slice end
SynchedEntityData.DataItem<T> datawatcher_item = this.getItem(key);
if (ObjectUtils.notEqual(value, datawatcher_item.getValue())) {
@@ -145,6 +151,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 +211,28 @@ public class SynchedEntityData {
return list;
}
+ // Slice start
+ @Nullable
+ public List<SynchedEntityData.DataItem<?>> packForeignDirty(List<DataItem<?>> unpackedData) {
+ List<SynchedEntityData.DataItem<?>> 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<SynchedEntityData.DataItem<?>> getAll() {
List<SynchedEntityData.DataItem<?>> list = null;
@@ -313,11 +346,14 @@ public class SynchedEntityData {
final EntityDataAccessor<T> accessor;
T value;
private boolean dirty;
+ @Nullable T foreignValue = null; // Slice
+ private boolean foreignDirty; // Slice
public DataItem(EntityDataAccessor<T> data, T value) {
this.accessor = data;
this.value = value;
this.dirty = true;
+ this.foreignDirty = true; // Slice
}
public EntityDataAccessor<T> getAccessor() {
@@ -343,5 +379,34 @@ public class SynchedEntityData {
public SynchedEntityData.DataItem<T> 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<T> 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 2d7e884d25f352e0a05e9aefb0ff6e296e73c361..8b64571c85e8e36d7ed48c42e4dc5957a874ea7c 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -390,7 +390,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<SynchedEntityData.DataItem<?>> 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 9b224ca33115aa7e7f100a45fe8bdb68ea7e4b59..f585b23c4f958184c4388c5c832dac1eaf7ae788 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3029,7 +3029,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 2483d7df7f1bf94344afd38b37602c645a4a2dff..5c16235115a9233bce1f5b30bb020d105bdca3d1 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 170c7469ac6ed343a8e4e43f03a972d106bcc640..d36a27c06b9b33fe762fcec3afe2bdb90ba0ec2c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2202,7 +2202,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();
}