diff options
Diffstat (limited to 'patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch')
-rw-r--r-- | patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch new file mode 100644 index 0000000000..112ee6f5a2 --- /dev/null +++ b/patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -0,0 +1,119 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: 2277 <[email protected]> +Date: Tue, 31 Mar 2020 10:33:55 +0100 +Subject: [PATCH] Move player to spawn point if spawn in unloaded world + +If the playerdata contains an invalid world (missing, unloaded, invalid, +etc.), spawn the player at the spawn point of the main world. + +Co-authored-by: Wyatt Childers <[email protected]> +Co-authored-by: Jake Potrebic <[email protected]> + +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index ed0ffff1cfc25f66e1947e40008c6c7259b17019..51426da5f3e7b9f8631880a04cef0a58b00233df 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -197,6 +197,7 @@ public abstract class PlayerList { + } + + Optional<CompoundTag> optional = this.load(player); // CraftBukkit - decompile error ++ ResourceKey<Level> resourcekey = null; // Paper + // CraftBukkit start - Better rename detection + if (optional.isPresent()) { + CompoundTag nbttagcompound = optional.get(); +@@ -206,19 +207,47 @@ public abstract class PlayerList { + } + } + // CraftBukkit end +- ResourceKey<Level> resourcekey = (ResourceKey) optional.flatMap((nbttagcompound) -> { ++ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found ++ boolean[] invalidPlayerWorld = {false}; ++ bukkitData: if (optional.isPresent()) { ++ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds ++ final org.bukkit.World bWorld; ++ if (optional.get().contains("WorldUUIDMost") && optional.get().contains("WorldUUIDLeast")) { ++ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(optional.get().getLong("WorldUUIDMost"), optional.get().getLong("WorldUUIDLeast"))); ++ } else if (optional.get().contains("world", net.minecraft.nbt.Tag.TAG_STRING)) { // Paper - legacy bukkit world name ++ bWorld = org.bukkit.Bukkit.getServer().getWorld(optional.get().getString("world")); ++ } else { ++ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section ++ } ++ if (bWorld != null) { ++ resourcekey = ((CraftWorld) bWorld).getHandle().dimension(); ++ } else { ++ resourcekey = Level.OVERWORLD; ++ invalidPlayerWorld[0] = true; ++ } ++ } ++ if (resourcekey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data ++ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers ++ resourcekey = optional.flatMap((nbttagcompound) -> { ++ // Paper end + DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); // CraftBukkit - decompile error + Logger logger = PlayerList.LOGGER; + + Objects.requireNonNull(logger); +- return dataresult.resultOrPartial(logger::error); +- }).orElse(player.serverLevel().dimension()); // CraftBukkit - SPIGOT-7507: If no dimension, fall back to existing dimension loaded from "WorldUUID", which in turn defaults to World.OVERWORLD ++ // Paper start - reset to main world spawn if no valid world is found ++ final Optional<ResourceKey<Level>> result = dataresult.resultOrPartial(logger::error); ++ invalidPlayerWorld[0] = result.isEmpty(); ++ return result; ++ }).orElse(Level.OVERWORLD); // Paper - revert to vanilla default main world, this isn't an "invalid world" since no player data existed ++ } ++ // Paper end + ServerLevel worldserver = this.server.getLevel(resourcekey); + ServerLevel worldserver1; + + if (worldserver == null) { + PlayerList.LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey); + worldserver1 = this.server.overworld(); ++ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found + } else { + worldserver1 = worldserver; + } +@@ -226,6 +255,10 @@ public abstract class PlayerList { + // Paper start - Entity#getEntitySpawnReason + if (optional.isEmpty()) { + player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login ++ // Paper start - reset to main world spawn if first spawn or invalid world ++ } ++ if (optional.isEmpty() || invalidPlayerWorld[0]) { ++ // Paper end - reset to main world spawn if first spawn or invalid world + player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); + } + // Paper end - Entity#getEntitySpawnReason +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 981b4d28f5f8c614b623f1482551d0f9281807f6..61ae5553a22adc84acbe2962632b8f564ed80d88 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -2386,27 +2386,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + // CraftBukkit end + +- // CraftBukkit start - Reset world +- if (this instanceof ServerPlayer) { +- Server server = Bukkit.getServer(); +- org.bukkit.World bworld = null; +- +- // TODO: Remove World related checks, replaced with WorldUID +- String worldName = nbt.getString("world"); +- +- if (nbt.contains("WorldUUIDMost") && nbt.contains("WorldUUIDLeast")) { +- UUID uid = new UUID(nbt.getLong("WorldUUIDMost"), nbt.getLong("WorldUUIDLeast")); +- bworld = server.getWorld(uid); +- } else { +- bworld = server.getWorld(worldName); +- } +- +- if (bworld == null) { +- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getLevel(Level.OVERWORLD).getWorld(); +- } +- +- ((ServerPlayer) this).setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle()); +- } ++ // CraftBukkit start ++ // Paper - move world parsing/loading to PlayerList#placeNewPlayer + this.getBukkitEntity().readBukkitValues(nbt); + if (nbt.contains("Bukkit.invisible")) { + boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible"); |