Compare commits

..
9 Commits
Author SHA1 Message Date
danyadev 93d8ebf6c6 fix alfheim crash (#72) 2026-09-20 07:13:13 -04:00
Roadhog360 4ed4fde3cf Merge pull request #68 from LegacyModdingMC/ah-OOG-ah/publishnotes
Add publishing notes to developer docs
2026-08-10 21:01:27 -05:00
danyadev c47090bcae fix ASMRemapperTransformer (#70) 2026-05-10 23:12:39 -04:00
ah-OOG-ah b7e3384ceb Update developer-usage.md 2026-04-21 20:38:42 -04:00
danyadev c5c5cbeca1 bump unimixMixinVersion 2026-04-07 09:47:00 -07:00
danyadev 6e8f572f7e optimize ASMRemapperTransformer 2026-04-07 09:47:00 -07:00
ah-OOG-ah e60b681529 Remove GTNHMix mixin flavor (#65)
* Remove GTNHMix mixin flavor

* Re-add comments IDEA stripped
2026-01-11 12:11:25 -05:00
ah-OOG-ah 0ef643d32f Bump publishing Gradle to 7.4.2 (#64) 2026-01-11 08:16:00 -05:00
ah-OOG-ah cb08fbd2f1 Remove legacy shaded MixinExtra and GasStation module (#61)
* Update GTNH Maven

* Remove GTNHMixins shaded MixinExtras generation

As far as I can tell, no current mods use this.

* remove HTTP maven support

secure only!

* Remove GasStation module

* Remove GasMix

* Bump Mixin and ASM

* Remove Jitpack nonsense

* actually remove jitpack

* Add third-party NH maven

* Required to work with UniMix
2025-12-24 20:59:29 -05:00
12 changed files with 340 additions and 220 deletions

No files matched your search

+4
View File
@@ -1,5 +1,9 @@
# Developer usage
To publish a release, you must publish a **draft release** (not pre-release) on GitHub. Make sure to create a tag (or pick the latest one if you screwed up the release), autogenerate (or manually write, I suppose) the description, and set it as the latest release.
If that doesn't get the GH action to build the mod, attach it to the release, and mark it un-draft, please figure out what broke and correct this section.
An example mod showcasing the mod's various features is available in the `example-*` branches of the repo:
- [`example-fg-g4`](https://github.com/LegacyModdingMC/UniMixins/tree/example-fg-g4) - ForgeGradle-based build script with Gradle 4
- [`example-fg-g6`](https://github.com/LegacyModdingMC/UniMixins/tree/example-fg-g6) - ForgeGradle-based build script with Gradle 6
+1 -1
View File
@@ -147,7 +147,7 @@ tasks.withType(ShadowJar) {
'FMLCorePluginContainsFMLMod': true,
'ForceLoadAsMod': true,
'FMLCorePlugin': 'io.github.legacymoddingmc.unimixins.all.AllCore',
'MixinConfigs': 'mixins.gtnhmixins.json,mixingasm.mixin.json',
'MixinConfigs': 'mixins.gtnhmixins.json,mixingasm.init.mixin.json,mixingasm.mixin.json',
'Premain-Class': 'org.spongepowered.tools.agent.MixinAgent',
'Agent-Class': 'org.spongepowered.tools.agent.MixinAgent',
'Can-Redefine-Classes': true,
@@ -2,7 +2,6 @@ package io.github.legacymoddingmc.unimixins.compat.asm;
import static io.github.legacymoddingmc.unimixins.compat.CompatCore.LOGGER;
import com.google.common.primitives.Bytes;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import org.apache.commons.lang3.StringUtils;
@@ -10,13 +9,11 @@ import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Arrays;
import java.util.List;
/**
* <p>The ASM package name used by Mixin differs between mixin loaders. This transformer remaps references to ASM to use the
@@ -28,12 +25,12 @@ import java.util.stream.Collectors;
* <li><code>org.objectweb.asm</code> (Mixin 0.8) in classes implementing {@link org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin} or annotated with {@link io.github.legacymoddingmc.unimixins.compat.api.RemapASMForMixin}</li>
*/
// TODO Measure the performance impact of this and switch to doing it selectively if it would improve things.
public class ASMRemapperTransformer implements IClassTransformer {
private static final String ASM_PACKAGE_UNSHADED = "org/objectweb/asm/";
private static final String ASM_PACKAGE_LEGACY = "org/spongepowered/asm/lib/";
private static final String ASM_PACKAGE_MBL = "org/spongepowered/libraries/org/objectweb/asm/";
private static final String REMAP_ANNOTATION = "Lio/github/legacymoddingmc/unimixins/compat/api/RemapASMForMixin;";
private static final List<String> ASM_PACKAGE_PREFIXES = Arrays.asList(
ASM_PACKAGE_UNSHADED,
@@ -41,79 +38,95 @@ public class ASMRemapperTransformer implements IClassTransformer {
ASM_PACKAGE_MBL
);
private static final List<byte[]> SHADED_ASM_PACKAGE_PREFIXES_RAW = Arrays.asList(
ASM_PACKAGE_LEGACY.getBytes(StandardCharsets.UTF_8),
ASM_PACKAGE_MBL.getBytes(StandardCharsets.UTF_8)
);
private static String realASMPackagePrefix;
private static List<byte[]> wrongASMPackagePrefixesRaw;
private static List<String> wrongASMPackagePrefixes;
private final BytePatternMatcher wrongAsmMatcher;
private final BytePatternMatcher shadedAsmMatcher;
private final BytePatternMatcher remapAnnotationMatcher;
public ASMRemapperTransformer() {
final String[] wrongAsmPackagePrefixes = ASM_PACKAGE_PREFIXES.stream()
.filter(x -> !x.equals(getRealASMPackagePrefix()))
.toArray(String[]::new);
final String[] shadedAsmPackagePrefixes = new String[] { ASM_PACKAGE_LEGACY, ASM_PACKAGE_MBL };
this.wrongAsmMatcher = new BytePatternMatcher(wrongAsmPackagePrefixes, BytePatternMatcher.Mode.Contains);
this.shadedAsmMatcher = new BytePatternMatcher(shadedAsmPackagePrefixes, BytePatternMatcher.Mode.Contains);
this.remapAnnotationMatcher = new BytePatternMatcher(REMAP_ANNOTATION, BytePatternMatcher.Mode.Equals);
}
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if(basicClass == null) {
if (basicClass == null) {
return null;
}
if(transformedName.startsWith("io.github.legacymoddingmc.unimixins.compat.asm.")
if (transformedName.startsWith("io.github.legacymoddingmc.unimixins.compat.asm.")
|| transformedName.startsWith("com.google.")
|| transformedName.startsWith("org.apache.")
|| transformedName.startsWith("org.objectweb.asm.")
) return basicClass;
) {
return basicClass;
}
boolean foundWrongAsm = containsAnyPattern(basicClass, getWrongASMPackagePrefixesRaw());
ClassReader classReader = new ClassReader(basicClass);
if(!foundWrongAsm) return basicClass;
boolean foundWrongAsm = matchUtf8Constant(classReader, basicClass, wrongAsmMatcher);
if (!foundWrongAsm) return basicClass;
boolean foundShadedAsm = containsAnyPattern(basicClass, SHADED_ASM_PACKAGE_PREFIXES_RAW);
boolean doRemap = matchUtf8Constant(classReader, basicClass, shadedAsmMatcher);
boolean doRemap = foundShadedAsm;
if(!doRemap) {
ClassNode classNode = new ClassNode();
ClassReader classReaderForNode = new ClassReader(basicClass);
classReaderForNode.accept(classNode, 0);
if(classNode.interfaces != null) {
for (String itf : classNode.interfaces) {
if (itf.equals("org/spongepowered/asm/mixin/extensibility/IMixinConfigPlugin")) {
doRemap = true;
break;
}
}
}
if(!doRemap) {
if(classNode.visibleAnnotations != null) {
for (AnnotationNode ann : classNode.visibleAnnotations) {
if (ann.desc.equals("Lio/github/legacymoddingmc/unimixins/compat/api/RemapASMForMixin;")) {
doRemap = true;
break;
}
}
if (!doRemap) {
for (String itf : classReader.getInterfaces()) {
if (itf.equals("org/spongepowered/asm/mixin/extensibility/IMixinConfigPlugin")) {
doRemap = true;
break;
}
}
}
if(doRemap) {
ClassReader classReader = new ClassReader(basicClass);
LOGGER.info("Transforming class " + transformedName + " to fit current mixin environment.");
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
RemappingClassAdapter remapAdapter = new SpongepoweredASMRemappingAdapter(classWriter);
classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES);
basicClass = classWriter.toByteArray();
if (!doRemap) {
doRemap = matchUtf8Constant(classReader, basicClass, remapAnnotationMatcher);
}
return basicClass;
if (!doRemap) {
return basicClass;
}
LOGGER.info("Transforming class {} to fit current mixin environment.", transformedName);
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
RemappingClassAdapter remapAdapter = new SpongepoweredASMRemappingAdapter(classWriter);
classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES);
return classWriter.toByteArray();
}
private static boolean containsAnyPattern(byte[] array, List<byte[]> patterns) {
if(array == null) {
return false;
}
for(byte[] pattern : patterns) {
if(Bytes.indexOf(array, pattern) != -1) {
private static boolean matchUtf8Constant(ClassReader classReader, byte[] basicClass, BytePatternMatcher matcher) {
final int itemCount = classReader.getItemCount();
// Constant pool entries start from index 1
for (int i = 1; i < itemCount; i++) {
final int itemOffset = classReader.getItem(i);
// Long and double take two CP slots, the second slot has no item
if (itemOffset == 0) {
continue;
}
// Only match the UTF8 constant (which tag is 1).
// getItem(i) points after the tag byte, i.e. at the first length byte.
// [tag][u2 length][bytes...]
if (basicClass[itemOffset - 1] != 1) {
continue;
}
// Length takes 2 bytes, so we read them and skip these 2 bytes
final int utfLen = classReader.readUnsignedShort(itemOffset);
final int utfStart = itemOffset + 2;
if (matcher.matches(basicClass, utfStart, utfLen)) {
return true;
}
}
return false;
}
@@ -146,20 +159,6 @@ public class ASMRemapperTransformer implements IClassTransformer {
}
return realASMPackagePrefix;
}
private static List<String> getWrongASMPackagePrefixes() {
if(wrongASMPackagePrefixes == null) {
wrongASMPackagePrefixes = ASM_PACKAGE_PREFIXES.stream().filter(x -> !x.equals(getRealASMPackagePrefix())).collect(Collectors.toList());
}
return wrongASMPackagePrefixes;
}
private static List<byte[]> getWrongASMPackagePrefixesRaw() {
if(wrongASMPackagePrefixesRaw == null) {
wrongASMPackagePrefixesRaw = getWrongASMPackagePrefixes().stream().map(x -> x.getBytes(StandardCharsets.UTF_8)).collect(Collectors.toList());
}
return wrongASMPackagePrefixesRaw;
}
private static class SpongepoweredASMRemappingAdapter extends RemappingClassAdapter {
public SpongepoweredASMRemappingAdapter(ClassWriter classWriter) {
@@ -0,0 +1,145 @@
package io.github.legacymoddingmc.unimixins.compat.asm;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* Was taken from <a href="https://github.com/GTNewHorizons/RetroFuturaBootstrap/pull/20">RFB</a>
*/
public class BytePatternMatcher {
final Mode mode;
// first byte -> matched patterns
final byte[][][] byFirst = new byte[256][][];
int minPatternLen = Integer.MAX_VALUE;
public enum Mode {
/** Checks if the constant pool entry contains a pattern */
Contains,
/** Checks if the whole constant pool entry equals a pattern */
Equals,
/** Checks if the constant pool entry starts with a pattern */
StartsWith
}
public BytePatternMatcher(String strPattern, Mode mode) {
this(new String[] {strPattern}, mode);
}
public BytePatternMatcher(String[] strPatterns, Mode mode) {
this.mode = mode;
final byte[][] patterns = new byte[strPatterns.length][];
final int[] bucketSizes = new int[256];
final int[] bucketIndices = new int[Math.min(strPatterns.length, 256)];
int bucketsCount = 0;
for (int i = 0; i < strPatterns.length; i++) {
final byte[] pattern = strPatterns[i].getBytes(StandardCharsets.UTF_8);
patterns[i] = pattern;
if (pattern.length < minPatternLen) {
minPatternLen = pattern.length;
}
final int bucketIndex = pattern[0] & 0xFF;
if (bucketSizes[bucketIndex]++ == 0) {
bucketIndices[bucketsCount++] = bucketIndex;
}
}
// Ascending sorting by length
Arrays.sort(patterns, (a, b) -> Integer.compare(a.length, b.length));
for (int i = 0; i < bucketsCount; i++) {
final int bucketIndex = bucketIndices[i];
byFirst[bucketIndex] = new byte[bucketSizes[bucketIndex]][];
bucketSizes[bucketIndex] = 0; // reuse as write index
}
for (final byte[] pattern : patterns) {
final int bucketIndex = pattern[0] & 0xFF;
byFirst[bucketIndex][bucketSizes[bucketIndex]++] = pattern;
}
}
public boolean matches(byte[] bytes, int start, int len) {
if (len < minPatternLen) {
return false;
}
switch (mode) {
case Contains:
return contains(bytes, start, len);
case Equals:
return equals(bytes, start, len);
case StartsWith:
return startsWith(bytes, start, len);
}
return false;
}
private boolean contains(byte[] bytes, int start, int len) {
final int end = start + len;
for (int pos = start; pos <= end - minPatternLen; pos++) {
final byte[][] patterns = byFirst[bytes[pos] & 0xFF];
if (patterns == null) {
continue;
}
for (final byte[] pattern : patterns) {
if (pattern.length > end - pos) {
break;
}
int k = pattern.length - 1;
while (k > 0 && bytes[pos + k] == pattern[k]) k--;
if (k == 0) return true;
}
}
return false;
}
private boolean equals(byte[] bytes, int start, int len) {
final byte[][] patterns = byFirst[bytes[start] & 0xFF];
if (patterns == null) {
return false;
}
for (final byte[] pattern : patterns) {
if (pattern.length < len) {
continue;
}
if (pattern.length > len) {
break;
}
int k = pattern.length - 1;
while (k > 0 && bytes[start + k] == pattern[k]) k--;
if (k == 0) return true;
}
return false;
}
private boolean startsWith(byte[] bytes, int start, int len) {
final byte[][] patterns = byFirst[bytes[start] & 0xFF];
if (patterns == null) {
return false;
}
for (final byte[] pattern : patterns) {
if (pattern.length > len) {
break;
}
int k = pattern.length - 1;
while (k > 0 && bytes[start + k] == pattern[k]) k--;
if (k == 0) return true;
}
return false;
}
}
@@ -24,8 +24,6 @@ public class HackClasspathModDiscoveryTransformer implements IClassTransformer {
if(basicClass == null) {
return null;
}
if(transformedName.startsWith("org.objectweb.asm.")) return basicClass;
if(transformedName.equals("cpw.mods.fml.common.discovery.ModDiscoverer")) {
basicClass = doTransformModDiscoverer(basicClass);
}
@@ -41,22 +39,20 @@ public class HackClasspathModDiscoveryTransformer implements IClassTransformer {
classReader.accept(classNode, 0);
for(MethodNode m : classNode.methods) {
if(m.name.equals("findClasspathMods")) {
Iterator<AbstractInsnNode> it = m.instructions.iterator();
while(it.hasNext()) {
AbstractInsnNode i = it.next();
for (AbstractInsnNode i = m.instructions.getFirst(); i != null; i = i.getNext()) {
if(i.getOpcode() == INVOKESTATIC) {
MethodInsnNode mi = (MethodInsnNode)i;
if(mi.owner.equals("cpw/mods/fml/relauncher/CoreModManager") && mi.name.equals("getReparseableCoremods") && mi.desc.equals("()Ljava/util/List;")) {
m.instructions.insertBefore(mi, new MethodInsnNode(INVOKESTATIC, "io/github/legacymoddingmc/unimixins/compat/asm/HackClasspathModDiscoveryTransformer$Hooks", "redirectGetReparseableCoremods", mi.desc));
it.remove();
m.instructions.insertBefore(mi, new MethodInsnNode(INVOKESTATIC, "io/github/legacymoddingmc/unimixins/compat/asm/HackClasspathModDiscoveryTransformer$Hooks", "redirectGetReparseableCoremods", mi.desc, false));
m.instructions.remove(mi);
break;
}
}
}
break;
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassWriter writer = new ClassWriter(0);
classNode.accept(writer);
return writer.toByteArray();
} catch(Exception e) {
@@ -74,11 +74,12 @@ public class IgnoreDuplicateJarsTransformer implements IClassTransformer {
if(m.name.equals("identifyMods")) {
InsnList patch = new InsnList();
patch.add(new VarInsnNode(ALOAD, 0));
patch.add(new MethodInsnNode(INVOKESTATIC, "io/github/legacymoddingmc/unimixins/compat/asm/IgnoreDuplicateJarsTransformer$Hooks", "preIdentifyMods", "(Lcpw/mods/fml/common/discovery/ModDiscoverer;)V"));
patch.add(new MethodInsnNode(INVOKESTATIC, "io/github/legacymoddingmc/unimixins/compat/asm/IgnoreDuplicateJarsTransformer$Hooks", "preIdentifyMods", "(Lcpw/mods/fml/common/discovery/ModDiscoverer;)V", false));
m.instructions.insert(patch);
break;
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
} catch(Exception e) {
+101 -130
View File
@@ -23,13 +23,13 @@ dependencies {
apply plugin: "com.github.johnrengelman.shadow"
def flavors = (!project.hasProperty("enableAltMixin") ? [] : ["spongepowered", "fabric", "gtnh"]) + ["unimix"]
def flavors = (!project.hasProperty("enableAltMixin") ? [] : ["spongepowered", "fabric"]) + ["unimix"]
flavors.each {
def mixinFlavor = it
def _flavor = it.capitalize()
def mixinFlavorClassifier = "UNKNOWN"
def mixinFlavorCapitalized = [spongepowered: "SpongePowered", fabric: "Fabric", gtnh: "GTNH", unimix: "UniMix"][mixinFlavor]
def mixinFlavorCapitalized = [spongepowered: "SpongePowered", fabric: "Fabric", unimix: "UniMix"][mixinFlavor]
def mixinVersion = "UNKNOWN"
configurations.create("shadow$_flavor")
@@ -42,159 +42,130 @@ flavors.each {
})
}
if (mixinFlavor == "fabric" || mixinFlavor == "spongepowered" || mixinFlavor == "unimix" || mixinFlavor == "gtnh") {
// Fabric / SpongePowered / UniMix / GTNH
if (mixinFlavor == "fabric" || mixinFlavor == "unimix") {
def uniLocal = mixinFlavor == "unimix" && project.hasProperty("local")
mixinVersion = mixinFlavor == "fabric" ? fabricMixinVersion : unimixMixinVersion
if (uniLocal) {
mixinVersion += "-local"
}
if (mixinFlavor == "fabric" || mixinFlavor == "unimix") {
def uniLocal = mixinFlavor == "unimix" && project.hasProperty("local")
mixinVersion = mixinFlavor == "fabric" ? fabricMixinVersion : unimixMixinVersion
if (uniLocal) {
mixinVersion += "-local"
}
def mixinGroup = mixinFlavor == "fabric" ? "net.fabricmc" : "io.github.legacymoddingmc"
def mixinArtifactId = "sponge-mixin"
def mixinDepVersion = mixinVersion
def mixinDep = "$mixinGroup:$mixinArtifactId:$mixinDepVersion"
def mixinGroup = mixinFlavor == "fabric" ? "net.fabricmc" : "io.github.legacymoddingmc"
def mixinArtifactId = "sponge-mixin"
def mixinDepVersion = mixinVersion
def mixinDep = "$mixinGroup:$mixinArtifactId:$mixinDepVersion"
mixinFlavorClassifier = "$mixinFlavor.${mixinVersion.replace('+', '-')}"
dependencies {
add("shadow$_flavor", "$mixinDep", {
exclude group: "org.ow2.asm"
})
add("shadow$_flavor", "org.ow2.asm:asm-tree:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-commons:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-util:$asmVersion")
mixinFlavorClassifier = "$mixinFlavor.${mixinVersion.replace('+', '-')}"
add("shadowBridge$_flavor", "$mixinDep", {
transitive = false
})
dependencies {
add("shadow$_flavor", "$mixinDep", {
exclude group: "org.ow2.asm"
})
add("shadow$_flavor", "org.ow2.asm:asm-tree:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-commons:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-util:$asmVersion")
add("shadowSources$_flavor", "$mixinDep:sources", {
transitive = false
})
}
} else if(mixinFlavor == "spongepowered") {
mixinVersion = spongepoweredMixinVersion
mixinFlavorClassifier = "spongepowered.$mixinVersion"
dependencies {
add("shadow$_flavor", "org.spongepowered:mixin:$mixinVersion")
add("shadowBridge$_flavor", "org.spongepowered:mixin:$mixinVersion", {
transitive = false
})
add("shadow$_flavor", "com.google.guava:guava:21.0")
add("shadow$_flavor", "com.google.code.gson:gson:2.2.4")
add("shadow$_flavor", "org.ow2.asm:asm-tree:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-commons:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-util:$asmVersion")
add("shadowBridge$_flavor", "$mixinDep", {
transitive = false
})
add("shadowSources$_flavor", "org.spongepowered:mixin:$mixinVersion:sources")
}
} else if(mixinFlavor == "gtnh") {
// Adapted from GTNHMixins's build script
add("shadowSources$_flavor", "$mixinDep:sources", {
transitive = false
})
}
} else if(mixinFlavor == "spongepowered") {
mixinVersion = spongepoweredMixinVersion
mixinVersion = gtnhMixinVersion
mixinFlavorClassifier = "gtnh.$mixinVersion"
dependencies {
add("shadow$_flavor", "org.spongepowered:mixin:$mixinVersion")
add("shadow$_flavor", "org.ow2.asm:asm-tree:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-commons:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-util:$asmVersion")
add("shadow$_flavor", "com.google.guava:guava:21.0")
add("shadowBridge$_flavor", "org.spongepowered:mixin:$spongepoweredMixinVersion")
add("shadowSources$_flavor", "org.spongepowered:mixin:$spongepoweredMixinVersion:sources")
}
mixinFlavorClassifier = "spongepowered.$mixinVersion"
}
dependencies {
add("shadow$_flavor", "org.spongepowered:mixin:$mixinVersion")
add("shadowBridge$_flavor", "org.spongepowered:mixin:$mixinVersion", {
transitive = false
})
add("shadow$_flavor", "com.google.guava:guava:21.0")
add("shadow$_flavor", "com.google.code.gson:gson:2.2.4")
add("shadow$_flavor", "org.ow2.asm:asm-tree:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-commons:$asmVersion")
add("shadow$_flavor", "org.ow2.asm:asm-util:$asmVersion")
// We want to *not* relocate ASM in the bridge classes. So we use a multi-step
// build procedure:
add("shadowSources$_flavor", "org.spongepowered:mixin:$mixinVersion:sources")
}
}
// 1. Create relocated Mixin jar, without the bridge classes
task("mixinJar$_flavor", type: ShadowJar) {
destinationDirectory = file("build/tmp")
classifier = "tmpMixin$_flavor"
configurations = [project.configurations."shadow$_flavor"]
// We want to *not* relocate ASM in the bridge classes. So we use a multi-step
// build procedure:
relocate 'org.objectweb.asm', 'org.spongepowered.asm.lib'
if(mixinFlavor != "gtnh") {
relocate 'com.google', 'org.spongepowered.libraries.com.google'
} else {
// we don't use this ASM package name
//relocate 'org.objectweb.asm', 'org.spongepowered.libraries.org.objectweb.asm'
relocate 'com.google.common', 'org.spongepowered.libraries.com.google.common'
relocate 'com.google.thirdparty.publicsuffix', 'org.spongepowered.libraries.com.google.thirdparty.publicsuffix'
}
// 1. Create relocated Mixin jar, without the bridge classes
task("mixinJar$_flavor", type: ShadowJar) {
destinationDirectory = file("build/tmp")
classifier = "tmpMixin$_flavor"
configurations = [project.configurations."shadow$_flavor"]
exclude 'org/spongepowered/asm/bridge/RemapperAdapter.class'
exclude 'org/spongepowered/asm/bridge/RemapperAdapterFML.class'
relocate 'org.objectweb.asm', 'org.spongepowered.asm.lib'
relocate 'com.google', 'org.spongepowered.libraries.com.google'
// Exclude stuff that's compiled for Java 16
exclude 'org/spongepowered/asm/bridge/RemapperAdapter.class'
exclude 'org/spongepowered/asm/bridge/RemapperAdapterFML.class'
exclude 'org/spongepowered/asm/service/modlauncher/*'
exclude 'org/spongepowered/asm/launch/MixinTransformationServiceLegacy*'
exclude 'org/spongepowered/asm/launch/MixinLaunchPlugin*'
exclude 'org/spongepowered/asm/launch/MixinTransformationService*'
exclude 'org/spongepowered/asm/launch/platform/container/ContainerHandleModLauncherEx*'
// Exclude stuff that's compiled for Java 16
exclude 'META-INF/services/cpw.mods.modlauncher.api.ITransformationService'
exclude 'META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService'
exclude '**/module-info.class'
exclude 'org/spongepowered/asm/service/modlauncher/*'
exclude 'org/spongepowered/asm/launch/MixinTransformationServiceLegacy*'
exclude 'org/spongepowered/asm/launch/MixinLaunchPlugin*'
exclude 'org/spongepowered/asm/launch/MixinTransformationService*'
exclude 'org/spongepowered/asm/launch/platform/container/ContainerHandleModLauncherEx*'
// Exclude jar-specific stuff
exclude 'META-INF/services/cpw.mods.modlauncher.api.ITransformationService'
exclude 'META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService'
exclude 'META-INF/MANIFEST.MF', 'META-INF/maven/**', 'META-INF/*.RSA', 'META-INF/*.SF'
}
exclude '**/module-info.class'
// 2. Create Mixin jar without relocation, with *only* the bridge classes
task("bridgeJar$_flavor", type: ShadowJar) {
destinationDirectory = file("build/tmp")
classifier = "tmpBridge$_flavor"
configurations = [project.configurations."shadowBridge$_flavor"]
// Exclude jar-specific stuff
include '*.jar'
include 'org/spongepowered/asm/bridge/*'
}
exclude 'META-INF/MANIFEST.MF', 'META-INF/maven/**', 'META-INF/*.RSA', 'META-INF/*.SF'
}
// 3. Combine the two jars
task("shadowJar$_flavor", type: ShadowJar) {
version = versionBase + "+" + mixinFlavorClassifier
from(sourceSets.main.output) {
exclude "mcmod.info"
}
// 2. Create Mixin jar without relocation, with *only* the bridge classes
task("bridgeJar$_flavor", type: ShadowJar) {
destinationDirectory = file("build/tmp")
classifier = "tmpBridge$_flavor"
configurations = [project.configurations."shadowBridge$_flavor"]
relocate 'io.github.legacymoddingmc.unimixins.common', 'io.github.legacymoddingmc.unimixins.mixin.repackage.common'
include '*.jar'
include 'org/spongepowered/asm/bridge/*'
}
dependsOn "mixinJar$_flavor"
dependsOn "bridgeJar$_flavor"
dependsOn "mixinJar$_flavor"
dependsOn "bridgeJar$_flavor"
// 3. Combine the two jars
task("shadowJar$_flavor", type: ShadowJar) {
version = versionBase + "+" + mixinFlavorClassifier
from(sourceSets.main.output) {
exclude "mcmod.info"
}
from zipTree(tasks."mixinJar$_flavor".archiveFile).matching {
exclude 'module-info.class'
eachFile {
if(it.path.startsWith("META-INF/services/")) {
it.filter({l -> !l.startsWith("org.spongepowered.asm.service.modlauncher.") ? l : null})
}
}
}
from zipTree(tasks."bridgeJar$_flavor".archiveFile).matching { include 'org/spongepowered/asm/bridge/*' }
relocate 'io.github.legacymoddingmc.unimixins.common', 'io.github.legacymoddingmc.unimixins.mixin.repackage.common'
doLast {
delete tasks."mixinJar$_flavor".archiveFile
delete tasks."bridgeJar$_flavor".archiveFile
}
}
dependsOn "mixinJar$_flavor"
dependsOn "bridgeJar$_flavor"
dependsOn "mixinJar$_flavor"
dependsOn "bridgeJar$_flavor"
jar.dependsOn("shadowJar$_flavor")
}
from zipTree(tasks."mixinJar$_flavor".archiveFile).matching {
exclude 'module-info.class'
eachFile {
if(it.path.startsWith("META-INF/services/")) {
it.filter({l -> !l.startsWith("org.spongepowered.asm.service.modlauncher.") ? l : null})
}
}
}
from zipTree(tasks."bridgeJar$_flavor".archiveFile).matching { include 'org/spongepowered/asm/bridge/*' }
// Common
doLast {
delete tasks."mixinJar$_flavor".archiveFile
delete tasks."bridgeJar$_flavor".archiveFile
}
}
jar.dependsOn("shadowJar$_flavor")
task("createMcmodInfo$_flavor", type: Copy) {
outputs.upToDateWhen { false }
+1 -2
View File
@@ -1,6 +1,5 @@
fabricMixinVersion=0.15.3+mixin.0.8.7
unimixMixinVersion=0.15.5+mixin.0.8.7
unimixMixinVersion=0.15.6+mixin.0.8.7
spongepoweredMixinVersion=0.8.7
gtnhMixinVersion=0.8.7-GTNH-2
asmVersion=9.9.1
+1 -1
View File
@@ -21,7 +21,7 @@ shadowJar {
'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
'FMLCorePluginContainsFMLMod': true,
'ForceLoadAsMod': true,
'MixinConfigs': 'mixingasm.mixin.json',
'MixinConfigs': 'mixingasm.init.mixin.json,mixingasm.mixin.json',
'TweakOrder': 0,
)
}
@@ -0,0 +1,9 @@
{
"required": true,
"minVersion": "0.6",
"target": "@env(INIT)",
"package": "makamys.mixingasm.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [],
"plugin": "makamys.mixingasm.MixinConfigPlugin"
}
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
-4
View File
@@ -108,10 +108,6 @@ compareVersion("Mixin (UniMix)",
stripBuildIdentifiers(property(localFile("module-mixin/gradle.properties"), "unimixMixinVersion")),
property(githubFile("LegacyModdingMC", "UniMix/main", "gradle.properties"), "buildVersion"))
compareVersion("Mixin (GTNH)",
stripBuildIdentifiers(property(localFile("module-mixin/gradle.properties"), "gtnhMixinVersion")),
lastVersionTag("GTNewHorizons/SpongePoweredMixin")) # GTNH doesn't have a master branch
compareVersions("GTNHMixins",
creditsSources("module-gtnhmixins"))