ChunkStore class

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

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

implements: WorldProvider

Поля (186)

МодификаторыТипИмя
public static final BuilderCodec<ChunkStore.ChunkStorage> CODEC
break
private final ResourceType<ChunkStore, ChunkStore.ChunkStorage> chunkStorageResourceType
boolean cleanupAttached
int failedCounter
long failedWhen
int flags
CompletableFuture<Ref<ChunkStore>> future
final AtomicInteger loadedSectionCount
final StampedLock lock
volatile Ref<ChunkStore> reference
return
long stampx
Throwable throwable
long var1
long var1
long var1
var1
ObjectArrayList var10
long var10
Ref var10
long var10
long var10
ChunkSection var10
int var10
long var10
Holder[] var10
var10
long var11
boolean var11
ChunkStore.LoadState var11
Ref var11
CompletableFuture var11
var11
var11
float var11
var11
Holder var12
ChunkStore.LoadState var12
long var12
int var12
long var12
long var12
long var12
Holder var12
IEventDispatcher var13
EntitySection var14
ChunkStore.LoadState var14
var14
ChunkPreLoadProcessEvent var14
long var15
long var17
ChunkStore.ChunkLoadState var19
long var2
Runnable var2
WorldChunk var2
WorldChunk var2
WorldChunk var2
long var2
ChunkStore var2
ChunkStore var2
long var2
int var21
long var22
Holder var24
ChunkColumn var28
ChunkStore.ChunkLoadState var28
long var28
Ref var29
Ref var29
boolean var3
var3
var3
ChunkStore.ChunkLoadState var3
WorldChunk var3
ChunkSection var3
ChunkStore.ChunkLoadState var3
ChunkStore.ChunkLoadState var3
ChunkStore.ChunkLoadState var3
World var3
IChunkLoader var3
long var3
Holder[] var30
WorldChunk var30
int var31
Holder[] var32
boolean var33
boolean var34
long var35
BlockChunk var36
long var36
var36
ChunkSection var38
Ref var38
ObjectIterator var4
Ref var4
var4
long var4
int var4
long var4
var4
long var4
Ref var4
ChunkStore.ChunkLoadState var4
var4
var4
long var4
float var4
var4
WorldChunk var4
IChunkStorageProvider var4
IChunkStorageProvider var4
Entry var5
long var5
int var5
ChunkStore.LoadState var5
var5
long var5
int var5
ChunkStore.ChunkLoadState var5
WorldChunk var5
Ref var5
ChunkStore.ChunkStorage var5
ChunkStore.ChunkLoadState var6
Ref[] var6
ChunkStore.ChunkLoadState var6
int var6
Ref var6
ChunkStore.LoadState var6
var6
long var6
boolean var6
boolean var6
long var6
ChunkStore.LoadState var6
int var6
long var6
ChunkStore.LoadState var6
var6
int var6
long var6
IChunkStorageProvider var6
IChunkSaver var6
long var7
WorldChunk var7
Ref var7
long var7
ChunkStore.LoadState var7
var7
long var7
var7
ChunkStore.LoadState var7
var7
long var7
boolean var7
long var7
int var7
World var7
int var8
long var8
ChunkStore.LoadState var8
IWorldGen.StillNeededSection var8
IEventDispatcher var8
AddReason var8
int var8
LongPredicate var8
BlockChunk var8
long var8
CompletableFuture var9
int var9
long var9
Ref var9
long var9
var9
CompletableFuture var9
var9
var9
long var9
ChunkSectionPreLoadProcessEvent var9
boolean var9
int var9
CompletableFuture var9
var9
var9
long var9
ChunkColumn var9

Методы (110)

