HytaleGenerator class

Пакет: com.hypixel.hytale.builtin.hytalegenerator.plugin

Файл: com/hypixel/hytale/builtin/hytalegenerator/plugin/HytaleGenerator.java

extends: JavaPlugin

Поля (96)

МодификаторыТипИмя
INSTANCE
INSTANCE
break
int var0
String var0
BuilderCodec var1
IntSet var1
ChunkRequest var1
boolean var1
HierarchicalTimingProfiler.Probe var10
boolean[] var11
List var12
WorkerIndexer.Id var13
CompletableFuture var14
WorldStructure var15
List var16
IntList var17
int var18
ParametrizedBufferType var19
ChunkGenerator var2
var2
int var2
Thread var2
Thread var2
Thread var2
long var2
int var2
double var2
Stage var20
ParametrizedBufferType var21
int var22
int var23
int var24
int var25
Stage var26
int var27
ParametrizedBufferType var28
var28
Stage var29
WorldStructureAsset var3
WorldStructureAsset var3
String var3
var3
var3
var3
HytaleGenerator.Concurrency var3
ParametrizedBufferType var30
var30
BufferType var31
var31
int var33
String var34
ParametrizedBufferType var35
BufferType var36
Stage var37
double var38
SeedBox var4
WorkerIndexer var4
SettingsAsset var4
int[] var4
LongPredicate var4
HytaleGenerator.Concurrency var4
IntSet var40
String var41
StagedChunkGenerator.Builder var42
int var46
Stage var47
String var48
Stage var49
PositionProvider var5
SeedBox var5
float var5
int var5
var5
var5
var5
Stage var50
double var51
double var52
List var6
MaterialCache var6
String var6
int var6
var6
var6
var6
Bounds3d var7
ThreadBridge var7
GeneratedChunk var7
int var7
var7
var7
var7
PositionProvider.Context var8
WorkerIndexer.Session var8
WorkerIndexer.Data var9

Методы (35)

МодификаторыВозвратСигнатура
public record Concurrencyrecord Concurrency(int low, int normal, int high)
abstract throw new RuntimeExceptionthrow new RuntimeException(var8)
abstract throw new RuntimeExceptionthrow new RuntimeException(var7)
abstract throw new RuntimeExceptionthrow new RuntimeException(var6)
for for(Biome var3 : var0)
public int getMaxConcurrencyLevelint getMaxConcurrencyLevel()
if if(this.mainExecutor == null)
if if(this.assetReloadListener == null)
if if(var3 == null)
if if(this.mainExecutor != null)
if if(var2x == null)
if if(var11[0])
if if(var2 == null)
if if(var3 == null)
if if(var4 == null)
if if(this.concurrencyOverride.low > 0)
if if(this.concurrencyOverride.normal > 0)
if if(this.concurrencyOverride.high > 0)
if if(var1 == Float.MAX_VALUE)
if if(var1 < 0.0F)
if if(var1)
if if(var0 <= 10)
if if(var0 != null)
static boolean isAppleSiliconboolean isAppleSilicon()
private void loadExecutorsvoid loadExecutors(@Nonnull HytaleGenerator.Concurrency var1)
synchronized void overrideConcurrencyvoid overrideConcurrency(@Nonnull HytaleGenerator.Concurrency var1)
private void reloadGeneratorsvoid reloadGenerators()
static void shutdownExecutorvoid shutdownExecutor(@Nullable ExecutorService var0)
abstract shutdownExecutor shutdownExecutor(this.lowExecutor)
abstract shutdownExecutor shutdownExecutor(this.normalExecutor)
abstract shutdownExecutor shutdownExecutor(this.highExecutor)
public void shutdownHandlevoid shutdownHandle(@Nonnull Handle var1)
abstract super super(var1)
return switchreturn switch(var0)
return switchreturn switch(var0)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.hytalegenerator.plugin;

class="kw">import com.hypixel.hytale.builtin.hytalegenerator.FutureUtils;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.PropRuntime;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.assets.AssetManager;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.assets.SettingsAsset;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.assets.ThreadBridge;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.assets.positionproviders.PositionProviderAsset;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.assets.worldstructures.WorldStructureAsset;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.biome.Biome;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.bounds.Bounds3d;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.commands.ViewportCommand;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.commands.WorldGenCommand;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.CountedPixelBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.EntityBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.SimplePixelBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.VoxelBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.type.BufferType;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.type.ParametrizedBufferType;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator.ChunkGenerator;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator.ChunkRequest;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator.FallbackGenerator;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator.StagedChunkGenerator;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.performanceinstruments.HierarchicalTimingProfiler;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.BiomeDistanceStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.BiomeStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.EnvironmentStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.PropStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.Stage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.TerrainStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.TintStage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.material.MaterialCache;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.math.Calculator;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.plugin.editor.BiomeEditor;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.positionproviders.PositionProvider;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.referencebundle.ReferenceBundle;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.rng.SeedBox;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.workerindexer.WorkerIndexer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.worldstructure.WorldStructure;
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.common.util.SystemUtil;
class="kw">import com.hypixel.hytale.server.core.Constants;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPlugin;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
class="kw">import com.hypixel.hytale.server.core.universe.world.events.RemoveWorldEvent;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.provider.IWorldGenProvider;
class="kw">import com.hypixel.hytale.server.core.util.Config;
class="kw">import it.unimi.dsi.fastutil.ints.IntArrayList;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import java.util.ArrayList;
class="kw">import java.util.HashMap;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ExecutorService;
class="kw">import java.util.concurrent.Executors;
class="kw">import java.util.concurrent.LinkedBlockingQueue;
class="kw">import java.util.concurrent.Semaphore;
class="kw">import java.util.concurrent.ThreadPoolExecutor;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicBoolean;
class="kw">import java.util.function.LongPredicate;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class HytaleGenerator class="kw">extends JavaPlugin {
   @Nonnull
   class="kw">public class="kw">static class="kw">final Vector3d DEFAULT_SPAWN_POSITION = new Vector3d(0.0, 140.0, 0.0);
   class="kw">public class="kw">static class="kw">final int AUTO_CONCURRENCY_LEVEL = 0;
   class="kw">public class="kw">static class="kw">final HytaleGenerator.Concurrency AUTO_CONCURRENCY = new HytaleGenerator.Concurrency(0, 0, 0);
   class="kw">public class="kw">static class="kw">final String LOW_CONCURRENCY_KEY = "Low";
   class="kw">public class="kw">static class="kw">final String NORMAL_CONCURRENCY_KEY = "Normal";
   class="kw">public class="kw">static class="kw">final String HIGH_EXECUTOR_KEY = "High";
   @Nullable
   class="kw">private class="kw">static HytaleGenerator INSTANCE;
   @Nullable
   class="kw">private AssetManager assetManager;
   @Nullable
   class="kw">private Runnable assetReloadListener;
   @Nonnull
   class="kw">public class="kw">final Config<BiomeEditor.Defaults> biomeEditorConfig;
   @Nonnull
   class="kw">private class="kw">final Map<ChunkRequest.GeneratorProfile, ChunkGenerator> generators;
   @Nonnull
   class="kw">private class="kw">final RequestQueue requestQueue;
   @Nonnull
   class="kw">private class="kw">final AtomicBoolean isShutdown;
   @Nonnull
   class="kw">private class="kw">final Semaphore chunkGenerationSemaphore = new Semaphore(1);
   @Nonnull
   class="kw">private HytaleGenerator.Concurrency concurrency;
   @Nonnull
   class="kw">private HytaleGenerator.Concurrency concurrencyOverride;
   @Nullable
   class="kw">private ExecutorService mainExecutor;
   @Nullable
   class="kw">private ThreadPoolExecutor lowExecutor;
   class="kw">private ThreadPoolExecutor normalExecutor;
   class="kw">private ThreadPoolExecutor highExecutor;
   class="kw">private int worldCounter;

   class="kw">public HytaleGenerator(@Nonnull JavaPluginInit var1) {
      super(var1);
      INSTANCE = this;
      this.biomeEditorConfig = this.withConfig("biome_editor", BiomeEditor.Defaults.CODEC);
      this.generators = new HashMap<>();
      this.requestQueue = new RequestQueue();
      this.isShutdown = new AtomicBoolean(false);
      this.concurrency = new HytaleGenerator.Concurrency(1, 1, 1);
      this.concurrencyOverride = AUTO_CONCURRENCY;
   }

   @Override
   class="kw">protected void start() {
      super.start();
      this.biomeEditorConfig.save();
      if (this.mainExecutor == null) {
         this.loadExecutors(this.getConcurrency(this.assetManager.getSettingsAsset()));
      }

      if (this.assetReloadListener == null) {
         this.assetReloadListener = () -> this.reloadGenerators();
         this.assetManager.registerReloadListener(this.assetReloadListener);
      }
   }

   @Nullable
   class="kw">public AssetManager getAssetManager() {
      class="kw">return this.assetManager;
   }

   class="kw">public int getMaxConcurrencyLevel() {
      class="kw">return Calculator.max(this.concurrency.low(), this.concurrency.normal(), this.concurrency.high());
   }

   @Nonnull
   class="kw">public HytaleGenerator.Concurrency getConcurrency() {
      class="kw">return this.concurrency;
   }

   class="kw">public class="kw">synchronized void overrideConcurrency(@Nonnull HytaleGenerator.Concurrency var1) {
      this.concurrencyOverride = var1;
      this.reloadGenerators();
   }

   @Nullable
   class="kw">public class="kw">static HytaleGenerator get() {
      class="kw">return INSTANCE;
   }

   @Nonnull
   class="kw">public List<Vector3d> getSpawnPositions(@Nonnull ChunkRequest.GeneratorProfile var1, int var2) {
      assert var2 >= 0;
      if (var1.worldStructureName() == null) {
         LoggerUtil.getLogger().warning("World Structure asset not loaded.");
         class="kw">return List.of(DEFAULT_SPAWN_POSITION);
      } else {
         WorldStructureAsset var3 = this.assetManager.getWorldStructureAsset(var1.worldStructureName());
         if (var3 == null) {
            LoggerUtil.getLogger().warning("World Structure asset not found: " + var1.worldStructureName());
            class="kw">return List.of(DEFAULT_SPAWN_POSITION);
         } else {
            SeedBox var4 = new SeedBox(var1.seed());
            PositionProvider var5 = var3.getSpawnPositionsAsset()
               .build(new PositionProviderAsset.Argument(var4, new ReferenceBundle(), WorkerIndexer.Id.MAIN, new ThreadBridge()));
            List var6 = new ArrayList<>(var2);
            Bounds3d var7 = new Bounds3d(
               new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
               new Vector3d(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)
            );
            PositionProvider.Context var8 = new PositionProvider.Context(var7, (var2x, var3x) -> {
               if (var6.size() >= var2) {
                  var3x.stop = true;
               } else {
                  var6.add(var2x);
               }
            }, null, null);
            var5.generate(var8);
            class="kw">return var6;
         }
      }
   }

   @Nonnull
   class="kw">public CompletableFuture<GeneratedChunk> submitChunkRequest(@Nonnull ChunkRequest var1) {
      if (this.isShutdown.get()) {
         class="kw">return CompletableFuture.completedFuture(null);
      }

      this.requestQueue.submit(var1);
      class="kw">return var1.getFutureGeneratedChunk();
   }

   @Override
   class="kw">protected void setup() {
      this.assetManager = new AssetManager(this.getEventRegistry(), this.getLogger());
      BuilderCodec var1 = BuilderCodec.<HandleProvider>builder(HandleProvider.class, () -> new HandleProvider(this, this.worldCounter++))
         .documentation("The standard generator for Hytale.")
         .append(new KeyedCodec<>("WorldStructure", Codec.STRING, true), HandleProvider::setWorldStructureName, HandleProvider::getWorldStructureName)
         .documentation("The world structure to be used for this world.")
         .add()
         .append(new KeyedCodec<>("SeedOverride", Codec.STRING, false), HandleProvider::setSeedOverride, HandleProvider::getSeedOverride)
         .documentation("If set, this will override the world's seed to ensure consistency.")
         .add()
         .build();
      IWorldGenProvider.CODEC.register("HytaleGenerator", HandleProvider.class, var1);
      this.getCommandRegistry().registerCommand(new ViewportCommand(this.assetManager));
      this.getCommandRegistry().registerCommand(new WorldGenCommand());
      this.getEventRegistry().registerGlobal(RemoveWorldEvent.class, var1x -> {
         if (var1x.getWorld().getChunkStore().getGenerator() class="kw">instanceof Handle var3) {
            this.generators.remove(var3.getGeneratorProfile());
         }
      });
   }

   @Override
   class="kw">protected void shutdown() {
      super.shutdown();
      this.isShutdown.set(true);
      if (this.mainExecutor != null) {
         this.mainExecutor.shutdownNow();

         try {
            if (!this.mainExecutor.awaitTermination(2L, TimeUnit.SECONDS)) {
               LoggerUtil.getLogger().warning("HytaleGenerator worker did not stop within timeout.");
            }
         } catch (InterruptedException var2) {
            Thread.currentThread().interrupt();
         }

         this.mainExecutor = null;
      }

