aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch')
-rw-r--r--Spigot-Server-Patches/0755-Fix-dangerous-end-portal-logic.patch99
1 files changed, 99 insertions, 0 deletions
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 0000000000..e7c930a3d4
--- /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 <[email protected]>
+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<World> 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
+ }
+
+ }