9
0
mirror of https://github.com/Samsuik/Sakura.git synced 2025-12-21 07:49:29 +00:00
Files
SakuraMC/patches/server/0010-Slice-Packet-obfuscation-and-reduction.patch
Samsuik 9a7b139975 Updated Upstream (1.21.4 Paper)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@c0a3d51 Start update, apply API patches
PaperMC/Paper@172c7dc Work
PaperMC/Paper@ab9a3db More work
PaperMC/Paper@c60e47f More more work
PaperMC/Paper@bd55e32 More more more work
PaperMC/Paper@5265287 More more more more work
PaperMC/Paper@4601dc9 Some fixes, start updating CustomModelData API
PaperMC/Paper@2331dad Even more work
PaperMC/Paper@dc74c6f moonrise
PaperMC/Paper@d7d2f88 Apply remaining patches, fix API
PaperMC/Paper@f863bb7 Update generated classes
PaperMC/Paper@71a4ef8 Set java launcher for api generate task
PaperMC/Paper@b8aeecb Compilation fixes
PaperMC/Paper@6c35392 Tests succeed (by removing one)
PaperMC/Paper@b0603da Fix jd gson version, move back mc util diff
PaperMC/Paper@e2dd1d5 Add back post_teleport chunk ticket
PaperMC/Paper@7045b2a Update DataConverter
PaperMC/Paper@65633e3 Update Moonrise
2024-12-04 00:31:13 +00:00

