ChunkStorage class

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

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

implements: Resource<ChunkStore>

Поля (1)

МодификаторыТипИмя
public static final BuilderCodec<ChunkStore.ChunkStorage> CODEC

Методы (1)

МодификаторыВозвратСигнатура
public Resource<ChunkStore> clonepublic Resource<ChunkStore> clone()

Исходный код

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

class="kw">import com.hypixel.fastutil.longs.Long2ObjectConcurrentHashMap;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.store.CodecKey;
class="kw">import com.hypixel.hytale.codec.store.CodecStore;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.Component;
class="kw">import com.hypixel.hytale.component.ComponentRegistry;
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.RemoveReason;
class="kw">import com.hypixel.hytale.component.Resource;
class="kw">import com.hypixel.hytale.component.ResourceType;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.SystemGroup;
class="kw">import com.hypixel.hytale.component.SystemType;
class="kw">import com.hypixel.hytale.component.system.StoreSystem;
class="kw">import com.hypixel.hytale.component.system.data.EntityDataSystem;
class="kw">import com.hypixel.hytale.event.IEventDispatcher;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.data.Int3ObjectOpenHashMap;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.protocol.ToClientPacket;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.WorldProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
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.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.ChunkPreLoadProcessEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.events.ChunkSectionPreLoadProcessEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.component.ChunkSavingSystems;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.component.ChunkUnloadingSystem;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.component.SectionUnloadingSystem;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.provider.IChunkStorageProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.IWorldGen;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import it.unimi.dsi.fastutil.longs.LongPredicate;
class="kw">import it.unimi.dsi.fastutil.longs.LongSet;
class="kw">import it.unimi.dsi.fastutil.longs.LongSets;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import java.io.IOException;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicInteger;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class ChunkStore class="kw">implements WorldProvider {
   @Nonnull
   class="kw">public class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">public class="kw">static class="kw">final MetricsRegistry<ChunkStore> METRICS_REGISTRY = new MetricsRegistry<ChunkStore>()
      .register("Store", ChunkStore::getStore, Store.METRICS_REGISTRY)
      .register("ChunkLoader", MetricProvider.maybe(ChunkStore::getLoader))
      .register("ChunkSaver", MetricProvider.maybe(ChunkStore::getSaver))
      .register("WorldGen", MetricProvider.maybe(ChunkStore::getGenerator))
      .register("SaveQueue", var0 -> var0.getStore().getResource(ChunkStore.SAVE_RESOURCE), ChunkSavingSystems.Data.METRICS_REGISTRY)
      .register("TotalGeneratedChunkCount", var0 -> (long)var0.totalGeneratedChunksCount.get(), Codec.LONG)
      .register("TotalLoadedChunkCount", var0 -> (long)var0.totalLoadedChunksCount.get(), Codec.LONG);
   class="kw">public class="kw">static class="kw">final long MAX_FAILURE_BACKOFF_NANOS = TimeUnit.SECONDS.toNanos(10L);
   class="kw">public class="kw">static class="kw">final long FAILURE_BACKOFF_NANOS = TimeUnit.MILLISECONDS.toNanos(1L);
   class="kw">public class="kw">static class="kw">final ComponentRegistry<ChunkStore> REGISTRY = new ComponentRegistry<>();
   class="kw">public class="kw">static class="kw">final CodecKey<Holder<ChunkStore>> HOLDER_CODEC_KEY = new CodecKey<>("ChunkHolder");
   @Nonnull
   class="kw">public class="kw">static class="kw">final SystemType<ChunkStore, ChunkStore.LoadPacketDataQuerySystem> LOAD_PACKETS_DATA_QUERY_SYSTEM_TYPE = REGISTRY.registerSystemType(
      ChunkStore.LoadPacketDataQuerySystem.class
   );
   @Nonnull
   class="kw">public class="kw">static class="kw">final SystemType<ChunkStore, ChunkStore.LoadFuturePacketDataQuerySystem> LOAD_FUTURE_PACKETS_DATA_QUERY_SYSTEM_TYPE = REGISTRY.registerSystemType(
      ChunkStore.LoadFuturePacketDataQuerySystem.class
   );
   @Nonnull
   class="kw">public class="kw">static class="kw">final SystemType<ChunkStore, ChunkStore.UnloadPacketDataQuerySystem> UNLOAD_PACKETS_DATA_QUERY_SYSTEM_TYPE = REGISTRY.registerSystemType(
      ChunkStore.UnloadPacketDataQuerySystem.class
   );
   @Nonnull
   class="kw">public class="kw">static class="kw">final ResourceType<ChunkStore, ChunkUnloadingSystem.Data> UNLOAD_RESOURCE = REGISTRY.registerResource(
      ChunkUnloadingSystem.Data.class, ChunkUnloadingSystem.Data::new
   );
   @Nonnull
   class="kw">public class="kw">static class="kw">final ResourceType<ChunkStore, SectionUnloadingSystem.Data> SECTION_UNLOAD_RESOURCE = REGISTRY.registerResource(
      SectionUnloadingSystem.Data.class, SectionUnloadingSystem.Data::new
   );
   @Nonnull
   class="kw">public class="kw">static class="kw">final ResourceType<ChunkStore, ChunkSavingSystems.Data> SAVE_RESOURCE = REGISTRY.registerResource(
      ChunkSavingSystems.Data.class, ChunkSavingSystems.Data::new
   );
   class="kw">public class="kw">static class="kw">final SystemGroup<ChunkStore> INIT_GROUP = REGISTRY.registerSystemGroup();
   @Nonnull
   class="kw">private class="kw">final World world;
   @Nonnull
   class="kw">private class="kw">final Long2ObjectConcurrentHashMap<ChunkStore.ChunkLoadState> chunks = new Long2ObjectConcurrentHashMap<>(true, ChunkUtil.NOT_FOUND);
   class="kw">private class="kw">final StampedLock lock = new StampedLock();
   class="kw">private class="kw">final Int3ObjectOpenHashMap<ChunkStore.LoadState> chunkSections = new Int3ObjectOpenHashMap<>();
   class="kw">private Store<ChunkStore> store;
   class="kw">private Object storageData;
   @Nullable
   class="kw">private Runnable pendingStorageMigration;
   @Nullable
   class="kw">private IChunkLoader loader;
   @Nullable
   class="kw">private IChunkSaver saver;
   @Nullable
   class="kw">private IWorldGen generator;
   @Nonnull
   class="kw">private CompletableFuture<Void> generatorLoaded = new CompletableFuture<>();
   class="kw">private class="kw">final StampedLock generatorLock = new StampedLock();
   class="kw">private class="kw">final AtomicInteger totalGeneratedChunksCount = new AtomicInteger();
   class="kw">private class="kw">final AtomicInteger totalLoadedChunksCount = new AtomicInteger();

   class="kw">public ChunkStore(@Nonnull World var1) {
      this.world = var1;
   }

   @Nonnull
   @Override
   class="kw">public World getWorld() {
      class="kw">return this.world;
   }

