diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java index 0dfb083a3..c7ff68b5d 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; import com.seibel.lod.common.wrappers.misc.LightMapWrapper; +import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.api.ModAccessorApi; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.SingletonHandler; @@ -148,6 +149,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper *

*/ + public boolean usingBackupGetVanillaRenderedChunks = false; @Override public HashSet getVanillaRenderedChunks() { @@ -164,14 +166,28 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper pos = getMaximumRenderedChunks(); return pos; } - - LevelRenderer levelRenderer = MC.levelRenderer; - LinkedHashSet chunks = levelRenderer.renderChunkStorage.get().renderChunks; - return (chunks.stream().map((chunk) -> { - AABB chunkBoundingBox = chunk.chunk.bb; - return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16), - Math.floorDiv((int) chunkBoundingBox.minZ, 16)); - }).collect(Collectors.toCollection(HashSet::new))); + if (!usingBackupGetVanillaRenderedChunks) { + try { + LevelRenderer levelRenderer = MC.levelRenderer; + LinkedHashSet chunks = levelRenderer.renderChunkStorage.get().renderChunks; + return (chunks.stream().map((chunk) -> { + AABB chunkBoundingBox = chunk.chunk.bb; + return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16), + Math.floorDiv((int) chunkBoundingBox.minZ, 16)); + }).collect(Collectors.toCollection(HashSet::new))); + } catch (LinkageError e) { + try { + MinecraftWrapper.INSTANCE.sendChatMessage( + "&e&l&uWRANING: Distant Horizons: getVanillaRenderedChunks method failed." + + " Using Backup Method."); + MinecraftWrapper.INSTANCE.sendChatMessage( + "&eOverdraw prevention will be worse than normal."); + } catch (Exception e2) {} + ClientApi.LOGGER.error("getVanillaRenderedChunks Error: {}", e); + usingBackupGetVanillaRenderedChunks = true; + } + } + return getMaximumRenderedChunks(); } @Override diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java index cd3bb8fea..87c62e62e 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java @@ -29,15 +29,13 @@ import com.seibel.lod.core.util.GridList; import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.SingletonHandler; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper; -import java.io.IOException; import java.time.Duration; -import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -60,10 +58,14 @@ import com.seibel.lod.common.wrappers.worldGeneration.step.StepSurface; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.levelgen.DebugLevelSource; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.lighting.LevelLightEngine; @@ -207,7 +209,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } } - public static final int TIMEOUT_SECONDS = 30; + public static final int TIMEOUT_SECONDS = 60; //=================Generation Step=================== @@ -220,12 +222,26 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv public final StepSurface stepSurface = new StepSurface(this); public final StepFeatures stepFeatures = new StepFeatures(this); public final StepLight stepLight = new StepLight(this); + public boolean unsafeThreadingRecorded = false; + //public boolean safeMode = false; private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY); public ExecutorService executors = Executors.newFixedThreadPool( CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory); + + public T joinSync(CompletableFuture f) { + if (!unsafeThreadingRecorded && !f.isDone()) { + MC.sendChatMessage("&4&l&uERROR: Distant Horizons: Unsafe Threading in Chunk Generator Detected!"); + MC.sendChatMessage("&eTo increase stability, it is recommended to set world generation threads count to 1."); + ClientApi.LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future")); + unsafeThreadingRecorded = true; + } + return f.join(); + } + public void resizeThreadPool(int newThreadCount) { @@ -297,16 +313,16 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv { super(serverlevel, lodBuilder, lodDim); ClientApi.LOGGER.info("================WORLD_GEN_STEP_INITING============="); + ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator(); + if (!(generator instanceof NoiseBasedChunkGenerator || + generator instanceof DebugLevelSource || + generator instanceof FlatLevelSource)) { + MC.sendChatMessage("&4&l&uWARNING: Distant Horizons: Unknown Chunk Generator Detected! Distant Generation May Fail!"); + MC.sendChatMessage("&eIf it does crash, set Distant Generation to OFF or Generation Mode to None."); + } params = new GlobalParameters((ServerLevel) ((WorldWrapper) serverlevel).getWorld(), lodBuilder, lodDim); } - public void startLoadingAllRegionsFromFile(LodDimension lodDim) - { - ServerLevel level = params.level; - level.getChunkSource(); - - } - @SuppressWarnings("resource") public static ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, ServerLevel level, LevelLightEngine lightEngine) { diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/GlobalParameters.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/GlobalParameters.java index e20cb6c31..e77ff713c 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/GlobalParameters.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/GlobalParameters.java @@ -38,7 +38,6 @@ public final class GlobalParameters public final ChunkScanAccess chunkScanner; public final ServerLevel level; // TODO: Figure out a way to remove this. Maybe ClientLevel also works? public final DataFixer fixerUpper; - private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) { @@ -55,12 +54,6 @@ public final class GlobalParameters biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed)); structures = server.getStructureManager(); generator = level.getChunkSource().getGenerator(); - if (!(generator instanceof NoiseBasedChunkGenerator || - generator instanceof DebugLevelSource || - generator instanceof FlatLevelSource)) { - MC.sendChatMessage("&4&l&uWARNING: Unknown Chunk Generator Detected! Distant Generation May Fail!"); - MC.sendChatMessage("&eIf it does crash, set Distant Generation to OFF or Generation Mode to None."); - } chunkScanner = level.getChunkSource().chunkScanner(); fixerUpper = server.getFixerUpper(); } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepBiomes.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepBiomes.java index e674e0e31..3018ad545 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepBiomes.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepBiomes.java @@ -14,6 +14,8 @@ import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.ProtoChunk; +import net.minecraft.world.level.levelgen.DebugLevelSource; +import net.minecraft.world.level.levelgen.FlatLevelSource; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.blending.Blender; @@ -33,13 +35,17 @@ public final class StepBiomes { public final ChunkStatus STATUS = ChunkStatus.BIOMES; + //FIXME: Bug with TerraBlender Mod! + private ChunkAccess createBiomes(ChunkGenerator generator, Registry registry, Blender blender, StructureFeatureManager structureFeatureManager, ChunkAccess chunkAccess) { if (generator instanceof NoiseBasedChunkGenerator) { ((NoiseBasedChunkGenerator) generator).doCreateBiomes(registry, blender, structureFeatureManager, chunkAccess); return chunkAccess; - } else { + } else if (generator instanceof FlatLevelSource || generator instanceof DebugLevelSource) { chunkAccess.fillBiomesFromNoise(generator.getBiomeSource()::getNoiseBiome, generator.climateSampler()); return chunkAccess; + } else { + return environment.joinSync(generator.fillFromNoise(Runnable::run, blender, structureFeatureManager, chunkAccess)); } } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepNoise.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepNoise.java index d319e57fa..67888e126 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepNoise.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepNoise.java @@ -35,10 +35,6 @@ public final class StepNoise { environment = batchGenerationEnvironment; } - private static T joinSync(CompletableFuture f) { - if (!f.isDone()) throw new RuntimeException("The future is concurrent!"); - return f.join(); - } public final ChunkStatus STATUS = ChunkStatus.NOISE; private ChunkAccess NoiseBased$fillFromNoise(NoiseBasedChunkGenerator generator, Blender blender, StructureFeatureManager structureFeatureManager, ChunkAccess chunkAccess) { @@ -83,7 +79,7 @@ public final class StepNoise { chunk = NoiseBased$fillFromNoise((NoiseBasedChunkGenerator)environment.params.generator,Blender.of(worldGenRegion), tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk); } else { - chunk = joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), + chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk)); } } diff --git a/gradle.properties b/gradle.properties index 0ba0251e0..42327827f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,8 +14,8 @@ mod_authors=James Seibel, Leonardo Amato, Cola, coolGi2007, Ran, Leetom mod_homepage=https://www.curseforge.com/minecraft/mc-mods/distant-horizons # Fabric loader -fabric_loader_version=0.12.12 -fabric_api_version=0.44.0+1.18 +fabric_loader_version=0.13.1 +fabric_api_version=0.46.4+1.18 # Fabric mods modmenu_version=3.0.0 starlight_version_fabric=3554912