Open dependency floors and gate EMI, Elytra, and compiled-density fixes to the versions that need them

This commit is contained in:
ms2k 2026-11-03 19:26:32 +09:00
commit 17e5817faa
12 changed files with 550 additions and 8 deletions

View file

@ -0,0 +1,34 @@
package dev.quorate.tune;
import java.util.function.IntSupplier;
public final class ElytraCooldown {
private static IntSupplier read = ElytraCooldown::bind;
private ElytraCooldown() {}
public static int get() {
return read.getAsInt();
}
private static int bind() {
try {
var configType = Class.forName("com.kyanite.deeperdarker.DeeperDarkerConfig");
var config = configType.getField("CONFIG").get(null);
var setting = config.getClass().getField("soulElytraCooldown").get(config);
var getter = setting.getClass().getMethod("getAsInt");
IntSupplier bound =
() -> {
try {
return (int) getter.invoke(setting);
} catch (ReflectiveOperationException failure) {
throw new IllegalStateException(failure);
}
};
read = bound;
return bound.getAsInt();
} catch (ReflectiveOperationException failure) {
throw new IllegalStateException(failure);
}
}
}

View file

@ -0,0 +1,15 @@
package dev.quorate.tune.mixin;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
// Declared on the parent. A shadow on either subclass does not see it.
@Mixin(
targets = "com.ishland.c2me.opts.dfc.common.gen.jvm.AbstractCompiledDensityFunction",
remap = false)
public interface DfcFallback {
@Invoker(value = "getFallback", remap = false)
DensityFunction fallback();
}

View file

@ -0,0 +1,40 @@
package dev.quorate.tune.mixin;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(
targets = {
"com.ishland.c2me.opts.dfc.common.gen.jvm.CompiledDensityFunction",
"com.ishland.c2me.opts.dfc.common.gen.jvm.SubCompiledDensityFunction"
},
remap = false)
public abstract class DfcMixin {
private static final Class<?> CACHING_VISITOR = cachingVisitor();
// Rebuilding for a foreign visitor casts every child to IFastCacheLike.
// C2ME's own visitors implement the caching interface and stay compiled.
@Inject(method = "mapAll", at = @At("HEAD"), cancellable = true, remap = false)
private void mctune$fallback(
DensityFunction.Visitor visitor, CallbackInfoReturnable<DensityFunction> cir) {
if (CACHING_VISITOR == null || CACHING_VISITOR.isInstance(visitor)) return;
var fallback = ((DfcFallback) (Object) this).fallback();
if (fallback == null) return;
cir.setReturnValue(fallback.mapAll(visitor));
}
private static Class<?> cachingVisitor() {
try {
return Class.forName(
"com.ishland.c2me.opts.dfc.common.ducks.ICompiledCachingAwareVisitor",
false,
DfcMixin.class.getClassLoader());
} catch (ClassNotFoundException _) {
return null;
}
}
}

View file

@ -0,0 +1,48 @@
package dev.quorate.tune.mixin;
import net.neoforged.fml.loading.LoadingModList;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public final class DfcPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
var mods = LoadingModList.get();
return mods != null && mods.getModFileById("c2me_opts_dfc") != null;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(
String targetClassName,
ClassNode targetClass,
String mixinClassName,
IMixinInfo mixinInfo) {}
@Override
public void postApply(
String targetClassName,
ClassNode targetClass,
String mixinClassName,
IMixinInfo mixinInfo) {}
}

View file

@ -0,0 +1,28 @@
package dev.quorate.tune.mixin;
import dev.quorate.tune.ElytraCooldown;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(
targets =
"com.illusivesoulworks.elytraslot.common.integration.deeperdarker.SoulElytraBoostPayload",
remap = false)
public abstract class ElytraBoostMixin {
// Both reads are in the queued lambda, not in handle. One redirect covers every read.
@Redirect(
method = "lambda$handle$0",
at =
@At(
value = "FIELD",
target =
"Lcom/kyanite/deeperdarker/DeeperDarkerConfig;soulElytraCooldown:I",
opcode = Opcodes.GETSTATIC),
remap = false)
private static int mctune$cooldown() {
return ElytraCooldown.get();
}
}

View file

@ -0,0 +1,52 @@
package dev.quorate.tune.mixin;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public final class ElytraPlugin implements IMixinConfigPlugin {
// 9.0.2 reads a static int. The open 9.0.3 fix reads CONFIG instead.
static final String ELYTRA = "[9.0.2+1.21.1,9.0.3+1.21.1)";
// 1.4 moved the cooldown onto CONFIG. 1.4.1 still stores an IntValue there.
static final String DEEPER_DARKER = "[1.4,1.5)";
@Override
public void onLoad(String mixinPackage) {}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return ModRanges.loaded("elytraslot", ELYTRA)
&& ModRanges.loaded("deeperdarker", DEEPER_DARKER);
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(
String targetClassName,
ClassNode targetClass,
String mixinClassName,
IMixinInfo mixinInfo) {}
@Override
public void postApply(
String targetClassName,
ClassNode targetClass,
String mixinClassName,
IMixinInfo mixinInfo) {}
}

