13
0
geforkt von Mirrors/Paper

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
Dieser Commit ist enthalten in:
Aikar 2018-04-30 17:15:26 -04:00
Ursprung cf7a1191a9
Commit 0d8c3dc008
2 geänderte Dateien mit 48 neuen und 33 gelöschten Zeilen

Datei anzeigen

@ -80,7 +80,7 @@
+ public final UUID uuid;
+ public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
+ public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
+
+ public LevelChunk getChunkIfLoaded(int x, int z) {
+ return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
+ }
@ -149,7 +149,7 @@
+ List<net.minecraft.world.level.chunk.ChunkAccess> ret = new java.util.ArrayList<>();
+ it.unimi.dsi.fastutil.ints.IntArrayList ticketLevels = new it.unimi.dsi.fastutil.ints.IntArrayList();
+ ServerChunkCache chunkProvider = this.getChunkSource();
+
+ int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1);
+ int[] loadedChunks = new int[1];
+
@ -487,9 +487,10 @@
if (flag != this.isRaining()) {
if (flag) {
- this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.STOP_RAINING, 0.0F));
+ this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.STOP_RAINING, 0.0F));
} else {
- } else {
- this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F));
+ this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.STOP_RAINING, 0.0F));
+ } else {
+ this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.START_RAINING, 0.0F));
}
@ -625,13 +626,13 @@
- return this.addEntity(entity);
+ // CraftBukkit start
+ return this.addWithUUID(entity, CreatureSpawnEvent.SpawnReason.DEFAULT);
}
+ }
+
+ public boolean addWithUUID(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
+ return this.addEntity(entity, reason);
+ // CraftBukkit end
+ }
+
}
public void addDuringTeleport(Entity entity) {
+ // CraftBukkit start
+ // SPIGOT-6415: Don't call spawn event for entities which travel trough worlds,
@ -1100,10 +1101,12 @@
return this.entityManager.getEntityGetter();
}
@@ -1802,6 +2239,27 @@
return this.serverLevelData.getGameRules();
}
@@ -1800,7 +2237,28 @@
public GameRules getGameRules() {
return this.serverLevelData.getGameRules();
+ }
+
+ // Paper start - respect global sound events gamerule
+ public List<net.minecraft.server.level.ServerPlayer> getPlayersForGlobalSoundGamerule() {
+ return this.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) ? ((ServerLevel) this).getServer().getPlayerList().players : ((ServerLevel) this).players();
@ -1122,13 +1125,12 @@
+ if (craftBlockState.getPosition().getY() == pos.getY() && this.getBlockState(craftBlockState.getPosition()) == craftBlockState.getHandle()) {
+ this.notifyAndUpdatePhysics(craftBlockState.getPosition(), null, craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getFlag(), 512);
+ }
+ }
}
+ // Paper end - notify observers even if grow failed
+
@Override
public CrashReportCategory fillReportDetails(CrashReport report) {
CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report);
@@ -1828,6 +2286,7 @@
@@ -1828,22 +2286,30 @@
}
public void onTickingStart(Entity entity) {
@ -1136,7 +1138,14 @@
ServerLevel.this.entityTickList.add(entity);
}
@@ -1836,14 +2295,15 @@
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) {
@ -1154,7 +1163,7 @@
String s = "onTrackingStart called during navigation iteration";
Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration"));
@@ -1864,9 +2324,58 @@
@@ -1864,9 +2330,58 @@
}
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
@ -1213,7 +1222,7 @@
ServerLevel.this.getChunkSource().removeEntity(entity);
if (entity instanceof ServerPlayer entityplayer) {
ServerLevel.this.players.remove(entityplayer);
@@ -1874,7 +2383,7 @@
@@ -1874,7 +2389,7 @@
}
if (entity instanceof Mob entityinsentient) {
@ -1222,7 +1231,7 @@
String s = "onTrackingStart called during navigation iteration";
Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration"));
@@ -1895,10 +2404,27 @@
@@ -1895,10 +2410,27 @@
}
entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);

Datei anzeigen

@ -58,7 +58,15 @@
return this.cachedOwner;
} else {
return null;
@@ -184,12 +210,20 @@
@@ -108,6 +134,7 @@
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");
@@ -184,12 +211,20 @@
this.shoot((double) f5, (double) f6, (double) f7, speed, divergence);
Vec3 vec3d = shooter.getKnownMovement();
@ -81,7 +89,7 @@
iprojectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot(), roll, power, divergence);
});
}
@@ -201,7 +235,12 @@
@@ -201,7 +236,12 @@
}
public static <T extends Projectile> T spawnProjectileUsingShoot(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) {
@ -95,12 +103,10 @@
projectile.shoot(velocityX, velocityY, velocityZ, power, divergence);
});
}
@@ -209,13 +248,47 @@
public static <T extends Projectile> T spawnProjectile(T projectile, ServerLevel world, ItemStack projectileStack) {
return Projectile.spawnProjectile(projectile, world, projectileStack, (iprojectile) -> {
@@ -211,11 +251,45 @@
});
+ }
+
}
+ // Paper start - delayed projectile spawning
+ public record Delayed<T extends Projectile>(
+ T projectile,
@ -129,9 +135,9 @@
+ this.attemptSpawn(reason);
+ return projectile();
+ }
}
+ }
+ // Paper end - delayed projectile spawning
+
public static <T extends Projectile> T spawnProjectile(T projectile, ServerLevel world, ItemStack projectileStack, Consumer<T> beforeSpawn) {
+ // Paper start - delayed projectile spawning
+ return spawnProjectileDelayed(projectile, world, projectileStack, beforeSpawn).spawn();
@ -146,7 +152,7 @@
}
public void applyOnProjectileSpawned(ServerLevel world, ItemStack projectileStack) {
@@ -232,6 +305,17 @@
@@ -232,6 +306,17 @@
}
@ -164,7 +170,7 @@
protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) {
if (hitResult.getType() == HitResult.Type.ENTITY) {
EntityHitResult movingobjectpositionentity = (EntityHitResult) hitResult;
@@ -269,7 +353,13 @@
@@ -269,7 +354,13 @@
public boolean deflect(ProjectileDeflection deflection, @Nullable Entity deflector, @Nullable Entity owner, boolean fromAttack) {
deflection.deflect(this, deflector, this.random);
if (!this.level().isClientSide) {
@ -179,7 +185,7 @@
this.onDeflection(deflector, fromAttack);
}
@@ -309,6 +399,11 @@
@@ -309,6 +400,11 @@
protected void onHitEntity(EntityHitResult entityHitResult) {}
protected void onHitBlock(BlockHitResult blockHitResult) {
@ -191,7 +197,7 @@
BlockState iblockdata = this.level().getBlockState(blockHitResult.getBlockPos());
iblockdata.onProjectileHit(this.level(), iblockdata, blockHitResult, this);
@@ -320,6 +415,15 @@
@@ -320,6 +416,15 @@
} else {
Entity entity1 = this.getOwner();
@ -207,7 +213,7 @@
return entity1 == null || this.leftOwner || !entity1.isPassengerOfSameVehicle(entity);
}
}
@@ -333,14 +437,8 @@
@@ -333,14 +438,8 @@
}
protected static float lerpRotation(float prevRot, float newRot) {