Snapshot Curios sync stacks and refine Turbo LODs when idle
This commit is contained in:
parent
124e20662c
commit
3ff084d278
16 changed files with 459 additions and 31 deletions
|
|
@ -2,6 +2,12 @@ version = '0.42.1'
|
||||||
base.archivesName = 'saltatory'
|
base.archivesName = 'saltatory'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
ivy {
|
||||||
|
url = 'https://github.com/Pocky-l/dhturbo/releases/download'
|
||||||
|
patternLayout { artifact 'v[revision]/[artifact]-[revision].[ext]' }
|
||||||
|
metadataSources { artifact() }
|
||||||
|
content { includeModule 'com.pockyl', 'dhturbo-neoforge-1.21.1' }
|
||||||
|
}
|
||||||
ivy {
|
ivy {
|
||||||
url = 'https://github.com/tlaplus/tlaplus/releases/download'
|
url = 'https://github.com/tlaplus/tlaplus/releases/download'
|
||||||
patternLayout { artifact '[revision]/[artifact].[ext]' }
|
patternLayout { artifact '[revision]/[artifact].[ext]' }
|
||||||
|
|
@ -48,6 +54,7 @@ dependencies {
|
||||||
compileOnly('curse.maven:functional-storage-556861:8459097') { transitive = false }
|
compileOnly('curse.maven:functional-storage-556861:8459097') { transitive = false }
|
||||||
compileOnly('maven.modrinth:refined-storage:lHHiI26k') { transitive = false }
|
compileOnly('maven.modrinth:refined-storage:lHHiI26k') { transitive = false }
|
||||||
compileOnly('maven.modrinth:distanthorizons:9w34y8ai') { transitive = false }
|
compileOnly('maven.modrinth:distanthorizons:9w34y8ai') { transitive = false }
|
||||||
|
compileOnly('com.pockyl:dhturbo-neoforge-1.21.1:1.5.0') { transitive = false }
|
||||||
compileOnly 'org.jetbrains:annotations:24.1.0'
|
compileOnly 'org.jetbrains:annotations:24.1.0'
|
||||||
compileOnly 'org.apiguardian:apiguardian-api:1.1.2'
|
compileOnly 'org.apiguardian:apiguardian-api:1.1.2'
|
||||||
compileOnly 'io.github.llamalad7:mixinextras-neoforge:0.5.3'
|
compileOnly 'io.github.llamalad7:mixinextras-neoforge:0.5.3'
|
||||||
|
|
|
||||||
56
server/src/main/java/dev/quorate/tune/LodWork.java
Normal file
56
server/src/main/java/dev/quorate/tune/LodWork.java
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
package dev.quorate.tune;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.LongPredicate;
|
||||||
|
|
||||||
|
public final class LodWork {
|
||||||
|
public interface Generator {
|
||||||
|
boolean saltatory$active();
|
||||||
|
|
||||||
|
boolean saltatory$ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Queue {
|
||||||
|
Generator saltatory$refiner();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<Object> LOADED = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
|
|
||||||
|
private LodWork() {}
|
||||||
|
|
||||||
|
public static synchronized void loaded(Object level) {
|
||||||
|
LOADED.add(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized boolean isLoaded(Object level) {
|
||||||
|
return LOADED.contains(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ready(int cores, double load, double tickMillis) {
|
||||||
|
return load >= 0 && (1 - load) * cores >= 1 && tickMillis < 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, R> R pick(
|
||||||
|
ConcurrentHashMap<Long, T> tasks,
|
||||||
|
long threshold,
|
||||||
|
Function<Map.Entry<Long, T>, R> mapper,
|
||||||
|
BiFunction<R, R, R> reducer,
|
||||||
|
LongPredicate pending,
|
||||||
|
BooleanSupplier ready) {
|
||||||
|
R first =
|
||||||
|
tasks.reduceEntries(
|
||||||
|
threshold,
|
||||||
|
entry -> pending.test(entry.getKey()) ? null : mapper.apply(entry),
|
||||||
|
reducer);
|
||||||
|
return first != null || !ready.getAsBoolean()
|
||||||
|
? first
|
||||||
|
: tasks.reduceEntries(threshold, mapper, reducer);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
server/src/main/java/dev/quorate/tune/mixin/CurioPlugin.java
Normal file
10
server/src/main/java/dev/quorate/tune/mixin/CurioPlugin.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
public final class CurioPlugin extends ModPlugin {
|
||||||
|
static final String CURIOS = "[9.5.1,10)";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldApplyMixin(String target, String mixin) {
|
||||||
|
return ModRanges.loaded("curios", CURIOS);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
server/src/main/java/dev/quorate/tune/mixin/CurioStack.java
Normal file
19
server/src/main/java/dev/quorate/tune/mixin/CurioStack.java
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(
|
||||||
|
targets = "top.theillusivec4.curios.common.network.server.sync.SPacketSyncStack",
|
||||||
|
remap = false)
|
||||||
|
public abstract class CurioStack {
|
||||||
|
@ModifyVariable(method = "<init>", at = @At("HEAD"), argsOnly = true)
|
||||||
|
private static ItemStack saltatory$snapshot(ItemStack stack) {
|
||||||
|
return stack.copy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,37 +1,14 @@
|
||||||
package dev.quorate.tune.mixin;
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
public final class LodPlugin extends ModPlugin {
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
static final String TURBO = "[1.5,1.6)";
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
static final String DH = "[3.3.3,3.4)";
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public final class LodPlugin implements IMixinConfigPlugin {
|
|
||||||
@Override
|
|
||||||
public void onLoad(String name) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRefMapperConfig() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldApplyMixin(String target, String mixin) {
|
public boolean shouldApplyMixin(String target, String mixin) {
|
||||||
|
if (mixin.endsWith(".LodMap") || mixin.endsWith(".LodQueueMixin")) {
|
||||||
return ModRanges.loaded("distanthorizons", "[3.3.3,)");
|
return ModRanges.loaded("distanthorizons", "[3.3.3,)");
|
||||||
}
|
}
|
||||||
|
return ModRanges.loaded("dhturbo", TURBO) && ModRanges.loaded("distanthorizons", DH);
|
||||||
@Override
|
|
||||||
public void acceptTargets(Set<String> own, Set<String> other) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getMixins() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preApply(String target, ClassNode node, String mixin, IMixinInfo info) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postApply(String target, ClassNode node, String mixin, IMixinInfo info) {}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkPyramid;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(
|
||||||
|
targets =
|
||||||
|
"com.seibel.distanthorizons.common.wrappers.worldGeneration.DhChunkGenerator_neoforge",
|
||||||
|
remap = false)
|
||||||
|
public abstract class RefineBorder {
|
||||||
|
@Shadow @Final @Mutable
|
||||||
|
public static ImmutableMap<EDhApiWorldGenerationStep, Integer>
|
||||||
|
WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP;
|
||||||
|
|
||||||
|
@Shadow @Final @Mutable public static int MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
||||||
|
|
||||||
|
@ModifyArg(
|
||||||
|
method = "generateChunks",
|
||||||
|
at =
|
||||||
|
@At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target =
|
||||||
|
"Lcom/seibel/distanthorizons/common/wrappers/worldGeneration/ChunkPosGenStream_neoforge;getIterator(IIII)Ljava/util/Iterator;"),
|
||||||
|
index = 3)
|
||||||
|
private int saltatory$halo(int margin) {
|
||||||
|
return margin == 0 ? 0 : MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<clinit>", at = @At("RETURN"))
|
||||||
|
private static void saltatory$border(CallbackInfo ci) {
|
||||||
|
var target = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FEATURES);
|
||||||
|
int radius = target.getAccumulatedRadiusOf(ChunkStatus.EMPTY);
|
||||||
|
var borders = ImmutableMap.<EDhApiWorldGenerationStep, Integer>builder();
|
||||||
|
for (var step : WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP.keySet()) {
|
||||||
|
ChunkStatus status =
|
||||||
|
switch (step) {
|
||||||
|
case EMPTY -> ChunkStatus.EMPTY;
|
||||||
|
case STRUCTURE_START -> ChunkStatus.STRUCTURE_STARTS;
|
||||||
|
case STRUCTURE_REFERENCE -> ChunkStatus.STRUCTURE_REFERENCES;
|
||||||
|
case BIOMES -> ChunkStatus.BIOMES;
|
||||||
|
case NOISE -> ChunkStatus.NOISE;
|
||||||
|
case SURFACE -> ChunkStatus.SURFACE;
|
||||||
|
case CARVERS, LIQUID_CARVERS -> ChunkStatus.CARVERS;
|
||||||
|
default -> ChunkStatus.FEATURES;
|
||||||
|
};
|
||||||
|
int reach =
|
||||||
|
status.isBefore(ChunkStatus.FEATURES)
|
||||||
|
? target.getAccumulatedRadiusOf(status)
|
||||||
|
: 0;
|
||||||
|
borders.put(step, radius - reach);
|
||||||
|
}
|
||||||
|
WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP = borders.build();
|
||||||
|
MAX_WORLD_GEN_CHUNK_BORDER_NEEDED = radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
server/src/main/java/dev/quorate/tune/mixin/RefineData.java
Normal file
36
server/src/main/java/dev/quorate/tune/mixin/RefineData.java
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||||
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||||
|
import com.seibel.distanthorizons.core.generation.queues.IFullDataSourceRetrievalQueue;
|
||||||
|
|
||||||
|
import dev.quorate.tune.LodWork;
|
||||||
|
|
||||||
|
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 java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@Mixin(
|
||||||
|
targets =
|
||||||
|
"com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataSourceProvider",
|
||||||
|
remap = false)
|
||||||
|
public abstract class RefineData {
|
||||||
|
@Shadow @Final public AtomicReference<IFullDataSourceRetrievalQueue> worldGenQueueRef;
|
||||||
|
|
||||||
|
@ModifyExpressionValue(
|
||||||
|
method = "getPositionsToRetrieve",
|
||||||
|
at =
|
||||||
|
@At(
|
||||||
|
value = "FIELD",
|
||||||
|
target =
|
||||||
|
"Lcom/seibel/distanthorizons/api/enums/worldGeneration/EDhApiWorldGenerationStep;FEATURES:Lcom/seibel/distanthorizons/api/enums/worldGeneration/EDhApiWorldGenerationStep;"))
|
||||||
|
private EDhApiWorldGenerationStep saltatory$step(EDhApiWorldGenerationStep step) {
|
||||||
|
return worldGenQueueRef.get() instanceof LodWork.Queue queue
|
||||||
|
&& queue.saltatory$refiner() != null
|
||||||
|
? EDhApiWorldGenerationStep.LIGHT
|
||||||
|
: step;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
server/src/main/java/dev/quorate/tune/mixin/RefineInit.java
Normal file
29
server/src/main/java/dev/quorate/tune/mixin/RefineInit.java
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataSourceProvider;
|
||||||
|
import com.seibel.distanthorizons.core.generation.queues.AbstractLodRequestState;
|
||||||
|
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||||
|
|
||||||
|
import dev.quorate.tune.LodWork;
|
||||||
|
|
||||||
|
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.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(
|
||||||
|
targets = "com.seibel.distanthorizons.core.generation.queues.LodRequestModule",
|
||||||
|
remap = false)
|
||||||
|
public abstract class RefineInit {
|
||||||
|
@Shadow @Final private IDhLevel level;
|
||||||
|
|
||||||
|
@Inject(method = "startWorldGen", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void saltatory$start(
|
||||||
|
GeneratedFullDataSourceProvider provider,
|
||||||
|
AbstractLodRequestState state,
|
||||||
|
CallbackInfo ci) {
|
||||||
|
if (!LodWork.isLoaded(level.getLevelWrapper().getWrappedMcObject())) ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
58
server/src/main/java/dev/quorate/tune/mixin/RefineQueue.java
Normal file
58
server/src/main/java/dev/quorate/tune/mixin/RefineQueue.java
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
|
||||||
|
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalTask;
|
||||||
|
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||||
|
|
||||||
|
import dev.quorate.tune.LodWork;
|
||||||
|
|
||||||
|
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.Redirect;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Mixin(
|
||||||
|
targets = "com.seibel.distanthorizons.core.generation.queues.WorldGenerationQueue",
|
||||||
|
remap = false)
|
||||||
|
public abstract class RefineQueue implements LodWork.Queue {
|
||||||
|
@Shadow @Final private IDhApiWorldGenerator generator;
|
||||||
|
|
||||||
|
@Shadow @Final
|
||||||
|
private ConcurrentHashMap<Long, DataSourceRetrievalTask> inProgressGenTasksByLodPos;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LodWork.Generator saltatory$refiner() {
|
||||||
|
return generator instanceof LodWork.Generator refine && refine.saltatory$active()
|
||||||
|
? refine
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "tryStartNextWorldGenTask",
|
||||||
|
at =
|
||||||
|
@At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target =
|
||||||
|
"Ljava/util/concurrent/ConcurrentHashMap;reduceEntries(JLjava/util/function/Function;Ljava/util/function/BiFunction;)Ljava/lang/Object;"))
|
||||||
|
private <T, R> R saltatory$pick(
|
||||||
|
ConcurrentHashMap<Long, T> tasks,
|
||||||
|
long threshold,
|
||||||
|
Function<Map.Entry<Long, T>, R> mapper,
|
||||||
|
BiFunction<R, R, R> reducer) {
|
||||||
|
var refine = saltatory$refiner();
|
||||||
|
if (refine == null) return tasks.reduceEntries(threshold, mapper, reducer);
|
||||||
|
return LodWork.pick(
|
||||||
|
tasks,
|
||||||
|
threshold,
|
||||||
|
mapper,
|
||||||
|
reducer,
|
||||||
|
pos -> DhSectionPos.getDetailLevel(pos) == 6,
|
||||||
|
() -> inProgressGenTasksByLodPos.isEmpty() && refine.saltatory$ready());
|
||||||
|
}
|
||||||
|
}
|
||||||
20
server/src/main/java/dev/quorate/tune/mixin/TurboInit.java
Normal file
20
server/src/main/java/dev/quorate/tune/mixin/TurboInit.java
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||||
|
|
||||||
|
import dev.quorate.tune.LodWork;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "com.pockyl.dhturbo.dh.DhIntegration", remap = false)
|
||||||
|
public abstract class TurboInit {
|
||||||
|
@Inject(method = "levelLoaded", at = @At("RETURN"))
|
||||||
|
private static void saltatory$loaded(IDhApiLevelWrapper wrapper, CallbackInfo ci) {
|
||||||
|
LodWork.loaded(wrapper.getWrappedMcObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
65
server/src/main/java/dev/quorate/tune/mixin/TurboMixin.java
Normal file
65
server/src/main/java/dev/quorate/tune/mixin/TurboMixin.java
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
package dev.quorate.tune.mixin;
|
||||||
|
|
||||||
|
import com.pockyl.dhturbo.Config;
|
||||||
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiGeneratorPlan;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
|
import com.seibel.distanthorizons.core.world.DhServerWorld;
|
||||||
|
|
||||||
|
import dev.quorate.tune.LodWork;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
|
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.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "com.pockyl.dhturbo.dh.TurboWorldGenerator", remap = false)
|
||||||
|
public abstract class TurboMixin implements LodWork.Generator {
|
||||||
|
@Shadow @Final private IDhApiLevelWrapper levelWrapper;
|
||||||
|
@Shadow @Final private ResourceKey<Level> dimension;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private EDhApiGeneratorPlan plan() {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "wantsRealChunks", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void saltatory$native(int x, int z, byte detail, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (detail == 0 && saltatory$hybrid()) cir.setReturnValue(saltatory$active());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saltatory$active() {
|
||||||
|
return saltatory$hybrid()
|
||||||
|
&& (!(SharedApi.getAbstractDhWorld() instanceof DhServerWorld world)
|
||||||
|
|| world.getPregenManager().getRunningPregen() == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saltatory$hybrid() {
|
||||||
|
return Config.generates(dimension)
|
||||||
|
&& Config.REAL_CHUNKS_NEARBY.get()
|
||||||
|
&& plan() == EDhApiGeneratorPlan.SURFACE_THEN_CHUNKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saltatory$ready() {
|
||||||
|
var cpu =
|
||||||
|
(com.sun.management.OperatingSystemMXBean)
|
||||||
|
ManagementFactory.getOperatingSystemMXBean();
|
||||||
|
var level = (ServerLevel) levelWrapper.getWrappedMcObject();
|
||||||
|
return LodWork.ready(
|
||||||
|
Runtime.getRuntime().availableProcessors(),
|
||||||
|
cpu.getCpuLoad(),
|
||||||
|
level.getServer().getCurrentSmoothedTickTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -85,3 +85,6 @@ config="tune.terrain.mixins.json"
|
||||||
|
|
||||||
[[mixins]]
|
[[mixins]]
|
||||||
config="tune.biome.mixins.json"
|
config="tune.biome.mixins.json"
|
||||||
|
|
||||||
|
[[mixins]]
|
||||||
|
config="tune.curio.mixins.json"
|
||||||
|
|
|
||||||
9
server/src/main/resources/tune.curio.mixins.json
Normal file
9
server/src/main/resources/tune.curio.mixins.json
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8.7",
|
||||||
|
"package": "dev.quorate.tune.mixin",
|
||||||
|
"plugin": "dev.quorate.tune.mixin.CurioPlugin",
|
||||||
|
"compatibilityLevel": "JAVA_21",
|
||||||
|
"server": ["CurioStack"],
|
||||||
|
"injectors": {"defaultRequire": 1}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,13 @@
|
||||||
"plugin": "dev.quorate.tune.mixin.LodPlugin",
|
"plugin": "dev.quorate.tune.mixin.LodPlugin",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"LodMap",
|
"LodMap",
|
||||||
"LodQueueMixin"
|
"LodQueueMixin",
|
||||||
|
"TurboInit",
|
||||||
|
"RefineInit",
|
||||||
|
"TurboMixin",
|
||||||
|
"RefineQueue",
|
||||||
|
"RefineData",
|
||||||
|
"RefineBorder"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
43
server/src/test/java/dev/quorate/tune/LodWorkTest.java
Normal file
43
server/src/test/java/dev/quorate/tune/LodWorkTest.java
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
package dev.quorate.tune;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
final class LodWorkTest {
|
||||||
|
@Test
|
||||||
|
void foregroundWinsEvenWhenRefinementIsNearer() {
|
||||||
|
var tasks = new ConcurrentHashMap<>(Map.of(1L, 1, 100L, 100));
|
||||||
|
assertEquals(
|
||||||
|
100,
|
||||||
|
LodWork.<Integer, Integer>pick(
|
||||||
|
tasks, 1024, Map.Entry::getValue, Math::min, pos -> pos == 1, () -> true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void refinementWaitsWithoutConsumingTheRequest() {
|
||||||
|
var tasks = new ConcurrentHashMap<>(Map.of(1L, 1));
|
||||||
|
assertNull(
|
||||||
|
LodWork.pick(
|
||||||
|
tasks, 1024, Map.Entry::getValue, Math::min, pos -> true, () -> false));
|
||||||
|
assertEquals(Map.of(1L, 1), tasks);
|
||||||
|
assertEquals(
|
||||||
|
1,
|
||||||
|
LodWork.<Integer, Integer>pick(
|
||||||
|
tasks, 1024, Map.Entry::getValue, Math::min, pos -> true, () -> true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void cpuAdmissionFitsOneNativeBatch() {
|
||||||
|
assertTrue(LodWork.ready(2, .4, 5));
|
||||||
|
assertFalse(LodWork.ready(16, .95, 5));
|
||||||
|
assertFalse(LodWork.ready(16, .5, 50));
|
||||||
|
assertFalse(LodWork.ready(16, -1, 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,29 @@ import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
final class ModRangesTest {
|
final class ModRangesTest {
|
||||||
|
@Test
|
||||||
|
void turboRefinementAllowsCompatiblePatches() {
|
||||||
|
assertFalse(ModRanges.contains(new DefaultArtifactVersion("1.4.0"), LodPlugin.TURBO));
|
||||||
|
assertTrue(ModRanges.contains(new DefaultArtifactVersion("1.5.0"), LodPlugin.TURBO));
|
||||||
|
assertTrue(ModRanges.contains(new DefaultArtifactVersion("1.5.1"), LodPlugin.TURBO));
|
||||||
|
assertFalse(ModRanges.contains(new DefaultArtifactVersion("1.6.0"), LodPlugin.TURBO));
|
||||||
|
assertFalse(ModRanges.contains(new DefaultArtifactVersion("3.3.2"), LodPlugin.DH));
|
||||||
|
assertTrue(ModRanges.contains(new DefaultArtifactVersion("3.3.3"), LodPlugin.DH));
|
||||||
|
assertTrue(ModRanges.contains(new DefaultArtifactVersion("3.3.4"), LodPlugin.DH));
|
||||||
|
assertFalse(ModRanges.contains(new DefaultArtifactVersion("3.4.0"), LodPlugin.DH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void curioSnapshotsAllowCompatibleUpdates() {
|
||||||
|
assertFalse(
|
||||||
|
ModRanges.contains(new DefaultArtifactVersion("9.5.0+1.21.1"), CurioPlugin.CURIOS));
|
||||||
|
assertTrue(
|
||||||
|
ModRanges.contains(new DefaultArtifactVersion("9.5.1+1.21.1"), CurioPlugin.CURIOS));
|
||||||
|
assertTrue(
|
||||||
|
ModRanges.contains(new DefaultArtifactVersion("9.6.0+1.21.1"), CurioPlugin.CURIOS));
|
||||||
|
assertFalse(ModRanges.contains(new DefaultArtifactVersion("10.0.0"), CurioPlugin.CURIOS));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void chunkSnapshotsAllowLaterCompatibleReleases() {
|
void chunkSnapshotsAllowLaterCompatibleReleases() {
|
||||||
assertFalse(
|
assertFalse(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue