From 9ddca587c2aa7ef5f42a9ab81d88e9e00b30b8a0 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:36:14 -0700 Subject: [PATCH] Implement dummy IO worker for compat with mods that directly call loadAsync This change is targeting Distant Horizons compatibility, however further changes are needed on their side to read starlight data. --- .../mixin/chunk_system/ChunkMapMixin.java | 69 ++++++++++++++++++- src/main/resources/moonrise.accesswidener | 1 + 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java index 86f253c1..55986f09 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java @@ -10,7 +10,10 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; import com.mojang.datafixers.DataFixer; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import java.util.concurrent.Executor; +import java.util.function.Supplier; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.StreamTagVisitor; import net.minecraft.server.level.ChunkGenerationTask; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; @@ -21,16 +24,26 @@ import net.minecraft.server.level.GenerationChunkHolder; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.util.Mth; import net.minecraft.util.StaticCache2D; +import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.util.thread.ProcessorHandle; 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.LevelChunk; +import net.minecraft.world.level.chunk.LightChunkGetter; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStep; import net.minecraft.world.level.chunk.storage.ChunkStorage; +import net.minecraft.world.level.chunk.storage.IOWorker; import net.minecraft.world.level.chunk.storage.RegionStorageInfo; +import net.minecraft.world.level.entity.ChunkStatusUpdateListener; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; +import net.minecraft.world.level.storage.DimensionDataStorage; +import net.minecraft.world.level.storage.LevelStorageSource; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -105,7 +118,12 @@ public ChunkMapMixin(RegionStorageInfo regionStorageInfo, Path path, DataFixer d value = "RETURN" ) ) - private void constructor(final CallbackInfo ci) { + private void constructor( + ServerLevel arg, LevelStorageSource.LevelStorageAccess arg2, DataFixer dataFixer, + StructureTemplateManager arg3, Executor executor, BlockableEventLoop arg4, + LightChunkGetter arg5, ChunkGenerator arg6, ChunkProgressListener arg7, + ChunkStatusUpdateListener arg8, Supplier supplier, int j, boolean bl, + final CallbackInfo ci) { // intentionally destroy old chunk system hooks this.updatingChunkMap = null; this.visibleChunkMap = null; @@ -115,6 +133,55 @@ private void constructor(final CallbackInfo ci) { this.mainThreadMailbox = null; this.pendingGenerationTasks = null; this.unloadQueue = null; + + // Dummy impl for mods that try to loadAsync directly + this.worker = new IOWorker( + // copied from super call + new RegionStorageInfo(arg2.getLevelId(), arg.dimension(), "chunk"), arg2.getDimensionPath(arg.dimension()).resolve("region"), bl + ) { + @Override + public boolean isOldChunkAround(final ChunkPos chunkPos, final int i) { + throw new UnsupportedOperationException(); + } + + @Override + public CompletableFuture store(final ChunkPos chunkPos, final @Nullable CompoundTag compoundTag) { + throw new UnsupportedOperationException(); + } + + @Override + public CompletableFuture> loadAsync(final ChunkPos chunkPos) { + final CompletableFuture> future = new CompletableFuture<>(); + MoonriseRegionFileIO.loadDataAsync(ChunkMapMixin.this.level, chunkPos.x, chunkPos.z, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, (tag, throwable) -> { + if (throwable != null) { + future.completeExceptionally(throwable); + } else { + future.complete(Optional.ofNullable(tag)); + } + }, false); + return future; + } + + @Override + public CompletableFuture synchronize(final boolean bl) { + throw new UnsupportedOperationException(); + } + + @Override + public CompletableFuture scanChunk(final ChunkPos chunkPos, final StreamTagVisitor streamTagVisitor) { + throw new UnsupportedOperationException(); + } + + @Override + public void close() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public RegionStorageInfo storageInfo() { + throw new UnsupportedOperationException(); + } + }; } /** diff --git a/src/main/resources/moonrise.accesswidener b/src/main/resources/moonrise.accesswidener index 949deaf2..76c9eaed 100644 --- a/src/main/resources/moonrise.accesswidener +++ b/src/main/resources/moonrise.accesswidener @@ -238,6 +238,7 @@ accessible method net/minecraft/server/level/Ticket (Lnet/minecraft/serve # ChunkStorage +accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; mutable field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker; accessible method net/minecraft/world/level/chunk/storage/ChunkStorage storageInfo ()Lnet/minecraft/world/level/chunk/storage/RegionStorageInfo;