Compare commits

...

2 commits

Author SHA1 Message Date
owlsys 9728a83d3e Merge pull request 'Fix remapping inherited/overriden members' (#2) from TheKodeToad/inheritence into main
All checks were successful
Publish to snapshot maven / build (push) Successful in 14s
Reviewed-on: https://git-esnesnon.ecorous.org/esnesnon/nonsense-remapper/pulls/2
Reviewed-by: owlsys <owlsys@noreply.localhost>
2024-05-19 11:38:38 -04:00
TheKodeToad e7bde3bab1
Fix remapping inherited/overriden members
All checks were successful
Publish to snapshot maven / build (push) Successful in 13s
2024-05-19 16:13:07 +01:00
2 changed files with 83 additions and 26 deletions

View file

@ -1,18 +1,19 @@
package org.ecorous.esnesnon.nonsense_remapper; package org.ecorous.esnesnon.nonsense_remapper;
import java.io.IOError;
import java.io.IOException; import java.io.IOException;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import org.ecorous.esnesnon.nonsense_remapper.api.Mapper; import org.ecorous.esnesnon.nonsense_remapper.api.Mapper;
import org.ecorous.esnesnon.nonsense_remapper.api.ParameterClassRemapper; import org.ecorous.esnesnon.nonsense_remapper.api.ParameterClassRemapper;
import org.ecorous.esnesnon.nonsense_remapper.api.data.MappingData; import org.ecorous.esnesnon.nonsense_remapper.api.data.MappingData;
import org.ecorous.esnesnon.nonsense_remapper.api.data.Member;
import org.ecorous.esnesnon.nonsense_remapper.api.data.Parchment; import org.ecorous.esnesnon.nonsense_remapper.api.data.Parchment;
import org.ecorous.esnesnon.nonsense_remapper.parser.ProguardParser; import org.ecorous.esnesnon.nonsense_remapper.parser.ProguardParser;
import org.ecorous.esnesnon.nonsense_remapper.provider.MojmapProvider; import org.ecorous.esnesnon.nonsense_remapper.provider.MojmapProvider;
@ -20,24 +21,23 @@ import org.ecorous.esnesnon.nonsense_remapper.provider.ParchmentProvider;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.ClassRemapper;
public class NonsenseRemapper { public class NonsenseRemapper {
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 {
MappingData data = ProguardParser.read(MojmapProvider.get(minecraftVersion, outputJar.resolveSibling("client-"+minecraftVersion+".txt")).orElseThrow()).reverse(); MappingData data = ProguardParser.read(MojmapProvider.get(minecraftVersion, outputJar.resolveSibling("client-" + minecraftVersion + ".txt")).orElseThrow()).reverse();
Mapper mapper = new Mapper(data);
Parchment paramMappings = null; Parchment paramMappings = null;
if (renameParameters) { if (renameParameters) {
paramMappings = ParchmentProvider.getParchment(minecraftVersion, outputJar.getParent()); paramMappings = ParchmentProvider.getParchment(minecraftVersion, outputJar.getParent());
} }
remap(mapper, inputJar, outputJar, skipMetaInf, paramMappings); remap(data, inputJar, outputJar, skipMetaInf, paramMappings);
} }
public static void remap(Mapper mapper, Path inputJar, Path outputJar, boolean skipMetaInf, Parchment paramMappings) throws IOException, InterruptedException { public static void remap(MappingData data, Path inputJar, Path outputJar, boolean skipMetaInf, Parchment paramMappings) throws IOException, InterruptedException {
Files.deleteIfExists(outputJar); Files.deleteIfExists(outputJar);
System.out.println("Remapping..."); System.out.println("Remapping...");
@ -49,12 +49,35 @@ public class NonsenseRemapper {
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<>();
Map<String, List<String>> lazyParents = new ConcurrentHashMap<>();
Mapper mapper = new Mapper(data, className -> lazyParents.computeIfAbsent(className, ignored -> {
try {
Path path = inFs.getPath("/" + className + ".class");
if (!Files.isRegularFile(path))
return List.of();
byte[] bytes = Files.readAllBytes(path);
ClassReader reader = new ClassReader(bytes);
List<String> superTypes = new ArrayList<>();
reader.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
superTypes.add(superName);
superTypes.addAll(Arrays.asList(interfaces));
}
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return superTypes;
} catch (IOException error) {
throw new Error(error); // not our problem :^) for now
}
}));
Files.walkFileTree(inFs.getPath("/"), new SimpleFileVisitor<>() { Files.walkFileTree(inFs.getPath("/"), new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) { public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) {
if (skipMetaInf && path.startsWith("/META-INF")) { if (skipMetaInf && path.startsWith("/META-INF"))
return FileVisitResult.SKIP_SUBTREE; return FileVisitResult.SKIP_SUBTREE;
}
tasks.add(() -> { tasks.add(() -> {
try { try {

View file

@ -4,26 +4,60 @@ import org.ecorous.esnesnon.nonsense_remapper.api.data.MappingData;
import org.ecorous.esnesnon.nonsense_remapper.api.data.Member; import org.ecorous.esnesnon.nonsense_remapper.api.data.Member;
import org.objectweb.asm.commons.Remapper; import org.objectweb.asm.commons.Remapper;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class Mapper extends Remapper { public class Mapper extends Remapper {
private final MappingData data; private final MappingData data;
private final Function<String, List<String>> parentProvider;
public Mapper(MappingData data) { public Mapper(MappingData data, Function<String, List<String>> parentProvider) {
this.data = data; this.data = data;
} this.parentProvider = parentProvider;
}
@Override @Override
public String map(String internalName) { public String map(String internalName) {
return data.classes().getOrDefault(internalName, internalName); return data.classes().getOrDefault(internalName, internalName);
} }
@Override @Override
public String mapMethodName(String owner, String name, String descriptor) { public String mapMethodName(String owner, String name, String descriptor) {
return data.methods().getOrDefault(new Member(owner, name, descriptor), name); String result = map(0, data.methods(), owner, name, descriptor);
} if (result != null)
return result;
@Override return name;
public String mapFieldName(String owner, String name, String descriptor) { }
return data.fields().getOrDefault(new Member(owner, name, descriptor), name);
} @Override
public String mapFieldName(String owner, String name, String descriptor) {
String result = map(0, data.fields(), owner, name, descriptor);
if (result != null)
return result;
return name;
}
private String map(int depth, Map<Member, String> map, String owner, String name, String descriptor) {
if (owner.startsWith("["))
return null;
String result = map.get(new Member(owner, name, descriptor));
if (result != null)
return result;
if (depth >= 64)
return null;
for (String parent : parentProvider.apply(owner)) {
result = map(depth + 1, map, parent, name, descriptor);
if (result != null)
return result;
}
return null;
}
} }