World class

Пакет: com.hypixel.hytale.server.core.universe.world

Файл: com/hypixel/hytale/server/core/universe/world/World.java

extends: TickingThread

implements: Executor, ExecutorMetricsRegistry.ExecutorMetric, ChunkAccessor, IWorldChunks, IMessageReceiver

Поля (167)

МодификаторыТипИмя
final float SAVE_INTERVAL
break
break
break
CompletableFuture var1
var1
var1
IResourceStorage var1
Path var1
long var1
MutableDeathConfig var1
String var1
Integer var1
Integer var1
ObjectArrayList var1
int var1
int var1
String var1
UpdateFeatures var1
boolean var1
int var1
PlayerConfig.ArmorVisibilityOption var10
int var10
Message var10
Store var10
PlayerConfigData var10
int var10
Ref var10
Ref var10
Ref var10
int var11
AddPlayerToWorldEvent var11
WorldTimeResource var11
ChunkTracker var11
CompletableFuture var11
BlockSection var11
BlockSection var11
BlockSection var11
int var12
ChunkTracker var12
World var12
Integer var12
Ref var12
int var13
boolean var13
Ref var13
Integer var13
WorldChunk var13
long var14
boolean var14
WorldMapTracker var14
JoinWorld var14
ChunkColumn var14
Vector3d var15
TransformComponent var15
boolean var15
WorldChunk var16
var16
long var16
String var16
HeadRotation var17
CompletableFuture var18
CompletableFuture var19
final ChunkSection var19
CompletableFuture var2
Message var2
Path var2
World var2
Path var2
TimeResource var2
SetUpdateRate var2
World var2
ServerSetPaused var2
boolean var2
Ref var2
Runnable var2
GameplayConfig var2
var2
int var2
World var2
CompletableFuture var20
ComponentType var20
CompletableFuture var21
EntitySection var21
UnknownComponents var24
int var26
int var27
int var28
Holder var29
CompletableFuture var3
IEventDispatcher var3
Message var3
var3
var3
var3
String var3
Object2ObjectOpenHashMap var3
TimeResource var3
Ref var3
Ref var3
Ref var3
Ref var3
long var3
PluginIdentifier var3
ObjectArrayList var3
int var30
int var31
var var32
FillerBlockUtil.ValidationResult var33
BlockType var34
BlockSection var36
BlockPhysics var37
int var39
Path var4
SetTimeDilation var4
WorldChunk var4
WorldChunk var4
WorldChunk var4
Ref var4
PlayerRef var4
Store var4
BlockType var41
Message var5
Holder var5
long var5
PacketHandler var5
StringBuilder var5
IWorldMap var6
Long2ObjectMap var6
HeadRotation var6
Holder var6
TimeResource var6
Holder var6
LongListIterator var6
int var6
int var6
int var6
Message var7
var7
var7
var7
long var7
TransformComponent var7
var7
float var7
DrainPlayerFromWorldEvent var7
long var7
int var7
int var7
int var7
GameplayConfig var8
int var8
Player var8
int var8
UUID var8
int var8
int var8
int var8
CombatConfig var9
int var9
boolean var9
UUID var9
int var9
int var9
CompletableFuture var9
CompletableFuture var9
CompletableFuture var9

Методы (85)