View file

@ -0,0 +1,27 @@
package dev.quorate.tune.mixin;
import dev.quorate.tune.ElytraCooldown;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(
targets =
"com.illusivesoulworks.elytraslot.common.integration.deeperdarker.DeeperDarkerPlugin",
remap = false)
public abstract class ElytraTickMixin {
@Redirect(
method = "tick",
at =
@At(
value = "FIELD",
target =
"Lcom/kyanite/deeperdarker/DeeperDarkerConfig;soulElytraCooldown:I",
opcode = Opcodes.GETSTATIC),
remap = false)
private static int mctune$remaining() {
return ElytraCooldown.get();
}
}

View file

@ -0,0 +1,31 @@
package dev.quorate.tune.mixin;
import net.neoforged.fml.loading.LoadingModList;
import net.neoforged.neoforgespi.language.MavenVersionAdapter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
public final class ModRanges {
private ModRanges() {}
public static boolean contains(ArtifactVersion version, String spec) {
return MavenVersionAdapter.createFromVersionSpec(spec).containsVersion(version);
}
public static boolean loaded(String modId, String spec) {
var mods = LoadingModList.get();
if (mods == null) {
return false;
}
var file = mods.getModFileById(modId);
if (file == null) {
return false;
}
for (var mod : file.getMods()) {
if (modId.equals(mod.getModId())) {
return contains(mod.getVersion(), spec);
}
}
return false;
}
}

View file

@ -11,10 +11,16 @@ description="Snapshot-local inventory prediction and copy-free NBT normalization
[[mixins]]
config="tune.mixins.json"
[[mixins]]
config="tune.dfc.mixins.json"
[[mixins]]
config="tune.elytra.mixins.json"
[[dependencies.saltatory]]
modId="neoforge"
type="required"
versionRange="[21.1.250]"
versionRange="[21.1.250,)"
ordering="NONE"
side="SERVER"
@ -28,21 +34,21 @@ side="SERVER"
[[dependencies.saltatory]]
modId="mekanism"
type="required"
versionRange="[10.7.19]"
versionRange="[10.7.19,)"
ordering="AFTER"
side="SERVER"
[[dependencies.saltatory]]
modId="almanac"
type="required"
versionRange="[1.5.2]"
versionRange="[1.5.2,)"
ordering="AFTER"
side="SERVER"
[[dependencies.saltatory]]
modId="functionalstorage"
type="required"
versionRange="[1.21.1-1.5.8]"
versionRange="[1.21.1-1.5.8,)"
ordering="AFTER"
side="SERVER"
@ -52,6 +58,6 @@ javaVersion="[25,)"
[[dependencies.saltatory]]
modId="refinedstorage"
type="required"
versionRange="[2.0.9]"
versionRange="[2.0.9,)"
ordering="AFTER"
side="SERVER"

View file

@ -0,0 +1,14 @@
{
"required": true,
"minVersion": "0.8.7",
"package": "dev.quorate.tune.mixin",
"compatibilityLevel": "JAVA_21",
"plugin": "dev.quorate.tune.mixin.DfcPlugin",
"mixins": [
"DfcFallback",
"DfcMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -0,0 +1,14 @@
{
"required": true,
"minVersion": "0.8.7",
"package": "dev.quorate.tune.mixin",
"compatibilityLevel": "JAVA_21",
"plugin": "dev.quorate.tune.mixin.ElytraPlugin",
"mixins": [
"ElytraBoostMixin",
"ElytraTickMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -0,0 +1,32 @@
package dev.quorate.tune.mixin;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.junit.jupiter.api.Test;
final class ModRangesTest {
@Test
void elytraGateMatchesTheBrokenReleaseOnly() {
assertTrue(
ModRanges.contains(
new DefaultArtifactVersion("9.0.2+1.21.1"), ElytraPlugin.ELYTRA));
assertFalse(
ModRanges.contains(
new DefaultArtifactVersion("9.0.1+1.21.1"), ElytraPlugin.ELYTRA));
assertFalse(
ModRanges.contains(
new DefaultArtifactVersion("9.0.3+1.21.1"), ElytraPlugin.ELYTRA));
assertTrue(
ModRanges.contains(
new DefaultArtifactVersion("1.4.1"), ElytraPlugin.DEEPER_DARKER));
assertTrue(
ModRanges.contains(new DefaultArtifactVersion("1.4"), ElytraPlugin.DEEPER_DARKER));
assertFalse(
ModRanges.contains(
new DefaultArtifactVersion("1.3.9"), ElytraPlugin.DEEPER_DARKER));
assertFalse(
ModRanges.contains(new DefaultArtifactVersion("1.5"), ElytraPlugin.DEEPER_DARKER));
}
}