From 70a25ecb1203283011ea863f250be4706e81b3ab Mon Sep 17 00:00:00 2001 From: Cryptite Date: Sat, 16 Nov 2024 09:34:34 -0600 Subject: [PATCH] Add PlayerLoadStatsEvent --- patches/api/0011-Add-ObjectId.patch | 85 ++++++++ patches/server/0019-Add-ObjectId.patch | 73 +++++++ ...020-Packet-obfuscation-and-reduction.patch | 185 ++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 patches/api/0011-Add-ObjectId.patch create mode 100644 patches/server/0019-Add-ObjectId.patch create mode 100644 patches/server/0020-Packet-obfuscation-and-reduction.patch diff --git a/patches/api/0011-Add-ObjectId.patch b/patches/api/0011-Add-ObjectId.patch new file mode 100644 index 000000000..7a46bb600 --- /dev/null +++ b/patches/api/0011-Add-ObjectId.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Sat, 16 Nov 2024 09:22:24 -0600 +Subject: [PATCH] Add ObjectId + + +diff --git a/build.gradle.kts b/build.gradle.kts +index e29e5024fa693baae469d47fe77b57118f14627c..5770f7c756d033076e0fb629d6aa11fb97ccb0f2 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -69,6 +69,8 @@ dependencies { + implementation("org.ow2.asm:asm-commons:9.7.1") + // Paper end + ++ implementation("org.mongodb:bson:4.11.1") // Slice - MongoDB Bson Library for ObjectIds ++ + api("org.apache.maven:maven-resolver-provider:3.9.6") // Paper - make API dependency for Paper Plugins + compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") + compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerResolveObjectIdEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerResolveObjectIdEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4c28994757812f9c7f59d9eb827908bb64e63118 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerResolveObjectIdEvent.java +@@ -0,0 +1,44 @@ ++package io.papermc.paper.event.player; ++ ++import org.bson.types.ObjectId; ++import org.bukkit.Bukkit; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.util.Objects; ++ ++/** ++ * Called when a player trades with a standalone merchant GUI. ++ */ ++public class PlayerResolveObjectIdEvent extends PlayerEvent { ++ private static final HandlerList handlers = new HandlerList(); ++ private ObjectId objectId; ++ ++ public PlayerResolveObjectIdEvent(@NotNull Player player) { ++ super(player, !Bukkit.isPrimaryThread()); ++ } ++ ++ @Nullable ++ public ObjectId getObjectId() { ++ return this.objectId; ++ } ++ ++ public void setObjectId(@NotNull ObjectId objectId) { ++ this.objectId = Objects.requireNonNull(objectId, "ObjectId cannot be null!"); ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++} +diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java +index 488604ba1a516b477693877c74712e4a45624a8b..2a3e40b0b7f058713634d99f61755b368e05fa74 100644 +--- a/src/main/java/org/bukkit/entity/HumanEntity.java ++++ b/src/main/java/org/bukkit/entity/HumanEntity.java +@@ -22,6 +22,11 @@ import org.jetbrains.annotations.Nullable; + */ + public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder { + ++ // Slice start ++ org.bson.types.@Nullable ObjectId getObjectId(); ++ void setObjectId(@Nullable org.bson.types.ObjectId objectId); ++ // Slice end ++ + // Paper start + @Override + org.bukkit.inventory.@NotNull EntityEquipment getEquipment(); diff --git a/patches/server/0019-Add-ObjectId.patch b/patches/server/0019-Add-ObjectId.patch new file mode 100644 index 000000000..0b851a979 --- /dev/null +++ b/patches/server/0019-Add-ObjectId.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Sat, 16 Nov 2024 09:22:24 -0600 +Subject: [PATCH] Add ObjectId + + +diff --git a/build.gradle.kts b/build.gradle.kts +index d6dae3101aa719b194a9426a13bf76379f281379..720672975286789da1d85e3b18b9eb34e00a74f1 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -33,6 +33,8 @@ dependencies { + implementation("com.fasterxml.jackson.core:jackson-annotations:2.13.0") + // Slice end + ++ implementation("org.mongodb:bson:4.11.1") // Slice - MongoDB Bson Library for ObjectIds ++ + // Paper start + implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("net.minecrell:terminalconsoleappender:1.3.0") +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index d10e360e664ae5ccb85c0c77848e527bc39ad775..f046cc8883af6d7fafb93aea3c7e4b664bbe7e8b 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -267,7 +267,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Paper start - Folia schedulers + synchronized (this) { + if (this.bukkitEntity == null) { +- return this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); ++ this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); ++ ++ // Slice start - resolve ObjectId ++ if (this.bukkitEntity instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity craftHumanEntity) { ++ io.papermc.paper.event.player.PlayerResolveObjectIdEvent event = new io.papermc.paper.event.player.PlayerResolveObjectIdEvent((org.bukkit.entity.Player) bukkitEntity); ++ event.callEvent(); ++ craftHumanEntity.setObjectId(event.getObjectId()); ++ } ++ // Slice end ++ ++ return this.bukkitEntity; + } + } + // Paper end - Folia schedulers +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +index 4312290ad970f71e1dc25b707ab312c597a481a9..17577943a77ac2bc4e2bdfa6f79489157004fd04 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +@@ -73,6 +73,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + protected final PermissibleBase perm = new PermissibleBase(this); + private boolean op; + private GameMode mode; ++ private org.bson.types.ObjectId objectId; + + public CraftHumanEntity(final CraftServer server, final Player entity) { + super(server, entity); +@@ -81,6 +82,18 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + this.enderChest = new CraftInventory(entity.getEnderChestInventory()); + } + ++ // Slice start ++ @Override ++ public org.bson.types.ObjectId getObjectId() { ++ return objectId; ++ } ++ ++ @Override ++ public void setObjectId(org.bson.types.ObjectId objectId) { ++ this.objectId = objectId; ++ } ++ // Slice end ++ + @Override + public PlayerInventory getInventory() { + return this.inventory; diff --git a/patches/server/0020-Packet-obfuscation-and-reduction.patch b/patches/server/0020-Packet-obfuscation-and-reduction.patch new file mode 100644 index 000000000..b5d69f47c --- /dev/null +++ b/patches/server/0020-Packet-obfuscation-and-reduction.patch @@ -0,0 +1,185 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Sat, 16 Nov 2024 09:26:55 -0600 +Subject: [PATCH] Packet obfuscation and reduction + + +diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java +index 0f99733660f91280e4c6262cf75b3c9cae86f65a..fd28ad10df3cfcfdb44cafc4182ead53a4200027 100644 +--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java ++++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java +@@ -63,15 +63,29 @@ public class SynchedEntityData { + } + + public void set(EntityDataAccessor key, T value, boolean force) { ++ // Slice start ++ this.set(key, value, force, null); ++ } ++ ++ public void set(EntityDataAccessor key, T value, @Nullable T foreignValue) { ++ this.set(key, value, false, foreignValue); ++ } ++ ++ public void set(EntityDataAccessor key, T value, boolean force, @Nullable T foreignValue) { // Slice end + SynchedEntityData.DataItem datawatcher_item = this.getItem(key); + ++ // Slice start ++ if (foreignValue != null && ObjectUtils.notEqual(foreignValue, datawatcher_item.getForeignValue())) { ++ datawatcher_item.setForeignValue(foreignValue); ++ } ++ // Slice end ++ + if (force || ObjectUtils.notEqual(value, datawatcher_item.getValue())) { + datawatcher_item.setValue(value); + this.entity.onSyncedDataUpdated(key); + datawatcher_item.setDirty(true); + this.isDirty = true; + } +- + } + + // CraftBukkit start - add method from above +@@ -108,6 +122,26 @@ public class SynchedEntityData { + } + } + ++ // Slice start ++ @Nullable ++ public List> packForeignDirty() { ++ List> list = null; ++ ++ for (DataItem dataItem : this.itemsById.values()) { ++ if (dataItem.isDirty(true)) { ++ dataItem.setForeignDirty(false); ++ if (list == null) { ++ list = new ArrayList(); ++ } ++ ++ list.add(dataItem.foreignValue != null ? dataItem.foreignValue() : dataItem.value()); ++ } ++ } ++ ++ return list; ++ } ++ // Slice end ++ + @Nullable + public List> getNonDefaultValues() { + List> list = null; +@@ -171,11 +205,14 @@ public class SynchedEntityData { + T value; + private final T initialValue; + private boolean dirty; ++ private @Nullable T foreignValue = null; // Slice ++ private boolean foreignDirty; // Slice + + public DataItem(EntityDataAccessor data, T value) { + this.accessor = data; + this.initialValue = value; + this.value = value; ++ this.foreignDirty = true; //Slice + } + + public EntityDataAccessor getAccessor() { +@@ -205,6 +242,36 @@ public class SynchedEntityData { + public SynchedEntityData.DataValue value() { + return SynchedEntityData.DataValue.create(this.accessor, this.value); + } ++ ++ ++ // Slice start ++ public SynchedEntityData.DataValue foreignValue() { ++ return SynchedEntityData.DataValue.create(this.accessor, this.foreignValue); ++ } ++ ++ 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; ++ } ++ // Slice end + } + + public static record DataValue(int id, EntityDataSerializer serializer, T value) { +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index 90eb4927fa51ce3df86aa7b6c71f49150a03e337..357f1d375cd92ce73516c6baceffe8dd89b9e499 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -449,7 +449,20 @@ public class ServerEntity { + + if (list != null) { + this.trackedDataValues = datawatcher.getNonDefaultValues(); +- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list)); ++// this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list)); ++ // Slice start ++ ClientboundSetEntityDataPacket dataPacket = new ClientboundSetEntityDataPacket(this.entity.getId(), list); ++ 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(); ++ if (dirtyItems != null) { ++ this.broadcast.accept(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 f046cc8883af6d7fafb93aea3c7e4b664bbe7e8b..cd16a08af2da0dca57472b9e264eb4b45e7546e9 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -3706,7 +3706,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/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java +index 551da84c834132d106457c123e1b195e4be904b8..e4041c58a23d3eaefd01402635f714404f3c82cf 100644 +--- a/src/main/java/net/minecraft/world/entity/player/Player.java ++++ b/src/main/java/net/minecraft/world/entity/player/Player.java +@@ -676,7 +676,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) { +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 2907a7ecf8b893717b5a436eadf4b49860d7df17..411531d6a7c4904540055d499b7fe71672031daf 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -2862,7 +2862,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 = this.getMaxHealth(); + }