mirror of
https://github.com/LegacyModdingMC/UniMixins.git
synced 2026-10-27 06:53:48 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93d8ebf6c6 | ||
|
|
4ed4fde3cf | ||
|
|
c47090bcae | ||
|
|
b7e3384ceb | ||
|
|
c5c5cbeca1 | ||
|
|
6e8f572f7e | ||
|
|
e60b681529 | ||
|
|
0ef643d32f | ||
|
|
cb08fbd2f1 |
No files matched your search
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
+69
-70
@@ -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) {
|
||||
|
||||
+145
@@ -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;
|
||||
}
|
||||
}
|
||||
+5
-9
@@ -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) {
|
||||
|
||||
+3
-2
@@ -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
@@ -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,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
|
||||
@@ -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
@@ -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
|
||||
@@ -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"))
|
||||
|
||||
|
||||
Reference in new issue
Block a user