Simplify Player#setInstance

This commit is contained in:
TheMode 2021-07-28 17:28:36 +02:00
parent 5ff7667691
commit 16fbc5ea2c
4 changed files with 18 additions and 23 deletions

View File

@ -518,27 +518,17 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@Override @Override
public CompletableFuture<Void> setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) { public CompletableFuture<Void> setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
Check.argCondition(this.instance == instance, "Instance should be different than the current one"); Check.argCondition(this.instance == instance, "Instance should be different than the current one");
// true if the chunks need to be sent to the client, can be false if the instances share the same chunks (eg SharedInstance) // true if the chunks need to be sent to the client, can be false if the instances share the same chunks (e.g. SharedInstance)
final boolean needWorldRefresh = !InstanceUtils.areLinked(this.instance, instance) || if (!InstanceUtils.areLinked(this.instance, instance) || !spawnPosition.sameChunk(this.position)) {
!spawnPosition.sameChunk(this.position);
if (needWorldRefresh) {
// TODO: Handle player reconnections, must be false in that case too
final boolean firstSpawn = this.instance == null;
// Send the new dimension if player isn't in any instance or if the dimension is different
final DimensionType instanceDimensionType = instance.getDimensionType();
final boolean dimensionChange = dimensionType != instanceDimensionType;
if (dimensionChange) {
sendDimension(instanceDimensionType);
}
return instance.loadOptionalChunk(spawnPosition) return instance.loadOptionalChunk(spawnPosition)
.thenRun(() -> spawnPlayer(instance, spawnPosition, firstSpawn, dimensionChange, true)); .thenRun(() -> spawnPlayer(instance, spawnPosition,
this.instance == null,
!Objects.equals(dimensionType, instance.getDimensionType()), true));
} else { } else {
// The player already has the good version of all the chunks. // The player already has the good version of all the chunks.
// We just need to refresh his entity viewing list and add him to the instance // We just need to refresh his entity viewing list and add him to the instance
spawnPlayer(instance, spawnPosition, false, false, false); return AsyncUtils.VOID_FUTURE
return AsyncUtils.NULL_FUTURE; .thenRun(() -> spawnPlayer(instance, spawnPosition, false, false, false));
} }
} }
@ -586,6 +576,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
} }
if (dimensionChange || firstSpawn) { if (dimensionChange || firstSpawn) {
if (dimensionChange) {
sendDimension(instance.getDimensionType());
}
synchronizePosition(true); // So the player doesn't get stuck synchronizePosition(true); // So the player doesn't get stuck
this.inventory.update(); this.inventory.update();
} }

View File

@ -194,7 +194,7 @@ public class AnvilLoader implements IChunkLoader {
} catch (AnvilException | IOException e) { } catch (AnvilException | IOException e) {
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
EXCEPTION_MANAGER.handleException(e); EXCEPTION_MANAGER.handleException(e);
return AsyncUtils.NULL_FUTURE; return AsyncUtils.VOID_FUTURE;
} }
} }
} }
@ -204,7 +204,7 @@ public class AnvilLoader implements IChunkLoader {
} catch (AnvilException | IOException e) { } catch (AnvilException | IOException e) {
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
EXCEPTION_MANAGER.handleException(e); EXCEPTION_MANAGER.handleException(e);
return AsyncUtils.NULL_FUTURE; return AsyncUtils.VOID_FUTURE;
} }
save(chunk, column); save(chunk, column);
try { try {
@ -213,9 +213,9 @@ public class AnvilLoader implements IChunkLoader {
} catch (IOException e) { } catch (IOException e) {
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
EXCEPTION_MANAGER.handleException(e); EXCEPTION_MANAGER.handleException(e);
return AsyncUtils.NULL_FUTURE; return AsyncUtils.VOID_FUTURE;
} }
return AsyncUtils.NULL_FUTURE; return AsyncUtils.VOID_FUTURE;
} }
private void save(Chunk chunk, ChunkColumn chunkColumn) { private void save(Chunk chunk, ChunkColumn chunkColumn) {

View File

@ -56,7 +56,7 @@ public interface IChunkLoader {
} catch (InterruptedException e) { } catch (InterruptedException e) {
MinecraftServer.getExceptionManager().handleException(e); MinecraftServer.getExceptionManager().handleException(e);
} }
return AsyncUtils.NULL_FUTURE; return AsyncUtils.VOID_FUTURE;
} else { } else {
CompletableFuture<Void> completableFuture = new CompletableFuture<>(); CompletableFuture<Void> completableFuture = new CompletableFuture<>();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();

View File

@ -1,12 +1,14 @@
package net.minestom.server.utils.async; package net.minestom.server.utils.async;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ApiStatus.Internal
public final class AsyncUtils { public final class AsyncUtils {
public static final CompletableFuture<Void> NULL_FUTURE = CompletableFuture.completedFuture(null); public static final CompletableFuture<Void> VOID_FUTURE = CompletableFuture.completedFuture(null);
public static @NotNull CompletableFuture<Void> runAsync(@NotNull Runnable runnable) { public static @NotNull CompletableFuture<Void> runAsync(@NotNull Runnable runnable) {
return CompletableFuture.runAsync(() -> { return CompletableFuture.runAsync(() -> {