From 5a186c986278af1e8f8c485f5b37c82a6a752b66 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Dec 2024 22:09:07 +0800 Subject: [PATCH] feat: find suitable pos in virtual thread --- .../java/org/allaymc/api/world/World.java | 8 ++++++- .../org/allaymc/server/world/AllayWorld.java | 23 ++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/org/allaymc/api/world/World.java b/api/src/main/java/org/allaymc/api/world/World.java index 403b619eb..031d68f8a 100644 --- a/api/src/main/java/org/allaymc/api/world/World.java +++ b/api/src/main/java/org/allaymc/api/world/World.java @@ -2,6 +2,7 @@ import org.allaymc.api.entity.interfaces.EntityPlayer; import org.allaymc.api.scheduler.Scheduler; +import org.allaymc.api.scheduler.TaskCreator; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.jetbrains.annotations.UnmodifiableView; @@ -14,7 +15,7 @@ * * @author daoge_cmd */ -public interface World { +public interface World extends TaskCreator { /** * Get the thread which the world is running on. * @@ -167,4 +168,9 @@ default void broadcastPacket(BedrockPacket packet) { * Set the weather to {@link Weather#CLEAR}. */ void clearWeather(); + + @Override + default boolean isValid() { + return isRunning(); + } } diff --git a/server/src/main/java/org/allaymc/server/world/AllayWorld.java b/server/src/main/java/org/allaymc/server/world/AllayWorld.java index b89eaac18..d7ea93427 100644 --- a/server/src/main/java/org/allaymc/server/world/AllayWorld.java +++ b/server/src/main/java/org/allaymc/server/world/AllayWorld.java @@ -173,18 +173,25 @@ protected void checkFirstTick() { } isFirstTick = false; + var overworld = getOverWorld(); if (Server.SETTINGS.worldSettings().loadSpawnPointChunks()) { // Add spawn point chunk loader - getOverWorld().getChunkService().addChunkLoader(new SpawnPointChunkLoader()); + overworld.getChunkService().addChunkLoader(new SpawnPointChunkLoader()); } - if (!isSafeStandingPos(new Position3i(worldData.getSpawnPoint(), getOverWorld()))) { - var newSpawnPoint = getOverWorld().findSuitableGroundPosAround(this::isSafeStandingPos, 0, 0, 32); - if (newSpawnPoint == null) { - log.warn("Cannot find a safe spawn point in the overworld dimension of world {}", worldData.getName()); - newSpawnPoint = new Vector3i(0, getOverWorld().getHeight(0, 0) + 1, 0); - } - worldData.setSpawnPoint(newSpawnPoint); + if (!isSafeStandingPos(new Position3i(worldData.getSpawnPoint(), overworld))) { + Thread.ofVirtual().name("Spawn Point Finding Thread - " + worldData.getName()).start(() -> { + var newSpawnPoint = overworld.findSuitableGroundPosAround(this::isSafeStandingPos, 0, 0, 32); + if (newSpawnPoint == null) { + log.warn("Cannot find a safe spawn point in the overworld dimension of world {}", worldData.getName()); + newSpawnPoint = new Vector3i(0, overworld.getHeight(0, 0) + 1, 0); + } + var finalNewSpawnPoint = newSpawnPoint; + overworld.getWorld().getScheduler().runLater(this, () -> { + // Set new spawn point in world thread as world data object is not thread-safe + worldData.setSpawnPoint(finalNewSpawnPoint); + }); + }); } }