Open dependency floors and gate EMI, Elytra, and compiled-density fixes to the versions that need them
This commit is contained in:
parent
5c04905561
commit
17e5817faa
20 changed files with 550 additions and 8 deletions
|
|
@ -20,6 +20,7 @@ configurations { testImplementation.extendsFrom compileOnly }
|
|||
dependencies {
|
||||
compileOnly('net.createmod.ponder:ponder-neoforge:1.0.82+mc1.21.1') { transitive = false }
|
||||
compileOnly('maven.modrinth:iris:t3ruzodq') { transitive = false }
|
||||
compileOnly('maven.modrinth:jei:Tn0dgwL0') { transitive = false }
|
||||
compileOnly('dev.engine-room.flywheel:flywheel-neoforge-1.21.1:1.0.6') { transitive = false }
|
||||
testImplementation 'org.ow2.asm:asm-tree:9.8'
|
||||
testImplementation 'org.ow2.asm:asm-commons:9.8'
|
||||
|
|
|
|||
51
client/src/main/java/dev/quorate/client/mixin/EmiPlugin.java
Normal file
51
client/src/main/java/dev/quorate/client/mixin/EmiPlugin.java
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package dev.quorate.client.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 EmiPlugin implements IMixinConfigPlugin {
|
||||
// 1.1.24 leaves JEI's aligned setPosition abstract. 1.1.25 is the next release.
|
||||
static final String EMI = "[1.1.24+1.21.1+neoforge,1.1.25+1.21.1+neoforge)";
|
||||
|
||||
// 19.57.0.450 declares the aligned method and places through getXPos/getYPos.
|
||||
static final String JEI = "[19.57.0.450,19.58)";
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {}
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return ModRanges.loaded("emi", EMI) && ModRanges.loaded("jei", JEI);
|
||||
}
|
||||
|
||||
@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) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package dev.quorate.client.mixin;
|
||||
|
||||
import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
|
||||
import mezz.jei.api.gui.placement.HorizontalAlignment;
|
||||
import mezz.jei.api.gui.placement.VerticalAlignment;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(targets = "dev.emi.emi.jemi.impl.JemiRecipeSlotBuilder", remap = false)
|
||||
public abstract class EmiSlotMixin {
|
||||
@Shadow(remap = false)
|
||||
public abstract IRecipeSlotBuilder setPosition(int x, int y);
|
||||
|
||||
@Shadow(remap = false)
|
||||
public abstract int getWidth();
|
||||
|
||||
@Shadow(remap = false)
|
||||
public abstract int getHeight();
|
||||
|
||||
// Same placement as JEI PlaceableUtil: origin plus alignment inside the area.
|
||||
public IRecipeSlotBuilder setPosition(
|
||||
int areaX,
|
||||
int areaY,
|
||||
int areaWidth,
|
||||
int areaHeight,
|
||||
HorizontalAlignment horizontal,
|
||||
VerticalAlignment vertical) {
|
||||
return setPosition(
|
||||
areaX + horizontal.getXPos(areaWidth, getWidth()),
|
||||
areaY + vertical.getYPos(areaHeight, getHeight()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package dev.quorate.client.mixin;
|
||||
|
||||
import mezz.jei.api.gui.placement.HorizontalAlignment;
|
||||
import mezz.jei.api.gui.placement.VerticalAlignment;
|
||||
import mezz.jei.api.gui.widgets.ITextWidget;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(targets = "dev.emi.emi.jemi.impl.extras.JemiTextWidget", remap = false)
|
||||
public abstract class EmiTextMixin {
|
||||
@Shadow(remap = false)
|
||||
public int x;
|
||||
|
||||
@Shadow(remap = false)
|
||||
public int y;
|
||||
|
||||
@Shadow(remap = false)
|
||||
public abstract int getWidth();
|
||||
|
||||
@Shadow(remap = false)
|
||||
public abstract int getHeight();
|
||||
|
||||
// ITextWidget.setPosition returns ITextWidget. The parent method returns IPlaceable.
|
||||
public ITextWidget setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
return (ITextWidget) (Object) this;
|
||||
}
|
||||
|
||||
public ITextWidget setPosition(
|
||||
int areaX,
|
||||
int areaY,
|
||||
int areaWidth,
|
||||
int areaHeight,
|
||||
HorizontalAlignment horizontal,
|
||||
VerticalAlignment vertical) {
|
||||
return setPosition(
|
||||
areaX + horizontal.getXPos(areaWidth, getWidth()),
|
||||
areaY + vertical.getYPos(areaHeight, getHeight()));
|
||||
}
|
||||
}
|
||||
31
client/src/main/java/dev/quorate/client/mixin/ModRanges.java
Normal file
31
client/src/main/java/dev/quorate/client/mixin/ModRanges.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package dev.quorate.client.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,10 +11,13 @@ description="Create rendering and collision query optimizations."
|
|||
[[mixins]]
|
||||
config="client.mixins.json"
|
||||
|
||||
[[mixins]]
|
||||
config="client.jemi.mixins.json"
|
||||
|
||||
[[dependencies.saltatory_client]]
|
||||
modId="neoforge"
|
||||
type="required"
|
||||
versionRange="[21.1.250]"
|
||||
versionRange="[21.1.250,)"
|
||||
ordering="NONE"
|
||||
side="CLIENT"
|
||||
|
||||
|
|
@ -31,13 +34,13 @@ javaVersion="[25,)"
|
|||
[[dependencies.saltatory_client]]
|
||||
modId="ponder"
|
||||
type="required"
|
||||
versionRange="[1.0.82+mc1.21.1]"
|
||||
versionRange="[1.0.82+mc1.21.1,)"
|
||||
ordering="AFTER"
|
||||
side="CLIENT"
|
||||
|
||||
[[dependencies.saltatory_client]]
|
||||
modId="iris"
|
||||
type="required"
|
||||
versionRange="[1.8.12-snapshot+mc1.21.1-local]"
|
||||
versionRange="[1.8.12-snapshot+mc1.21.1-local,)"
|
||||
ordering="AFTER"
|
||||
side="CLIENT"
|
||||
|
|
|
|||
14
client/src/main/resources/client.jemi.mixins.json
Normal file
14
client/src/main/resources/client.jemi.mixins.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8.7",
|
||||
"package": "dev.quorate.client.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"plugin": "dev.quorate.client.mixin.EmiPlugin",
|
||||
"client": [
|
||||
"EmiSlotMixin",
|
||||
"EmiTextMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package dev.quorate.client.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 jemiGateMatchesTheBrokenPairOnly() {
|
||||
assertTrue(
|
||||
ModRanges.contains(
|
||||
new DefaultArtifactVersion("1.1.24+1.21.1+neoforge"), EmiPlugin.EMI));
|
||||
assertFalse(
|
||||
ModRanges.contains(
|
||||
new DefaultArtifactVersion("1.1.23+1.21.1+neoforge"), EmiPlugin.EMI));
|
||||
assertFalse(
|
||||
ModRanges.contains(
|
||||
new DefaultArtifactVersion("1.1.25+1.21.1+neoforge"), EmiPlugin.EMI));
|
||||
assertTrue(ModRanges.contains(new DefaultArtifactVersion("19.57.0.450"), EmiPlugin.JEI));
|
||||
assertTrue(ModRanges.contains(new DefaultArtifactVersion("19.57.0.451"), EmiPlugin.JEI));
|
||||
assertFalse(ModRanges.contains(new DefaultArtifactVersion("19.56.0.1"), EmiPlugin.JEI));
|
||||
assertFalse(ModRanges.contains(new DefaultArtifactVersion("19.58"), EmiPlugin.JEI));
|
||||
}
|
||||
}
|
||||
34
server/src/main/java/dev/quorate/tune/ElytraCooldown.java
Normal file
34
server/src/main/java/dev/quorate/tune/ElytraCooldown.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
server/src/main/java/dev/quorate/tune/mixin/DfcFallback.java
Normal file
15
server/src/main/java/dev/quorate/tune/mixin/DfcFallback.java
Normal 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();
|
||||
}
|
||||
40
server/src/main/java/dev/quorate/tune/mixin/DfcMixin.java
Normal file
40
server/src/main/java/dev/quorate/tune/mixin/DfcMixin.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
server/src/main/java/dev/quorate/tune/mixin/DfcPlugin.java
Normal file
48
server/src/main/java/dev/quorate/tune/mixin/DfcPlugin.java
Normal 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) {}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
31
server/src/main/java/dev/quorate/tune/mixin/ModRanges.java
Normal file
31
server/src/main/java/dev/quorate/tune/mixin/ModRanges.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
14
server/src/main/resources/tune.dfc.mixins.json
Normal file
14
server/src/main/resources/tune.dfc.mixins.json
Normal 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
|
||||
}
|
||||
}
|
||||
14
server/src/main/resources/tune.elytra.mixins.json
Normal file
14
server/src/main/resources/tune.elytra.mixins.json
Normal 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
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue