Merge branch 'distant-horizons-feature/server-backed-distant-gen'

Also remove ChunkWrapper LevelReader parameter
This commit is contained in:
James Seibel
2024-12-14 14:07:16 -06:00
parent 528beb8384
commit 7d6aecc4c7
24 changed files with 266 additions and 64 deletions
@@ -77,7 +77,7 @@ public class MixinChunkMapCommon
// submit the update event // submit the update event
ServerApi.INSTANCE.serverChunkSaveEvent( ServerApi.INSTANCE.serverChunkSaveEvent(
new ChunkWrapper(chunk, level, ServerLevelWrapper.getWrapper(level)), new ChunkWrapper(chunk, ServerLevelWrapper.getWrapper(level)),
ServerLevelWrapper.getWrapper(level) ServerLevelWrapper.getWrapper(level)
); );
} }
@@ -174,8 +174,6 @@ public class WrapperFactory implements IWrapperFactory
} }
// the level is needed for the DH level wrapper... // the level is needed for the DH level wrapper...
Level level = (Level) objectArray[1]; Level level = (Level) objectArray[1];
// ...the LevelReader is needed for chunk lighting
LevelReader lightSource = level;
// level wrapper // level wrapper
@@ -184,7 +182,7 @@ public class WrapperFactory implements IWrapperFactory
: ServerLevelWrapper.getWrapper((ServerLevel)level); : ServerLevelWrapper.getWrapper((ServerLevel)level);
return new ChunkWrapper(chunk, lightSource, levelWrapper); return new ChunkWrapper(chunk, levelWrapper);
} }
// incorrect number of parameters from the API // incorrect number of parameters from the API
else else
@@ -86,7 +86,6 @@ public class ChunkWrapper implements IChunkWrapper
private final ChunkAccess chunk; private final ChunkAccess chunk;
private final DhChunkPos chunkPos; private final DhChunkPos chunkPos;
private final LevelReader lightSource;
private final ILevelWrapper wrappedLevel; private final ILevelWrapper wrappedLevel;
private boolean isDhBlockLightCorrect = false; private boolean isDhBlockLightCorrect = false;
@@ -111,10 +110,9 @@ public class ChunkWrapper implements IChunkWrapper
// constructor // // constructor //
//=============// //=============//
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource, ILevelWrapper wrappedLevel) public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel)
{ {
this.chunk = chunk; this.chunk = chunk;
this.lightSource = lightSource;
this.wrappedLevel = wrappedLevel; this.wrappedLevel = wrappedLevel;
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z); this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
@@ -525,32 +523,6 @@ public class ChunkWrapper implements IChunkWrapper
// other methods // // other methods //
//===============// //===============//
@Override
public boolean doNearbyChunksExist()
{
if (this.lightSource instanceof DhLitWorldGenRegion)
{
return true;
}
for (int dx = -1; dx <= 1; dx++)
{
for (int dz = -1; dz <= 1; dz++)
{
if (dx == 0 && dz == 0)
{
continue;
}
else if (this.lightSource.getChunk(dx + this.chunk.getPos().x, dz + this.chunk.getPos().z, ChunkStatus.BIOMES, false) == null)
{
return false;
}
}
}
return true;
}
@Override @Override
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; } public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
@@ -242,7 +242,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
return null; return null;
} }
return new ChunkWrapper(chunk, this.level, this); return new ChunkWrapper(chunk, this);
} }
@Override @Override
@@ -142,7 +142,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
return null; return null;
} }
return new ChunkWrapper(chunk, this.level, this); return new ChunkWrapper(chunk, this);
} }
@Override @Override
@@ -44,6 +44,7 @@ import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@@ -55,7 +56,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepStruc
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepStructureStart; import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepStructureStart;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepSurface; import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepSurface;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.*;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkGenerator;
@@ -110,6 +111,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"), new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
() -> Config.Common.Logging.logWorldGenLoadEvent.get()); () -> Config.Common.Logging.logWorldGenLoadEvent.get());
private static final TicketType<ChunkPos> DH_SERVER_GEN_TICKET = TicketType.create("dh_server_gen_ticket", Comparator.comparingLong(ChunkPos::toLong));
public static class PerfCalculator public static class PerfCalculator
{ {
private static final String[] TIME_NAMES = { private static final String[] TIME_NAMES = {
@@ -365,7 +369,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
//==================// //==================//
/** @throws RejectedExecutionException if the given {@link Executor} is cancelled. */ /** @throws RejectedExecutionException if the given {@link Executor} is cancelled. */
public CompletableFuture<Void> generateLodFromListAsync(GenerationEvent genEvent, Executor executor) throws RejectedExecutionException public CompletableFuture<Void> generateLodFromListAsync(GenerationEvent genEvent, Executor executor) throws RejectedExecutionException, InterruptedException
{ {
EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos); EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos);
@@ -374,7 +378,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
// We handle this later, although that handling would need to change if the gen size ever changes. // We handle this later, although that handling would need to change if the gen size ever changes.
LodUtil.assertTrue(genEvent.size % 2 == 0, "Generation events are expected to be an evan number of chunks wide."); LodUtil.assertTrue(genEvent.size % 2 == 0, "Generation events are expected to be an evan number of chunks wide.");
if (genEvent.targetGenerationStep == EDhApiWorldGenerationStep.LIGHT) // TODO using something other than LIGHT would be good for clarity
{
return this.generateChunksViaInternalServerAsync(genEvent);
}
int borderSize = MAX_WORLD_GEN_CHUNK_BORDER_NEEDED; int borderSize = MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
// genEvent.size - 1 converts the even width size to an odd number for MC compatability // genEvent.size - 1 converts the even width size to an odd number for MC compatability
@@ -471,20 +478,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
// ArrayGridList's use relative positions and don't have a center position // ArrayGridList's use relative positions and don't have a center position
// so we need to use the offsetFinal to select the correct position // so we need to use the offsetFinal to select the correct position
DhChunkPos chunkPos = new DhChunkPos(relX + refPosX + xOffsetFinal, relZ + refPosZ + zOffsetFinal); DhChunkPos chunkPos = new DhChunkPos(relX + refPosX + xOffsetFinal, relZ + refPosZ + zOffsetFinal);
ChunkAccess chunk = regionChunks.get(relX, relZ);
ChunkAccess chunk;
if (genEvent.targetGenerationStep != EDhApiWorldGenerationStep.LIGHT) // TODO using something other than LIGHT would be good for clarity
{
// DH's world gen will be used
chunk = regionChunks.get(relX, relZ);
}
else
{
// use the internal server's world gen
// this will cause a lot of server lag, but is the most accurate world gen option
chunk = this.params.level.getChunk(chunkPos.getX(), chunkPos.getZ(), ChunkStatus.FULL, true);
}
if (chunkWrappersByDhPos.containsKey(chunkPos)) if (chunkWrappersByDhPos.containsKey(chunkPos))
{ {
@@ -493,7 +487,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
else if (chunk != null) else if (chunk != null)
{ {
// wrap the chunk // wrap the chunk
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper()); ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverlevel.getLevelWrapper());
chunkWrapperList.set(relX, relZ, chunkWrapper); chunkWrapperList.set(relX, relZ, chunkWrapper);
// try setting the wrapper's lighting // try setting the wrapper's lighting
@@ -725,6 +719,196 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
private CompletableFuture<Void> generateChunksViaInternalServerAsync(GenerationEvent genEvent) throws InterruptedException
{
genEvent.timer.nextEvent("requestFromServer");
LinkedBlockingQueue<Runnable> runnableQueue = new LinkedBlockingQueue<>();
Map<DhChunkPos, ChunkWrapper> chunkWrappersByDhPos = Collections.synchronizedMap(new HashMap<>());
//===================================//
// create generation queue runnables //
//===================================//
// request each chunk pos from the server
CompletableFuture<?>[] requestFutures =
getChunkPosToGenerateStream(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.size, 0)
.map(chunkPos ->
{
return requestChunkFromServerAsync(this.params.level, chunkPos, true)
.whenCompleteAsync((chunk, throwable) ->
{
// unwrap the CompletionException if necessary
Throwable actualThrowable = throwable;
while (actualThrowable instanceof CompletionException)
{
actualThrowable = actualThrowable.getCause();
}
if (throwable != null)
{
LOAD_LOGGER.warn("DistantHorizons: Couldn't load chunk [" + chunkPos + "] from server, error: [" + actualThrowable.getMessage() + "].", actualThrowable);
}
if (chunk != null)
{
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverlevel.getLevelWrapper());
chunkWrappersByDhPos.put(new DhChunkPos(chunkPos.x, chunkPos.z), chunkWrapper);
}
}, runnableQueue::add);
})
.toArray(CompletableFuture[]::new);
// handle each generated chunk
CompletableFuture<Void> processGeneratedChunksFuture =
CompletableFuture.allOf(requestFutures)
.whenCompleteAsync((voidObj, throwable) ->
{
// generate chunk lighting using DH's lighting engine
genEvent.timer.nextEvent("light");
int maxSkyLight = this.serverlevel.getServerLevelWrapper().hasSkyLight() ? LodUtil.MAX_MC_LIGHT : LodUtil.MIN_MC_LIGHT;
ArrayList<IChunkWrapper> chunksToLight = new ArrayList<>(chunkWrappersByDhPos.values());
for (IChunkWrapper iChunkWrapper : chunksToLight)
{
((ChunkWrapper) iChunkWrapper).recalculateDhHeightMaps();
// pre-generated chunks should have lighting but new ones won't
if (!iChunkWrapper.isDhBlockLightingCorrect())
{
DhLightingEngine.INSTANCE.bakeChunkBlockLighting(iChunkWrapper, chunksToLight, maxSkyLight);
}
}
genEvent.timer.nextEvent("cleanup");
for (IChunkWrapper iChunkWrapper : chunksToLight)
{
genEvent.resultConsumer.accept(iChunkWrapper);
}
}, runnableQueue::add)
.whenCompleteAsync((unused, throwable) ->
{
// cleanup
// release the generated chunks
Iterator<ChunkPos> iterator = getChunkPosToGenerateStream(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.size, 0).iterator();
while (iterator.hasNext())
{
ChunkPos chunkPos = iterator.next();
releaseChunkToServer(this.params.level, chunkPos, true);
}
genEvent.timer.complete();
genEvent.refreshTimeout();
if (PREF_LOGGER.canMaybeLog())
{
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
PREF_LOGGER.debugInc(genEvent.timer.toString());
}
});
processGeneratedChunksFuture.whenCompleteAsync((unused, throwable) -> { }, runnableQueue::add); // trigger wakeup
//===============//
// run each step //
//===============//
while (!processGeneratedChunksFuture.isDone())
{
try
{
Runnable command = runnableQueue.poll(1, TimeUnit.SECONDS);
if (command != null)
{
command.run();
}
}
catch (InterruptedException e)
{
// interrupted, release chunk to server
Iterator<ChunkPos> iterator = getChunkPosToGenerateStream(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.size, 0).iterator();
while (iterator.hasNext())
{
ChunkPos chunkPos = iterator.next();
releaseChunkToServer(this.params.level, chunkPos, true);
}
throw e;
}
}
return processGeneratedChunksFuture;
}
/** @param generateUpToFeatures if false this generate the chunk up to "FULL" status */
private static CompletableFuture<ChunkAccess> requestChunkFromServerAsync(ServerLevel level, ChunkPos pos, boolean generateUpToFeatures)
{
return CompletableFuture.supplyAsync(() ->
{
int chunkLevel;
#if MC_VER <= MC_1_19_4
// 33 is equivalent to FULL Chunk
chunkLevel = generateUpToFeatures ? 33 + ChunkStatus.getDistance(ChunkStatus.FEATURES) : 33;
#else
// 33 is equivalent to FULL Chunk
chunkLevel = generateUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
#endif
level.getChunkSource().distanceManager.addTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap); // probably not the most optimal to run updates here, but fast enough
ChunkHolder holder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(pos.toLong());
if (holder == null)
{
throw new IllegalStateException("No chunk holder after ticket has been added");
}
#if MC_VER <= MC_1_20_6
return holder.getOrScheduleFuture(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
.thenApply(result -> result.left().orElseThrow(() -> new RuntimeException(result.right().get().toString()))); // can throw if the server is shutting down
#elif MC_VER <= MC_1_20_4
return holder.getOrScheduleFuture(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
.thenApply(result -> result.left().orElseThrow(() -> new RuntimeException(result.right().get().toString()))); // can throw if the server is shutting down
#else
return holder.scheduleChunkGenerationTask(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
.thenApply(result -> result.orElseThrow(() -> new RuntimeException(result.getError()))); // can throw if the server is shutting down
#endif
}, level.getChunkSource().chunkMap.mainThreadExecutor).thenCompose(Function.identity());
}
/** @param chunkWasGeneratedUpToFeatures if false this assumes the chunk was generated to "FULL" status */
private static void releaseChunkToServer(ServerLevel level, ChunkPos pos, boolean chunkWasGeneratedUpToFeatures)
{
level.getChunkSource().chunkMap.mainThreadExecutor.execute(() ->
{
try
{
int chunkLevel;
#if MC_VER <= MC_1_19_4
// 33 is equivalent to FULL Chunk
chunkLevel = chunkWasGeneratedUpToFeatures ? 33 + ChunkStatus.getDistance(ChunkStatus.FEATURES) : 33;
#else
// 33 is equivalent to FULL Chunk
chunkLevel = chunkWasGeneratedUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
#endif
level.getChunkSource().distanceManager.removeTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
// mitigate OOM issues in vanilla chunk system: see https://github.com/pop4959/Chunky/pull/383
level.getChunkSource().chunkMap.tick(() -> false);
#if MC_VER > MC_1_16_5
level.entityManager.tick();
#endif
}
catch (Exception e)
{
EVENT_LOGGER.warn("Failed to release chunk back to internal server. Error: ["+e.getMessage()+"]", e);
}
});
}
public void generateDirect( public void generateDirect(
GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunkWrappersToGenerate, int border, GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunkWrappersToGenerate, int border,
EDhApiWorldGenerationStep step, DhLitWorldGenRegion region) throws InterruptedException EDhApiWorldGenerationStep step, DhLitWorldGenRegion region) throws InterruptedException
@@ -33,6 +33,9 @@ accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecr
#accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder; #accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V #accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
# lod generation from save file # lod generation from save file
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop; accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
@@ -32,6 +32,11 @@ accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecr
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder; # accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V #accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop; accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
@@ -17,6 +17,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
# world generation # world generation
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -17,6 +17,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
# world generation # world generation
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -17,6 +17,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
# world generation # world generation
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -19,6 +19,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage; accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -18,6 +18,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage; accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -18,6 +18,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage; accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -18,6 +18,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage; accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -18,6 +18,11 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage; accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# lod generation from save file # lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
@@ -126,7 +126,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
if (MC.clientConnectedToDedicatedServer()) if (MC.clientConnectedToDedicatedServer())
{ {
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level); IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, level, wrappedLevel), wrappedLevel); SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
} }
}); });
@@ -154,7 +154,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level); IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
SharedApi.INSTANCE.chunkBlockChangedEvent( SharedApi.INSTANCE.chunkBlockChangedEvent(
new ChunkWrapper(chunk, level, wrappedLevel), new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel wrappedLevel
); );
} }
@@ -194,7 +194,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level); IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
SharedApi.INSTANCE.chunkBlockChangedEvent( SharedApi.INSTANCE.chunkBlockChangedEvent(
new ChunkWrapper(chunk, level, wrappedLevel), new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel wrappedLevel
); );
} }
@@ -142,7 +142,7 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
if (this.isValidTime()) if (this.isValidTime())
{ {
ServerApi.INSTANCE.serverChunkLoadEvent( ServerApi.INSTANCE.serverChunkLoadEvent(
new ChunkWrapper(chunk, chunk.getLevel(), level), new ChunkWrapper(chunk, level),
level); level);
} }
}); });
@@ -46,7 +46,7 @@ public class MixinClientPacketListener
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci) void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
{ {
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) chunk.getLevel()); IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) chunk.getLevel());
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, chunk.getLevel(), clientLevel), clientLevel); SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, clientLevel), clientLevel);
} }
#endif #endif
@@ -228,7 +228,7 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk) private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{ {
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level); ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, level, wrappedLevel), wrappedLevel); SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
} }
@SubscribeEvent @SubscribeEvent
@@ -237,7 +237,7 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
if (MC.clientConnectedToDedicatedServer()) if (MC.clientConnectedToDedicatedServer())
{ {
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event)); ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), wrappedLevel); IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), wrappedLevel);
SharedApi.INSTANCE.chunkLoadEvent(chunk, wrappedLevel); SharedApi.INSTANCE.chunkLoadEvent(chunk, wrappedLevel);
} }
} }
@@ -146,7 +146,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
{ {
ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event)); ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), levelWrapper); IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), levelWrapper);
this.serverApi.serverChunkLoadEvent(chunk, levelWrapper); this.serverApi.serverChunkLoadEvent(chunk, levelWrapper);
} }
@@ -213,7 +213,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk) private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{ {
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level); ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, level, wrappedLevel), wrappedLevel); SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
} }
@@ -124,7 +124,7 @@ public class NeoforgeServerProxy implements AbstractModInitializer.IEventProxy
{ {
ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event)); ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetEventLevel(event), levelWrapper); IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), levelWrapper);
this.serverApi.serverChunkLoadEvent(chunk, levelWrapper); this.serverApi.serverChunkLoadEvent(chunk, levelWrapper);
} }