2021-06-11 14:02:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2277 <38501234+2277@users.noreply.github.com>
Date: Tue, 31 Mar 2020 10:33:55 +0100
Subject: [PATCH] Move player to spawn point if spawn in unloaded world
2023-11-04 22:11:55 +01:00
If the playerdata contains an invalid world (missing, unloaded, invalid,
etc.), spawn the player at the spawn point of the main world.
2021-06-11 14:02:28 +02:00
2023-11-04 22:11:55 +01:00
Co-authored-by: Wyatt Childers <wchilders@nearce.com>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
2024-11-04 18:42:38 +01:00
index ac5725230b04bc1a333863e251fe86580f909ea9..54de4e701adea123c0fdfb5787e951699305bb81 100644
2023-11-04 22:11:55 +01:00
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
2024-10-27 18:11:15 +01:00
@@ -197,6 +197,7 @@ public abstract class PlayerList {
2023-11-04 22:11:55 +01:00
}
2024-04-24 08:44:48 +02:00
Optional<CompoundTag> optional = this.load(player); // CraftBukkit - decompile error
2023-11-04 22:11:55 +01:00
+ ResourceKey<Level> resourcekey = null; // Paper
// CraftBukkit start - Better rename detection
2024-04-24 08:44:48 +02:00
if (optional.isPresent()) {
CompoundTag nbttagcompound = optional.get();
2024-10-27 18:11:15 +01:00
@@ -206,19 +207,47 @@ public abstract class PlayerList {
2024-04-24 08:44:48 +02:00
}
2023-11-04 22:11:55 +01:00
}
// CraftBukkit end
2024-04-24 08:44:48 +02:00
- ResourceKey<Level> resourcekey = (ResourceKey) optional.flatMap((nbttagcompound) -> {
2023-11-04 22:11:55 +01:00
+ // 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
2024-04-24 08:44:48 +02:00
+ boolean[] invalidPlayerWorld = {false};
+ bukkitData: if (optional.isPresent()) {
2023-11-04 22:11:55 +01:00
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
+ final org.bukkit.World bWorld;
2024-04-24 08:44:48 +02:00
+ 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"));
2023-11-04 22:11:55 +01:00
+ } 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;
2024-04-24 08:44:48 +02:00
+ invalidPlayerWorld[0] = true;
2023-11-04 22:11:55 +01:00
+ }
+ }
+ 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
2024-04-24 08:44:48 +02:00
+ resourcekey = optional.flatMap((nbttagcompound) -> {
+ // Paper end
2023-11-04 22:11:55 +01:00
DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); // CraftBukkit - decompile error
Logger logger = PlayerList.LOGGER;
Objects.requireNonNull(logger);
2024-04-24 08:44:48 +02:00
- 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
2023-11-04 22:11:55 +01:00
+ // Paper start - reset to main world spawn if no valid world is found
+ final Optional<ResourceKey<Level>> result = dataresult.resultOrPartial(logger::error);
2024-04-24 08:44:48 +02:00
+ 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;
2023-11-04 22:11:55 +01:00
if (worldserver == null) {
2024-04-24 08:44:48 +02:00
PlayerList.LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey);
2023-11-04 22:11:55 +01:00
worldserver1 = this.server.overworld();
2024-04-24 08:44:48 +02:00
+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found
2023-11-04 22:11:55 +01:00
} else {
worldserver1 = worldserver;
}
2024-10-27 18:11:15 +01:00
@@ -226,6 +255,10 @@ public abstract class PlayerList {
2024-01-21 13:56:22 +01:00
// Paper start - Entity#getEntitySpawnReason
2024-04-24 08:44:48 +02:00
if (optional.isEmpty()) {
2023-11-04 22:11:55 +01:00
player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
2024-01-21 12:11:43 +01:00
+ // Paper start - reset to main world spawn if first spawn or invalid world
2023-11-04 22:11:55 +01:00
+ }
2024-04-24 08:44:48 +02:00
+ if (optional.isEmpty() || invalidPlayerWorld[0]) {
2024-01-21 12:11:43 +01:00
+ // Paper end - reset to main world spawn if first spawn or invalid world
2024-06-13 22:14:13 +02:00
player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
2023-11-04 22:11:55 +01:00
}
2024-01-21 13:56:22 +01:00
// Paper end - Entity#getEntitySpawnReason
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
2024-11-04 18:42:38 +01:00
index 01ea0f81aecbf642d238e6cf6409df2cc83000f3..416e76f2124aba0c9ad6e6ecb052e73a8b743f37 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
2024-11-04 18:42:38 +01:00
@@ -2503,27 +2503,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
2023-11-04 22:11:55 +01:00
}
// CraftBukkit end
2021-06-11 14:02:28 +02:00
2023-11-04 22:11:55 +01:00
- // 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);
- }
-
2021-06-11 14:02:28 +02:00
- if (bworld == null) {
- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getLevel(Level.OVERWORLD).getWorld();
- }
2023-11-04 22:11:55 +01:00
-
- ((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");