   @Nonnull
   class="kw">public Store<ChunkStore> getStore() {
      class="kw">return this.store;
   }

   class="kw">public Object getStorageData() {
      class="kw">return this.storageData;
   }

   @Nullable
   class="kw">public IChunkLoader getLoader() {
      class="kw">return this.loader;
   }

   @Nullable
   class="kw">public IChunkSaver getSaver() {
      class="kw">return this.saver;
   }

   @Nullable
   class="kw">public IWorldGen getGenerator() {
      long var1 = this.generatorLock.readLock();

      try {
         class="kw">return this.generator;
      } class="kw">finally {
         this.generatorLock.unlockRead(var1);
      }
   }

   class="kw">public boolean supportsCubicSections() {
      if (this.loader class="kw">instanceof IChunkLoader.Cubic) {
         class="kw">return true;
      }

      long var1 = this.generatorLock.readLock();

      try {
         class="kw">return this.generator class="kw">instanceof IWorldGen.Cubic;
      } class="kw">finally {
         this.generatorLock.unlockRead(var1);
      }
   }

   class="kw">public void shutdownGenerator() {
      this.setGenerator(null);
   }

   class="kw">public void setGenerator(@Nullable IWorldGen var1) {
      long var2 = this.generatorLock.writeLock();

      try {
         if (this.generator != null) {
            this.generator.shutdown();
         }

         this.totalGeneratedChunksCount.set(0);
         this.generator = var1;
         if (var1 != null) {
            this.generatorLoaded.complete(null);
            this.generatorLoaded = new CompletableFuture<>();
         }
      } class="kw">finally {
         this.generatorLock.unlockWrite(var2);
      }
   }

   @Nonnull
   class="kw">public LongSet getChunkIndexes() {
      class="kw">return LongSets.unmodifiable(this.chunks.keySet());
   }

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

   class="kw">public int getTotalGeneratedChunksCount() {
      class="kw">return this.totalGeneratedChunksCount.get();
   }

   class="kw">public int getTotalLoadedChunksCount() {
      class="kw">return this.totalLoadedChunksCount.get();
   }

   class="kw">public void start(@Nonnull IResourceStorage var1) {
      this.store = REGISTRY.addStore(this, var1, var1x -> this.store = var1x);
      if (this.pendingStorageMigration != null) {
         Runnable var2 = this.pendingStorageMigration;
         this.pendingStorageMigration = null;
         var2.run();
      }
   }

   class="kw">public void waitForLoadingChunks() {
      long var1 = System.nanoTime();

      boolean var3;
      do {
         this.world.consumeTaskQueue();
         Thread.yield();
         var3 = false;
         ObjectIterator var4 = this.chunks.long2ObjectEntrySet().iterator();

         while (var4.hasNext()) {
            Entry var5 = (Entry<ChunkStore.ChunkLoadState>)var4.next();
            ChunkStore.ChunkLoadState var6 = (ChunkStore.ChunkLoadState)var5.getValue();
            long var7 = var6.lock.readLock();

            try {
               CompletableFuture var9 = var6.future;
               if (var9 != null && !var9.isDone()) {
                  var3 = true;
                  break;
               }
            } class="kw">finally {
               var6.lock.unlockRead(var7);
            }
         }
      } while (var3 && System.nanoTime() - var1 <= 5000000000L);

      this.world.consumeTaskQueue();
   }

   class="kw">public void shutdown() {
      this.store.shutdown();
      this.chunks.clear();
   }

   @Nonnull
   class="kw">private Ref<ChunkStore> add(@Nonnull Holder<ChunkStore> var1) {
      this.world.debugAssertInTickingThread();
      WorldChunk var2 = var1.getComponent(WorldChunk.getComponentType());
      assert var2 != null;
      ChunkStore.ChunkLoadState var3 = this.chunks.get(var2.getIndex());
      if (var3 == null) {
         throw new IllegalStateException("Expected the ChunkLoadState to exist!");
      }

      Ref var4 = null;
      long var5 = var3.lock.writeLock();

      try {
         if (var3.future == null) {
            throw new IllegalStateException("Expected the ChunkLoadState to have a future!");
         }

         if (var3.reference != null) {
            var4 = var3.reference;
            var3.reference = null;
         }
      } class="kw">finally {
         var3.lock.unlockWrite(var5);
      }

      if (var4 != null) {
         WorldChunk var7 = this.store.getComponent(var4, WorldChunk.getComponentType());
         assert var7 != null;
         if (var3.loadedSectionCount.get() > 10) {
            int var8 = var2.getX();
            int var9 = var2.getZ();
            ObjectArrayList var10 = new ObjectArrayList();
            long var11 = this.lock.readLock();

            try {
               this.chunkSections.forEach((var3x, var4x, var5x, var6x) -> {
                  if (var3x == var8 && var5x == var9 && (var4x < 0 || var4x >= 10)) {
                     Ref var7 = var6x.reference;
                     if (var7 != null && var7.isValid()) {
                        var10.add(var7);
                     }
                  }
               });
            } class="kw">finally {
               this.lock.unlockRead(var11);
            }

            for (int var13 = 0; var13 < var10.size(); var13++) {
               this.removeSection((Ref<ChunkStore>)var10.get(var13), RemoveReason.REMOVE);
            }
         }

         var7.setFlag(ChunkFlag.TICKING, false);
         this.store.removeEntity(var4, RemoveReason.REMOVE);
         int var31 = var3.loadedSectionCount.addAndGet(-10);
         if (var31 != 0) {
            throw new IllegalStateException(
               "Expected loadedSectionCount == 0 after column replacement at " + var2.getX() + ", " + var2.getZ() + ", got " + var31
            );
         }

         this.world.getNotificationHandler().updateChunk(var2.getIndex());
      }

      ChunkColumn var28 = var1.ensureAndGetComponent(ChunkColumn.getComponentType());
      Ref var29 = this.store.addEntity(var1, AddReason.SPAWN);
      if (var29 == null) {
         throw new UnsupportedOperationException("Unable to add the chunk to the world!");
      }

      Ref[] var6 = var28.getSections();
      Holder[] var30 = var28.takeSectionHolders();
      Holder[] var32 = new Holder[var6.length];
      boolean var33 = var2.is(ChunkFlag.TICKING);
      boolean var34 = var2.is(ChunkFlag.NEEDS_FORMAT_REWRITE);

      for (int var35 = 0; var35 < var6.length; var35++) {
         Holder var12 = var30[var35];
         var32[var35] = var12;
         var6[var35] = this.postLoadChunkSection(var29, var2.getX(), var35, var2.getZ(), var12, var2.is(ChunkFlag.NEWLY_GENERATED), var33);
         if (var34 && var6[var35] != null && var6[var35].isValid()) {
            ChunkSection var38 = this.store.getComponent(var6[var35], ChunkSection.getComponentType());
            if (var38 != null) {
               var38.markNeedsSaving();
            }

            EntitySection var14 = this.store.getComponent(var6[var35], EntitySection.getComponentType());
            if (var14 != null) {
               var14.markNeedsSaving();
            }
         }
      }

