Port two chunk system patches from Paper

This commit is contained in:
embeddedt 2023-04-27 20:48:53 -04:00
parent c861c99c79
commit da6e9dc075
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
5 changed files with 128 additions and 0 deletions

View File

@ -70,6 +70,7 @@ public class ModernFixEarlyConfig {
this.addMixinRule("perf.dynamic_structure_manager", true);
this.addMixinRule("bugfix.mc218112", true);
this.addMixinRule("bugfix.chunk_deadlock", true);
this.addMixinRule("bugfix.chunk_not_unloading", true);
this.addMixinRule("bugfix.chunk_deadlock.valhesia", modPresent("valhelsia_structures"));
this.addMixinRule("bugfix.tf_cme_on_load", modPresent("twilightforest"));
this.addMixinRule("bugfix.refinedstorage", modPresent("refinedstorage"));

View File

@ -0,0 +1,5 @@
package org.embeddedt.modernfix.duck;
public interface IPaperChunkHolder {
boolean mfix$canAdvanceStatus();
}

View File

@ -0,0 +1,61 @@
package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches;
import com.mojang.datafixers.util.Either;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import org.embeddedt.modernfix.duck.IPaperChunkHolder;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Mixin(ChunkHolder.class)
public abstract class ChunkHolderMixin implements IPaperChunkHolder {
@Shadow public abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getFutureIfPresentUnchecked(ChunkStatus arg);
@Shadow @Final private static List<ChunkStatus> CHUNK_STATUSES;
public ChunkStatus mfix$getChunkHolderStatus() {
for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getParent(); curr != next; curr = next, next = next.getParent()) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = this.getFutureIfPresentUnchecked(curr);
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = future.getNow(null);
if (either == null || !either.left().isPresent()) {
continue;
}
return curr;
}
return null;
}
public ChunkAccess mfix$getAvailableChunkNow() {
// TODO can we just getStatusFuture(EMPTY)?
for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getParent(); curr != next; curr = next, next = next.getParent()) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = this.getFutureIfPresentUnchecked(curr);
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = future.getNow(null);
if (either == null || !either.left().isPresent()) {
continue;
}
return either.left().get();
}
return null;
}
public static ChunkStatus mfix$getNextStatus(ChunkStatus status) {
if (status == ChunkStatus.FULL) {
return status;
}
return CHUNK_STATUSES.get(status.getIndex() + 1);
}
@Override
public boolean mfix$canAdvanceStatus() {
ChunkStatus status = mfix$getChunkHolderStatus();
ChunkAccess chunk = mfix$getAvailableChunkNow();
return chunk != null && (status == null || chunk.getStatus().isOrAfter(mfix$getNextStatus(status)));
}
}

View File

@ -0,0 +1,59 @@
package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import org.embeddedt.modernfix.duck.IPaperChunkHolder;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Executor;
@Mixin(ChunkMap.class)
public class ChunkMapMixin {
@Shadow @Final private BlockableEventLoop<Runnable> mainThreadExecutor;
private Executor mainInvokingExecutor;
@Inject(method = "<init>", at = @At("RETURN"), cancellable = true)
private void setup(CallbackInfo ci) {
this.mainInvokingExecutor = (runnable) -> {
if(ServerLifecycleHooks.getCurrentServer().isSameThread())
runnable.run();
else
this.mainThreadExecutor.execute(runnable);
};
}
/* https://github.com/PaperMC/Paper/blob/ver/1.17.1/patches/server/0752-Fix-chunks-refusing-to-unload-at-low-TPS.patch */
@ModifyArg(method = "unpackTicks", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 1)
private Executor useMainThreadExecutor(Executor executor) {
return this.mainThreadExecutor;
}
/* https://github.com/PaperMC/Paper/blob/master/patches/removed/1.19.2-legacy-chunksystem/0482-Improve-Chunk-Status-Transition-Speed.patch */
@ModifyArg(method = "getEntityTickingRangeFuture", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 1)
private Executor useMainInvokingExecutor(Executor executor) {
return this.mainInvokingExecutor;
}
@ModifyArg(method = "scheduleChunkGeneration", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenComposeAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 1)
private Executor skipWorkerIfPossible(Executor executor, ChunkHolder chunkHolder) {
return (runnable) -> {
if(((IPaperChunkHolder)chunkHolder).mfix$canAdvanceStatus()) {
this.mainInvokingExecutor.execute(runnable);
return;
}
executor.execute(runnable);
};
}
}

View File

@ -9,6 +9,8 @@
"core.BootstrapMixin",
"bugfix.edge_chunk_not_saved.ChunkManagerMixin",
"bugfix.starlight_emptiness.StarLightEngineMixin",
"bugfix.paper_chunk_patches.ChunkMapMixin",
"bugfix.paper_chunk_patches.ChunkHolderMixin",
"perf.dynamic_structure_manager.StructureManagerMixin",
"bugfix.tf_cme_on_load.TwilightForestModMixin",
"bugfix.refinedstorage.te_bug.ItemExternalStorageProviderMixin",