108 lines
5.3 KiB
Diff
108 lines
5.3 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Spottedleaf <spottedleaf@users.noreply.github.com>
|
||
|
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/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||
|
index 779b926921fd435620cbbc69ed6f9931a422b652..25711ab723386db0f448c54e18ef069bfcd0dd99 100644
|
||
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||
|
@@ -1020,6 +1020,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||
|
return b(destination, TeleportCause.UNKNOWN);
|
||
|
}
|
||
|
|
||
|
+ @Nullable public final Entity changeDimension(ServerLevel worldserver, PlayerTeleportEvent.TeleportCause cause) { return this.b(worldserver, cause); } // Paper - OBFHELPER
|
||
|
@Nullable
|
||
|
public Entity b(ServerLevel 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 d055b362459e5b4658aa220e16118ee6174c0de4..2462a78d976937cf4737f1ce0bfde2b2b7d5b1f7 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
@@ -312,6 +312,37 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||
|
}
|
||
|
// Paper end - optimise entity tracking
|
||
|
|
||
|
+ // Paper start - make end portalling safe
|
||
|
+ public BlockPos portalBlock;
|
||
|
+ public ServerLevel portalWorld;
|
||
|
+ public void tickEndPortal() {
|
||
|
+ BlockPos pos = this.portalBlock;
|
||
|
+ ServerLevel world = this.portalWorld;
|
||
|
+ this.portalBlock = null;
|
||
|
+ this.portalWorld = null;
|
||
|
+
|
||
|
+ if (pos == null || world == null || world != this.level) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (this.isPassenger() || this.isVehicle() || !this.canChangeDimensions() || this.removed || !this.valid || !this.isAlive()) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ ResourceKey<Level> resourcekey = world.getTypeKey() == DimensionType.END_LOCATION ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
|
||
|
+ ServerLevel worldserver = world.getServer().getLevel(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 ServerPlayer) {
|
||
|
+ ((ServerPlayer)this).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ this.teleportTo(worldserver, null);
|
||
|
+ }
|
||
|
+ // Paper end - make end portalling safe
|
||
|
+
|
||
|
public Entity(EntityType<?> type, Level world) {
|
||
|
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
|
||
|
this.passengers = Lists.newArrayList();
|
||
|
@@ -2297,6 +2328,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||
|
}
|
||
|
|
||
|
this.processPortalCooldown();
|
||
|
+ this.tickEndPortal(); // Paper - make end portalling safe
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||
|
index 2231680140d0e3c4c10b6722fd13fe0ee55ce294..52884b87b25bef8abfa824f40d02efe3f947f330 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||
|
@@ -3,7 +3,6 @@ package net.minecraft.world.level.block;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.resources.ResourceKey;
|
||
|
import net.minecraft.server.level.ServerLevel;
|
||
|
-import net.minecraft.server.level.ServerPlayer;
|
||
|
import net.minecraft.world.entity.Entity;
|
||
|
import net.minecraft.world.level.BlockGetter;
|
||
|
import net.minecraft.world.level.Level;
|
||
|
@@ -50,16 +49,10 @@ public class EndPortalBlock extends BaseEntityBlock {
|
||
|
// 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(), pos.getX(), pos.getY(), pos.getZ()));
|
||
|
- world.getCraftServer().getPluginManager().callEvent(event);
|
||
|
-
|
||
|
- if (entity instanceof ServerPlayer) {
|
||
|
- ((ServerPlayer) entity).b(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
|
||
|
- return;
|
||
|
- }
|
||
|
- // CraftBukkit end
|
||
|
- entity.changeDimension(worldserver);
|
||
|
+ // Paper start - move all of this logic into portal tick
|
||
|
+ entity.portalWorld = ((ServerLevel)world);
|
||
|
+ entity.portalBlock = pos.immutable();
|
||
|
+ // Paper end - move all of this logic into portal tick
|
||
|
}
|
||
|
|
||
|
}
|