This commit is contained in:
embeddedt 2024-02-28 14:05:14 -05:00
parent 139b967ce6
commit eacab89181
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
4 changed files with 25 additions and 30 deletions

View File

@ -7,7 +7,7 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View File

@ -1,16 +1,15 @@
package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock; package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock;
import com.mojang.datafixers.util.Either;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkResult;
import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.chunk.EmptyLevelChunk; import net.minecraft.world.level.chunk.EmptyLevelChunk;
import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.ModernFix;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@ -26,7 +25,7 @@ public abstract class ServerChunkCacheMixin {
@Shadow @Final private Thread mainThread; @Shadow @Final private Thread mainThread;
@Shadow @Final public ServerLevel level; @Shadow @Final public ServerLevel level;
@Shadow protected abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int k, int l, ChunkStatus arg, boolean bl); @Shadow protected abstract CompletableFuture<ChunkResult<ChunkAccess>> getChunkFutureMainThread(int k, int l, ChunkStatus arg, boolean bl);
@Shadow @Final private ServerChunkCache.MainThreadExecutor mainThreadProcessor; @Shadow @Final private ServerChunkCache.MainThreadExecutor mainThreadProcessor;
private final boolean debugDeadServerAccess = Boolean.getBoolean("modernfix.debugBadChunkloading"); private final boolean debugDeadServerAccess = Boolean.getBoolean("modernfix.debugBadChunkloading");
@ -41,24 +40,24 @@ public abstract class ServerChunkCacheMixin {
Holder<Biome> plains = this.level.registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(Biomes.PLAINS); Holder<Biome> plains = this.level.registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(Biomes.PLAINS);
cir.setReturnValue(new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ), plains)); cir.setReturnValue(new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ), plains));
} else if(Thread.currentThread() != this.mainThread) { } else if(Thread.currentThread() != this.mainThread) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = CompletableFuture.supplyAsync(() -> this.getChunkFutureMainThread(chunkX, chunkZ, requiredStatus, false), this.mainThreadProcessor).join(); CompletableFuture<ChunkResult<ChunkAccess>> future = CompletableFuture.supplyAsync(() -> this.getChunkFutureMainThread(chunkX, chunkZ, requiredStatus, false), this.mainThreadProcessor).join();
if(!future.isDone()) { if(!future.isDone()) {
// Wait at least 500 milliseconds before printing anything // Wait at least 500 milliseconds before printing anything
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> resultingChunk = null; ChunkResult<ChunkAccess> resultingChunk = null;
try { try {
resultingChunk = future.get(500, TimeUnit.MILLISECONDS); resultingChunk = future.get(500, TimeUnit.MILLISECONDS);
} catch(InterruptedException | ExecutionException | TimeoutException ignored) { } catch(InterruptedException | ExecutionException | TimeoutException ignored) {
} }
if(resultingChunk != null && resultingChunk.left().isPresent()) { if(resultingChunk != null && resultingChunk.isSuccess()) {
cir.setReturnValue(resultingChunk.left().get()); cir.setReturnValue(resultingChunk.orElse(null));
return; return;
} }
if(debugDeadServerAccess) if(debugDeadServerAccess)
ModernFix.LOGGER.warn("Async loading of a chunk was requested, this might not be desirable", new Exception()); ModernFix.LOGGER.warn("Async loading of a chunk was requested, this might not be desirable", new Exception());
try { try {
resultingChunk = future.get(10, TimeUnit.SECONDS); resultingChunk = future.get(10, TimeUnit.SECONDS);
if(resultingChunk.left().isPresent()) { if(resultingChunk.isSuccess()) {
cir.setReturnValue(resultingChunk.left().get()); cir.setReturnValue(resultingChunk.orElse(null));
return; return;
} }
} catch(InterruptedException | ExecutionException | TimeoutException e) { } catch(InterruptedException | ExecutionException | TimeoutException e) {

View File

@ -1,13 +1,12 @@
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches; package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
import com.mojang.datafixers.util.Either;
import net.minecraft.server.level.*; import net.minecraft.server.level.*;
import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.util.thread.BlockableEventLoop;
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.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import net.minecraft.world.level.chunk.status.WorldGenContext;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -16,7 +15,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -27,15 +25,13 @@ public abstract class ChunkMapMixin {
@Shadow @Final private ChunkMap.DistanceManager distanceManager; @Shadow @Final private ChunkMap.DistanceManager distanceManager;
@Shadow protected abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> protoChunkToFullChunk(ChunkHolder arg); @Shadow protected abstract CompletableFuture<ChunkAccess> protoChunkToFullChunk(ChunkHolder arg, ChunkAccess chunkAccess);
@Shadow @Final private ServerLevel level;
@Shadow @Final private ThreadedLevelLightEngine lightEngine;
@Shadow @Final private ChunkProgressListener progressListener; @Shadow @Final private ChunkProgressListener progressListener;
@Shadow protected abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkGeneration(ChunkHolder chunkHolder, ChunkStatus chunkStatus); @Shadow protected abstract CompletableFuture<ChunkResult<ChunkAccess>> scheduleChunkGeneration(ChunkHolder chunkHolder, ChunkStatus chunkStatus);
@Shadow @Final private StructureTemplateManager structureTemplateManager; @Shadow private WorldGenContext worldGenContext;
/* https://github.com/PaperMC/Paper/blob/ver/1.17.1/patches/server/0752-Fix-chunks-refusing-to-unload-at-low-TPS.patch */ /* https://github.com/PaperMC/Paper/blob/ver/1.17.1/patches/server/0752-Fix-chunks-refusing-to-unload-at-low-TPS.patch */
@ModifyArg(method = "prepareAccessibleChunk", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 1) @ModifyArg(method = "prepareAccessibleChunk", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 1)
@ -48,24 +44,24 @@ public abstract class ChunkMapMixin {
* @reason revert 1.17 chunk system changes, significantly reduces time and RAM needed to load chunks * @reason revert 1.17 chunk system changes, significantly reduces time and RAM needed to load chunks
*/ */
@Inject(method = "schedule", at = @At("HEAD"), cancellable = true) @Inject(method = "schedule", at = @At("HEAD"), cancellable = true)
private void useLegacySchedulingLogic(ChunkHolder holder, ChunkStatus requiredStatus, CallbackInfoReturnable<CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> cir) { private void useLegacySchedulingLogic(ChunkHolder holder, ChunkStatus requiredStatus, CallbackInfoReturnable<CompletableFuture<ChunkResult<ChunkAccess>>> cir) {
if(requiredStatus != ChunkStatus.EMPTY && !requiredStatus.hasLoadDependencies()) { if(requiredStatus != ChunkStatus.EMPTY && !requiredStatus.hasLoadDependencies()) {
ChunkPos chunkpos = holder.getPos(); ChunkPos chunkpos = holder.getPos();
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = holder.getOrScheduleFuture(requiredStatus.getParent(), (ChunkMap)(Object)this); CompletableFuture<ChunkResult<ChunkAccess>> future = holder.getOrScheduleFuture(requiredStatus.getParent(), (ChunkMap)(Object)this);
cir.setReturnValue(future.thenComposeAsync((either) -> { cir.setReturnValue(future.thenComposeAsync((either) -> {
Optional<ChunkAccess> optional = either.left(); ChunkAccess partialChunk = either.orElse(null);
if (requiredStatus == ChunkStatus.LIGHT) { if (requiredStatus == ChunkStatus.LIGHT) {
this.distanceManager.addTicket(TicketType.LIGHT, chunkpos, 33 + ChunkStatus.getDistance(ChunkStatus.LIGHT), chunkpos); this.distanceManager.addTicket(TicketType.LIGHT, chunkpos, 33 + ChunkStatus.getDistance(ChunkStatus.LIGHT), chunkpos);
} }
// from original method // from original method
if (optional.isPresent() && optional.get().getStatus().isOrAfter(requiredStatus)) { if (partialChunk != null && partialChunk.getStatus().isOrAfter(requiredStatus)) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = requiredStatus.load(this.level, this.structureTemplateManager, this.lightEngine, (arg2) -> { CompletableFuture<ChunkAccess> completablefuture = requiredStatus.load(this.worldGenContext, (partialChunkAccess) -> {
return this.protoChunkToFullChunk(holder); return this.protoChunkToFullChunk(holder, partialChunkAccess);
}, (ChunkAccess)optional.get()); }, partialChunk);
this.progressListener.onStatusChange(chunkpos, requiredStatus); this.progressListener.onStatusChange(chunkpos, requiredStatus);
return completablefuture; return completablefuture.thenApply(ChunkResult::of);
} else { } else {
return this.scheduleChunkGeneration(holder, requiredStatus); return this.scheduleChunkGeneration(holder, requiredStatus);
} }

View File

@ -5,7 +5,7 @@ junit_version=5.10.0-M1
mixinextras_version=0.3.2 mixinextras_version=0.3.2
mod_id=modernfix mod_id=modernfix
minecraft_version=24w07a minecraft_version=24w09a
enabled_platforms=fabric enabled_platforms=fabric
forge_version=20.4.132-beta forge_version=20.4.132-beta
# parchment_version=2023.07.09 # parchment_version=2023.07.09
@ -15,7 +15,7 @@ rei_version=13.0.678
ctm_version=1.20.1-1.1.8+4 ctm_version=1.20.1-1.1.8+4
kubejs_version=1902.6.0-build.142 kubejs_version=1902.6.0-build.142
rhino_version=1902.2.2-build.268 rhino_version=1902.2.2-build.268
supported_minecraft_versions=24w07a supported_minecraft_versions=24w09a
fabric_loader_version=0.15.6 fabric_loader_version=0.15.6
fabric_api_version=0.91.1+1.20.4 fabric_api_version=0.91.1+1.20.4