From aec1d2bbe89a3fc960f18a731ff322e8ec0d681a Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 14 Mar 2023 21:43:59 -0500 Subject: [PATCH] add StepStructure retry logic --- .../worldGeneration/ThreadedParameters.java | 58 ++++++++++++++----- .../step/StepStructureStart.java | 18 +++++- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java index 5b82538f7..f750a33fb 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java @@ -25,55 +25,81 @@ import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenStruct import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.levelgen.WorldGenSettings; #if POST_MC_1_18_1 import net.minecraft.world.level.levelgen.structure.StructureCheck; #endif public final class ThreadedParameters { - private static final ThreadLocal localParam = new ThreadLocal(); + private static final ThreadLocal LOCAL_PARAM = new ThreadLocal<>(); + final ServerLevel level; public WorldGenStructFeatManager structFeat = null; #if POST_MC_1_18_1 - public final StructureCheck structCheck; + public StructureCheck structCheck; #endif boolean isValid = true; public final PerfCalculator perf = new PerfCalculator(); + private static GlobalParameters previousGlobalParameters = null; + + + public static ThreadedParameters getOrMake(GlobalParameters param) { - ThreadedParameters tParam = localParam.get(); + ThreadedParameters tParam = LOCAL_PARAM.get(); if (tParam != null && tParam.isValid && tParam.level == param.level) + { return tParam; + } + tParam = new ThreadedParameters(param); - localParam.set(tParam); + LOCAL_PARAM.set(tParam); return tParam; } - public void markAsInvalid() - { - isValid = false; - } - private ThreadedParameters(GlobalParameters param) { - level = param.level; + previousGlobalParameters = param; + + this.level = param.level; #if PRE_MC_1_18_1 - structFeat = new WorldGenStructFeatManager(param.worldGenSettings, level); + this.structFeat = new WorldGenStructFeatManager(param.worldGenSettings, level); #elif PRE_MC_1_19 - structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures, - param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed, - param.fixerUpper); + this.structCheck = this.createStructureCheck(param); #else - structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures, + this.structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures, param.level.dimension(), param.generator, param.randomState, level, param.generator.getBiomeSource(), param.worldSeed, param.fixerUpper); #endif } + + + public void markAsInvalid() { isValid = false; } + public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param) { structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if POST_MC_1_18_1, structCheck #endif); } + + + #if PRE_MC_1_19 + public void recreateStructureCheck() + { + if (previousGlobalParameters != null) + { + this.structCheck = createStructureCheck(previousGlobalParameters); + } + } + private StructureCheck createStructureCheck(GlobalParameters param) + { + return new StructureCheck(param.chunkScanner, param.registry, param.structures, + param.level.dimension(), param.generator, this.level, param.generator.getBiomeSource(), param.worldSeed, + param.fixerUpper); + } + #else + public void recreateStructureCheck() { /* do nothing */ } + #endif + } \ No newline at end of file diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepStructureStart.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepStructureStart.java index b854b35f9..ec1dd313d 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepStructureStart.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepStructureStart.java @@ -98,8 +98,22 @@ public final class StepStructureStart // There's a rare issue with StructStart where it throws ArrayIndexOutOfBounds // This means the structFeat is corrupted (For some reason) and I need to reset it. // TODO: Figure out in the future why this happens even though I am using new structFeat - OLD - // TODO: Is this still a problem? - throw new StepStructureStart.StructStartCorruptedException(e); + + // reset the structureStart + tParams.recreateStructureCheck(); + + try + { + // try running the structure logic again + tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts()); + } + catch (ArrayIndexOutOfBoundsException secondEx) + { + // the structure logic failed again, log it and move on + LOGGER.error("Unable to create structure starts for "+chunk.getPos()+". This is an error with MC's world generation. Ignoring and continuing generation. Error: "+secondEx.getMessage()); // don't log the full stack trace since it is long and will generally end up in MC's code + + //throw new StepStructureStart.StructStartCorruptedException(secondEx); + } } #endif }