МодификаторыВозвратСигнатура
private ChunkLoadStateprivate ChunkLoadState()
public ChunkLoaderSaverSetupSystempublic ChunkLoaderSaverSetupSystem()
public ChunkStoragepublic ChunkStorage(@Nullable IChunkStorageProvider<?> var1)
public ChunkStoragepublic ChunkStorage()
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Expected the ChunkLoadState to exist!")
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Expected the ChunkLoadState to have a future!")
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Section reference was failed to be removed")
public LoadFuturePacketDataQuerySystempublic LoadFuturePacketDataQuerySystem()
public LoadPacketDataQuerySystempublic LoadPacketDataQuerySystem()
private LoadStateprivate LoadState()
public UnloadPacketDataQuerySystempublic UnloadPacketDataQuerySystem()
abstract throw new UnsupportedOperationExceptionthrow new UnsupportedOperationException("Unable to add the chunk to the world!")
boolean checkAndResetBackoffboolean checkAndResetBackoff()
public Resource<ChunkStore> clonepublic Resource<ChunkStore> clone()
void failvoid fail(Throwable var1)
private float fetchColumnPriorityfloat fetchColumnPriority(long var1)
private float fetchSectionPriorityfloat fetchSectionPriority(int var1, int var2, int var3)
for for(int var35 = 0; var35 < var6.length; var35++)
for for(int var11 = 0; var11 < 10; var11++)
for for(int var11 = 0; var11 < var10.length; var11++)
for for(int var23 = 0; var23 < var10.length; var23++)
abstract for for(int var13 = 0; var13 < var10.size()
public SystemGroup<ChunkStore> getGrouppublic SystemGroup<ChunkStore> getGroup()
public int getLoadedChunksCountint getLoadedChunksCount()
public Object getStorageDataObject getStorageData()
public int getTotalGeneratedChunksCountint getTotalGeneratedChunksCount()
public int getTotalLoadedChunksCountint getTotalLoadedChunksCount()
public boolean hasLoadedSectionsboolean hasLoadedSections(long var1)
if if(this.loader instanceof IChunkLoader.Cubic)
if if(this.generator != null)
if if(var1 != null)
if if(this.pendingStorageMigration != null)
if if(var3 == null)
if if(var3.future == null)
if if(var3.reference != null)
if if(var4 != null)
if if(var31 != 0)
if if(var29 == null)
if if(var38 != null)
if if(var14 != null)
if if(var36 != null)
if if(var34)
if if(var6.future == null)
if if(var12 != null)
if if(var12.future == null)
if if(var21 != 0)
if if(var7 == null)
if if(var28 != null)
if if(var3 == null)
if if(var6 == null)
if if(var7 == null)
if if(var7.reference != null)
if if(var5 == null)
if if(var5.future == null && var5.reference != null)
if if(var11)
if if(var11)
if if(!var11)
if if(var6x != null)
if if(!var11)
if if(var7x != null)
if if(this.generator == null)
if if(!var5.cleanupAttached)
if if(var6x == null && var5x == null)
if if(var8.reference == null)
if if(var11 == var8)
if if(var9 != 0L)
if if(var1 == null)
if if(var1 == null)
if if(var10 != null)
if if(var9)
if if(!var7)
if if(var14 == null)
if if(var19 != null)
if if(var4 == null)
if if(var4.reference != null)
if if(var4.future == null)
if if(var7)
if if(var4.future == null)
if if(var4.future == null)
if if(this.generator == null)
if if(var7x != null)
if if(this.generator == null)
if if(var4.future != null)
if if(var1x != null)
if if(var2 >= 0 && var2 < 10)
if if(var5 == null)
if if(var6 == null)
if if(var5 == null)
if if(var8 == null)
if if(var10 == null)
if if(this.saver != null)
if if(var2.loader != null)
if if(var2.saver != null)
if if(this.throwable == null)
public boolean isChunkOnBackoffboolean isChunkOnBackoff(long var1, long var3)
public boolean isChunkSectionOnBackoffboolean isChunkSectionOnBackoff(int var1, int var2, int var3, long var4)
private boolean isChunkStillNeededboolean isChunkStillNeeded(long var1)
boolean isOnBackoffboolean isOnBackoff(long var1)
private boolean isSectionStillNeededboolean isSectionStillNeeded(int var1, int var2, int var3)
public void onSystemAddedToStorepublic void onSystemAddedToStore(@Nonnull Store<ChunkStore> var1)
public void onSystemRemovedFromStorepublic void onSystemRemovedFromStore(@Nonnull Store<ChunkStore> var1)
public void pauseBackgroundSavingvoid pauseBackgroundSaving(ChunkSavingSystems.Data var1)
public void removevoid remove(@Nonnull Ref<ChunkStore> var1, @Nonnull RemoveReason var2)
public void removeSectionvoid removeSection(@Nonnull Ref<ChunkStore> var1, @Nonnull RemoveReason var2)
public void setGeneratorvoid setGenerator(@Nullable IWorldGen var1)
public void shutdownvoid shutdown()
public void shutdownGeneratorvoid shutdownGenerator()
public void startvoid start(@Nonnull IResourceStorage var1)
public boolean supportsCubicSectionsboolean supportsCubicSections()
public void waitForLoadingChunksvoid waitForLoadingChunks()

Исходный код

Показать/скрыть
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() {
      }
   }
}