      this.requestQueue.shutdown();
      shutdownExecutor(this.lowExecutor);
      this.lowExecutor = null;
      shutdownExecutor(this.normalExecutor);
      this.normalExecutor = null;
      shutdownExecutor(this.highExecutor);
      this.highExecutor = null;
      INSTANCE = null;
      this.generators.clear();
   }

   @Nonnull
   class="kw">public ChunkGenerator createStagedChunkGenerator(@Nonnull ChunkRequest.GeneratorProfile var1, @Nonnull WorldStructureAsset var2, @Nonnull SettingsAsset var3) {
      WorkerIndexer var4 = new WorkerIndexer(this.getMaxConcurrencyLevel());
      SeedBox var5 = new SeedBox(var1.seed());
      MaterialCache var6 = new MaterialCache();
      ThreadBridge var7 = new ThreadBridge();
      WorkerIndexer.Session var8 = var4.createSession();
      WorkerIndexer.Data var9 = new WorkerIndexer.Data<>(var4.getWorkerCount(), () -> null);
      HierarchicalTimingProfiler.Probe var10 = new HierarchicalTimingProfiler.Probe("Assets Loading").start(true);
      boolean[] var11 = new boolean[]{false};
      List var12 = new ArrayList<>();

      while (var8.hasNext()) {
         WorkerIndexer.Id var13 = var8.next();
         CompletableFuture var14 = CompletableFuture.runAsync(() -> {
            WorldStructure var6 = var2.build(new WorldStructureAsset.Argument(var6, var5, var13, var7));
            var9.set(var13, var6);
         }, this.highExecutor).handle((var1x, var2x) -> {
            if (var2x == null) {
               class="kw">return null;
            }

            var11[0] |= true;
            LoggerUtil.logException("during async initialization of world-gen logic from assets", var2x);
            class="kw">return null;
         });
         var12.add(var14);
      }

      if (var11[0]) {
         class="kw">return FallbackGenerator.INSTANCE;
      }

      FutureUtils.allOf(var12).join();
      var2.cleanUp();
      var10.stop(true);
      String var41 = LoggerUtil.nsToMsDecimal(var10.getTotalTime_ns());
      LoggerUtil.getLogger().info("Loaded World Structure " + var1.worldStructureName() + ": " + var41 + " ms");
      StagedChunkGenerator.Builder var42 = new StagedChunkGenerator.Builder();
      WorldStructure var15 = var9.get(var4.createSession().next());
      List var16 = var15.getBiomeRegistry().getAllValues();
      IntList var17 = new IntArrayList(getAllPossibleRuntimeIndices(var16));
      var17.sort(null);
      int var18 = 0;
      ParametrizedBufferType var19 = new ParametrizedBufferType(
         "Biome", var18++, BiomeStage.bufferClass, BiomeStage.biomeClass, () -> new CountedPixelBuffer<>(BiomeStage.biomeClass)
      );
      Stage var20 = new BiomeStage("BiomeStage", var19, var9);
      var42.appendStage(var20);
      ParametrizedBufferType var21 = new ParametrizedBufferType(
         "BiomeDistance",
         var18++,
         BiomeDistanceStage.biomeDistanceBufferClass,
         BiomeDistanceStage.biomeDistanceClass,
         () -> new SimplePixelBuffer<>(BiomeDistanceStage.biomeDistanceClass)
      );
      int var22 = 512;
      int var23 = Math.clamp(var15.getBiomeTransitionDistance() / 2, 0, 512);
      int var24 = Math.clamp(var15.getMaxBiomeEdgeDistance(), 0, 512);
      int var25 = Math.max(var23, var24);
      Stage var26 = new BiomeDistanceStage("BiomeDistanceStage", var19, var21, var25);
      var42.appendStage(var26);
      int var27 = 0;
      ParametrizedBufferType var28 = var42.MATERIAL_OUTPUT_BUFFER_TYPE;
      if (!var17.isEmpty()) {
         var28 = new ParametrizedBufferType(
            "Material" + var27, var18++, TerrainStage.materialBufferClass, TerrainStage.materialClass, () -> new VoxelBuffer<>(TerrainStage.materialClass)
         );
         var27++;
      }

