Use same position selection during spawn pos selection fallback

If we cannot find a spawn pos in the spawn radius,
use the same fallback logic as when the world type or player's
gamemode does not support spawn selection. This adjusts the spawn
position to not be inside a wall or on water.
This commit is contained in:
Spottedleaf 2024-12-03 01:59:04 -08:00
parent eb5ec0b932
commit f50f36339c
3 changed files with 30 additions and 33 deletions

View File

@ -12412,7 +12412,7 @@ index 585e2b43a0326f0b81597fa1234d3c67c76af550..cb2c0358fb462c4a5ebf94299119c208
for (ServerPlayer player : ServerLevel.this.server.getPlayerList().players) { // Paper - call onEntityRemove for all online players for (ServerPlayer player : ServerLevel.this.server.getPlayerList().players) { // Paper - call onEntityRemove for all online players
player.getBukkitEntity().onEntityRemove(entity); player.getBukkitEntity().onEntityRemove(entity);
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490dff95144a8 100644 index 5a8f396d47577f087abb415c972fd4f51e50faba..cb34ed2fe8d1bc087d57eca39f71286d81c7bb71 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -221,7 +221,7 @@ import org.bukkit.inventory.MainHand; @@ -221,7 +221,7 @@ import org.bukkit.inventory.MainHand;
@ -12424,7 +12424,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25; private static final int FLY_STAT_RECORDING_SPEED = 25;
@@ -543,8 +543,152 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -543,8 +543,149 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
} }
// CraftBukkit end // CraftBukkit end
@ -12526,42 +12526,39 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
+ do { + do {
+ if (attemptCount[0] >= maxAttempts) { + if (attemptCount[0] >= maxAttempts) {
+ BlockPos sharedSpawn = world.getSharedSpawnPos(); + BlockPos sharedSpawn = world.getSharedSpawnPos();
+ BlockPos selected = world.getWorldBorder().clampToBounds((double)sharedSpawn.getX(), (double)sharedSpawn.getY(), (double)sharedSpawn.getZ());
+ +
+ LOGGER.warn("Found no spawn in radius for player '" + player.getName() + "', ignoring radius"); + LOGGER.warn("Found no spawn in radius for player '" + player.getName() + "', ignoring radius");
+ +
+ // this call requires to return a location with loaded chunks, so we need to schedule a load here + selectSpawnWithoutRadius(world, player, sharedSpawn, toComplete);
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(
+ world, selected.getX() >> 4, selected.getZ() >> 4, net.minecraft.world.level.chunk.status.ChunkStatus.FULL,
+ true, ca.spottedleaf.concurrentutil.util.Priority.HIGHER,
+ (unused) -> {
+ completeSpawn(world, selected, toComplete);
+ }
+ );
+ return; + return;
+ } + }
+ } while (!trySpawnOrSchedule(world, player, random, attemptCount, maxAttempts, toComplete)); + } while (!trySpawnOrSchedule(world, player, random, attemptCount, maxAttempts, toComplete));
+ } + }
+ +
+
+ private static void selectSpawnWithoutRadius(ServerLevel world, ServerPlayer player, BlockPos spawn, ca.spottedleaf.concurrentutil.completable.CallbackCompletable<Location> toComplete) {
+ world.loadChunksForMoveAsync(player.getBoundingBoxAt(spawn.getX() + 0.5, spawn.getY(), spawn.getZ() + 0.5),
+ ca.spottedleaf.concurrentutil.util.Priority.HIGHER,
+ (c) -> {
+ BlockPos ret = spawn;
+ while (!player.noCollisionNoLiquid(world, player.getBoundingBoxAt(ret.getX() + 0.5, ret.getY(), ret.getZ() + 0.5)) && ret.getY() < (double)world.getMaxY()) {
+ ret = ret.above();
+ }
+ while (player.noCollisionNoLiquid(world, player.getBoundingBoxAt(ret.getX() + 0.5, ret.getY() - 1, ret.getZ() + 0.5)) && ret.getY() > (double)(world.getMinY() + 1)) {
+ ret = ret.below();
+ }
+ toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(ret), world.levelData.getSpawnAngle(), 0.0f));
+ }
+ );
+ }
+
+ public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.CallbackCompletable<Location> toComplete) { // Folia - region threading + public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.CallbackCompletable<Location> toComplete) { // Folia - region threading
+ BlockPos blockposition = world.getSharedSpawnPos(); + BlockPos blockposition = world.getSharedSpawnPos();
+ +
+ if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit + if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
+ selectSpawn(world, player, player.random, new int[1], 500, toComplete); + selectSpawn(world, player, player.random, new int[1], 500, toComplete);
+ } else { + } else {
+ world.loadChunksForMoveAsync(player.getBoundingBoxAt(blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5), + selectSpawnWithoutRadius(world, player, blockposition, toComplete);
+ ca.spottedleaf.concurrentutil.util.Priority.HIGHER,
+ (c) -> {
+ BlockPos ret = blockposition;
+ while (!player.noCollisionNoLiquid(world, player.getBoundingBoxAt(ret.getX() + 0.5, ret.getY(), ret.getZ() + 0.5)) && ret.getY() < (double)world.getMaxY()) {
+ ret = ret.above();
+ }
+ while (player.noCollisionNoLiquid(world, player.getBoundingBoxAt(ret.getX() + 0.5, ret.getY() - 1, ret.getZ() + 0.5)) && ret.getY() > (double)(world.getMinY() + 1)) {
+ ret = ret.below();
+ }
+ toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(ret), world.levelData.getSpawnAngle(), 0.0f));
+ }
+ );
+ } + }
+ +
+ } + }
@ -12577,7 +12574,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
AABB axisalignedbb = this.getDimensions(Pose.STANDING).makeBoundingBox(Vec3.ZERO); AABB axisalignedbb = this.getDimensions(Pose.STANDING).makeBoundingBox(Vec3.ZERO);
BlockPos blockposition1 = basePos; BlockPos blockposition1 = basePos;
@@ -885,11 +1029,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -885,11 +1026,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
if (worldserver != null) { if (worldserver != null) {
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, worldserver, EntitySpawnReason.LOAD, (entity1) -> { Entity entity = EntityType.loadEntityRecursive(nbttagcompound, worldserver, EntitySpawnReason.LOAD, (entity1) -> {
@ -12598,7 +12595,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
} else { } else {
ServerPlayer.LOGGER.warn("Failed to spawn player ender pearl in level ({}), skipping", optional1.get()); ServerPlayer.LOGGER.warn("Failed to spawn player ender pearl in level ({}), skipping", optional1.get());
} }
@@ -1581,6 +1732,323 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -1581,6 +1729,323 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
} }
@ -12922,7 +12919,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
@Nullable @Nullable
@Override @Override
public ServerPlayer teleport(TeleportTransition teleportTarget) { public ServerPlayer teleport(TeleportTransition teleportTarget) {
@@ -2625,6 +3093,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -2625,6 +3090,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
public void setCamera(@Nullable Entity entity) { public void setCamera(@Nullable Entity entity) {
Entity entity1 = this.getCamera(); Entity entity1 = this.getCamera();
@ -12935,7 +12932,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
this.camera = (Entity) (entity == null ? this : entity); this.camera = (Entity) (entity == null ? this : entity);
if (entity1 != this.camera) { if (entity1 != this.camera) {
// Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
@@ -3118,11 +3592,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -3118,11 +3589,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
} }
public void registerEnderPearl(ThrownEnderpearl enderPearl) { public void registerEnderPearl(ThrownEnderpearl enderPearl) {
@ -12949,7 +12946,7 @@ index 5a8f396d47577f087abb415c972fd4f51e50faba..f2884eefe00a35e19c83e069f65490df
} }
public Set<ThrownEnderpearl> getEnderPearls() { public Set<ThrownEnderpearl> getEnderPearls() {
@@ -3281,7 +3755,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -3281,7 +3752,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.experienceLevel = this.newLevel; this.experienceLevel = this.newLevel;
this.totalExperience = this.newTotalExp; this.totalExperience = this.newTotalExp;
this.experienceProgress = 0; this.experienceProgress = 0;

View File

@ -9,10 +9,10 @@ data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly. some accesses may throw and as such we need to fix this directly.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index f2884eefe00a35e19c83e069f65490dff95144a8..19eb204e5d3cd6ef8f2a31fae32e75dbf07ffb96 100644 index cb34ed2fe8d1bc087d57eca39f71286d81c7bb71..8c4f658ce87ef49d2b46e50d5957933e1b912b82 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -799,7 +799,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -796,7 +796,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.getBukkitEntity().readExtraData(nbt); // CraftBukkit this.getBukkitEntity().readExtraData(nbt); // CraftBukkit
if (this.isSleeping()) { if (this.isSleeping()) {

View File

@ -7,10 +7,10 @@ This allows the player to be re-positioned before logging into
the world without causing thread checks to trip on Folia. the world without causing thread checks to trip on Folia.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 19eb204e5d3cd6ef8f2a31fae32e75dbf07ffb96..68a88928a3aae9d2ea6cd18088ede0a54c31d0d2 100644 index 8c4f658ce87ef49d2b46e50d5957933e1b912b82..fb3ea176726fa01c2ab7220432121db4ad5e54ae 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -925,7 +925,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -922,7 +922,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
if (world instanceof ServerLevel) { if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world; ServerLevel worldserver = (ServerLevel) world;
CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle"); CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle");