Allow using old ender pearl behavior & apply ender pearl exploit patch (#11524)

When enabled, ender pearls will not load chunks and will save to the world instead of the player.

Also changes the exploit config to be default false, as it only makes sense when legacy behavior is enabled.
This commit is contained in:
Jason Penilla 2024-10-30 10:09:05 -07:00
parent bafaa407e4
commit ec53bd41e7
3 changed files with 113 additions and 1 deletions

View file

@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sun, 27 Oct 2024 12:36:53 -0700
Subject: [PATCH] Allow using old ender pearl behavior
When enabled, ender pearls will not load chunks and will save to the world instead of the player.
== AT ==
public net.minecraft.world.entity.projectile.Projectile cachedOwner
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
while (iterator.hasNext()) {
ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next();
+ if (entityenderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) continue; // Paper - Allow using old ender pearl behavior
if (entityenderpearl.isRemoved()) {
ServerPlayer.LOGGER.warn("Trying to save removed ender pearl, skipping");
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
}
public static long placeEnderPearlTicket(ServerLevel world, ChunkPos chunkPos) {
- world.getChunkSource().addRegionTicket(TicketType.ENDER_PEARL, chunkPos, 2, chunkPos);
+ if (!world.paperConfig().misc.legacyEnderPearlBehavior) world.getChunkSource().addRegionTicket(TicketType.ENDER_PEARL, chunkPos, 2, chunkPos); // Paper - Allow using old ender pearl behavior
return TicketType.ENDER_PEARL.timeout();
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
while (iterator.hasNext()) {
ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next();
+ // Paper start - Allow using old ender pearl behavior
+ if (!entityenderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) {
entityenderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause
+ } else {
+ entityenderpearl.cachedOwner = null;
+ }
+ // Paper end - Allow using old ender pearl behavior
}
worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
@@ -0,0 +0,0 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
Entity entity = super.teleport(teleportTarget);
if (entity != null) {
- entity.placePortalTicket(BlockPos.containing(entity.position()));
+ if (!this.level().paperConfig().misc.legacyEnderPearlBehavior) entity.placePortalTicket(BlockPos.containing(entity.position())); // Paper - Allow using old ender pearl behavior
}
return entity;

View file

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 17:15:26 -0400
Subject: [PATCH] Block Enderpearl Travel Exploit
Players are able to use alt accounts and enderpearls to travel
long distances utilizing the pearls in unloaded chunks and loading
the chunk later when convenient.
This disables that by not saving the thrower when the chunk is unloaded.
This is mainly useful for survival servers that do not allow freeform teleporting.
Note: Currently removed as enderpearls are ticked as long as their owner is online in 1.21.2.
Might be worth to re-add once an option to disable the above vanilla mechanic is added, to
fully prevent enderpearl travel exploits.
== AT ==
public net.minecraft.world.entity.projectile.Projectile ownerUUID
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public void onTickingEnd(Entity entity) {
ServerLevel.this.entityTickList.remove(entity);
+ // Paper start - Reset pearls when they stop being ticked
+ if (ServerLevel.this.paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && ServerLevel.this.paperConfig().misc.legacyEnderPearlBehavior && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) {
+ pearl.cachedOwner = null;
+ pearl.ownerUUID = null;
+ }
+ // Paper end - Reset pearls when they stop being ticked
}
public void onTrackingStart(Entity entity) {
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
protected void readAdditionalSaveData(CompoundTag nbt) {
if (nbt.hasUUID("Owner")) {
this.setOwnerThroughUUID(nbt.getUUID("Owner"));
+ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit
}
this.leftOwner = nbt.getBoolean("LeftOwner");

View file

@ -1889,7 +1889,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public class Fixes extends ConfigurationPart {
+ public boolean fixItemsMergingThroughWalls = false;
+ public boolean disableUnloadedChunkEnderpearlExploit = true;
+ public boolean disableUnloadedChunkEnderpearlExploit = false;
+ public boolean preventTntFromMovingInWater = false;
+ public boolean splitOverstackedLoot = true;
+ public IntOr.Disabled fallingBlockHeightNerf = IntOr.Disabled.DISABLED;
@ -1997,6 +1997,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public boolean disableSprintInterruptionOnAttack = false;
+ public int shieldBlockingDelay = 5;
+ public boolean disableRelativeProjectileVelocity = false;
+ public boolean legacyEnderPearlBehavior = false;
+
+ public enum RedstoneImplementation {
+ VANILLA, EIGENCRAFT, ALTERNATE_CURRENT