possibility for additional context jars to aid in inheritance resolving
All checks were successful
Publish to snapshot maven / build (push) Successful in 17s

This commit is contained in:
moehreag 2024-08-03 18:36:38 +02:00
parent 2d524c0eea
commit f90baaef1b
3 changed files with 64 additions and 30 deletions

View file

@ -8,7 +8,7 @@ plugins {
} }
group = "dev.frogmc" group = "dev.frogmc"
version = "0.0.1-alpha.9" version = "0.0.1-alpha.10"
repositories { repositories {
mavenCentral() mavenCentral()

View file

@ -16,6 +16,9 @@ import dev.frogmc.thyroxine.api.Mapper;
import dev.frogmc.thyroxine.api.ParameterClassRemapper; import dev.frogmc.thyroxine.api.ParameterClassRemapper;
import dev.frogmc.thyroxine.api.data.MappingBundle; import dev.frogmc.thyroxine.api.data.MappingBundle;
import dev.frogmc.thyroxine.api.data.MappingData; import dev.frogmc.thyroxine.api.data.MappingData;
import dev.frogmc.thyroxine.parser.ProguardParser;
import dev.frogmc.thyroxine.parser.tiny.TinyV1Parser;
import dev.frogmc.thyroxine.parser.tiny.TinyV2Parser;
import dev.frogmc.thyroxine.provider.MojmapProvider; import dev.frogmc.thyroxine.provider.MojmapProvider;
import dev.frogmc.thyroxine.provider.ParchmentProvider; import dev.frogmc.thyroxine.provider.ParchmentProvider;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
@ -25,6 +28,8 @@ import org.objectweb.asm.commons.ClassRemapper;
public class Thyroxine { public class Thyroxine {
private static boolean SYSOUT = false;
public static void run(String minecraftVersion, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters) throws IOException, InterruptedException { public static void run(String minecraftVersion, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters) throws IOException, InterruptedException {
MappingBundle data = MojmapProvider.get(minecraftVersion, MappingBundle data = MojmapProvider.get(minecraftVersion,
outputJar.resolveSibling("client-" + minecraftVersion + ".txt")).orElseThrow().reverse(); outputJar.resolveSibling("client-" + minecraftVersion + ".txt")).orElseThrow().reverse();
@ -41,29 +46,33 @@ public class Thyroxine {
result = data; result = data;
} }
SYSOUT = true;
remap(result, inputJar, outputJar, skipMetaInf, renameParameters, "official", "named"); remap(result, inputJar, outputJar, skipMetaInf, renameParameters, "official", "named");
SYSOUT = false;
} }
public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf) throws IOException, InterruptedException { public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, Path... context) throws IOException, InterruptedException {
remap(data, inputJar, outputJar, skipMetaInf, true); remap(data, inputJar, outputJar, skipMetaInf, true, context);
} }
public static void remap(MappingBundle bundle, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters, String srcNamespace, String dstNamespace) throws IOException, InterruptedException { public static void remap(MappingBundle bundle, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters, String srcNamespace, String dstNamespace, Path... context) throws IOException, InterruptedException {
remap(bundle.forNamespaces(srcNamespace, dstNamespace), inputJar, outputJar, skipMetaInf, renameParameters); remap(bundle.forNamespaces(srcNamespace, dstNamespace), inputJar, outputJar, skipMetaInf, renameParameters, context);
} }
public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters) throws IOException, InterruptedException { public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters, Path... context) throws IOException, InterruptedException {
List<RemappingStep> steps = List.of( List<RemappingStep> steps = List.of(
ClassRemapper::new, ClassRemapper::new,
(cv, mapper) -> renameParameters ? new ParameterClassRemapper(cv, mapper, data) : cv (cv, mapper) -> renameParameters ? new ParameterClassRemapper(cv, mapper, data) : cv
); );
remap(data, inputJar, outputJar, skipMetaInf, steps); remap(data, inputJar, outputJar, skipMetaInf, steps, context);
} }
public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, List<RemappingStep> steps) throws IOException, InterruptedException { public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, List<RemappingStep> steps, Path... context) throws IOException, InterruptedException {
Files.deleteIfExists(outputJar); Files.deleteIfExists(outputJar);
if (SYSOUT) {
System.out.println("Remapping..."); System.out.println("Remapping...");
}
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@ -71,11 +80,17 @@ public class Thyroxine {
FileSystem inFs = FileSystems.newFileSystem(inputJar); FileSystem inFs = FileSystems.newFileSystem(inputJar);
FileSystem outFs = FileSystems.newFileSystem(outputJar, Map.of("create", "true"))) { FileSystem outFs = FileSystems.newFileSystem(outputJar, Map.of("create", "true"))) {
List<Callable<Void>> tasks = new ArrayList<>(); List<Callable<Void>> tasks = new ArrayList<>();
FileSystem[] contexts = new FileSystem[context.length+1];
contexts[0] = inFs;
for (int i = 0, contextLength = context.length; i < contextLength; i++) {
Path path = context[i];
contexts[i+1] = FileSystems.newFileSystem(path);
}
Map<String, List<String>> lazyParents = new ConcurrentHashMap<>(); Map<String, List<String>> lazyParents = new ConcurrentHashMap<>();
MappingData reverseData = data.reverse(); MappingData reverseData = data.reverse();
Mapper mapper = new Mapper(data, className -> lazyParents.computeIfAbsent(className, ignored -> Mapper mapper = new Mapper(data, className -> lazyParents.computeIfAbsent(className, ignored ->
computeInheritances(className, inFs, reverseData))); computeInheritances(className, reverseData, contexts)));
Files.walkFileTree(inFs.getPath("/"), new SimpleFileVisitor<>() { Files.walkFileTree(inFs.getPath("/"), new SimpleFileVisitor<>() {
@ -127,9 +142,27 @@ public class Thyroxine {
exec.invokeAll(tasks); exec.invokeAll(tasks);
for (FileSystem fs : contexts) {
fs.close();
}
if (SYSOUT) {
System.out.printf("Finished remapping (%.2fs)%n", (System.currentTimeMillis() - startTime) / 1000F); System.out.printf("Finished remapping (%.2fs)%n", (System.currentTimeMillis() - startTime) / 1000F);
} }
} }
}
public static MappingBundle parse(Path mappings) throws IOException {
String data = Files.readString(mappings);
String header = data.split("\n", 2)[0];
if (header.matches("tiny\t+v2\t+.*")) {
return TinyV2Parser.parse(data);
} else if (TinyV1Parser.HEADER.matcher(header).matches()) {
return TinyV1Parser.parse(data);
} else {
return new MappingBundle(ProguardParser.read(data));
}
}
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
// temporary // temporary
@ -145,7 +178,6 @@ public class Thyroxine {
boolean remapParams = args.length > 3 && hasArg(args, "--remap-parameters"); boolean remapParams = args.length > 3 && hasArg(args, "--remap-parameters");
run(minecraftVersion, Paths.get(minecraftJar), Paths.get(outJar), removeMetaInf, remapParams); run(minecraftVersion, Paths.get(minecraftJar), Paths.get(outJar), removeMetaInf, remapParams);
} }
private static boolean hasArg(String[] arguments, String arg) { private static boolean hasArg(String[] arguments, String arg) {
@ -157,18 +189,20 @@ public class Thyroxine {
return false; return false;
} }
private static List<String> computeInheritances(String className, FileSystem inFs, MappingData reverse) { private static List<String> computeInheritances(String className, MappingData reverse, FileSystem... jars) {
try { try {
if (reverse.classes().containsKey(className)) { if (reverse.classes().containsKey(className)) {
className = reverse.classes().get(className); className = reverse.classes().get(className);
} }
Path path = inFs.getPath("/" + className + ".class"); List<String> superTypes = new ArrayList<>();
if (!Files.isRegularFile(path)) for (FileSystem fs : jars) {
return List.of(); Path path = fs.getPath("/" + className + ".class");
if (!Files.isRegularFile(path)) {
continue;
}
byte[] bytes = Files.readAllBytes(path); byte[] bytes = Files.readAllBytes(path);
ClassReader reader = new ClassReader(bytes); ClassReader reader = new ClassReader(bytes);
List<String> superTypes = new ArrayList<>();
reader.accept(new ClassVisitor(Constants.ASM_VERSION) { reader.accept(new ClassVisitor(Constants.ASM_VERSION) {
@Override @Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
@ -180,7 +214,7 @@ public class Thyroxine {
} }
} }
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
}
return superTypes; return superTypes;
} catch (IOException error) { } catch (IOException error) {
throw new Error(error); // not our problem :^) for now throw new Error(error); // not our problem :^) for now

View file

@ -9,7 +9,7 @@ import dev.frogmc.thyroxine.api.data.Member;
public class TinyV1Parser { public class TinyV1Parser {
private static final Pattern HEADER = Pattern.compile("v(?<majorVer>[12]+)\\s\\w*\\s?(?<srcns>\\S+)\\s(?<dstns>\\S+)"); public static final Pattern HEADER = Pattern.compile("v(?<majorVer>[12]+)\\s\\w*\\s?(?<srcns>\\S+)\\s(?<dstns>\\S+)");
public static MappingBundle parse(String mappings) { public static MappingBundle parse(String mappings) {
String[] lines = mappings.split("\n"); String[] lines = mappings.split("\n");