      Stage var29 = new TerrainStage("TerrainStage", var19, var21, var28, var23, var6, var4, var9);
      var42.appendStage(var29);
      ParametrizedBufferType var30 = var28;
      BufferType var31 = null;

      for (int var32 = 0; var32 < var17.size() - 1; var32++) {
         int var33 = var17.getInt(var32);
         String var34 = Integer.toString(var33);
         ParametrizedBufferType var35 = new ParametrizedBufferType(
            "Material" + var27, var18++, TerrainStage.materialBufferClass, TerrainStage.materialClass, () -> new VoxelBuffer<>(TerrainStage.materialClass)
         );
         BufferType var36 = new BufferType("Entity" + var27, var18++, EntityBuffer.class, EntityBuffer::new);
         Stage var37 = new PropStage("PropStage" + var34, var19, var21, var30, var31, var35, var36, var6, var9, var33);
         var42.appendStage(var37);
         var30 = var35;
         var31 = var36;
         var27++;
      }

      if (!var17.isEmpty()) {
         int var46 = var17.getInt(var17.size() - 1);
         String var48 = Integer.toString(var46);
         Stage var50 = new PropStage(
            "PropStage" + var48, var19, var21, var30, var31, var42.MATERIAL_OUTPUT_BUFFER_TYPE, var42.ENTITY_OUTPUT_BUFFER_TYPE, var6, var9, var46
         );
         var42.appendStage(var50);
      }

      Stage var47 = new TintStage("TintStage", var19, var21, var42.TINT_OUTPUT_BUFFER_TYPE, var23, var9);
      var42.appendStage(var47);
      Stage var49 = new EnvironmentStage("EnvironmentStage", var19, var42.ENVIRONMENT_OUTPUT_BUFFER_TYPE, var9);
      var42.appendStage(var49);
      double var51 = Math.max(0.0, var3.getBufferCapacityFactor());
      double var52 = Math.max(0.0, var3.getTargetViewDistance());
      double var38 = Math.max(0.0, var3.getTargetPlayerCount());
      IntSet var40 = new IntOpenHashSet(var3.getStatsCheckpoints());
      var42.withStats("WorldStructure Name: " + var1.worldStructureName(), var40)
         .withMaterialCache(var6)
         .withBufferCapacity(var51, var52, var38)
         .withSpawnPositions(var15.getSpawnPositions())
         .addExecutorTier("Low", new StagedChunkGenerator.ExecutorTier(this.lowExecutor, new WorkerIndexer(this.concurrency.low())))
         .addExecutorTier("Normal", new StagedChunkGenerator.ExecutorTier(this.normalExecutor, new WorkerIndexer(this.concurrency.normal)))
         .addExecutorTier("High", new StagedChunkGenerator.ExecutorTier(this.highExecutor, new WorkerIndexer(this.concurrency.high())))
         .setProfiledExecutorKey("Normal");
      class="kw">return var42.build();
   }

   class="kw">public void shutdownHandle(@Nonnull Handle var1) {
      this.requestQueue.shutdownRequestsFromProfile(var1.getGeneratorProfile());
   }

   @Nonnull
   class="kw">private class="kw">static IntSet getAllPossibleRuntimeIndices(@Nonnull List<Biome> var0) {
      IntSet var1 = new IntOpenHashSet();

      for (Biome var3 : var0) {
         for (PropRuntime var5 : var3.getPropRuntimes()) {
            var1.add(var5.getRuntimeIndex());
         }
      }

      class="kw">return var1;
   }

   @Nonnull
   class="kw">private ChunkGenerator getGenerator(@Nonnull ChunkRequest.GeneratorProfile var1) {
      ChunkGenerator var2 = this.generators.get(var1);
      if (var2 == null) {
         if (var1.worldStructureName() == null) {
            LoggerUtil.getLogger().warning("World Structure asset not loaded.");
            class="kw">return FallbackGenerator.INSTANCE;
         }

         WorldStructureAsset var3 = this.assetManager.getWorldStructureAsset(var1.worldStructureName());
         if (var3 == null) {
            LoggerUtil.getLogger().warning("World Structure asset not found: " + var1.worldStructureName());
            class="kw">return FallbackGenerator.INSTANCE;
         }

         SettingsAsset var4 = this.assetManager.getSettingsAsset();
         if (var4 == null) {
            LoggerUtil.getLogger().warning("Settings asset not found.");
            class="kw">return FallbackGenerator.INSTANCE;
         }

         var2 = this.createStagedChunkGenerator(var1, var3, var4);
         this.generators.put(var1.clone(), var2);
      }

