eff22eb054
Looks like they would not have been removed if they disconnected during the chunk load, preventing the world from being unloaded.
199 Zeilen
11 KiB
Diff
199 Zeilen
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
|
Date: Sun, 5 Sep 2021 12:15:59 -0400
|
|
Subject: [PATCH] More Teleport API
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index 13c253b1d7f6d4713135baba2bc2ad9cd84224f8..0e365529695321ab2b164c75d4c67bdd2f51492d 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -1729,11 +1729,17 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
|
return false; // CraftBukkit - Return event status
|
|
}
|
|
|
|
- PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
|
|
+ // Paper start - Teleport API
|
|
+ Set<io.papermc.paper.entity.RelativeTeleportFlag> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.RelativeTeleportFlag.class);
|
|
+ for (net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument relativeArgument : set) {
|
|
+ relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument));
|
|
+ }
|
|
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, flag, java.util.Set.copyOf(relativeFlags));
|
|
+ // Paper end
|
|
this.cserver.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled() || !to.equals(event.getTo())) {
|
|
- set.clear(); // Can't relative teleport
|
|
+ //set.clear(); // Can't relative teleport // Paper - Teleport API: Now you can!
|
|
to = event.isCancelled() ? event.getFrom() : event.getTo();
|
|
d0 = to.getX();
|
|
d1 = to.getY();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
index 2a6c67634c31c332102d24bef293da1bacd0c000..b80cc0938b2b3928f4450f1314a9fbd7ea9c116b 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
@@ -571,15 +571,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
|
|
|
@Override
|
|
public boolean teleport(Location location, TeleportCause cause) {
|
|
+ // Paper start - Teleport passenger API
|
|
+ return teleport(location, cause, false);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean teleport(Location location, TeleportCause cause, boolean ignorePassengers, boolean dismount) {
|
|
+ // Paper end
|
|
Preconditions.checkArgument(location != null, "location cannot be null");
|
|
location.checkFinite();
|
|
+ // Paper start - Teleport passenger API
|
|
+ // Don't allow teleporting between worlds while keeping passengers
|
|
+ if (ignorePassengers && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Don't allow to teleport between worlds if remaining on vehicle
|
|
+ if (!dismount && this.entity.isPassenger() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
- if (this.entity.isVehicle() || this.entity.isRemoved()) {
|
|
+ if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API
|
|
return false;
|
|
}
|
|
|
|
// If this entity is riding another entity, we must dismount before teleporting.
|
|
- this.entity.stopRiding();
|
|
+ if (dismount) this.entity.stopRiding(); // Paper - Teleport passenger API
|
|
|
|
// Let the server handle cross world teleports
|
|
if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3706c39b4 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -1135,7 +1135,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
|
|
@Override
|
|
public void setRotation(float yaw, float pitch) {
|
|
- throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead.");
|
|
+ // Paper start - Teleport API
|
|
+ Location targetLocation = this.getEyeLocation();
|
|
+ targetLocation.setYaw(yaw);
|
|
+ targetLocation.setPitch(pitch);
|
|
+
|
|
+ org.bukkit.util.Vector direction = targetLocation.getDirection();
|
|
+ targetLocation.add(direction);
|
|
+ this.lookAt(targetLocation, io.papermc.paper.entity.LookAnchor.EYES);
|
|
+ // Paper end
|
|
}
|
|
|
|
// Paper start - Chunk priority
|
|
@@ -1150,8 +1158,79 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
|
|
@Override
|
|
public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) {
|
|
+ // Paper start - Teleport API
|
|
+ return this.teleport(location, cause, false);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause, boolean ignorePassengers, boolean dismount) {
|
|
+ return this.teleport(location, cause, ignorePassengers, dismount, new io.papermc.paper.entity.RelativeTeleportFlag[0]);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor, @NotNull io.papermc.paper.entity.LookAnchor entityAnchor) {
|
|
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), ((CraftEntity) entity).getHandle(), toNmsAnchor(entityAnchor));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void lookAt(double x, double y, double z, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor) {
|
|
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), new Vec3(x, y, z));
|
|
+ }
|
|
+
|
|
+ public static net.minecraft.commands.arguments.EntityAnchorArgument.Anchor toNmsAnchor(io.papermc.paper.entity.LookAnchor nmsAnchor) {
|
|
+ return switch (nmsAnchor) {
|
|
+ case EYES -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.EYES;
|
|
+ case FEET -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.FEET;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static io.papermc.paper.entity.LookAnchor toApiAnchor(net.minecraft.commands.arguments.EntityAnchorArgument.Anchor playerAnchor) {
|
|
+ return switch (playerAnchor) {
|
|
+ case EYES -> io.papermc.paper.entity.LookAnchor.EYES;
|
|
+ case FEET -> io.papermc.paper.entity.LookAnchor.FEET;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument toNmsRelativeFlag(io.papermc.paper.entity.RelativeTeleportFlag apiFlag) {
|
|
+ return switch (apiFlag) {
|
|
+ case X -> net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.X;
|
|
+ case Y -> net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.Y;
|
|
+ case Z -> net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.Z;
|
|
+ case PITCH -> net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.X_ROT;
|
|
+ case YAW -> net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.Y_ROT;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static io.papermc.paper.entity.RelativeTeleportFlag toApiRelativeFlag(net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument nmsFlag) {
|
|
+ return switch (nmsFlag) {
|
|
+ case X -> io.papermc.paper.entity.RelativeTeleportFlag.X;
|
|
+ case Y -> io.papermc.paper.entity.RelativeTeleportFlag.Y;
|
|
+ case Z -> io.papermc.paper.entity.RelativeTeleportFlag.Z;
|
|
+ case X_ROT -> io.papermc.paper.entity.RelativeTeleportFlag.PITCH;
|
|
+ case Y_ROT -> io.papermc.paper.entity.RelativeTeleportFlag.YAW;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, boolean ignorePassengers, boolean dismount, io.papermc.paper.entity.RelativeTeleportFlag... flags) {
|
|
+ var relativeArguments = java.util.EnumSet.noneOf(net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket.RelativeArgument.class);
|
|
+ for (io.papermc.paper.entity.RelativeTeleportFlag flag : flags) {
|
|
+ relativeArguments.add(toNmsRelativeFlag(flag));
|
|
+ }
|
|
+ // Paper end - Teleport API
|
|
Preconditions.checkArgument(location != null, "location");
|
|
Preconditions.checkArgument(location.getWorld() != null, "location.world");
|
|
+ // Paper start - Teleport passenger API
|
|
+ // Don't allow teleporting between worlds while keeping passengers
|
|
+ if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Don't allow to teleport between worlds if remaining on vehicle
|
|
+ if (!dismount && entity.isPassenger() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
location.checkFinite();
|
|
|
|
ServerPlayer entity = this.getHandle();
|
|
@@ -1164,7 +1243,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
return false;
|
|
}
|
|
|
|
- if (entity.isVehicle()) {
|
|
+ if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API
|
|
return false;
|
|
}
|
|
|
|
@@ -1182,7 +1261,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
}
|
|
|
|
// If this player is riding another entity, we must dismount before teleporting.
|
|
- entity.stopRiding();
|
|
+ if (dismount) entity.stopRiding(); // Paper - Teleport API
|
|
|
|
// SPIGOT-5509: Wakeup, similar to riding
|
|
if (this.isSleeping()) {
|
|
@@ -1204,7 +1283,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
|
|
// Check if the fromWorld and toWorld are the same.
|
|
if (fromWorld == toWorld) {
|
|
- entity.connection.teleport(to);
|
|
+ entity.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), relativeArguments, dismount); // Paper - Teleport API
|
|
} else {
|
|
server.getHandle().respawn(entity, toWorld, true, to, !toWorld.paperConfig().environment.disableTeleportationSuffocationCheck); // Paper
|
|
}
|