      BlockChunk var36 = var1.getComponent(BlockChunk.getComponentType());
      if (var36 != null) {
         var36.refreshSectionRefs(var32);
      }

      if (var34) {
         var2.markNeedsSaving();
         var2.setFlag(ChunkFlag.NEEDS_FORMAT_REWRITE, false);
      }

      var2.setReference(var29);
      long stampx = var3.lock.writeLock();

      try {
         var3.reference = var29;
         var3.flags = 0;
         var3.future = null;
         var3.throwable = null;
         var3.failedWhen = 0L;
         var3.failedCounter = 0;
         class="kw">return var29;
      } class="kw">finally {
         var3.lock.unlockWrite(stampx);
      }
   }

   class="kw">public void remove(@Nonnull Ref<ChunkStore> var1, @Nonnull RemoveReason var2) {
      this.world.debugAssertInTickingThread();
      WorldChunk var3 = this.store.getComponent(var1, WorldChunk.getComponentType());
      assert var3 != null;
      long var4 = var3.getIndex();
      ChunkStore.ChunkLoadState var6 = this.chunks.get(var4);
      long var7 = var6.lock.writeLock();

      try {
         var3.setFlag(ChunkFlag.TICKING, false);
         this.store.removeEntity(var1, var2);
         var6.reference = null;
         if (var6.future == null) {
            this.chunks.remove(var4, var6);
         }

         long var9 = this.lock.writeLock();

         try {
            for (int var11 = 0; var11 < 10; var11++) {
               ChunkStore.LoadState var12 = this.chunkSections.get(var3.getX(), var11, var3.getZ());
               if (var12 != null) {
                  if (var12.reference != null && var12.reference.isValid()) {
                     throw new IllegalStateException("Section reference was failed to be removed");
                  }

                  var12.reference = null;
                  if (var12.future == null) {
                     this.chunkSections.remove(var3.getX(), var11, var3.getZ());
                  }
               }
            }
         } class="kw">finally {
            this.lock.unlockWrite(var9);
         }

         int var21 = var6.loadedSectionCount.addAndGet(-10);
         if (var21 != 0) {
            throw new IllegalStateException("Expected loadedSectionCount == 0 after column unload at " + var3.getX() + ", " + var3.getZ() + ", got " + var21);
         }
      } class="kw">finally {
         var6.lock.unlockWrite(var7);
      }
   }

   class="kw">public void removeSection(@Nonnull Ref<ChunkStore> var1, @Nonnull RemoveReason var2) {
      this.world.debugAssertInTickingThread();
      ChunkSection var3 = this.store.getComponent(var1, ChunkSection.getComponentType());
      assert var3 != null;
      int var4 = var3.getX();
      int var5 = var3.getY();
      int var6 = var3.getZ();
      this.store.ensureComponent(var1, REGISTRY.getNonTickingComponentType());
      long var8 = this.lock.readLock();

      ChunkStore.LoadState var7;
      try {
         var7 = this.chunkSections.get(var4, var5, var6);
      } class="kw">finally {
         this.lock.unlockRead(var8);
      }

      if (var7 == null) {
         this.store.removeEntity(var1, var2);
      } else {
         long var10 = var7.lock.writeLock();

         try {
            this.store.removeEntity(var1, var2);
            var7.reference = null;
            long var12 = this.lock.writeLock();

            try {
               assert var7.future == null : "removeSection raced an in-flight section load at " + var4 + ", " + var5 + ", " + var6;
               this.chunkSections.remove(var4, var5, var6);
            } class="kw">finally {
               this.lock.unlockWrite(var12);
            }
         } class="kw">finally {
            var7.lock.unlockWrite(var10);
         }
      }

      ChunkStore.ChunkLoadState var28 = this.chunks.get(ChunkUtil.indexChunk(var4, var6));
      if (var28 != null) {
         var28.loadedSectionCount.decrementAndGet();
      }
   }

   @Nullable
   class="kw">public Ref<ChunkStore> getChunkReference(long var1) {
      ChunkStore.ChunkLoadState var3 = this.chunks.get(var1);
      if (var3 == null) {
         class="kw">return null;
      }

      long var4 = var3.lock.tryOptimisticRead();
      Ref var6 = var3.reference;
      if (var3.lock.validate(var4)) {
         class="kw">return var6;
      }

      var4 = var3.lock.readLock();

      try {
         class="kw">return var3.reference;
      } class="kw">finally {
         var3.lock.unlockRead(var4);
      }
   }

   class="kw">public boolean hasLoadedSections(long var1) {
      ChunkStore.ChunkLoadState var3 = this.chunks.get(var1);
      class="kw">return var3 != null && var3.loadedSectionCount.get() > 10;
   }

   @Nullable
   class="kw">public Ref<ChunkStore> getChunkSectionReference(int var1, int var2, int var3) {
      long var4 = this.lock.readLock();

      ChunkStore.LoadState var6;
      try {
         var6 = this.chunkSections.get(var1, var2, var3);
      } class="kw">finally {
         this.lock.unlockRead(var4);
      }

      if (var6 == null) {
         class="kw">return null;
      }

      long var7 = var6.lock.tryOptimisticRead();
      Ref var9 = var6.reference;
      if (var6.lock.validate(var7)) {
         class="kw">return var9;
      }

      var7 = var6.lock.readLock();

