From 73ec7f224a8eaf0a313a45ddb964aa9ffc05c93d Mon Sep 17 00:00:00 2001 From: lexikiq Date: Tue, 28 Sep 2021 21:43:24 -0400 Subject: [PATCH] Add patch from EMC --- build-data/mcdev-imports.txt | 2 - ...Passenger-Teleporting-for-Bukkit-API.patch | 201 ++++++++++++++++++ 2 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 patches/server/0015-Allow-Vehicle-Passenger-Teleporting-for-Bukkit-API.patch diff --git a/build-data/mcdev-imports.txt b/build-data/mcdev-imports.txt index 6837ce8..6f0ec2f 100644 --- a/build-data/mcdev-imports.txt +++ b/build-data/mcdev-imports.txt @@ -2,5 +2,3 @@ # both fully qualified and a file based syntax are accepted here: # net.minecraft.world.level.entity.LevelEntityGetterAdapter # net/minecraft/world/level/entity/LevelEntityGetter.java -net.minecraft.world.damagesource.BadRespawnPointDamage -net.minecraft.world.level.block.RespawnAnchorBlock \ No newline at end of file diff --git a/patches/server/0015-Allow-Vehicle-Passenger-Teleporting-for-Bukkit-API.patch b/patches/server/0015-Allow-Vehicle-Passenger-Teleporting-for-Bukkit-API.patch new file mode 100644 index 0000000..0f2aba3 --- /dev/null +++ b/patches/server/0015-Allow-Vehicle-Passenger-Teleporting-for-Bukkit-API.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 10 Apr 2016 22:50:33 -0400 +Subject: [PATCH] Allow Vehicle/Passenger Teleporting for Bukkit API + +If Bukkit teleport is called, teleport the whole set of entities together and maintain the chain. +Patch from EMC: https://github.com/starlis/empirecraft/blob/f73510d91048d8b01bf8c50b0a2b0d054cb7c0b5/patches/server/0056-Allow-Vehicle-Passenger-Teleporting-for-Bukkit-API.patch + +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 4032f499fd533e8d35d050758ea2358ad6878b94..c35331ea354b7c464677acc3c724d2e22bb375c1 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -819,7 +819,7 @@ public abstract class PlayerList { + + public ServerPlayer moveToWorld(ServerPlayer entityplayer, ServerLevel worldserver, boolean flag, Location location, boolean avoidSuffocation, org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag...respawnFlags) { + // Paper end +- entityplayer.stopRiding(); // CraftBukkit ++ //entityplayer.stopRiding(); // CraftBukkit // Parchment - remove stop riding + this.players.remove(entityplayer); + this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot + entityplayer.getLevel().removePlayerImmediately(entityplayer, Entity.RemovalReason.DISCARDED); +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 94857a736d2a16e8ade286c6f2ddf8bd798008eb..8a5f4d0f01ce1d22790ccf6b11547b5e7cdd99bb 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -217,7 +217,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n + public ImmutableList passengers; + protected int boardingCooldown; + @Nullable +- private Entity vehicle; ++ public Entity vehicle; // Parchment - make public + public Level level; + public double xo; + public double yo; +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index 2712aa554383a3b2b742c945e2f0be7ee96eea69..b3e21bc2347854fb39ba7c25c6de586f084119d4 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.entity; + import com.google.common.base.Function; + import com.google.common.base.Preconditions; + import com.google.common.base.Predicates; ++import com.google.common.collect.ImmutableList; + import com.google.common.collect.Lists; + import java.util.List; + import java.util.Set; +@@ -556,23 +557,103 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + return this.teleport(location, TeleportCause.PLUGIN); + } + ++ // Parchment start - vehicle passenger teleporting ++ private static CraftEntity teleportingEntity; ++ private CraftEntity storedRoot; ++ private ImmutableList storedPassengers; ++ void detachEntities() { ++ if (teleportingEntity == null) { ++ teleportingEntity = this; ++ this.storedRoot = entity.getRootVehicle().getBukkitEntity(); ++ this.storedRoot.detachEntities(); ++ teleportingEntity = null; ++ return; ++ } ++ this.storedPassengers = this.entity.passengers.stream().map(Entity::getBukkitEntity).collect(ImmutableList.toImmutableList()); ++ this.forceEjectPassengers(); ++ for (CraftEntity ent : this.storedPassengers) { ++ ent.detachEntities(); ++ } ++ } ++ void forceEjectPassengers() { ++ for (int i = this.entity.passengers.size() - 1; i >= 0; --i) { ++ Entity passenger = (this.entity.passengers.get(i)); ++ passenger.vehicle = null; ++ } ++ this.entity.passengers = ImmutableList.of(); ++ } ++ void teleportAndReattachEntities(Location location) { ++ if (teleportingEntity == null) { ++ if (this.storedRoot != null) { ++ teleportingEntity = this; ++ this.storedRoot.teleportAndReattachEntities(location); ++ CraftEntity root = this.storedRoot; ++ this.storedRoot = null; ++ root.reattachPassengers(); ++ teleportingEntity = null; ++ } ++ return; ++ } ++ if (!teleportingEntity.equals(this)) { ++ this.teleportEntity(location); ++ } ++ for (CraftEntity ent : this.storedPassengers) { ++ ent.teleportAndReattachEntities(location); ++ } ++ } ++ void teleportEntity(Location location) { ++ if (getWorld().equals(location.getWorld())) { ++ if (this.storedPassengers == null || this.storedPassengers.isEmpty()) { ++ this.entity.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); ++ this.entity.setYHeadRot(location.getYaw()); ++ } else { ++ ServerLevel world = (ServerLevel) this.entity.level; ++ Entity target = this.entity.getType().create(world); ++ if (target == null) { ++ return; ++ } ++ target.restoreFrom(this.entity); ++ target.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); ++ target.setYHeadRot(location.getYaw()); ++ this.entity.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); ++ this.setHandle(target); ++ world.addDuringTeleport(target); ++ } ++ } else { ++ this.entity.teleportTo(((CraftWorld) location.getWorld()).getHandle(), new BlockPos(location.getX(), location.getY(), location.getZ())); ++ } ++ } ++ private void reattachPassengers() { ++ if (this.storedPassengers == null) { ++ return; ++ } ++ this.entity.passengers = this.storedPassengers.stream().map(CraftEntity::getHandle).collect(ImmutableList.toImmutableList()); ++ for (CraftEntity passenger : this.storedPassengers) { ++ passenger.getHandle().vehicle = this.getHandle(); ++ passenger.reattachPassengers(); ++ } ++ this.storedPassengers = null; ++ } ++ // Parchment end - vehicle passenger teleporting + @Override + public boolean teleport(Location location, TeleportCause cause) { + Preconditions.checkArgument(location != null, "location"); + location.checkFinite(); + +- if (this.entity.isVehicle() || this.entity.isRemoved()) { ++ if (this.entity.isRemoved()) { // Parchment + return false; + } + + // If this entity is riding another entity, we must dismount before teleporting. +- this.entity.stopRiding(); ++ //this.entity.stopRiding(); // Parchment ++ this.detachEntities(); // Parchment + + // Let the server handle cross world teleports + if (!location.getWorld().equals(this.getWorld())) { + // Prevent teleportation to an other world during world generation + Preconditions.checkState(!entity.generation, "Cannot teleport entity to an other world during world generation"); + this.entity.teleportTo(((CraftWorld) location.getWorld()).getHandle(), new BlockPos(location.getX(), location.getY(), location.getZ())); ++ this.teleportAndReattachEntities(location); // Parchment + return true; + } + +@@ -581,6 +662,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + // SPIGOT-619: Force sync head rotation also + this.entity.setYHeadRot(location.getYaw()); + ++ this.teleportAndReattachEntities(location); // Parchment + return true; + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 2b8e31ae00e786dfbfbf5bb5228b846752cd2543..1a09026ccbe785a37e935e77e35f629068df4d83 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1021,7 +1021,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + } + + // If this player is riding another entity, we must dismount before teleporting. +- entity.stopRiding(); ++ //entity.stopRiding(); // Parchment + + // SPIGOT-5509: Wakeup, similar to riding + if (this.isSleeping()) { +@@ -1043,12 +1043,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + // Check if the fromWorld and toWorld are the same. + if (fromWorld == toWorld) { ++ this.detachEntities(); // Parchment + entity.connection.teleport(to); + } else { ++ this.detachEntities(); // Parchment + server.getHandle().moveToWorld(entity, toWorld, true, to, !toWorld.paperConfig.disableTeleportationSuffocationCheck); // Paper + } ++ this.teleportAndReattachEntities(location); // Parchment + return true; + } ++ // Parchment start ++ @Override ++ void teleportEntity(Location location) { ++ ServerPlayer entity = this.getHandle(); ++ if (getWorld().equals(location.getWorld())) { ++ entity.connection.teleport(location); ++ } else { ++ ServerLevel toWorld = ((CraftWorld) location.getWorld()).getHandle(); ++ server.getHandle().moveToWorld(entity, toWorld, true, location, !toWorld.paperConfig.disableTeleportationSuffocationCheck); ++ } ++ } ++ // Parchment end + + // Paper start - Ugly workaround for SPIGOT-1915 & GH-114 + @Override