239 lines
10 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] (Slice) Packet obfuscation and reduction
Minecraft is overzealous about packet updates for Entities. In Loka's case, we want to reduce as many unnecessary
packet updates as possible. This patch is likely to be updated over and over in terms of reducing packet sends.
In summary, this patch creates the concept of a "foreignValue" of a packet's data. We treat packets in two ways:
1) The packet sent to the player itself (the normal way). This always has all of the values as usual.
2) The packet data as seen by any other (foreign) players.
This patch adds the ability to set a "foreignValue" for an entity value so as to obfuscate data received by other players.
The current packets modified/obfuscated are the following:
# This reduces the amount of health packet updates as well which is great for players in combat.
# Air level packets are sent PER-TICK, and as such a player with any change in air level will only spam themselves
# with packets instead of every single player within tracking distance
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
index 0f99733660f91280e4c6262cf75b3c9cae86f65a..ba9f8fe6fafc54bbdfb104de28af4b392feb4483 100644
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
@@ -22,6 +22,7 @@ public class SynchedEntityData {
private final SyncedDataHolder entity;
private final SynchedEntityData.DataItem<?>[] itemsById;
private boolean isDirty;
+ private boolean isForeignDirty; // Slice
SynchedEntityData(SyncedDataHolder trackedEntity, SynchedEntityData.DataItem<?>[] entries) {
this.entity = trackedEntity;
@@ -63,6 +64,16 @@ public class SynchedEntityData {
}
public <T> void set(EntityDataAccessor<T> key, T value, boolean force) {
+ // Slice start
+ this.set(key, value, null, force);
+ }
+
+ public <T> void set(EntityDataAccessor<T> key, T value, T foreignValue) {
+ this.set(key, value, foreignValue, false);
+ }
+
+ public <T> void set(EntityDataAccessor<T> key, T value, T foreignValue, boolean force) {
+ // Slice end
SynchedEntityData.DataItem<T> datawatcher_item = this.getItem(key);
if (force || ObjectUtils.notEqual(value, datawatcher_item.getValue())) {
@@ -72,6 +83,12 @@ public class SynchedEntityData {
this.isDirty = true;
}
+ // Slice start
+ if (foreignValue != null && ObjectUtils.notEqual(foreignValue, datawatcher_item.getForeignValue())) {
+ datawatcher_item.setForeignValue(foreignValue);
+ this.isForeignDirty = true;
+ }
+ // Slice end
}
// CraftBukkit start - add method from above
@@ -81,6 +98,12 @@ public class SynchedEntityData {
}
// CraftBukkit end
+ // Slice start
+ public boolean isForeignDirty() {
+ return this.isForeignDirty;
+ }
+ // Slice end
+
public boolean isDirty() {
return this.isDirty;
}
@@ -108,6 +131,29 @@ public class SynchedEntityData {
}
}
+ // Slice start
+ @Nullable
+ public List<SynchedEntityData.DataValue<?>> packForeignDirty(List<DataValue<?>> unpackedData) {
+ List<SynchedEntityData.DataValue<?>> list = null;
+
+ for (DataValue<?> dataItem : unpackedData) {
+ DataItem<?> item = this.itemsById[dataItem.id()];
+ if (item.isDirty(true)) {
+ item.setForeignDirty(false);
+
+ if (list == null) {
+ list = new ArrayList<>();
+ }
+
+ list.add(item.copy(true));
+ }
+ }
+
+ this.isForeignDirty = false;
+ return list;
+ }
+ // Slice end
+
@Nullable
public List<SynchedEntityData.DataValue<?>> getNonDefaultValues() {
List<SynchedEntityData.DataValue<?>> list = null;
@@ -171,11 +217,14 @@ public class SynchedEntityData {
T value;
private final T initialValue;
private boolean dirty;
+ @Nullable T foreignValue = null; // Slice
+ private boolean foreignDirty; // Slice
public DataItem(EntityDataAccessor<T> data, T value) {
this.accessor = data;
this.initialValue = value;
this.value = value;
+ this.foreignDirty = true; // Slice
}
public EntityDataAccessor<T> getAccessor() {
@@ -202,6 +251,35 @@ public class SynchedEntityData {
return this.initialValue.equals(this.value);
}
+ // Slice start
+ public void setForeignValue(T foreignValue) {
+ this.foreignValue = foreignValue;
+ this.foreignDirty = true;
+ }
+
+ public @Nullable T getForeignValue() {
+ return this.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 this.foreignValue == null || this.foreignDirty;
+ }
+
+ return this.dirty;
+ }
+
+ public void setForeignDirty(boolean dirty) {
+ this.foreignDirty = dirty;
+ }
+
+ public SynchedEntityData.DataValue<T> copy(boolean foreign) {
+ return SynchedEntityData.DataValue.create(this.accessor, this.accessor.serializer().copy((foreign && this.foreignValue != null ? this.foreignValue : this.value)));
+ }
+ // Slice end
+
public SynchedEntityData.DataValue<T> value() {
return SynchedEntityData.DataValue.create(this.accessor, this.value);
}
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 103e2c414780be66324bcb9cd4ea539bbdfe12ad..8004c920f9709723c9f4fe1a430247b5ee1520f1 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -156,7 +156,7 @@ public class ServerEntity {
}
}
- if (this.forceStateResync || this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) { // Paper - fix desync when a player is added to the tracker
+ if (this.forceStateResync || this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isForeignDirty()) { // Slice // Paper - fix desync when a player is added to the tracker
byte b0 = Mth.packDegrees(this.entity.getYRot());
byte b1 = Mth.packDegrees(this.entity.getXRot());
boolean flag = Math.abs(b0 - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
@@ -449,7 +449,15 @@ public class ServerEntity {
if (list != null) {
this.trackedDataValues = datawatcher.getNonDefaultValues();
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
+ // Slice start
+ if (!(this.entity instanceof ServerPlayer)) {
+ list = datawatcher.packForeignDirty(list);
+ }
+
+ if (list != null) {
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
+ }
+ // 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 20980e5a180e0e7951d5c9a97b8b8f792c619b9a..384b64cfbc2fef49fa22baf1f640ea8f440093cd 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3703,7 +3703,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
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/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
index 20fa9a70f2d51aaa7f9ea01150d65c1f73caa374..81d02da6afd4b77c0ca60e9c8c5100ce6988753c 100644
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -124,7 +124,7 @@ public class FallingBlockEntity extends Entity {
}
public void setStartPos(BlockPos pos) {
- this.entityData.set(FallingBlockEntity.DATA_START_POS, pos);
+ this.entityData.set(FallingBlockEntity.DATA_START_POS, pos, BlockPos.ZERO); // Slice
}
public BlockPos getStartPos() {
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
index 539219a4117c67278461ee483a457c005e6edcfc..46b729ecf0c58bdbe7a4717e73b098dcffd910f1 100644
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
@@ -217,7 +217,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
}
public void setFuse(int fuse) {
- this.entityData.set(PrimedTnt.DATA_FUSE_ID, fuse);
+ this.entityData.set(PrimedTnt.DATA_FUSE_ID, fuse, (fuse / 10) * 10); // Slice
}
public int getFuse() {
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 5b8b85a295a08ae495f729c595b3a78778965342..99133ad27aac31f68101aff4a4c4965c7ff1fd6b 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -679,7 +679,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, float riptideAttackDamage, ItemStack stack) {