      try {
         class="kw">return var6.reference;
      } class="kw">finally {
         var6.lock.unlockRead(var7);
      }
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkSectionReferenceAsync(int var1, int var2, int var3) {
      class="kw">return this.getChunkSectionReferenceAsync(var1, var2, var3, 0);
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkSectionReferenceAsync(int var1, int var2, int var3, int var4) {
      if ((var4 & 3) == 3) {
         long var35 = this.lock.readLock();

         ChunkStore.LoadState var7;
         try {
            var7 = this.chunkSections.get(var1, var2, var3);
         } class="kw">finally {
            this.lock.unlockRead(var35);
         }

         if (var7 == null) {
            class="kw">return CompletableFuture.completedFuture(null);
         }

         long var36 = var7.lock.tryOptimisticRead();
         Ref var10 = var7.reference;
         if (var7.lock.validate(var36) && var10 != null) {
            class="kw">return CompletableFuture.completedFuture(var10);
         }

         var36 = var7.lock.readLock();

         try {
            if (var7.reference != null) {
               class="kw">return CompletableFuture.completedFuture(var7.reference);
            } else {
               class="kw">return var7.future == null ? CompletableFuture.completedFuture(null) : var7.future;
            }
         } class="kw">finally {
            var7.lock.unlockRead(var36);
         }
      } else {
         long var6 = this.lock.writeLock();

         ChunkStore.LoadState var5;
         try {
            var5 = this.chunkSections.get(var1, var2, var3);
            if (var5 == null) {
               this.chunkSections.put(var1, var2, var3, var5 = new ChunkStore.LoadState());
            }
         } class="kw">finally {
            this.lock.unlockWrite(var6);
         }

         ChunkStore.LoadState var8 = var5;
         long var9 = var5.lock.writeLock();

         try {
            if (var5.checkAndResetBackoff()) {
               class="kw">return CompletableFuture.failedFuture(new RuntimeException("Chunk section failure backoff", var5.throwable));
            }

            if (var5.future == null && var5.reference != null) {
               Ref var38 = var5.reference;
               if ((var4 & 4) == 0) {
                  class="kw">return CompletableFuture.completedFuture(var38);
               }

               var5.lock.unlockWrite(var9);
               var9 = 0L;
               if (this.world.isInThread() && (var4 & -2147483648) == 0) {
                  if (var38.isValid()) {
                     this.store.tryRemoveComponent(var38, REGISTRY.getNonTickingComponentType());
                  }

                  class="kw">return CompletableFuture.completedFuture(var38);
               } else {
                  class="kw">return CompletableFuture.supplyAsync(() -> {
                     if (var38.isValid()) {
                        this.store.tryRemoveComponent(var38, REGISTRY.getNonTickingComponentType());
                     }

                     class="kw">return var38;
                  }, this.world);
               }
            } else {
               boolean var11 = var5.future == null;
               if (var11) {
                  var5.flags = var4;
               }

               if ((var4 & 32) != 0) {
                  var5.flags |= 32;
               }

               if (var11) {
                  var5.future = this.getChunkReferenceAsync(ChunkUtil.indexChunk(var1, var3), var4).thenApply(var1x -> var8.reference).exceptionally(var1x -> {
                     var8.fail(var1x);
                     throw SneakyThrow.sneakyThrow(var1x);
                  });
               }

               if ((var11 || (var5.flags & 1) != 0) && (var4 & 1) == 0) {
                  if (!var11) {
                     var5.flags &= -2;
                  }

                  var5.future = var5.future
                     .thenCompose(
                        var6x -> {
                           if (var6x != null) {
                              class="kw">return CompletableFuture.completedFuture((Ref<ChunkStore>)var6x);
                           } else {
                              class="kw">return this.loader class="kw">instanceof IChunkLoader.Cubic var7
                                 ? var7.loadSectionHolder(var1, var2, var3)
                                    .thenApplyAsync(
                                       var4x -> var4x != null && !this.store.isShutdown()
                                          ? this.preLoadChunkSectionAsync((Holder<ChunkStore>)var4x, var1, var2, var3, false)
                                          : null
                                    )
                                    .thenApplyAsync(var5x -> {
                                       if (var5x != null && !this.store.isShutdown()) {
                                          boolean var6 = (var4 & 4) != 0;
                                          class="kw">return this.postLoadChunkSection(null, var1, var2, var3, (Holder<ChunkStore>)var5x, false, var6);
                                       } else {
                                          class="kw">return null;
                                       }
                                    }, this.world)
                                    .exceptionally(var4x -> {
                                       ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var4x))
                                          .log("Failed to load chunk section! %d, %d, %d", var1, var2, var3);
                                       var8.fail(var4x);
                                       throw SneakyThrow.sneakyThrow(var4x);
                                    })
                                 : CompletableFuture.completedFuture(null);
                           }
                        }
                     );
               }

               if ((var11 || (var5.flags & 2) != 0) && (var4 & 2) == 0) {
                  if (!var11) {
                     var5.flags &= -3;
                  }

                  int var12 = (int)this.world.getWorldConfig().getSeed();
                  var5.future = var5.future
                     .thenCompose(
                        var7x -> {
                           if (var7x != null) {
                              class="kw">return CompletableFuture.completedFuture((Ref<ChunkStore>)var7x);
                           }

                           IWorldGen.StillNeededSection var8 = (var4 & 16) != 0 ? this::isSectionStillNeeded : null;
                           long var10 = this.generatorLock.readLock();

                           CompletableFuture var9;
                           try {
                              if (this.generator == null) {
                                 var9 = this.generatorLoaded
                                    .thenCompose(
                                       var6x -> this.loader class="kw">instanceof IChunkLoader.Cubic && this.generator class="kw">instanceof IWorldGen.Cubic var7
                                          ? var7.generate(var12, var1, var2, var3, var8, this::fetchSectionPriority)
                                          : CompletableFuture.completedFuture(null)
                                    );
                              } else {
                                 if (!(this.loader class="kw">instanceof IChunkLoader.Cubic && this.generator class="kw">instanceof IWorldGen.Cubic var12)) {
                                    class="kw">return CompletableFuture.completedFuture(null);
                                 }

                                 var9 = var12.generate(var12, var1, var2, var3, var8, this::fetchSectionPriority);
                              }
                           } class="kw">finally {
                              this.generatorLock.unlockRead(var10);
                           }

                           class="kw">return var9.<Holder<ChunkStore>>thenApplyAsync(
                                 var4x -> var4x != null && !this.store.isShutdown()
                                    ? this.preLoadChunkSectionAsync((Holder<ChunkStore>)var4x, var1, var2, var3, true)
                                    : null
                              )
                              .thenApplyAsync(var5x -> {
                                 if (var5x != null && !this.store.isShutdown()) {
                                    boolean var6 = (var4 & 4) != 0;
                                    class="kw">return this.postLoadChunkSection(null, var1, var2, var3, (Holder<ChunkStore>)var5x, true, var6);
                                 } else {
                                    class="kw">return null;
                                 }
                              }, this.world)
                              .exceptionally(var4x -> {
                                 ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var4x))
                                    .log("Failed to generate chunk section! %d, %d, %d", var1, var2, var3);
                                 var8.fail(var4x);
                                 throw SneakyThrow.sneakyThrow(var4x);
                              });
                        }
                     );
               }

               if ((var11 || (var5.flags & 4) == 0) && (var4 & 4) != 0) {
                  var5.flags |= 4;
                  var5.future = var5.future.thenApplyAsync(var0 -> {
                     if (var0 != null && var0.isValid()) {
                        var0.getStore().tryRemoveComponent((Ref<ChunkStore>)var0, REGISTRY.getNonTickingComponentType());
                     }

                     class="kw">return var0;
                  }, this.world);
               }

               if (!var5.cleanupAttached) {
                  var5.cleanupAttached = true;
                  var5.future = var5.future
                     .whenCompleteAsync(
                        (var5x, var6x) -> {
                           if (var6x == null && var5x == null) {
                              try {
                                 long var7 = var8.lock.writeLock();

                                 try {
                                    if (var8.reference == null) {
                                       long var9 = this.lock.writeLock();

                                       try {
                                          ChunkStore.LoadState var11 = this.chunkSections.get(var1, var2, var3);
                                          if (var11 == var8) {
                                             this.chunkSections.remove(var1, var2, var3);
                                             var8.future = null;
                                          }

                                          class="kw">return;
                                       } class="kw">finally {
                                          this.lock.unlockWrite(var9);
                                       }
                                    }
                                 } class="kw">finally {
                                    var8.lock.unlockWrite(var7);
                                 }
                              } catch (Throwable var22) {
                                 ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var22))
                                    .log("Failed to clean up empty section state %d, %d, %d", var1, var2, var3);
                              }
                           }
                        },
                        this.world
                     );
               }