МодификаторыВозвратСигнатура
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Unknown entity")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Entity can't be a Player!")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Unable to spawn entity below the world! -32 < " + var2)
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Player is already in a world")
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Connection of joining player closed before they could be added to the world store")
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Failed to add player ref of joining player to the world store")
abstract throw new RuntimeExceptionthrow new RuntimeException(var2 + " directory exists but this version of the server doesn't support migrating RFF worlds!")
abstract throw new SkipSentryExceptionthrow new SkipSentryException("Failed to load WorldGen!", var3)
abstract throw new SkipSentryExceptionthrow new SkipSentryException("Failed to load WorldGen!", var4)
abstract void applyvoid apply(World var1, T var2, long var3, WorldChunk var5, int var6, int var7, int var8, int var9, int var10, int var11)
public void broadcastFeaturesvoid broadcastFeatures()
public boolean consumeGCHasRunboolean consumeGCHasRun()
private void deleteWorldFromDiskvoid deleteWorldFromDisk()
for for(ClientFeature var7 : ClientFeature.VALUES)
for for(PlayerRef var5 : this.playerRefs)
for for(PlayerRef var6 : var2.playerRefs)
for for(PlayerRef var3 : this.playerRefs)
for for(PlayerRef var5 : var2)
for for(PlayerRef var3 : this.playerRefs)
for for(int var38 = 0; var38 < 32; var38++)
for for(int var40 = 0; var40 < 32; var40++)
for for(int var25 = 0; var25 < 32; var25++)
abstract for for(int var3 = 0; var3 < var1x.size()
public int getBlockpublic int getBlock(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5)
public <T> void getBlockBulkRelative<T> void getBlockBulkRelative(@Nonnull Long2ObjectMap<T> var1, @Nonnull IntUnaryOperator var2, @Nonnull IntUnaryOperator var3, @Nonnull IntUnaryOperator var4, @Nonnull World.GenericBlockBulkUpdater<T> var5)
public int getDaytimeDurationSecondsint getDaytimeDurationSeconds()
public int getFillerpublic int getFiller(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5)
public int getNighttimeDurationSecondsint getNighttimeDurationSeconds()
public int getNonSpectatorPlayerCountint getNonSpectatorPlayerCount()
public int getPlayerCountint getPlayerCount()
public int getRotationIndexpublic int getRotationIndex(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5)
public long getTicklong getTick()
public WorldPathConfig getWorldPathConfigWorldPathConfig getWorldPathConfig()
if if(var2x != null)
if if(!this.isPaused)
if if(this.isTicking && !this.isPaused)
if if(this.isPaused != var1)
if if(var16 == null)
if if(var3 == null)
if if(var3 == null)
if if(var3 == null)
if if(var3 == null)
if if(var1 instanceof Player)
if if(var3 != null)
if if(var7 > var1)
if if(var7 == null && var2 == null)
if if(var7 == null)
if if(var2 != null)
if if(var3 == null)
if if(this.isPaused)
if if(var5)
if if(var6)
if if(var11 != null)
if if(var2 == null)
if if(this == var1)
if if(var14 != null)
if if(var21 != null)
if if(var36 != null)
if if(var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32)
if if(var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32)
if if(var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32)
public boolean isAliveboolean isAlive()
public boolean isCompassUpdatingboolean isCompassUpdating()
public boolean isFeatureEnabledboolean isFeatureEnabled(@Nonnull ClientFeature var1)
public boolean isPausedboolean isPaused()
public boolean isSavingLockedboolean isSavingLocked()
public boolean isTickingboolean isTicking()
public void lockSavingvoid lockSaving()
public void markGCHasRunvoid markGCHasRun()
private void onSetupPlayerJoiningvoid onSetupPlayerJoining(@Nonnull Holder<EntityStore> var1, @Nonnull Player var2, @Nonnull PlayerRef var3, @Nonnull PacketHandler var4, @Nullable Transform var5, boolean var6, boolean var7)
public void registerFeaturevoid registerFeature(@Nonnull ClientFeature var1, boolean var2)
public void setCompassUpdatingvoid setCompassUpdating(boolean var1)
public void setPausedvoid setPaused(boolean var1)
public void setTickingvoid setTicking(boolean var1)
static void setTimeDilationvoid setTimeDilation(float var0, @Nonnull ComponentAccessor<EntityStore> var1)
public void stopIndividualWorldvoid stopIndividualWorld()
public void stopIndividualWorldvoid stopIndividualWorld(Map<UUID, PlayerRef> var1)
abstract super super("WorldThread - " + var1)
switch switch(var33)
public void trackPlayerRefvoid trackPlayerRef(@Nonnull PlayerRef var1)
public void unlockSavingvoid unlockSaving()
public void untrackPlayerRefvoid untrackPlayerRef(@Nonnull PlayerRef var1)
public void updateEntitySeedvoid updateEntitySeed(@Nonnull Store<EntityStore> var1)
public void validatevoid validate(@Nonnull StringBuilder var1, @Nonnull IPrefabBuffer.RawBlockConsumer<Void> var2, @Nonnull EnumSet<ValidationOption> var3)
public void validateDeleteOnRemovevoid validateDeleteOnRemove()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world;

class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.common.plugin.PluginIdentifier;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.IResourceStorage;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.data.unknown.UnknownComponents;
class="kw">import com.hypixel.hytale.event.EventRegistry;
class="kw">import com.hypixel.hytale.event.IEventDispatcher;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.math.block.BlockUtil;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.vector.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Transform;
class="kw">import com.hypixel.hytale.metrics.ExecutorMetricsRegistry;
class="kw">import com.hypixel.hytale.metrics.metric.HistoricMetric;
class="kw">import com.hypixel.hytale.protocol.packets.entities.SetEntitySeed;
class="kw">import com.hypixel.hytale.protocol.packets.player.JoinWorld;
class="kw">import com.hypixel.hytale.protocol.packets.player.SetClientId;
class="kw">import com.hypixel.hytale.protocol.packets.setup.ClientFeature;
class="kw">import com.hypixel.hytale.protocol.packets.setup.SetTimeDilation;
class="kw">import com.hypixel.hytale.protocol.packets.setup.SetUpdateRate;
class="kw">import com.hypixel.hytale.protocol.packets.setup.UpdateFeatures;
class="kw">import com.hypixel.hytale.protocol.packets.setup.ViewRadius;
class="kw">import com.hypixel.hytale.protocol.packets.world.ClearChunks;
class="kw">import com.hypixel.hytale.protocol.packets.world.ServerSetPaused;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.ShutdownReason;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.CombatConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.DeathConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.MutableDeathConfig;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.PlayerConfig;
class="kw">import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
class="kw">import com.hypixel.hytale.server.core.console.ConsoleModule;
class="kw">import com.hypixel.hytale.server.core.entity.Entity;
class="kw">import com.hypixel.hytale.server.core.entity.EntityUtils;
class="kw">import com.hypixel.hytale.server.core.entity.UUIDComponent;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData;
class="kw">import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.DrainPlayerFromWorldEvent;
class="kw">import com.hypixel.hytale.server.core.io.PacketHandler;
class="kw">import com.hypixel.hytale.server.core.modules.entity.EntityModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.Spectating;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker;
class="kw">import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
class="kw">import com.hypixel.hytale.server.core.modules.time.TimeResource;
class="kw">import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
class="kw">import com.hypixel.hytale.server.core.receiver.IMessageReceiver;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.ChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkFlag;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.EntitySection;
class="kw">import com.hypixel.hytale.server.core.universe.world.events.StartWorldEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.lighting.ChunkLightingManager;
class="kw">import com.hypixel.hytale.server.core.universe.world.path.WorldPathConfig;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.resources.DiskResourceStorageProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.IWorldGen;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.WorldGenLoadException;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.IWorldMap;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.WorldMapLoadException;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.WorldMapManager;
class="kw">import com.hypixel.hytale.server.core.util.FillerBlockUtil;
class="kw">import com.hypixel.hytale.server.core.util.MessageUtil;
class="kw">import com.hypixel.hytale.server.core.util.io.FileUtil;
class="kw">import com.hypixel.hytale.server.core.util.thread.TickingThread;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.longs.LongListIterator;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.awt.Color;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Collection;
class="kw">import java.util.Collections;
class="kw">import java.util.Deque;
class="kw">import java.util.EnumMap;
class="kw">import java.util.EnumSet;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Random;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.CompletionException;
class="kw">import java.util.concurrent.CompletionStage;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.CopyOnWriteArrayList;
class="kw">import java.util.concurrent.Executor;
class="kw">import java.util.concurrent.LinkedBlockingDeque;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicBoolean;
class="kw">import java.util.concurrent.atomic.AtomicInteger;
class="kw">import java.util.function.IntUnaryOperator;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class World class="kw">extends TickingThread class="kw">implements Executor, ExecutorMetricsRegistry.ExecutorMetric, ChunkAccessor, IWorldChunks, IMessageReceiver {
   class="kw">public class="kw">static class="kw">final float SAVE_INTERVAL = 10.0F;
   class="kw">public class="kw">static class="kw">final String DEFAULT = "class="kw">default";
   @Nonnull
   class="kw">public class="kw">static class="kw">final ExecutorMetricsRegistry<World> METRICS_REGISTRY = new ExecutorMetricsRegistry<World>()
      .register("Name", var0 -> var0.name, Codec.STRING)
      .register("Alive", var0 -> var0.alive.get(), Codec.BOOLEAN)
      .register("TickLength", TickingThread::getBufferedTickLengthMetricSet, HistoricMetric.METRICS_CODEC)
      .register("EntityStore", World::getEntityStore, EntityStore.METRICS_REGISTRY)
      .register("ChunkStore", World::getChunkStore, ChunkStore.METRICS_REGISTRY);
   @Nonnull
   class="kw">private class="kw">final HytaleLogger logger;
   @Nonnull
   class="kw">private class="kw">final String name;
   @Nonnull
   class="kw">private class="kw">final Path savePath;
   @Nonnull
   class="kw">private class="kw">final WorldConfig worldConfig;
   @Nonnull
   class="kw">private class="kw">final ChunkStore chunkStore = new ChunkStore(this);
   @Nonnull
   class="kw">private class="kw">final EntityStore entityStore = new EntityStore(this);
   @Nonnull
   class="kw">private class="kw">final ChunkLightingManager chunkLighting;
   @Nonnull
   class="kw">private class="kw">final WorldMapManager worldMapManager;
   class="kw">private WorldPathConfig worldPathConfig;
   class="kw">private class="kw">final AtomicBoolean acceptingTasks = new AtomicBoolean(true);
   @Nonnull
   class="kw">private class="kw">final Deque<Runnable> taskQueue = new LinkedBlockingDeque<>();
   @Nonnull
   class="kw">private class="kw">final AtomicBoolean alive = new AtomicBoolean(true);
   @Nonnull
   class="kw">private class="kw">final EventRegistry eventRegistry = new EventRegistry(new CopyOnWriteArrayList<>(), () -> true, null, HytaleServer.get().getEventBus());
   @Nonnull
   class="kw">private class="kw">final WorldNotificationHandler notificationHandler = new WorldNotificationHandler(this);
   class="kw">private boolean isTicking;
   class="kw">private boolean isPaused;
   class="kw">private long tick;
   @Nonnull
   class="kw">private class="kw">final Random random = new Random();
   @Nonnull
   class="kw">private class="kw">final AtomicInteger entitySeed = new AtomicInteger();
   @Nonnull
   class="kw">private class="kw">final Map<UUID, PlayerRef> players = new ConcurrentHashMap<>();
   @Nonnull
   class="kw">private class="kw">final Collection<PlayerRef> playerRefs = Collections.unmodifiableCollection(this.players.values());
   @Nonnull
   class="kw">private class="kw">final Map<ClientFeature, Boolean> features = Collections.synchronizedMap(new EnumMap<>(ClientFeature.class));
   class="kw">private class="kw">volatile boolean gcHasRun;
   class="kw">private class="kw">final AtomicInteger savingLocks = new AtomicInteger(0);

   class="kw">public World(@Nonnull String var1, @Nonnull Path var2, @Nonnull WorldConfig var3) {
      super("WorldThread - " + var1);
      this.name = var1;
      this.logger = HytaleLogger.get("World|" + var1);
      this.savePath = var2;
      this.worldConfig = var3;
      this.logger
         .at(Level.INFO)
         .log("Loading world '%s' with generator type: '%s' and chunk storage: '%s'...", var1, var3.getWorldGenProvider(), var3.getChunkStorageProvider());
      this.worldMapManager = new WorldMapManager(this);
      this.chunkLighting = new ChunkLightingManager(this);
      this.isTicking = var3.isTicking();

      for (ClientFeature var7 : ClientFeature.VALUES) {
         this.features.put(var7, true);
      }

      GameplayConfig var8 = this.getGameplayConfig();
      CombatConfig var9 = var8.getCombatConfig();
      this.features.put(ClientFeature.DisplayHealthBars, var9.isDisplayHealthBars());
      this.features.put(ClientFeature.DisplayCombatText, var9.isDisplayCombatText());
      PlayerConfig.ArmorVisibilityOption var10 = var8.getPlayerConfig().getArmorVisibilityOption();
      this.features.put(ClientFeature.CanHideHelmet, var10.canHideHelmet());
      this.features.put(ClientFeature.CanHideCuirass, var10.canHideCuirass());
      this.features.put(ClientFeature.CanHideGauntlets, var10.canHideGauntlets());
      this.features.put(ClientFeature.CanHidePants, var10.canHidePants());
      this.logger.at(Level.INFO).log("Added world '%s' - Seed: %s, GameTime: %s", var1, Long.toString(var3.getSeed()), var3.getGameTime());
   }

   @Nonnull
   class="kw">public CompletableFuture<World> init() {
      CompletableFuture var1;
      if (this.worldConfig.isSavingConfig()) {
         var1 = Universe.get().getWorldConfigProvider().save(this.savePath, this.worldConfig, this);
      } else {
         var1 = CompletableFuture.completedFuture(null);
      }

      CompletableFuture var2 = CompletableFuture.<World>supplyAsync(() -> {
         try {
            IWorldGen var1 = this.worldConfig.getWorldGenProvider().getGenerator();
            this.chunkStore.setGenerator(var1);
            this.worldConfig.setDefaultSpawnProvider(var1);
            IWorldMap var6 = this.worldConfig.getWorldMapProvider().getGenerator(this);
            this.worldMapManager.setGenerator(var6);
            class="kw">return this;
         } catch (WorldGenLoadException var3) {
            if (this.name.equals(HytaleServer.get().getConfig().getDefaults().getWorld())) {
               Message var5 = Message.translation("client.disconnection.shutdownReason.worldGen.detail").param("detail", var3.getTraceMessage("\n"));
               HytaleServer.get().shutdownServer(ShutdownReason.WORLD_GEN.withMessage(var5));
            }

            throw new SkipSentryException("Failed to load WorldGen!", var3);
         } catch (WorldMapLoadException var4) {
            if (this.name.equals(HytaleServer.get().getConfig().getDefaults().getWorld())) {
               Message var2 = Message.translation("client.disconnection.shutdownReason.worldGen.detail").param("detail", var4.getTraceMessage("\n"));
               HytaleServer.get().shutdownServer(ShutdownReason.WORLD_GEN.withMessage(var2));
            }

            throw new SkipSentryException("Failed to load WorldGen!", var4);
         }
      }).whenComplete((var1x, var2x) -> {
         if (var2x != null) {
            ((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(var2x)).log("Failed to load WorldGen for world '%s'", this.name);
         }
      });
      CompletableFuture var3 = WorldPathConfig.load(this).thenAccept(var1x -> this.worldPathConfig = var1x);
      class="kw">return this.worldConfig.getSpawnProvider() != null
         ? CompletableFuture.allOf(var1, var3).thenApply(var1x -> this)
         : CompletableFuture.allOf(var1, var3).thenCompose(var1x -> var2);
   }

   @Override
   class="kw">protected void onStart() {
      DiskResourceStorageProvider.migrateFiles(this);
      IResourceStorage var1 = this.worldConfig.getResourceStorageProvider().getResourceStorage(this);
      this.chunkStore.start(var1);
      this.entityStore.start(var1);
      this.chunkLighting.start();
      this.worldMapManager.updateTickingState(this.worldMapManager.isStarted());
      Path var2 = this.savePath.resolve("rff");
      if (Files.exists(var2)) {
         throw new RuntimeException(var2 + " directory exists but this version of the server doesn't support migrating RFF worlds!");
      }

      IEventDispatcher var3 = HytaleServer.get().getEventBus().dispatchFor(StartWorldEvent.class, this.name);
      if (var3.hasListener()) {
         var3.dispatch(new StartWorldEvent(this));
      }
   }

   class="kw">public void stopIndividualWorld() {
      this.stopIndividualWorld(this.players);
   }

   class="kw">public void stopIndividualWorld(Map<UUID, PlayerRef> var1) {
      this.logger.at(Level.INFO).log("Removing individual world: %s", this.name);
      World var2 = Universe.get().getDefaultWorld();
      if (var2 != null && !var2.equals(this)) {
         Message var7;
         if (this.getFailureException() == null) {
            var7 = Message.translation("server.universe.worldRemoved");
         } else if (this.getPossibleFailureCause() == null) {
            var7 = Message.translation("server.universe.worldCrash.unknown");
         } else {
            var7 = Message.translation("server.universe.worldCrash.mod").param("mod", this.getPossibleFailureCause().toString());
         }

         var7.color(Color.RED);

         for (PlayerRef var9 : var1.values()) {
            var9.sendMessage(var7);
         }

         if (this.isInThread()) {
            this.drainPlayersTo(var2, var1.values()).join();
         } else {
            CompletableFuture.<CompletableFuture<Void>>supplyAsync(() -> this.drainPlayersTo(var2, var1.values()), this)
               .thenCompose(var0 -> (CompletionStage<Void>)var0)
               .join();
         }
      } else {
         Message var3;
         if (this.getFailureException() == null) {
            var3 = Message.translation("server.general.disconnect.worldRemoved");
         } else if (this.getPossibleFailureCause() == null) {
            var3 = Message.translation("server.general.disconnect.worldCrashed");
         } else {
            var3 = Message.translation("server.general.disconnect.worldCrashedCause").param("cause", this.getPossibleFailureCause().toString());
         }

         for (PlayerRef var5 : var1.values()) {
            var5.getPacketHandler().disconnect(var3);
         }
      }

      if (this.alive.getAndSet(false)) {
         try {
            super.stop();
         } catch (Throwable var6) {
            ((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var6)).log("Exception while shutting down world:");
         }
      }
   }

   class="kw">public void validateDeleteOnRemove() {
      if (this.worldConfig.isDeleteOnRemove()) {
         try {
            this.deleteWorldFromDisk();
         } catch (Throwable var2) {
            ((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var2)).log("Exception while deleting world on remove:");
         }
      }
   }

   class="kw">private void deleteWorldFromDisk() class="kw">throws IOException {
      Path var1 = this.savePath;
      Path var2 = var1.getFileName();
      String var3 = var2 + "_del" + UUID.randomUUID().toString().substring(0, 8);
      Path var4 = Universe.get().getWorldsDeletedPath().resolve(var3);
      Files.createDirectories(var4.getParent());
      FileUtil.atomicMove(var1, var4);
      FileUtil.deleteDirectory(var4);
   }

   @Override
   class="kw">protected boolean isIdle() {
      class="kw">return this.players.isEmpty();
   }

   @Override
   class="kw">protected void tick(float var1) {
      if (this.alive.get()) {
         TimeResource var2 = this.entityStore.getStore().getResource(TimeResource.getResourceType());
         var1 *= var2.getTimeDilationModifier();
         AssetRegistry.ASSET_LOCK.readLock().lock();

         try {
            this.consumeTaskQueue();
            if (!this.isPaused) {
               this.entityStore.getStore().tick(var1);
            } else {
               this.entityStore.getStore().pausedTick(var1);
            }

            if (this.isTicking && !this.isPaused) {
               this.chunkStore.getStore().tick(var1);
            } else {
               this.chunkStore.getStore().pausedTick(var1);
            }

            this.consumeTaskQueue();
         } class="kw">finally {
            AssetRegistry.ASSET_LOCK.readLock().unlock();
         }

         this.tick++;
      }
   }

   @Override
   class="kw">protected void onShutdown() {
      this.logger.at(Level.INFO).log("Stopping world %s...", this.name);
      this.logger.at(Level.INFO).log("Stopping background threads...");
      long var1 = System.nanoTime();

      while (this.chunkLighting.interrupt() || this.worldMapManager.interrupt()) {
         this.consumeTaskQueue();
         if (System.nanoTime() - var1 > 5000000000L) {
            break;
         }
      }

      this.chunkLighting.stop();
      this.worldMapManager.stop();
      this.logger.at(Level.INFO).log("Removing players...");
      Object2ObjectOpenHashMap var3 = new Object2ObjectOpenHashMap(this.players);

      for (PlayerRef var5 : this.playerRefs) {
         if (var5.getReference() != null) {
            var5.removeFromStore();
         }
      }

      this.consumeTaskQueue();
      this.logger.at(Level.INFO).log("Waiting for loading chunks...");
      this.chunkStore.waitForLoadingChunks();

      try {
         this.logger.at(Level.INFO).log("Shutting down stores...");
         HytaleServer.get().reportSingleplayerStatus(Message.translation("client.gameLoadingView.status.savingWorld").param("name", this.name));
         this.chunkStore.shutdown();
         this.consumeTaskQueue();
         this.entityStore.shutdown();
         this.consumeTaskQueue();
         this.eventRegistry.shutdownAndCleanup(true);
      } class="kw">finally {
         this.logger.at(Level.INFO).log("Saving Config...");
         if (this.worldConfig.isSavingConfig()) {
            Universe.get().getWorldConfigProvider().save(this.savePath, this.worldConfig, this).join();
         }
      }

      this.acceptingTasks.set(false);
      if (this.alive.getAndSet(false)) {
         this.stopIndividualWorld(var3);
         Universe.get().removeWorldExceptionally(this.name, var3);
      }

      HytaleServer.get().reportSingleplayerStatus(Message.translation("client.gameLoadingView.status.closingWorld").param("name", this.name));
   }

   @Override
   class="kw">public void setTps(int var1) {
      super.setTps(var1);
      SetUpdateRate var2 = new SetUpdateRate(var1);
      this.entityStore
         .getStore()
         .forEachEntityParallel(
            PlayerRef.getComponentType(), (var1x, var2x, var3) -> var2x.getComponent(var1x, PlayerRef.getComponentType()).getPacketHandler().writeNoCache(var2)
         );
   }

   class="kw">public class="kw">static void setTimeDilation(float var0, @Nonnull ComponentAccessor<EntityStore> var1) {
      World var2 = var1.getExternalData().getWorld();
      if (!(var0 <= 0.01) && !(var0 > 4.0F)) {
         TimeResource var3 = var1.getResource(TimeResource.getResourceType());
         var3.setTimeDilationModifier(var0);
         SetTimeDilation var4 = new SetTimeDilation(var0);

         for (PlayerRef var6 : var2.playerRefs) {
            var6.getPacketHandler().writeNoCache(var4);
         }
      } else {
         throw new IllegalArgumentException("TimeDilation is out of bounds (<=0.01 or >4)");
      }
   }

   @Nonnull
   class="kw">public String getName() {
      class="kw">return this.name;
   }

   class="kw">public boolean isAlive() {
      class="kw">return this.alive.get();
   }

   @Nonnull
   class="kw">public WorldConfig getWorldConfig() {
      class="kw">return this.worldConfig;
   }

   @Nonnull
   class="kw">public DeathConfig getDeathConfig() {
      MutableDeathConfig var1 = this.worldConfig.getDeathConfigOverride();
      class="kw">return var1 != null ? var1 : this.getGameplayConfig().getDeathConfig();
   }

   @Nullable
   class="kw">public String getGameModeTypeOnDeath() {
      String var1 = this.getDeathConfig().getGameModeTypeOnDeath();
      class="kw">return var1 != null ? var1 : HytaleServer.get().getConfig().getDefaults().getGameModeTypeOnDeath();
   }

   class="kw">public int getDaytimeDurationSeconds() {
      Integer var1 = this.worldConfig.getDaytimeDurationSecondsOverride();
      class="kw">return var1 != null ? var1 : this.getGameplayConfig().getWorldConfig().getDaytimeDurationSeconds();
   }

   class="kw">public int getNighttimeDurationSeconds() {
      Integer var1 = this.worldConfig.getNighttimeDurationSecondsOverride();
      class="kw">return var1 != null ? var1 : this.getGameplayConfig().getWorldConfig().getNighttimeDurationSeconds();
   }

   class="kw">public boolean isTicking() {
      class="kw">return this.isTicking;
   }

   class="kw">public void setTicking(boolean var1) {
      this.isTicking = var1;
      this.worldConfig.setTicking(var1);
      this.worldConfig.markChanged();
   }

   class="kw">public boolean isPaused() {
      class="kw">return this.isPaused;
   }

   class="kw">public void setPaused(boolean var1) {
      if (this.isPaused != var1) {
         this.isPaused = var1;
         ServerSetPaused var2 = new ServerSetPaused(var1);
         PlayerUtil.broadcastPacketToPlayersNoCache(this.entityStore.getStore(), var2);
      }
   }

   class="kw">public long getTick() {
      class="kw">return this.tick;
   }

   @Nonnull
   class="kw">public HytaleLogger getLogger() {
      class="kw">return this.logger;
   }

   class="kw">public boolean isCompassUpdating() {
      class="kw">return this.worldConfig.isCompassUpdating();
   }

   class="kw">public void setCompassUpdating(boolean var1) {
      boolean var2 = this.worldMapManager.shouldTick();
      this.worldConfig.setCompassUpdating(var1);
      this.worldConfig.markChanged();
      this.worldMapManager.updateTickingState(var2);
   }

   class="kw">public <T> void getBlockBulkRelative(
      @Nonnull Long2ObjectMap<T> var1,
      @Nonnull IntUnaryOperator var2,
      @Nonnull IntUnaryOperator var3,
      @Nonnull IntUnaryOperator var4,
      @Nonnull World.GenericBlockBulkUpdater<T> var5
   ) {
      Long2ObjectMap var6 = new Long2ObjectOpenHashMap();
      var1.forEach((var6x, var7) -> {
         int var8 = BlockUtil.unpackX(var6x);
         int var9 = BlockUtil.unpackY(var6x);
         int var10 = BlockUtil.unpackZ(var6x);
         int var11 = var2.applyAsInt(var8);
         int var12 = var3.applyAsInt(var9);
         int var13 = var4.applyAsInt(var10);
         long var14 = ChunkUtil.indexChunkFromBlock(var11, var13);
         WorldChunk var16 = (WorldChunk)var6.get(var14);
         if (var16 == null) {
            var16 = this.getNonTickingChunk(var14);
            var6.put(var14, var16);
         }

         var5.apply(this, (T)var7, var14, var16, var11, var12, var13, var8, var9, var10);
      });
   }

   @Nullable
   @Override
   class="kw">public WorldChunk loadChunkIfInMemory(long var1) {
      if (!this.isInThread()) {
         class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.loadChunkIfInMemory(var1), this).join();
      }

      Ref var3 = this.chunkStore.getChunkReference(var1);
      if (var3 == null) {
         class="kw">return null;
      }

      WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
      assert var4 != null;
      var4.setFlag(ChunkFlag.TICKING, true);
      class="kw">return var4;
   }

   @Nullable
   @Deprecated
   @Override
   class="kw">public WorldChunk getChunkIfInMemory(long var1) {
      Ref var3 = this.chunkStore.getChunkReference(var1);
      if (var3 == null) {
         class="kw">return null;
      } else {
         class="kw">return !this.isInThread()
            ? CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfInMemory(var1), this).join()
            : this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
      }
   }

   @Nullable
   @Deprecated
   @Override
   class="kw">public WorldChunk getChunkIfLoaded(long var1) {
      if (!this.isInThread()) {
         class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfLoaded(var1), this).join();
      }

      Ref var3 = this.chunkStore.getChunkReference(var1);
      if (var3 == null) {
         class="kw">return null;
      }

      WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
      assert var4 != null;
      class="kw">return var4.is(ChunkFlag.TICKING) ? var4 : null;
   }

   @Nullable
   @Deprecated
   @Override
   class="kw">public WorldChunk getChunkIfNonTicking(long var1) {
      if (!this.isInThread()) {
         class="kw">return CompletableFuture.<WorldChunk>supplyAsync(() -> this.getChunkIfNonTicking(var1), this).join();
      }

      Ref var3 = this.chunkStore.getChunkReference(var1);
      if (var3 == null) {
         class="kw">return null;
      }

      WorldChunk var4 = this.chunkStore.getStore().getComponent(var3, WorldChunk.getComponentType());
      assert var4 != null;
      class="kw">return var4.is(ChunkFlag.TICKING) ? null : var4;
   }

   @Nonnull
   @Deprecated
   @Override
   class="kw">public CompletableFuture<WorldChunk> getChunkAsync(long var1) {
      class="kw">return this.chunkStore
         .getChunkReferenceAsync(var1, 4)
         .thenApplyAsync(var1x -> var1x == null ? null : this.chunkStore.getStore().getComponent((Ref<ChunkStore>)var1x, WorldChunk.getComponentType()), this);
   }

   @Nonnull
   @Deprecated
   @Override
   class="kw">public CompletableFuture<WorldChunk> getNonTickingChunkAsync(long var1) {
      class="kw">return this.chunkStore
         .getChunkReferenceAsync(var1)
         .thenApplyAsync(var1x -> var1x == null ? null : this.chunkStore.getStore().getComponent((Ref<ChunkStore>)var1x, WorldChunk.getComponentType()), this);
   }

   @Deprecated(forRemoval = true)
   class="kw">public List<Player> getPlayers() {
      if (!this.isInThread()) {
         class="kw">return !this.isStarted() ? Collections.emptyList() : CompletableFuture.supplyAsync(this::getPlayers, this).join();
      }

      ObjectArrayList var1 = new ObjectArrayList(32);
      this.entityStore.getStore().forEachChunk(Player.getComponentType(), (var1x, var2) -> {
         var1.ensureCapacity(var1.size() + var1x.size());

         for (int var3 = 0; var3 < var1x.size(); var3++) {
            var1.add(var1x.getComponent(var3, Player.getComponentType()));
         }
      });
      class="kw">return var1;
   }

   @Nullable
   @Deprecated
   class="kw">public Entity getEntity(@Nonnull UUID var1) {
      if (!this.isInThread()) {
         class="kw">return CompletableFuture.<Entity>supplyAsync(() -> this.getEntity(var1), this).join();
      }

      Ref var2 = this.entityStore.getRefFromUUID(var1);
      class="kw">return EntityUtils.getEntity(var2, this.entityStore.getStore());
   }

   @Nullable
   class="kw">public Ref<EntityStore> getEntityRef(@Nonnull UUID var1) {
      class="kw">return !this.isInThread()
         ? CompletableFuture.<Ref<EntityStore>>supplyAsync(() -> this.getEntityRef(var1), this).join()
         : this.entityStore.getRefFromUUID(var1);
   }

   class="kw">public int getPlayerCount() {
      class="kw">return this.players.size();
   }

   class="kw">public int getNonSpectatorPlayerCount() {
      int var1 = 0;

      for (PlayerRef var3 : this.playerRefs) {
         Ref var4 = var3.getReference();
         if (var4 == null || !var4.isValid() || !this.entityStore.getStore().getArchetype(var4).contains(Spectating.getComponentType())) {
            var1++;
         }
      }

      class="kw">return var1;
   }

   @Nonnull
   class="kw">public Collection<PlayerRef> getPlayerRefs() {
      class="kw">return this.playerRefs;
   }

   class="kw">public void trackPlayerRef(@Nonnull PlayerRef var1) {
      this.players.put(var1.getUuid(), var1);
   }

   class="kw">public void untrackPlayerRef(@Nonnull PlayerRef var1) {
      this.players.remove(var1.getUuid(), var1);
   }

   @Deprecated
   @Nullable
   class="kw">public <T class="kw">extends Entity> T spawnEntity(T var1, @Nonnull Vector3d var2, Rotation3f var3) {
      class="kw">return this.addEntity(var1, var2, var3, AddReason.SPAWN);
   }

   @Deprecated
   @Nullable
   class="kw">public <T class="kw">extends Entity> T addEntity(T var1, @Nonnull Vector3d var2, @Nullable Rotation3f var3, @Nonnull AddReason var4) {
      if (!EntityModule.get().isKnown(var1)) {
         throw new IllegalArgumentException("Unknown entity");
      }

      if (var1 class="kw">instanceof Player) {
         throw new IllegalArgumentException("Entity can't be a Player!");
      }

      if (var1.getNetworkId() == -1) {
         throw new IllegalArgumentException("Entity id can't be Entity.UNASSIGNED_ID (-1)!");
      }

      if (!this.equals(var1.getWorld())) {
         throw new IllegalStateException("Expected entity to already have its world set to " + this.name + " but it has " + var1.getWorld());
      }

      if (var1.getReference() != null && var1.getReference().isValid()) {
         throw new IllegalArgumentException("Entity already has a valid EntityReference: " + var1.getReference());
      }

      if (var2.y() < -32.0) {
         throw new IllegalArgumentException("Unable to spawn entity below the world! -32 < " + var2);
      }

      if (!this.isInThread()) {
         ((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(new SkipSentryException())).log("Warning addEntity was called off thread!");
         this.execute(() -> this.addEntity(var1, var2, var3, var4));
         class="kw">return var1;
      }

      var1.unloadFromWorld();
      Holder var5 = var1.toHolder();
      HeadRotation var6 = var5.ensureAndGetComponent(HeadRotation.getComponentType());
      if (var3 != null) {
         var6.teleportRotation(var3);
      }

      var5.addComponent(TransformComponent.getComponentType(), new TransformComponent(var2, var3));
      var5.ensureComponent(UUIDComponent.getComponentType());
      this.entityStore.getStore().addEntity(var5, var4);
      class="kw">return var1;
   }

   @Override
   class="kw">public void sendMessage(@Nonnull Message var1) {
      if (!this.isInThread()) {
         this.execute(() -> this.sendMessage(var1));
      } else {
         this.entityStore.getStore().forEachEntityParallel(PlayerRef.getComponentType(), (var1x, var2, var3) -> {
            PlayerRef var4 = var2.getComponent(var1x, PlayerRef.getComponentType());
            assert var4 != null;
            var4.sendMessage(var1);
         });
         this.logger.at(Level.INFO).log("[Broadcast] [Message] %s", MessageUtil.toAnsiString(var1).toAnsi(ConsoleModule.get().getTerminal()));
      }
   }

   @Override
   class="kw">public void execute(@Nonnull Runnable var1) {
      if (!this.acceptingTasks.get()) {
         throw new SkipSentryException(new IllegalThreadStateException("World thread is not accepting tasks: " + this.name + ", " + this.getThread()));
      }

      this.taskQueue.offer(var1);
   }

   class="kw">public ScheduledFuture<?> scheduleAfter(@Nonnull Runnable var1, long var2, @Nonnull TimeUnit var4) {
      class="kw">return HytaleServer.SCHEDULED_EXECUTOR.schedule(() -> {
         if (this.acceptingTasks.get()) {
            this.taskQueue.offer(var1);
         }
      }, var2, var4);
   }

   @Override
   class="kw">public void consumeTaskQueue() {
      this.debugAssertInTickingThread();
      int var1 = this.getTickStepNanos();

      Runnable var2;
      while ((var2 = this.taskQueue.poll()) != null) {
         try {
            long var3 = System.nanoTime();
            var2.run();
            long var5 = System.nanoTime();
            long var7 = var5 - var3;
            if (var7 > var1) {
               this.logger.at(Level.WARNING).log("Task took %s ns: %s", FormatUtil.nanosToString(var7), var2);
            }
         } catch (Exception var9) {
            ((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var9)).log("Failed to run task!");
         }
      }
   }

   @Nonnull
   class="kw">public ChunkStore getChunkStore() {
      class="kw">return this.chunkStore;
   }

   @Nonnull
   class="kw">public EntityStore getEntityStore() {
      class="kw">return this.entityStore;
   }

   @Nonnull
   class="kw">public ChunkLightingManager getChunkLighting() {
      class="kw">return this.chunkLighting;
   }

   @Nonnull
   class="kw">public WorldMapManager getWorldMapManager() {
      class="kw">return this.worldMapManager;
   }

   class="kw">public WorldPathConfig getWorldPathConfig() {
      class="kw">return this.worldPathConfig;
   }

   @Nonnull
   class="kw">public WorldNotificationHandler getNotificationHandler() {
      class="kw">return this.notificationHandler;
   }

   @Nonnull
   class="kw">public EventRegistry getEventRegistry() {
      class="kw">return this.eventRegistry;
   }

   @Nullable
   class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1) {
      class="kw">return this.addPlayer(var1, null);
   }

   @Nullable
   class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1, @Nullable Transform var2) {
      class="kw">return this.addPlayer(var1, var2, null, null);
   }

   @Nullable
   class="kw">public CompletableFuture<PlayerRef> addPlayer(@Nonnull PlayerRef var1, @Nullable Transform var2, @Nullable Boolean var3, @Nullable Boolean var4) {
      if (!this.alive.get()) {
         class="kw">return CompletableFuture.failedFuture(new SkipSentryException(new IllegalStateException("This world has already been shutdown!")));
      }

      if (var1.getReference() != null) {
         throw new IllegalStateException("Player is already in a world");
      }

      PacketHandler var5 = var1.getPacketHandler();
      if (!var5.stillActive()) {
         class="kw">return null;
      }

      Holder var6 = var1.getHolder();
      assert var6 != null;
      var1.setWorldUuid(this.worldConfig.getUuid());
      TransformComponent var7 = var6.getComponent(TransformComponent.getComponentType());
      if (var7 == null && var2 == null) {
         var7 = SpawnUtil.applyFirstSpawnTransform(var6, this, this.worldConfig, var1.getUuid());
         if (var7 == null) {
            class="kw">return CompletableFuture.failedFuture(new IllegalStateException("Spawn provider cannot be null for positioning new entities!"));
         }
      }

      assert var7 != null;
      Player var8 = var6.getComponent(Player.getComponentType());
      assert var8 != null;
      boolean var9 = !var8.getPlayerConfigData().getPerWorldData().containsKey(this.name);
      var8.setFirstSpawn(var9);
      if (var2 != null) {
         SpawnUtil.applyTransform(var6, var2);
      }

      Message var10 = Message.translation("server.general.playerJoinedWorld")
         .param("username", var1.getUsername())
         .param("world", this.worldConfig.getDisplayName() != null ? this.worldConfig.getDisplayName() : WorldConfig.formatDisplayName(this.name));
      AddPlayerToWorldEvent var11 = HytaleServer.get()
         .getEventBus()
         .dispatchFor(AddPlayerToWorldEvent.class, this.name)
         .dispatch(new AddPlayerToWorldEvent(var6, this, var10));
      ChunkTracker var12 = var6.getComponent(ChunkTracker.getComponentType());
      boolean var13 = var3 != null ? var3 : true;
      boolean var14 = var4 != null ? var4 : true;
      if (var12 != null && (var13 || var14)) {
         var12.setReadyForChunks(false);
      }

      Vector3d var15 = var7.getPosition();
      long var16 = ChunkUtil.indexChunkFromBlock(var15.x(), var15.z());
      CompletableFuture var18 = this.chunkStore.getChunkReferenceAsync(var16, 32).thenAccept(var1x -> var8.startClientReadyTimeout());
      CompletableFuture var19 = new CompletableFuture<>();
      var5.setClientReadyForChunksFuture(var19);
      CompletableFuture var20 = CompletableFuture.runAsync(() -> this.onSetupPlayerJoining(var6, var8, var1, var5, var2, var13, var14));
      CompletableFuture var21 = var19.orTimeout(30L, TimeUnit.SECONDS);
      class="kw">return CompletableFuture.allOf(var20, var21, var18)
         .thenApplyAsync(var5x -> this.onFinishPlayerJoining(var8, var1, var5, var11.getJoinMessage(), var11.shouldBroadcastJoinMessage()), this)
         .exceptionally(var2x -> {
            ((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(var2x)).log("Exception when adding player to world!");
            PluginIdentifier var3 = PluginIdentifier.identifyThirdPartyPlugin(var2x);
            if (var3 == null) {
               var1.getPacketHandler().disconnect(Message.translation("server.general.disconnect.exceptionJoiningWorld"));
            } else {
               var1.getPacketHandler().disconnect(Message.translation("server.general.disconnect.exceptionJoiningWorldCause").param("cause", var3.toString()));
            }

            throw new RuntimeException("Exception when adding player '" + var1.getUsername() + "' to world '" + this.name + "'", var2x);
         });
   }

   @Nonnull
   class="kw">private PlayerRef onFinishPlayerJoining(@Nonnull Player var1, @Nonnull PlayerRef var2, @Nonnull PacketHandler var3, @Nullable Message var4, boolean var5) {
      TimeResource var6 = this.entityStore.getStore().getResource(TimeResource.getResourceType());
      float var7 = var6.getTimeDilationModifier();
      int var8 = HytaleServer.get().getConfig().getMaxViewRadius();
      var3.write(new ViewRadius(var8 * 32));
      var3.write(new SetEntitySeed(this.entitySeed.get()), new SetClientId(var1.getNetworkId()), new SetTimeDilation(var7));
      var3.write(new UpdateFeatures(this.features));
      var3.write(this.worldConfig.getClientEffects().createSunSettingsPacket());
      var3.write(this.worldConfig.getClientEffects().createPostFxSettingsPacket());
      UUID var9 = var2.getUuid();
      Store var10 = this.entityStore.getStore();
      WorldTimeResource var11 = var10.getResource(WorldTimeResource.getResourceType());
      World var12 = var10.getExternalData().getWorld();
      var3.writeNoCache(new SetUpdateRate(this.getTps()));
      if (this.isPaused) {
         this.setPaused(false);
      }

      if (!var3.stillActive()) {
         throw new IllegalStateException("Connection of joining player closed before they could be added to the world store");
      }

      Ref var13 = var2.addToStore(var10);
      if (var13 != null && var13.isValid()) {
         var11.sendTimePackets(var2);
         WorldMapTracker var14 = var1.getWorldMapTracker();
         var14.clear();
         var14.sendSettings(var12);
         if (var5) {
            PlayerUtil.broadcastMessageToPlayers(var9, var4, var10);
         }

         TransformComponent var15 = var10.getComponent(var13, TransformComponent.getComponentType());
         assert var15 != null;
         String var16 = var15.getPosition().toString();
         this.logger.at(Level.INFO).log("Player '%s' joined world '%s' at location %s (%s)", var2.getUsername(), this.name, var16, var9);
         HeadRotation var17 = var10.getComponent(var13, HeadRotation.getComponentType());
         assert var17 != null;
         class="kw">return var2;
      } else {
         throw new IllegalStateException("Failed to add player ref of joining player to the world store");
      }
   }

   class="kw">private void onSetupPlayerJoining(
      @Nonnull Holder<EntityStore> var1,
      @Nonnull Player var2,
      @Nonnull PlayerRef var3,
      @Nonnull PacketHandler var4,
      @Nullable Transform var5,
      boolean var6,
      boolean var7
   ) {
      UUID var8 = var3.getUuid();
      this.logger.at(Level.INFO).log("Adding player '%s' to world '%s' at location %s (%s)", var3.getUsername(), this.name, var5, var8);
      int var9 = this.entityStore.takeNextNetworkId();
      var2.setNetworkId(var9);
      PlayerConfigData var10 = var2.getPlayerConfigData();
      var10.setWorld(this.name);
      if (var6) {
         EntityTrackerSystems.clear(var1);
         ChunkTracker var11 = var1.getComponent(ChunkTracker.getComponentType());
         if (var11 != null) {
            var11.clear();
            var4.writeNoCache(new ClearChunks());
         }
      }

      var2.getPageManager().clearCustomPageAcknowledgements();
      boolean var15 = this.chunkStore.supportsCubicSections();
      Integer var12 = var15 ? null : 0;
      Integer var13 = var15 ? null : 9;
      JoinWorld var14 = new JoinWorld(var6, var7, this.worldConfig.getUuid(), var12, var13);
      var4.write(var14);
      var4.tryFlush();
      HytaleLogger.getLogger().at(Level.INFO).log("%s: Sent %s", var4.getIdentifier(), var14);
      var4.setQueuePackets(true);
   }

   @Nonnull
   class="kw">public CompletableFuture<Void> drainPlayersTo(@Nonnull World var1, Collection<PlayerRef> var2) {
      ObjectArrayList var3 = new ObjectArrayList();

      for (PlayerRef var5 : var2) {
         Holder var6 = var5.getReference() != null ? var5.removeFromStore() : var5.getHolder();
         DrainPlayerFromWorldEvent var7 = HytaleServer.get()
            .getEventBus()
            .dispatchFor(DrainPlayerFromWorldEvent.class, this.name)
            .dispatch(new DrainPlayerFromWorldEvent(var6, var1, null));
         var3.add(var7.getWorld().addPlayer(var5, var7.getTransform()));
      }

      class="kw">return CompletableFuture.allOf((CompletableFuture<?>[])var3.toArray(CompletableFuture[]::new));
   }

   @Nonnull
   class="kw">public GameplayConfig getGameplayConfig() {
      String var1 = this.worldConfig.getGameplayConfig();
      GameplayConfig var2 = GameplayConfig.getAssetMap().getAsset(var1);
      if (var2 == null) {
         var2 = GameplayConfig.DEFAULT;
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">public Map<ClientFeature, Boolean> getFeatures() {
      class="kw">return Collections.unmodifiableMap(this.features);
   }

   class="kw">public boolean isFeatureEnabled(@Nonnull ClientFeature var1) {
      class="kw">return this.features.getOrDefault(var1, false);
   }

   class="kw">public void registerFeature(@Nonnull ClientFeature var1, boolean var2) {
      this.features.put(var1, var2);
      this.broadcastFeatures();
   }

   class="kw">public void broadcastFeatures() {
      UpdateFeatures var1 = new UpdateFeatures(this.features);

      for (PlayerRef var3 : this.playerRefs) {
         var3.getPacketHandler().write(var1);
      }
   }

   @Nonnull
   class="kw">public Path getSavePath() {
      class="kw">return this.savePath;
   }

   class="kw">public void updateEntitySeed(@Nonnull Store<EntityStore> var1) {
      int var2 = this.random.nextInt();
      this.entitySeed.set(var2);
      PlayerUtil.broadcastPacketToPlayers(var1, new SetEntitySeed(var2));
   }

   class="kw">public void markGCHasRun() {
      this.gcHasRun = true;
   }

   class="kw">public boolean consumeGCHasRun() {
      boolean var1 = this.gcHasRun;
      this.gcHasRun = false;
      class="kw">return var1;
   }

   class="kw">public boolean isSavingLocked() {
      class="kw">return this.savingLocks.get() > 0;
   }

   class="kw">public void lockSaving() {
      this.savingLocks.incrementAndGet();
   }

   class="kw">public void unlockSaving() {
      int var1 = this.savingLocks.decrementAndGet();
      assert var1 >= 0 : "savingLocks underflow";
   }

   @Override
   class="kw">public int hashCode() {
      class="kw">return this.name != null ? this.name.hashCode() : 0;
   }

   @Override
   class="kw">public boolean equals(@Nullable Object var1) {
      if (this == var1) {
         class="kw">return true;
      } else if (var1 != null && this.getClass() == var1.getClass()) {
         World var2 = (World)var1;
         class="kw">return this.name.equals(var2.name);
      } else {
         class="kw">return false;
      }
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "World{name='"
         + this.name
         + "', alive="
         + this.alive.get()
         + ", loadedChunksCount="
         + this.chunkStore.getLoadedChunksCount()
         + ", totalLoadedChunksCount="
         + this.chunkStore.getTotalLoadedChunksCount()
         + ", totalGeneratedChunksCount="
         + this.chunkStore.getTotalGeneratedChunksCount()
         + ", entityCount="
         + (this.entityStore.getStore() != null ? this.entityStore.getStore().getEntityCount() : 0)
         + "}";
   }

   class="kw">public void validate(@Nonnull StringBuilder var1, @Nonnull IPrefabBuffer.RawBlockConsumer<Void> var2, @Nonnull EnumSet<ValidationOption> var3) class="kw">throws IOException {
      this.setThread(Thread.currentThread());
      this.onStart();
      Store var4 = this.chunkStore.getStore();
      StringBuilder var5 = new StringBuilder();
      LongListIterator var6 = this.chunkStore.getLoader().getIndexes().iterator();

      while (var6.hasNext()) {
         long var7 = (Long)var6.next();
         int var9 = ChunkUtil.xOfChunkIndex(var7);
         int var10 = ChunkUtil.zOfChunkIndex(var7);

         try {
            CompletableFuture var11 = this.chunkStore.getChunkReferenceAsync(var7, 2);

            while (!var11.isDone()) {
               this.consumeTaskQueue();
            }

            Ref var12 = var11.join();
            if (var12 != null && var12.isValid()) {
               WorldChunk var13 = var4.getComponent(var12, WorldChunk.getComponentType());
               ChunkColumn var14 = var4.getComponent(var12, ChunkColumn.getComponentType());
               if (var14 != null) {
                  for (Ref var18 : var14.getSections()) {
                     class="kw">final ChunkSection var19 = var4.getComponent(var18, ChunkSection.getComponentType());
                     if (var3.contains(ValidationOption.ENTITIES)) {
                        ComponentType var20 = EntityStore.REGISTRY.getUnknownComponentType();
                        EntitySection var21 = var4.getComponent(var18, EntitySection.getComponentType());
                        if (var21 != null) {
                           for (Holder var23 : var21.getEntityHolders()) {
                              UnknownComponents var24 = var23.getComponent(var20);
                              if (var24 != null && !var24.getUnknownComponents().isEmpty()) {
                                 var1.append("\tUnknown Entity Components: ").append(var24.getUnknownComponents()).append("\n");
                              }
                           }
                        }
                     }

                     BlockSection var36 = var4.getComponent(var18, BlockSection.getComponentType());
                     if (var36 != null) {
                        BlockPhysics var37 = var4.getComponent(var18, BlockPhysics.getComponentType());

                        for (int var38 = 0; var38 < 32; var38++) {
                           int var39 = (var19.getY() << 5) + var38;

                           for (int var40 = 0; var40 < 32; var40++) {
                              for (int var25 = 0; var25 < 32; var25++) {
                                 int var26 = var36.get(var25, var38, var40);
                                 int var27 = var36.getFiller(var25, var38, var40);
                                 int var28 = var36.getRotationIndex(var25, var38, var40);
                                 Holder var29 = var13.getBlockComponentHolder(var25, var39, var40);
                                 int var30 = ChunkUtil.minBlock(var13.getX()) + var25;
                                 int var31 = ChunkUtil.minBlock(var13.getZ()) + var40;
                                 var2.accept(var30, var39, var31, var26, 0, 1.0F, var29, var37 != null ? var37.get(var25, var38, var40) : 0, var28, var27, null);
                                 if (var3.contains(ValidationOption.BLOCK_FILLER)) {
                                    var var32 = new FillerBlockUtil.FillerFetcher<BlockSection, ChunkStore>() {
                                       class="kw">public int getBlock(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
                                          if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
                                             class="kw">return var1.get(var3x, var4, var5);
                                          }

                                          int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
                                          int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
                                          int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
                                          CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);

                                          while (!var9.isDone()) {
                                             World.this.consumeTaskQueue();
                                          }

                                          Ref var10 = var9.join();
                                          BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
                                          class="kw">return var11 == null ? Integer.MIN_VALUE : var11.get(var3x, var4, var5);
                                       }

                                       class="kw">public int getFiller(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
                                          if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
                                             class="kw">return var1.getFiller(var3x, var4, var5);
                                          }

                                          int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
                                          int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
                                          int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
                                          CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);

                                          while (!var9.isDone()) {
                                             World.this.consumeTaskQueue();
                                          }

                                          Ref var10 = var9.join();
                                          BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
                                          class="kw">return var11 == null ? Integer.MIN_VALUE : var11.getFiller(var3x, var4, var5);
                                       }

                                       class="kw">public int getRotationIndex(BlockSection var1, ChunkStore var2x, int var3x, int var4, int var5) {
                                          if (var3x >= 0 && var4 >= 0 && var5 >= 0 && var3x < 32 && var4 < 32 && var5 < 32) {
                                             class="kw">return var1.getFiller(var3x, var4, var5);
                                          }

                                          int var6 = var19.getX() + ChunkUtil.chunkCoordinate(var3x);
                                          int var7 = var19.getY() + ChunkUtil.chunkCoordinate(var4);
                                          int var8 = var19.getZ() + ChunkUtil.chunkCoordinate(var5);
                                          CompletableFuture var9 = var2x.getChunkSectionReferenceAsync(var6, var7, var8);

                                          while (!var9.isDone()) {
                                             World.this.consumeTaskQueue();
                                          }

                                          Ref var10 = var9.join();
                                          BlockSection var11 = var2x.getStore().getComponent(var10, BlockSection.getComponentType());
                                          class="kw">return var11 == null ? Integer.MIN_VALUE : var11.getRotationIndex(var3x, var4, var5);
                                       }
                                    };
                                    FillerBlockUtil.ValidationResult var33 = FillerBlockUtil.validateBlock(
                                       var25, var38, var40, var26, var28, var27, var36, this.chunkStore, var32
                                    );
                                    class="kw">switch (var33) {
                                       case OK:
                                       class="kw">default:
                                          break;
                                       case INVALID_BLOCK: {
                                          BlockType var41 = BlockType.getAssetMap().getAsset(var26);
                                          var5.append("\tBlock ")
                                             .append(var41 != null ? var41.getId() : "<missing>")
                                             .append(" at ")
                                             .append(var25)
                                             .append(", ")
                                             .append(var38)
                                             .append(", ")
                                             .append(var40)
                                             .append(" is not valid filler")
                                             .append('\n');
                                          break;
                                       }
                                       case INVALID_FILLER: {
                                          BlockType var34 = BlockType.getAssetMap().getAsset(var26);
                                          var5.append("\tBlock ")
                                             .append(var34 != null ? var34.getId() : "<missing>")
                                             .append(" at ")
                                             .append(var25)
                                             .append(", ")
                                             .append(var38)
                                             .append(", ")
                                             .append(var40)
                                             .append(" has invalid/missing filler blocks")
                                             .append('\n');
                                       }
                                    }
                                 }
                              }
                           }
                        }

                        if (!var5.isEmpty()) {
                           var1.append("\tChunk ")
                              .append(var19.getX())
                              .append(", ")
                              .append(var19.getY())
                              .append(", ")
                              .append(var19.getZ())
                              .append(" validation errors:")
                              .append(var5);
                           var5.setLength(0);
                        }
                     }
                  }

                  var4.tick(1.0F);
               }
            }
         } catch (CompletionException var35) {
            ((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var35)).log("Failed to validate chunk: %d, %d", var9, var10);
            var1.append('\t')
               .append("Exception validating chunk: ")
               .append(var9)
               .append(", ")
               .append(var10)
               .append('\n')
               .append("\t\t")
               .append(var35.getCause().getMessage())
               .append('\n');
         }
      }

      if (this.alive.getAndSet(false)) {
         this.onShutdown();
      }

      this.setThread(null);
   }

   @FunctionalInterface
   class="kw">public class="kw">interface GenericBlockBulkUpdater<T> {
      void apply(World var1, T var2, long var3, WorldChunk var5, int var6, int var7, int var8, int var9, int var10, int var11);
   }
}