From 7d751ad8d33b85f2bb6b1cddc438b19418c01318 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Fri, 4 Jun 2021 17:58:45 -0400 Subject: [PATCH] Fix dangerous end portal logic (#5776) Co-authored-by: Spottedleaf --- .../0655-added-Wither-API.patch | 4 +- .../0755-Fix-dangerous-end-portal-logic.patch | 99 +++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch diff --git a/Spigot-Server-Patches/0655-added-Wither-API.patch b/Spigot-Server-Patches/0655-added-Wither-API.patch index 29bb22ea9..e4d69e8e8 100644 --- a/Spigot-Server-Patches/0655-added-Wither-API.patch +++ b/Spigot-Server-Patches/0655-added-Wither-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] added Wither API diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java -index 30290c0208a4725b2eb0e7764465c354e592e4ee..891905712903bf3ba241187791cfa995375430d5 100644 +index 30290c0208a4725b2eb0e7764465c354e592e4ee..170b085c76e092f6d7b14095c66c84fa9a96a1fc 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java @@ -82,6 +82,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity { @@ -33,7 +33,7 @@ index 30290c0208a4725b2eb0e7764465c354e592e4ee..891905712903bf3ba241187791cfa995 @Override public boolean canPortal() { - return false; -+ return canPortal; // Paper ++ return super.canPortal() && canPortal; // Paper } @Override diff --git a/Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch b/Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch new file mode 100644 index 000000000..e7c930a3d --- /dev/null +++ b/Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch @@ -0,0 +1,99 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 4 Jun 2021 17:06:52 -0400 +Subject: [PATCH] Fix dangerous end portal logic + +End portals could teleport entities during move calls. Stupid +logic given the caller will never expect that kind of thing, +and will result in all kinds of dupes. + +Move the tick logic into the post tick, where portaling was +designed to happen in the first place. + +diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java +index 558af73ac16550ee6964c4dce681a404633b2552..75bcfb3a2b4a104aeebb2fe3298714b2e5b569d2 100644 +--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java +@@ -1023,6 +1023,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + return b(worldserver, TeleportCause.UNKNOWN); + } + ++ @Nullable public final Entity changeDimension(WorldServer worldserver, PlayerTeleportEvent.TeleportCause cause) { return this.b(worldserver, cause); } // Paper - OBFHELPER + @Nullable + public Entity b(WorldServer worldserver, PlayerTeleportEvent.TeleportCause cause) { + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 6fdcd96fd75cd63d769b012827519f554af4cf54..8ef41182056052686055b7eb88ab19c161e84ed4 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -314,6 +314,37 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne + } + // Paper end - optimise entity tracking + ++ // Paper start - make end portalling safe ++ public BlockPosition portalBlock; ++ public WorldServer portalWorld; ++ public void tickEndPortal() { ++ BlockPosition pos = this.portalBlock; ++ WorldServer world = this.portalWorld; ++ this.portalBlock = null; ++ this.portalWorld = null; ++ ++ if (pos == null || world == null || world != this.world) { ++ return; ++ } ++ ++ if (this.isPassenger() || this.isVehicle() || !this.canPortal() || this.dead || !this.valid || !this.isAlive()) { ++ return; ++ } ++ ++ ResourceKey resourcekey = world.getTypeKey() == DimensionManager.THE_END ? World.OVERWORLD : World.THE_END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends ++ WorldServer worldserver = world.getMinecraftServer().getWorldServer(resourcekey); ++ ++ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(this.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); ++ event.callEvent(); ++ ++ if (this instanceof EntityPlayer) { ++ ((EntityPlayer)this).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL); ++ return; ++ } ++ this.teleportTo(worldserver, null); ++ } ++ // Paper end - make end portalling safe ++ + public Entity(EntityTypes entitytypes, World world) { + this.id = Entity.entityCount.incrementAndGet(); + this.passengers = Lists.newArrayList(); +@@ -2294,6 +2325,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne + } + + this.E(); ++ this.tickEndPortal(); // Paper - make end portalling safe + } + } + +diff --git a/src/main/java/net/minecraft/world/level/block/BlockEnderPortal.java b/src/main/java/net/minecraft/world/level/block/BlockEnderPortal.java +index ed916f69747b44b75eb06db4cf27adaf5e47fd1e..9483d75fbe2a8c8f7cce00355e93ff1f943f3444 100644 +--- a/src/main/java/net/minecraft/world/level/block/BlockEnderPortal.java ++++ b/src/main/java/net/minecraft/world/level/block/BlockEnderPortal.java +@@ -52,16 +52,10 @@ public class BlockEnderPortal extends BlockTileEntity { + // return; // CraftBukkit - always fire event in case plugins wish to change it + } + +- // CraftBukkit start - Entity in portal +- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); +- world.getServer().getPluginManager().callEvent(event); +- +- if (entity instanceof EntityPlayer) { +- ((EntityPlayer) entity).b(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL); +- return; +- } +- // CraftBukkit end +- entity.b(worldserver); ++ // Paper start - move all of this logic into portal tick ++ entity.portalWorld = ((WorldServer)world); ++ entity.portalBlock = blockposition.immutableCopy(); ++ // Paper end - move all of this logic into portal tick + } + + }