      class="kw">return var2;
   }

   class="kw">private void loadExecutors(@Nonnull HytaleGenerator.Concurrency var1) {
      int var2 = Runtime.getRuntime().availableProcessors();
      String var3 = "Concurrency report:\n";
      var3 = var3 + "\tLow Priority: " + var1.low + " / " + var2 + " threads\n";
      var3 = var3 + "\tNormal Priority: " + var1.normal + " / " + var2 + " threads\n";
      var3 = var3 + "\tHigh Priority: " + var1.high + " / " + var2 + " threads";
      LoggerUtil.getLogger().info(var3);
      if (this.mainExecutor == null || this.lowExecutor == null || this.normalExecutor == null || this.highExecutor == null || !this.concurrency.equals(var1)) {
         this.concurrency = var1;
         if (this.lowExecutor != null && !this.lowExecutor.isShutdown()) {
            try {
               this.lowExecutor.shutdown();
               if (!this.lowExecutor.awaitTermination(1L, TimeUnit.MINUTES)) {
               }
            } catch (InterruptedException var8) {
               throw new RuntimeException(var8);
            }
         }

         int[] var4 = new int[]{0};
         this.lowExecutor = new ThreadPoolExecutor(var1.low(), var1.low(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), var1x -> {
            Thread var2 = new Thread(var1x, "HytaleGenerator-Worker-Low-" + var4[0]++);
            var2.setPriority(1);
            var2.setDaemon(true);
            class="kw">return var2;
         });
         if (this.normalExecutor != null && !this.normalExecutor.isShutdown()) {
            try {
               this.normalExecutor.shutdown();
               if (!this.normalExecutor.awaitTermination(1L, TimeUnit.MINUTES)) {
               }
            } catch (InterruptedException var7) {
               throw new RuntimeException(var7);
            }
         }

         var4[0] = 0;
         this.normalExecutor = new ThreadPoolExecutor(var1.normal(), var1.normal(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), var1x -> {
            Thread var2 = new Thread(var1x, "HytaleGenerator-Worker-Normal-" + var4[0]++);
            var2.setPriority(1);
            var2.setDaemon(true);
            class="kw">return var2;
         });
         if (this.highExecutor != null && !this.highExecutor.isShutdown()) {
            try {
               this.highExecutor.shutdown();
               if (!this.highExecutor.awaitTermination(1L, TimeUnit.MINUTES)) {
               }
            } catch (InterruptedException var6) {
               throw new RuntimeException(var6);
            }
         }

         var4[0] = 0;
         this.highExecutor = new ThreadPoolExecutor(var1.high(), var1.high(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), var1x -> {
            Thread var2 = new Thread(var1x, "HytaleGenerator-Worker-High-" + var4[0]++);
            var2.setPriority(1);
            var2.setDaemon(true);
            class="kw">return var2;
         });
         if (this.mainExecutor == null || this.mainExecutor.isShutdown()) {
            this.mainExecutor = Executors.newSingleThreadExecutor();
            this.mainExecutor.submit(() -> {
               while (!this.isShutdown.get()) {
                  try {
                     ChunkRequest var1 = this.requestQueue.takeFirst();
                     long var2 = var1.arguments().index();
                     LongPredicate var4 = var1.arguments().stillNeeded();
                     if (var4 != null && !var4.test(var2)) {
                        var1.getFutureGeneratedChunk().complete(null);
                     } else {
                        float var5 = var1.arguments().priority() == null ? 0.0F : var1.arguments().priority().get(var2);
                        String var6 = this.getExecutorKey(var5);

                        try {
                           this.chunkGenerationSemaphore.acquireUninterruptibly();
                           GeneratedChunk var7 = this.getGenerator(var1.generatorProfile()).generate(var1.arguments(), var6);
                           var1.getFutureGeneratedChunk().complete(var7);
                        } catch (Exception var12) {
                           var1.getFutureGeneratedChunk().completeExceptionally(var12);
                        } class="kw">finally {
                           this.chunkGenerationSemaphore.release();
                        }
                     }
                  } catch (InterruptedException var14) {
                     if (!this.isShutdown.get()) {
                        Thread.currentThread().interrupt();
                     }
                     break;
                  }
               }
            });
         }
      }
   }

