Improve cross-world teleportation handling

By: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot 2024-06-23 16:45:29 +10:00
parent 477394d314
commit 5d025bbee8
3 changed files with 41 additions and 23 deletions

View File

@ -83,8 +83,8 @@
+ this.displayName = this.getScoreboardName();
+ this.bukkitPickUpLoot = true;
+ this.maxHealthCache = this.getMaxHealth();
+ }
+
}
+ // Use method to resend items in hands in case of client desync, because the item use got cancelled.
+ // For example, when cancelling the leash event
+ public void resendItemInHands() {
@ -130,9 +130,9 @@
+ }
+
+ return blockposition;
}
+ }
+ // CraftBukkit end
+
@Override
public BlockPosition adjustSpawnLocation(WorldServer worldserver, BlockPosition blockposition) {
AxisAlignedBB axisalignedbb = this.getDimensions(EntityPose.STANDING).makeBoundingBox(Vec3D.ZERO);
@ -457,11 +457,11 @@
} else {
- return new DimensionTransition(this.server.overworld(), this, dimensiontransition_a);
+ dimensionTransition = new DimensionTransition(this.server.overworld(), this, dimensiontransition_a); // CraftBukkit
}
+ }
+ // CraftBukkit start
+ if (reason == null) {
+ return dimensionTransition;
+ }
}
+
+ Player respawnPlayer = this.getBukkitEntity();
+ Location location = CraftLocation.toBukkit(dimensionTransition.pos(), dimensionTransition.newLevel().getWorld(), dimensionTransition.yRot(), dimensionTransition.xRot());
@ -913,6 +913,24 @@
}
@Override
@@ -1433,7 +1832,7 @@
this.gameMode.setGameModeForPlayer(entityplayer.gameMode.getGameModeForPlayer(), entityplayer.gameMode.getPreviousGameModeForPlayer());
this.onUpdateAbilities();
this.getAttributes().assignBaseValues(entityplayer.getAttributes());
- this.setHealth(this.getMaxHealth());
+ // this.setHealth(this.getMaxHealth()); // CraftBukkit
if (flag) {
this.getInventory().replaceWith(entityplayer.getInventory());
this.setHealth(entityplayer.getHealth());
@@ -1443,7 +1842,7 @@
while (iterator.hasNext()) {
MobEffect mobeffect = (MobEffect) iterator.next();
- this.addEffect(new MobEffect(mobeffect));
+ // this.addEffect(new MobEffect(mobeffect)); // CraftBukkit
}
this.experienceLevel = entityplayer.experienceLevel;
@@ -1465,7 +1864,7 @@
this.lastSentExp = -1;
this.lastSentHealth = -1.0F;

View File

@ -461,7 +461,7 @@
UUID uuid = gameprofile.getId();
Set<EntityPlayer> set = Sets.newIdentityHashSet();
Iterator iterator = this.players.iterator();
@@ -469,22 +651,42 @@
@@ -469,22 +651,41 @@
}
return !set.isEmpty();
@ -488,7 +488,6 @@
+ EntityPlayer entityplayer1 = entityplayer;
+ World fromWorld = entityplayer.level();
+ entityplayer.wonGame = false;
+ entityplayer.portalProcess = null; // CraftBukkit - SPIGOT-7785: there is no need to carry this over as it contains the old world/location
+ // CraftBukkit end
entityplayer1.connection = entityplayer.connection;
@ -505,7 +504,7 @@
Iterator iterator = entityplayer.getTags().iterator();
@@ -494,11 +696,26 @@
@@ -494,11 +695,26 @@
entityplayer1.addTag(s);
}
@ -533,7 +532,7 @@
}
int i = flag ? 1 : 0;
@@ -506,17 +723,19 @@
@@ -506,17 +722,19 @@
WorldData worlddata = worldserver1.getLevelData();
entityplayer1.connection.send(new PacketPlayOutRespawn(entityplayer1.createCommonSpawnInfo(worldserver1), (byte) i));
@ -558,7 +557,7 @@
entityplayer1.setHealth(entityplayer1.getHealth());
if (!flag) {
BlockPosition blockposition = BlockPosition.containing(dimensiontransition.pos());
@@ -526,6 +745,27 @@
@@ -526,6 +744,27 @@
entityplayer1.connection.send(new PacketPlayOutNamedSoundEffect(SoundEffects.RESPAWN_ANCHOR_DEPLETE, SoundCategory.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F, worldserver.getRandom().nextLong()));
}
}
@ -586,7 +585,7 @@
return entityplayer1;
}
@@ -554,7 +794,18 @@
@@ -554,7 +793,18 @@
public void tick() {
if (++this.sendAllPlayerInfoIn > 600) {
@ -606,7 +605,7 @@
this.sendAllPlayerInfoIn = 0;
}
@@ -571,6 +822,25 @@
@@ -571,6 +821,25 @@
}
@ -632,7 +631,7 @@
public void broadcastAll(Packet<?> packet, ResourceKey<World> resourcekey) {
Iterator iterator = this.players.iterator();
@@ -649,7 +919,7 @@
@@ -649,7 +918,7 @@
}
public void deop(GameProfile gameprofile) {
@ -641,7 +640,7 @@
EntityPlayer entityplayer = this.getPlayer(gameprofile.getId());
if (entityplayer != null) {
@@ -673,6 +943,7 @@
@@ -673,6 +942,7 @@
entityplayer.connection.send(new PacketPlayOutEntityStatus(entityplayer, b0));
}
@ -649,7 +648,7 @@
this.server.getCommands().sendCommands(entityplayer);
}
@@ -703,6 +974,12 @@
@@ -703,6 +973,12 @@
for (int i = 0; i < this.players.size(); ++i) {
EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
@ -662,7 +661,7 @@
if (entityplayer != entityhuman && entityplayer.level().dimension() == resourcekey) {
double d4 = d0 - entityplayer.getX();
double d5 = d1 - entityplayer.getY();
@@ -742,15 +1019,19 @@
@@ -742,15 +1018,19 @@
public void reloadWhiteList() {}
public void sendLevelInfo(EntityPlayer entityplayer, WorldServer worldserver) {
@ -686,7 +685,7 @@
}
entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.LEVEL_CHUNKS_LOAD_START, 0.0F));
@@ -759,8 +1040,16 @@
@@ -759,8 +1039,16 @@
public void sendAllPlayerInfo(EntityPlayer entityplayer) {
entityplayer.inventoryMenu.sendAllDataToRemote();
@ -704,7 +703,7 @@
}
public int getPlayerCount() {
@@ -816,12 +1105,22 @@
@@ -816,12 +1104,22 @@
}
public void removeAll() {
@ -729,7 +728,7 @@
public void broadcastSystemMessage(IChatBaseComponent ichatbasecomponent, boolean flag) {
this.broadcastSystemMessage(ichatbasecomponent, (entityplayer) -> {
return ichatbasecomponent;
@@ -879,16 +1178,23 @@
@@ -879,16 +1177,23 @@
return playerchatmessage.hasSignature() && !playerchatmessage.hasExpiredServer(Instant.now());
}
@ -757,7 +756,7 @@
Path path = file2.toPath();
if (FileUtils.isPathNormalized(path) && FileUtils.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
@@ -897,7 +1203,7 @@
@@ -897,7 +1202,7 @@
}
serverstatisticmanager = new ServerStatisticManager(this.server, file1);
@ -766,7 +765,7 @@
}
return serverstatisticmanager;
@@ -905,13 +1211,13 @@
@@ -905,13 +1210,13 @@
public AdvancementDataPlayer getPlayerAdvancements(EntityPlayer entityplayer) {
UUID uuid = entityplayer.getUUID();
@ -782,7 +781,7 @@
}
advancementdataplayer.setPlayer(entityplayer);
@@ -962,13 +1268,20 @@
@@ -962,13 +1267,20 @@
}
public void reloadResources() {

View File

@ -1075,6 +1075,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (fromWorld == toWorld) {
entity.connection.teleport(to);
} else {
entity.portalProcess = null; // SPIGOT-7785: there is no need to carry this over as it contains the old world/location and we might run into trouble if there is a portal in the same spot in both worlds
// The respawn reason should never be used if the passed location is non null.
server.getHandle().respawn(entity, true, Entity.RemovalReason.CHANGED_DIMENSION, null, to);
}