               class="kw">return var5.future;
            }
         } class="kw">finally {
            if (var9 != 0L) {
               var5.lock.unlockWrite(var9);
            }
         }
      }
   }

   @Nonnull
   class="kw">private Holder<ChunkStore> preLoadChunkSectionAsync(@Nonnull Holder<ChunkStore> var1, int var2, int var3, int var4, boolean var5) {
      if (!var1.getArchetype().contains(ChunkSection.getComponentType())) {
         var1.putComponent(ChunkSection.getComponentType(), new ChunkSection(null, var2, var3, var4, var5 && this.world.getWorldConfig().shouldSaveNewChunks()));
      }

      long var6 = System.nanoTime();
      IEventDispatcher var8 = HytaleServer.get().getEventBus().dispatchFor(ChunkSectionPreLoadProcessEvent.class, this.world.getName());
      if (var8.hasListener()) {
         ChunkSectionPreLoadProcessEvent var9 = var8.dispatch(new ChunkSectionPreLoadProcessEvent(this.world, var1, var5, var6));
         if (!var9.didLog()) {
            long var10 = System.nanoTime();
            long var12 = var10 - var6;
            if (var12 > this.world.getTickStepNanos()) {
               LOGGER.at(Level.SEVERE)
                  .log(
                     "Took too long to pre-load process chunk section: %s > TICK_STEP, Has GC Run: %s, %s",
                     FormatUtil.nanosToString(var12),
                     this.world.consumeGCHasRun(),
                     var1
                  );
            }
         }
      }

      class="kw">return var1;
   }

   @Nullable
   class="kw">private Ref<ChunkStore> postLoadChunkSection(
      @Nullable Ref<ChunkStore> var1, int var2, int var3, int var4, @Nonnull Holder<ChunkStore> var5, boolean var6, boolean var7
   ) {
      AddReason var8 = var6 ? AddReason.SPAWN : AddReason.LOAD;
      if (var1 == null) {
         var1 = this.getChunkReference(ChunkUtil.indexChunk(var2, var4));
      }

      if (var1 == null) {
         class="kw">return null;
      }

      boolean var9 = this.world.getWorldConfig().shouldSaveNewChunks() && var8 == AddReason.SPAWN;
      ChunkSection var10 = var5.getComponent(ChunkSection.getComponentType());
      if (var10 != null) {
         assert var10.getX() == var2;
         assert var10.getY() == var3;
         assert var10.getZ() == var4;
         if (var9) {
            var10.markNeedsSaving();
         }

         var10.updateChunkColumnReference(var1);
      } else {
         var5.putComponent(ChunkSection.getComponentType(), new ChunkSection(var1, var2, var3, var4, var9));
      }

      if (!var7) {
         var5.ensureComponent(REGISTRY.getNonTickingComponentType());
      } else {
         var5.tryRemoveComponent(REGISTRY.getNonTickingComponentType());
      }

      Ref var11 = this.store.addEntity(var5, var8);
      long var12 = this.lock.writeLock();

      try {
         ChunkStore.LoadState var14 = this.chunkSections.get(var2, var3, var4);
         if (var14 == null) {
            var14 = new ChunkStore.LoadState();
            var14.reference = var11;
            this.chunkSections.put(var2, var3, var4, var14);
         } else {
            var14.reference = var11;
            var14.future = null;
            var14.cleanupAttached = false;
         }
      } class="kw">finally {
         this.lock.unlockWrite(var12);
      }

      ChunkStore.ChunkLoadState var19 = this.chunks.get(ChunkUtil.indexChunk(var2, var4));
      if (var19 != null) {
         var19.loadedSectionCount.incrementAndGet();
      }

      class="kw">return var11;
   }

   @Nullable
   class="kw">public Ref<ChunkStore> getChunkSectionReferenceAtBlock(int var1, int var2, int var3) {
      class="kw">return this.getChunkSectionReference(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3));
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkSectionReferenceAtBlockAsync(int var1, int var2, int var3) {
      class="kw">return this.getChunkSectionReferenceAsync(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3));
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkSectionReferenceAtBlockAsync(int var1, int var2, int var3, int var4) {
      class="kw">return this.getChunkSectionReferenceAsync(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3), var4);
   }

   @Nullable
   class="kw">public <T class="kw">extends Component<ChunkStore>> T getChunkComponent(long var1, @Nonnull ComponentType<ChunkStore, T> var3) {
      Ref var4 = this.getChunkReference(var1);
      class="kw">return var4 != null && var4.isValid() ? this.store.getComponent(var4, var3) : null;
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkReferenceAsync(long var1) {
      class="kw">return this.getChunkReferenceAsync(var1, 0);
   }

   @Nonnull
   class="kw">public CompletableFuture<Ref<ChunkStore>> getChunkReferenceAsync(long var1, int var3) {
      if (this.store.isShutdown()) {
         class="kw">return CompletableFuture.completedFuture(null);
      }

      ChunkStore.ChunkLoadState var4;
      if ((var3 & 3) == 3) {
         var4 = this.chunks.get(var1);
         if (var4 == null) {
            class="kw">return CompletableFuture.completedFuture(null);
         }

         long var5 = var4.lock.readLock();

         try {
            if ((var3 & 4) == 0 || (var4.flags & 4) != 0) {
               if (var4.reference != null) {
                  class="kw">return CompletableFuture.completedFuture(var4.reference);
               }

               if (var4.future == null) {
                  class="kw">return CompletableFuture.completedFuture(null);
               }

               class="kw">return var4.future;
            }
         } class="kw">finally {
            var4.lock.unlockRead(var5);
         }
      } else {
         var4 = this.chunks.computeIfAbsent(var1, var0 -> new ChunkStore.ChunkLoadState());
      }

      long var28 = var4.lock.writeLock();
      if (var4.future == null && var4.reference != null && (var3 & 8) == 0) {
         Ref var29 = var4.reference;
         if ((var3 & 4) == 0) {
            var4.lock.unlockWrite(var28);
            class="kw">return CompletableFuture.completedFuture(var29);
         } else if (this.world.isInThread() && (var3 & -2147483648) == 0) {
            var4.lock.unlockWrite(var28);
            WorldChunk var30 = this.store.getComponent(var29, WorldChunk.getComponentType());
            assert var30 != null;
            var30.setFlag(ChunkFlag.TICKING, true);
            class="kw">return CompletableFuture.completedFuture(var29);
         } else {
            var4.lock.unlockWrite(var28);
            class="kw">return CompletableFuture.supplyAsync(() -> {
               WorldChunk var2 = this.store.getComponent(var29, WorldChunk.getComponentType());
               assert var2 != null;
               var2.setFlag(ChunkFlag.TICKING, true);
               class="kw">return var29;
            }, this.world);
         }
      } else {
         try {
            if (var4.checkAndResetBackoff()) {
               class="kw">return CompletableFuture.failedFuture(new RuntimeException("Chunk failure backoff", var4.throwable));
            }

            boolean var7 = var4.future == null;
            if (var7) {
               var4.flags = var3;
            }

            if ((var3 & 32) != 0) {
               var4.flags |= 32;
            }

            int var8 = ChunkUtil.xOfChunkIndex(var1);
            int var9 = ChunkUtil.zOfChunkIndex(var1);
            if ((var7 || (var4.flags & 1) != 0) && (var3 & 1) == 0) {
               if (var4.future == null) {
                  var4.future = this.loader.loadHolder(var8, var9).thenApplyAsync(var3x -> {
                     if (var3x != null && !this.store.isShutdown()) {
                        this.totalLoadedChunksCount.getAndIncrement();
                        class="kw">return this.preLoadChunkAsync(var1, (Holder<ChunkStore>)var3x, false);
                     } else {
                        class="kw">return null;
                     }
                  }).thenApplyAsync(this::postLoadChunk, this.world).exceptionally(var3x -> {
                     ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var3x)).log("Failed to load chunk! %s, %s", var8, var9);
                     var4.fail(var3x);
                     throw SneakyThrow.sneakyThrow(var3x);
                  });
               } else {
                  var4.flags &= -2;
                  var4.future = var4.future
                     .thenCompose(
                        var6 -> var6 != null
                           ? CompletableFuture.completedFuture((Ref<ChunkStore>)var6)
                           : this.loader.loadHolder(var8, var9).thenApplyAsync(var3x -> {
                              if (var3x != null && !this.store.isShutdown()) {
                                 this.totalLoadedChunksCount.getAndIncrement();
                                 class="kw">return this.preLoadChunkAsync(var1, (Holder<ChunkStore>)var3x, false);
                              } else {
                                 class="kw">return null;
                              }
                           }).thenApplyAsync(this::postLoadChunk, this.world).exceptionally(var3x -> {
                              ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var3x)).log("Failed to load chunk! %s, %s", var8, var9);
                              var4.fail(var3x);
                              throw SneakyThrow.sneakyThrow(var3x);
                           })
                     );
               }
            }

            if ((var7 || (var4.flags & 2) != 0) && (var3 & 2) == 0) {
               int var10 = (int)this.world.getWorldConfig().getSeed();
               if (var4.future == null) {
                  long var12 = this.generatorLock.readLock();

                  CompletableFuture var11;
                  try {
                     if (this.generator == null) {
                        var11 = this.generatorLoaded
                           .thenCompose(
                              var7x -> this.generator
                                 .generate(var10, var1, var8, var9, (var3 & 16) != 0 ? this::isChunkStillNeeded : null, this::fetchColumnPriority)
                           );
                     } else {
                        var11 = this.generator.generate(var10, var1, var8, var9, (var3 & 16) != 0 ? this::isChunkStillNeeded : null, this::fetchColumnPriority);
                     }
                  } class="kw">finally {
                     this.generatorLock.unlockRead(var12);
                  }

                  var4.future = var11.<Holder<ChunkStore>>thenApplyAsync(var3x -> {
                     if (var3x != null && !this.store.isShutdown()) {
                        this.totalGeneratedChunksCount.getAndIncrement();
                        class="kw">return this.preLoadChunkAsync(var1, var3x.toHolder(this.world), true);
                     } else {
                        class="kw">return null;
                     }
                  }).thenApplyAsync(this::postLoadChunk, this.world).exceptionally(var3x -> {
                     ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var3x)).log("Failed to generate chunk! %s, %s", var8, var9);
                     var4.fail(var3x);
                     throw SneakyThrow.sneakyThrow(var3x);
                  });
               } else {
                  var4.flags &= -3;
                  var4.future = var4.future.thenCompose(var7x -> {
                     if (var7x != null) {
                        class="kw">return CompletableFuture.completedFuture((Ref<ChunkStore>)var7x);
                     }

                     LongPredicate var8 = var1x -> this.world.isAlive();
                     long var10 = this.generatorLock.readLock();

                     CompletableFuture var9;
                     try {
                        if (this.generator == null) {
                           var9 = this.generatorLoaded.thenCompose(var7xx -> this.generator.generate(var10, var1, var8, var9, var8, this::fetchColumnPriority));
                        } else {
                           var9 = this.generator.generate(var10, var1, var8, var9, var8, this::fetchColumnPriority);
                        }
                     } class="kw">finally {
                        this.generatorLock.unlockRead(var10);
                     }

                     class="kw">return var9.<Holder<ChunkStore>>thenApplyAsync(var3x -> {
                        if (var3x != null && !this.store.isShutdown()) {
                           this.totalGeneratedChunksCount.getAndIncrement();
                           class="kw">return this.preLoadChunkAsync(var1, var3x.toHolder(this.world), true);
                        } else {
                           class="kw">return null;
                        }
                     }).thenApplyAsync(this::postLoadChunk, this.world).exceptionally(var3x -> {
                        ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var3x)).log("Failed to generate chunk! %s, %s", var8, var9);
                        var4.fail(var3x);
                        throw SneakyThrow.sneakyThrow(var3x);
                     });
                  });
               }
            }

            if ((var7 || (var4.flags & 4) == 0) && (var3 & 4) != 0) {
               var4.flags |= 4;
               if (var4.future != null) {
                  var4.future = var4.future.<Ref<ChunkStore>>thenApplyAsync(var1x -> {
                     if (var1x != null) {
                        WorldChunk var2 = this.store.getComponent((Ref<ChunkStore>)var1x, WorldChunk.getComponentType());
                        assert var2 != null;
                        var2.setFlag(ChunkFlag.TICKING, true);
                     }

                     class="kw">return var1x;
                  }, this.world).exceptionally(var3x -> {
                     ((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var3x)).log("Failed to set chunk ticking! %s, %s", var8, var9);
                     var4.fail(var3x);
                     throw SneakyThrow.sneakyThrow(var3x);
                  });
               }
            }

            class="kw">return var4.future == null ? CompletableFuture.completedFuture(null) : var4.future;
         } class="kw">finally {
            var4.lock.unlockWrite(var28);
         }
      }
   }

   class="kw">private boolean isSectionStillNeeded(int var1, int var2, int var3) {
      if (var2 >= 0 && var2 < 10) {
         class="kw">return this.isChunkStillNeeded(ChunkUtil.indexChunk(var1, var3));
      }

      for (PlayerRef var5 : this.world.getPlayerRefs()) {
         if (var5.getChunkTracker().shouldBeVisible(var1, var2, var3)) {
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">private boolean isChunkStillNeeded(long var1) {
      for (PlayerRef var4 : this.world.getPlayerRefs()) {
         if (var4.getChunkTracker().shouldBeVisible(var1)) {
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">private float fetchSectionPriority(int var1, int var2, int var3) {
      long var4 = this.lock.readLock();

      try {
         ChunkStore.LoadState var6 = this.chunkSections.get(var1, var2, var3);
         if (var6 != null && (var6.flags & 32) != 0) {
            class="kw">return -1.0F;
         }
      } class="kw">finally {
         this.lock.unlockRead(var4);
      }

      float var11 = Float.MAX_VALUE;

      for (PlayerRef var8 : this.world.getPlayerRefs()) {
         if (var8.getChunkTracker().shouldBeVisible(var1, var2, var3)) {
            var11 = Math.min(var11, var8.getChunkTracker().calculateSectionPriority(var1, var2, var3));
         }
      }

      class="kw">return var11;
   }

   class="kw">private float fetchColumnPriority(long var1) {
      ChunkStore.ChunkLoadState var3 = this.chunks.get(var1);
      if (var3 != null && (var3.flags & 32) != 0) {
         class="kw">return -1.0F;
      }

      float var4 = Float.MAX_VALUE;
      int var5 = ChunkUtil.xOfChunkIndex(var1);
      int var6 = ChunkUtil.zOfChunkIndex(var1);

      for (PlayerRef var8 : this.world.getPlayerRefs()) {
         if (var8.getChunkTracker().shouldBeVisible(var1)) {
            var4 = Math.min(var4, var8.getChunkTracker().calculateColumnPriority(var5, var6));
         }
      }

      class="kw">return var4;
   }

   class="kw">public boolean isChunkOnBackoff(long var1, long var3) {
      ChunkStore.ChunkLoadState var5 = this.chunks.get(var1);
      if (var5 == null) {
         class="kw">return false;
      }

      long var6 = var5.lock.readLock();

      try {
         class="kw">return var5.isOnBackoff(var3);
      } class="kw">finally {
         var5.lock.unlockRead(var6);
      }
   }

   class="kw">public boolean isChunkSectionOnBackoff(int var1, int var2, int var3, long var4) {
      long var7 = this.lock.readLock();

      ChunkStore.LoadState var6;
      try {
         var6 = this.chunkSections.get(var1, var2, var3);
      } class="kw">finally {
         this.lock.unlockRead(var7);
      }

      if (var6 == null) {
         class="kw">return false;
      }

      long var9 = var6.lock.readLock();

      try {
         class="kw">return var6.isOnBackoff(var4);
      } class="kw">finally {
         var6.lock.unlockRead(var9);
      }
   }

   @Nonnull
   class="kw">private Holder<ChunkStore> preLoadChunkAsync(long var1, @Nonnull Holder<ChunkStore> var3, boolean var4) {
      WorldChunk var5 = var3.getComponent(WorldChunk.getComponentType());
      int var6 = ChunkUtil.xOfChunkIndex(var1);
      int var7 = ChunkUtil.zOfChunkIndex(var1);
      if (var5 == null) {
         throw new IllegalStateException(String.format("Holder missing WorldChunk component! (%d, %d)", var6, var7));
      }

      if (var5.getIndex() != var1) {
         throw new IllegalStateException(String.format("Incorrect chunk index! Got (%d, %d) expected (%d, %d)", var5.getX(), var5.getZ(), var6, var7));
      }

      BlockChunk var8 = var3.getComponent(BlockChunk.getComponentType());
      if (var8 == null) {
         throw new IllegalStateException(String.format("Holder missing BlockChunk component! (%d, %d)", var6, var7));
      }

      ChunkColumn var9 = var3.getComponent(ChunkColumn.getComponentType());
      Holder[] var10 = var9.getSectionHolders();
      if (var10 == null) {
         var10 = new Holder[var9.getSections().length];
      }

      for (int var11 = 0; var11 < var10.length; var11++) {
         Holder var12 = var10[var11] == null ? REGISTRY.newHolder() : var10[var11];
         if (!var12.getArchetype().contains(ChunkSection.getComponentType())) {
            var12.putComponent(
               ChunkSection.getComponentType(), new ChunkSection(null, var6, var11, var7, var4 && this.world.getWorldConfig().shouldSaveNewChunks())
            );
         }

         var10[var11] = var12;
      }

      var9.putSectionHolders(var10);
      var8.loadFromHolder(var3);
      var5.setFlag(ChunkFlag.NEWLY_GENERATED, var4);
      var5.setFlag(ChunkFlag.ON_DISK, !var4);
      var5.setLightingUpdatesEnabled(false);
      if (var4 && this.world.getWorldConfig().shouldSaveNewChunks()) {
         var5.markNeedsSaving();
      }

      try {
         long var22 = System.nanoTime();
         IEventDispatcher var13 = HytaleServer.get().getEventBus().dispatchFor(ChunkPreLoadProcessEvent.class, this.world.getName());
         if (var13.hasListener()) {
            ChunkPreLoadProcessEvent var14 = var13.dispatch(new ChunkPreLoadProcessEvent(var3, var5, var4, var22));
            if (!var14.didLog()) {
               long var15 = System.nanoTime();
               long var17 = var15 - var22;
               if (var17 > this.world.getTickStepNanos()) {
                  LOGGER.at(Level.SEVERE)
                     .log(
                        "Took too long to pre-load process chunk: %s > TICK_STEP, Has GC Run: %s, %s",
                        FormatUtil.nanosToString(var17),
                        this.world.consumeGCHasRun(),
                        var5
                     );
               }
            }
         }
      } class="kw">finally {
         var5.setLightingUpdatesEnabled(true);
      }

      for (int var23 = 0; var23 < var10.length; var23++) {
         Holder var24 = var10[var23];
         var10[var23] = this.preLoadChunkSectionAsync(var24, var6, var23, var7, var5.is(ChunkFlag.NEWLY_GENERATED));
      }

      var9.putSectionHolders(var10);
      class="kw">return var3;
   }

   @Nullable
   class="kw">private Ref<ChunkStore> postLoadChunk(@Nullable Holder<ChunkStore> var1) {
      this.world.debugAssertInTickingThread();
      if (var1 != null && !this.store.isShutdown()) {
         long var2 = System.nanoTime();
         WorldChunk var4 = var1.getComponent(WorldChunk.getComponentType());
         assert var4 != null;
         var4.setFlag(ChunkFlag.START_INIT, true);
         if (var4.is(ChunkFlag.TICKING)) {
            var1.tryRemoveComponent(REGISTRY.getNonTickingComponentType());
         } else {
            var1.ensureComponent(REGISTRY.getNonTickingComponentType());
         }

         Ref var5 = this.add(var1);
         var4.initFlags();
         this.world.getChunkLighting().init(var4);
         long var6 = System.nanoTime();
         long var8 = var6 - var2;
         if (var8 > this.world.getTickStepNanos()) {
            LOGGER.at(Level.SEVERE)
               .log(
                  "Took too long to post-load process chunk: %s > TICK_STEP, Has GC Run: %s, %s",
                  FormatUtil.nanosToString(var8),
                  this.world.consumeGCHasRun(),
                  var4
               );
         }

         class="kw">return var5;
      } else {
         class="kw">return null;
      }
   }

   class="kw">public void pauseBackgroundSaving(ChunkSavingSystems.Data var1) {
      if (this.saver != null) {
         this.saver.pauseBackgroundSaving(var1);
      }
   }

   @Nonnull
   class="kw">public CompletableFuture<Void> resumeBackgroundSaving() {
      class="kw">return this.saver != null ? this.saver.resumeBackgroundSaving() : CompletableFuture.completedFuture(null);
   }

   class="kw">static {
      CodecStore.STATIC.putCodecSupplier(HOLDER_CODEC_KEY, REGISTRY::getEntityCodec);
      REGISTRY.registerSystem(new ChunkStore.ChunkLoaderSaverSetupSystem());
      REGISTRY.registerSystem(new ChunkUnloadingSystem());
      REGISTRY.registerSystem(new SectionUnloadingSystem());
      REGISTRY.registerSystem(new ChunkSavingSystems.WorldRemoved());
      REGISTRY.registerSystem(new ChunkSavingSystems.Ticking());
   }

   class="kw">private class="kw">static class ChunkLoadState class="kw">extends ChunkStore.LoadState {
      class="kw">final AtomicInteger loadedSectionCount = new AtomicInteger();

      class="kw">private ChunkLoadState() {
      }
   }

   class="kw">public class="kw">static class ChunkLoaderSaverSetupSystem class="kw">extends StoreSystem<ChunkStore> {
      class="kw">private class="kw">final ResourceType<ChunkStore, ChunkStore.ChunkStorage> chunkStorageResourceType = this.registerResource(
         ChunkStore.ChunkStorage.class, "ChunkStorage", ChunkStore.ChunkStorage.CODEC
      );

      class="kw">public ChunkLoaderSaverSetupSystem() {
      }

      @Nullable
      @Override
      class="kw">public SystemGroup<ChunkStore> getGroup() {
         class="kw">return ChunkStore.INIT_GROUP;
      }

      @Override
      class="kw">public void onSystemAddedToStore(@Nonnull Store<ChunkStore> var1) {
         ChunkStore var2 = var1.getExternalData();
         World var3 = var2.getWorld();
         IChunkStorageProvider var4 = var3.getWorldConfig().getChunkStorageProvider();
         ChunkStore.ChunkStorage var5 = var1.getResource(this.chunkStorageResourceType);
         if (var5.currentProvider != null && !var5.currentProvider.isSame(var4)) {
            IChunkStorageProvider var6 = var5.currentProvider;
            var2.pendingStorageMigration = () -> {
               try {
                  var2.storageData = var4.migrateFrom(var1, var6);
                  var5.currentProvider = var4;
                  var2.loader = ((IChunkStorageProvider<Object>)var4).getLoader(var2.storageData, var1);
                  var2.saver = ((IChunkStorageProvider<Object>)var4).getSaver(var2.storageData, var1);
               } catch (IOException var6) {
                  throw SneakyThrow.sneakyThrow(var6);
               }
            };
         } else {
            try {
               var2.storageData = var4.initialize(var1);
               var5.currentProvider = var4;
               var2.loader = ((IChunkStorageProvider<Object>)var4).getLoader(var2.storageData, var1);
               var2.saver = ((IChunkStorageProvider<Object>)var4).getSaver(var2.storageData, var1);
            } catch (IOException var7) {
               throw SneakyThrow.sneakyThrow(var7);
            }
         }
      }

      @Override
      class="kw">public void onSystemRemovedFromStore(@Nonnull Store<ChunkStore> var1) {
         ChunkStore var2 = var1.getExternalData();

         try {
            if (var2.loader != null) {
               IChunkLoader var3 = var2.loader;
               var2.loader = null;
               var3.close();
            }

            if (var2.saver != null) {
               IChunkSaver var6 = var2.saver;
               var2.saver = null;
               var6.close();
            }

            World var7 = var2.getWorld();
            IChunkStorageProvider var4 = var7.getWorldConfig().getChunkStorageProvider();
            ((IChunkStorageProvider<Object>)var4).close(var2.storageData, var1);
         } catch (IOException var5) {
            ((HytaleLogger.Api)ChunkStore.LOGGER.at(Level.SEVERE).withCause(var5)).log("Failed to close storage!");
         }
      }
   }

   class="kw">private class="kw">static class ChunkStorage class="kw">implements Resource<ChunkStore> {
      class="kw">public class="kw">static class="kw">final BuilderCodec<ChunkStore.ChunkStorage> CODEC = BuilderCodec.builder(ChunkStore.ChunkStorage.class, ChunkStore.ChunkStorage::new)
         .append(new KeyedCodec<>("CurrentProvider", IChunkStorageProvider.CODEC), (var0, var1) -> var0.currentProvider = var1, var0 -> var0.currentProvider)
         .add()
         .build();
      @Nullable
      class="kw">private IChunkStorageProvider<?> currentProvider;

      class="kw">public ChunkStorage(@Nullable IChunkStorageProvider<?> var1) {
         this.currentProvider = var1;
      }

      class="kw">public ChunkStorage() {
      }

      @Nullable
      @Override
      class="kw">public Resource<ChunkStore> clone() {
         class="kw">return new ChunkStore.ChunkStorage(this.currentProvider);
      }
   }

   class="kw">public class="kw">abstract class="kw">static class LoadFuturePacketDataQuerySystem class="kw">extends EntityDataSystem<ChunkStore, PlayerRef, CompletableFuture<ToClientPacket>> {
      class="kw">public LoadFuturePacketDataQuerySystem() {
      }
   }

   class="kw">public class="kw">abstract class="kw">static class LoadPacketDataQuerySystem class="kw">extends EntityDataSystem<ChunkStore, PlayerRef, ToClientPacket> {
      class="kw">public LoadPacketDataQuerySystem() {
      }
   }

   class="kw">private class="kw">static class LoadState {
      class="kw">final StampedLock lock = new StampedLock();
      int flags = 0;
      @Nullable
      CompletableFuture<Ref<ChunkStore>> future;
      @Nullable
      class="kw">volatile Ref<ChunkStore> reference;
      @Nullable
      Throwable throwable;
      long failedWhen;
      int failedCounter;
      boolean cleanupAttached;

      class="kw">private LoadState() {
      }

      void fail(Throwable var1) {
         long var2 = this.lock.writeLock();

         try {
            this.flags = 0;
            this.future = null;
            this.cleanupAttached = false;
            this.throwable = var1;
            this.failedWhen = System.nanoTime();
            this.failedCounter++;
         } class="kw">finally {
            this.lock.unlockWrite(var2);
         }
      }

      boolean isOnBackoff(long var1) {
         if (this.throwable == null) {
            class="kw">return false;
         }

         long var3 = System.nanoTime() - this.failedWhen;
         class="kw">return var3 < Math.min(var1, (long)this.failedCounter * this.failedCounter * ChunkStore.FAILURE_BACKOFF_NANOS);
      }

      boolean checkAndResetBackoff() {
         if (this.isOnBackoff(ChunkStore.MAX_FAILURE_BACKOFF_NANOS)) {
            class="kw">return true;
         }

         this.throwable = null;
         this.failedWhen = 0L;
         class="kw">return false;
      }
   }

   class="kw">public class="kw">abstract class="kw">static class UnloadPacketDataQuerySystem class="kw">extends EntityDataSystem<ChunkStore, PlayerRef, ToClientPacket> {
      class="kw">public UnloadPacketDataQuerySystem() {
      }
   }
}