   class="kw">private void reloadGenerators() {
      try {
         this.chunkGenerationSemaphore.acquireUninterruptibly();
         this.loadExecutors(this.getConcurrency(this.assetManager.getSettingsAsset()));
         this.generators.clear();
      } class="kw">finally {
         this.chunkGenerationSemaphore.release();
      }

      LoggerUtil.getLogger().info("Reloaded HytaleGenerator.");
   }

   @Nonnull
   class="kw">private HytaleGenerator.Concurrency getConcurrency(@Nonnull SettingsAsset var1) {
      int var2 = Runtime.getRuntime().availableProcessors();
      HytaleGenerator.Concurrency var3 = var1.getConcurrency();
      HytaleGenerator.Concurrency var4 = getDefaultConcurrency();
      int var5 = 0;
      int var6 = 0;
      int var7 = 0;
      if (this.concurrencyOverride.low > 0) {
         var5 = Math.min(this.concurrencyOverride.low, var2);
      } else if (var3.low > 0) {
         var5 = var3.low;
      } else {
         var5 = var4.low;
      }

      if (this.concurrencyOverride.normal > 0) {
         var6 = Math.min(this.concurrencyOverride.normal, var2);
      } else if (var3.normal > 0) {
         var6 = var3.normal;
      } else {
         var6 = var4.normal;
      }

      if (this.concurrencyOverride.high > 0) {
         var7 = Math.min(this.concurrencyOverride.high, var2);
      } else if (var3.high > 0) {
         var7 = var3.high;
      } else {
         var7 = var4.high;
      }

      class="kw">return new HytaleGenerator.Concurrency(var5, var6, var7);
   }

   @Nonnull
   class="kw">private String getExecutorKey(float var1) {
      if (var1 == Float.MAX_VALUE) {
         class="kw">return "Low";
      }

      if (var1 < 0.0F) {
         class="kw">return "High";
      }

      double var2 = Math.sqrt(var1);
      class="kw">return var2 < 32.0 ? "High" : "Normal";
   }

   @Nonnull
   class="kw">private class="kw">static HytaleGenerator.Concurrency getDefaultConcurrency() {
      int var0 = Runtime.getRuntime().availableProcessors();
      boolean var1 = Constants.SINGLEPLAYER;
      if (var1) {
         if (isAppleSilicon()) {
            if (var0 <= 10) {
               class="kw">return new HytaleGenerator.Concurrency(1, 4, var0 - 2);
            } else {
               class="kw">return var0 <= 14 ? new HytaleGenerator.Concurrency(1, 6, var0 - 2) : new HytaleGenerator.Concurrency(1, 8, var0 - 2);
            }
         } else {
            class="kw">return class="kw">switch (var0) {
               case 1, 2 -> new HytaleGenerator.Concurrency(1, 1, 1);
               case 3 -> new HytaleGenerator.Concurrency(1, 2, 3);
               case 4, 5 -> new HytaleGenerator.Concurrency(1, 3, 4);
               class="kw">default -> new HytaleGenerator.Concurrency(2, var0 - 3, var0 - 1);
            };
         }
      } else {
         class="kw">return class="kw">switch (var0) {
            case 1, 2 -> new HytaleGenerator.Concurrency(1, 1, 1);
            case 3 -> new HytaleGenerator.Concurrency(1, 2, 3);
            case 4, 5 -> new HytaleGenerator.Concurrency(1, 3, 4);
            case 6, 7 -> new HytaleGenerator.Concurrency(2, var0 - 2, var0 - 1);
            class="kw">default -> new HytaleGenerator.Concurrency(3, var0 - 3, var0 - 1);
         };
      }
   }

   class="kw">private class="kw">static void shutdownExecutor(@Nullable ExecutorService var0) {
      if (var0 != null) {
         var0.shutdown();

         try {
            if (!var0.awaitTermination(2L, TimeUnit.SECONDS)) {
               LoggerUtil.getLogger().warning("HytaleGenerator worker did not stop within timeout.");
            }
         } catch (InterruptedException var2) {
            Thread.currentThread().interrupt();
         }
      }
   }

   class="kw">private class="kw">static boolean isAppleSilicon() {
      String var0 = System.getProperty("os.arch", "");
      class="kw">return SystemUtil.TYPE == SystemUtil.SystemType.MACOS && "aarch64".equalsIgnoreCase(var0);
   }

   class="kw">public record Concurrency(int low, int normal, int high) {
      class="kw">public Concurrency {
      }
   }
}