mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-04-02 13:37:45 -05:00
Remap forge added inner classes correctly
This commit is contained in:
@@ -30,12 +30,13 @@ import net.fabricmc.loom.util.DependencyProvider;
|
||||
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
||||
import net.fabricmc.loom.util.srg.AtRemapper;
|
||||
import net.fabricmc.loom.util.srg.CoreModClassRemapper;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.tinyremapper.NonClassCopyMode;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import org.gradle.api.Project;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
@@ -137,7 +138,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
|
||||
getProject().getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")");
|
||||
|
||||
TinyRemapper remapper = getTinyRemapper(fromM, toM);
|
||||
TinyRemapper remapper = getTinyRemapper(input, fromM, toM);
|
||||
|
||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
||||
if (getExtension().isForge()) {
|
||||
@@ -201,7 +202,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public TinyRemapper getTinyRemapper(String fromM, String toM) throws IOException {
|
||||
public TinyRemapper getTinyRemapper(@Nullable Path fromJar, String fromM, String toM) throws IOException {
|
||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper()
|
||||
.withMappings(TinyRemapperMappingsHelper.create(getExtension().isForge() ? getExtension().getMappingsProvider().getMappingsWithSrg() : getExtension().getMappingsProvider().getMappings(), fromM, toM, true))
|
||||
.renameInvalidLocals(true)
|
||||
@@ -213,6 +214,9 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
* They won't get remapped to their proper packages, so IllegalAccessErrors will happen without ._.
|
||||
*/
|
||||
builder.fixPackageAccess(true);
|
||||
if (fromJar != null) {
|
||||
builder.withMappings(InnerClassRemapper.of(fromJar, getExtension().getMappingsProvider().getMappingsWithSrg(), fromM, toM));
|
||||
}
|
||||
} else {
|
||||
builder.withMappings(out -> JSR_TO_JETBRAINS.forEach(out::acceptClass));
|
||||
}
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
package net.fabricmc.loom.providers;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Files;
|
||||
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
|
||||
import net.fabricmc.loom.util.*;
|
||||
import net.fabricmc.loom.util.function.FsPathConsumer;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.minecraftforge.accesstransformer.TransformerProcessor;
|
||||
@@ -46,33 +47,28 @@ import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
private File minecraftClientSrgJar;
|
||||
private File minecraftServerSrgJar;
|
||||
private File minecraftClientPatchedSrgJar;
|
||||
private File minecraftServerPatchedSrgJar;
|
||||
private File minecraftClientPatchedJar;
|
||||
private File minecraftServerPatchedJar;
|
||||
private File minecraftClientPatchedOfficialJar;
|
||||
private File minecraftServerPatchedOfficialJar;
|
||||
private File minecraftMergedPatchedJar;
|
||||
private File projectAtHash;
|
||||
@Nullable
|
||||
@@ -101,7 +97,7 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
writeAtHash();
|
||||
atDirty = projectAt != null;
|
||||
} else {
|
||||
byte[] expected = Files.asByteSource(projectAtHash).read();
|
||||
byte[] expected = com.google.common.io.Files.asByteSource(projectAtHash).read();
|
||||
byte[] current = projectAt != null ? Checksum.sha256(projectAt) : Checksum.sha256("");
|
||||
boolean mismatched = !Arrays.equals(current, expected);
|
||||
|
||||
@@ -120,24 +116,29 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
File cache = usesProjectCache() ? getExtension().getProjectPersistentCache() : getExtension().getUserCache();
|
||||
|
||||
minecraftClientPatchedJar = new File(cache, "minecraft-" + minecraftVersion + "-client" + jarSuffix + ".jar");
|
||||
minecraftServerPatchedJar = new File(cache, "minecraft-" + minecraftVersion + "-server" + jarSuffix + ".jar");
|
||||
minecraftClientPatchedOfficialJar = new File(cache, "minecraft-" + minecraftVersion + "-client" + jarSuffix + ".jar");
|
||||
minecraftServerPatchedOfficialJar = new File(cache, "minecraft-" + minecraftVersion + "-server" + jarSuffix + ".jar");
|
||||
minecraftClientSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-client-srg.jar");
|
||||
minecraftServerSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-server-srg.jar");
|
||||
minecraftClientPatchedSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-client-srg" + jarSuffix + ".jar");
|
||||
minecraftServerPatchedSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-server-srg" + jarSuffix + ".jar");
|
||||
minecraftMergedPatchedJar = new File(cache, "minecraft-" + minecraftVersion + "-merged" + jarSuffix + ".jar");
|
||||
|
||||
|
||||
if (isRefreshDeps()) {
|
||||
cleanCache();
|
||||
}
|
||||
|
||||
if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()) {
|
||||
minecraftClientPatchedJar.delete();
|
||||
minecraftServerPatchedJar.delete();
|
||||
if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()
|
||||
|| !minecraftClientPatchedSrgJar.exists() || !minecraftServerPatchedSrgJar.exists()
|
||||
|| !minecraftMergedPatchedJar.exists()) {
|
||||
minecraftClientSrgJar.delete();
|
||||
minecraftServerSrgJar.delete();
|
||||
minecraftClientPatchedSrgJar.delete();
|
||||
minecraftServerPatchedSrgJar.delete();
|
||||
minecraftMergedPatchedJar.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void cleanCache() {
|
||||
for (File file : Arrays.asList(
|
||||
projectAtHash,
|
||||
@@ -145,8 +146,8 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
minecraftServerSrgJar,
|
||||
minecraftClientPatchedSrgJar,
|
||||
minecraftServerPatchedSrgJar,
|
||||
minecraftClientPatchedJar,
|
||||
minecraftServerPatchedJar,
|
||||
minecraftClientPatchedOfficialJar,
|
||||
minecraftServerPatchedOfficialJar,
|
||||
minecraftMergedPatchedJar
|
||||
)) {
|
||||
file.delete();
|
||||
@@ -156,13 +157,14 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
@Override
|
||||
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||
initFiles();
|
||||
|
||||
|
||||
if (atDirty) {
|
||||
getProject().getLogger().lifecycle(":found dirty access transformers");
|
||||
}
|
||||
|
||||
if (atDirty || !minecraftClientPatchedJar.exists() || !minecraftServerPatchedJar.exists()) {
|
||||
if (atDirty || !minecraftClientPatchedOfficialJar.exists() || !minecraftServerPatchedOfficialJar.exists()) {
|
||||
if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()) {
|
||||
// Remap official jars to MCPConfig remapped srg jars
|
||||
createSrgJars(getProject().getLogger());
|
||||
}
|
||||
|
||||
@@ -191,12 +193,12 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
private void createSrgJars(Logger logger) throws Exception {
|
||||
// TODO: FORGE: Get rid of *this*
|
||||
logger.lifecycle(":remapping minecraft (MCP, official -> srg)");
|
||||
logger.lifecycle(":remapping minecraft (MCPRuntime, official -> srg)");
|
||||
|
||||
McpConfigProvider volde = getExtension().getMcpConfigProvider();
|
||||
McpConfigProvider mcpProvider = getExtension().getMcpConfigProvider();
|
||||
File root = new File(getExtension().getUserCache(), "mcp_root");
|
||||
root.mkdirs();
|
||||
MCPWrapper wrapper = new MCPWrapper(volde.getMcp(), root);
|
||||
MCPWrapper wrapper = new MCPWrapper(mcpProvider.getMcp(), root);
|
||||
|
||||
// Client
|
||||
{
|
||||
@@ -212,25 +214,25 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
FileUtils.copyFile(output, minecraftServerSrgJar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fixParameterAnnotation(File jarFile) throws Exception {
|
||||
getProject().getLogger().info(":fixing parameter annotations for " + jarFile.toString());
|
||||
try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:" + jarFile.toURI()), ImmutableMap.of("create", false))) {
|
||||
for (Path rootDir : fs.getRootDirectories()) {
|
||||
for (Path file : (Iterable<? extends Path>) java.nio.file.Files.walk(rootDir)::iterator) {
|
||||
for (Path file : (Iterable<? extends Path>) Files.walk(rootDir)::iterator) {
|
||||
if (!file.toString().endsWith(".class")) continue;
|
||||
byte[] bytes = java.nio.file.Files.readAllBytes(file);
|
||||
byte[] bytes = Files.readAllBytes(file);
|
||||
ClassReader reader = new ClassReader(bytes);
|
||||
ClassNode cn = new ClassNode();
|
||||
ClassVisitor visitor = new ParameterAnnotationFixer(cn, null);
|
||||
ClassNode node = new ClassNode();
|
||||
ClassVisitor visitor = new ParameterAnnotationFixer(node, null);
|
||||
reader.accept(visitor, 0);
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(writer);
|
||||
node.accept(writer);
|
||||
byte[] out = writer.toByteArray();
|
||||
if (!Arrays.equals(bytes, out)) {
|
||||
java.nio.file.Files.delete(file);
|
||||
java.nio.file.Files.write(file, out);
|
||||
Files.delete(file);
|
||||
Files.write(file, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,18 +258,15 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
walkFileSystems(injection, minecraftServerPatchedSrgJar, it -> !it.getFileName().toString().equals("MANIFEST.MF"), this::copyReplacing);
|
||||
|
||||
logger.lifecycle(":access transforming minecraft");
|
||||
|
||||
boolean[] bools = { true, false };
|
||||
|
||||
for (boolean isClient : bools) {
|
||||
String side = isClient ? "client" : "server";
|
||||
File target = isClient ? minecraftClientPatchedSrgJar : minecraftServerPatchedSrgJar;
|
||||
for (Environment environment : Environment.values()) {
|
||||
String side = environment.side();
|
||||
File target = environment.patchedSrgJar.apply(this);
|
||||
|
||||
File atJar = File.createTempFile("at" + side, ".jar");
|
||||
File at = File.createTempFile("at" + side, ".cfg");
|
||||
Files.copy(target, atJar);
|
||||
FileUtils.copyFile(target, atJar);
|
||||
JarUtil.extractFile(atJar, "META-INF/accesstransformer.cfg", at);
|
||||
String[] args = new String[] {
|
||||
String[] args = new String[]{
|
||||
"--inJar", atJar.getAbsolutePath(),
|
||||
"--outJar", target.getAbsolutePath(),
|
||||
"--atFile", at.getAbsolutePath()
|
||||
@@ -283,8 +282,24 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private enum Environment {
|
||||
CLIENT(provider -> provider.minecraftClientPatchedSrgJar, provider -> provider.minecraftClientPatchedOfficialJar),
|
||||
SERVER(provider -> provider.minecraftServerPatchedSrgJar, provider -> provider.minecraftServerPatchedOfficialJar);
|
||||
|
||||
Function<MinecraftPatchedProvider, File> patchedSrgJar;
|
||||
Function<MinecraftPatchedProvider, File> patchedOfficialJar;
|
||||
|
||||
Environment(Function<MinecraftPatchedProvider, File> patchedSrgJar, Function<MinecraftPatchedProvider, File> patchedOfficialJar) {
|
||||
this.patchedSrgJar = patchedSrgJar;
|
||||
this.patchedOfficialJar = patchedOfficialJar;
|
||||
}
|
||||
|
||||
public String side() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
private void remapPatchedJars(Logger logger) throws Exception {
|
||||
boolean[] bools = { true, false };
|
||||
Path[] libraries = getExtension()
|
||||
.getMinecraftProvider()
|
||||
.getLibraryProvider()
|
||||
@@ -295,21 +310,26 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
ExecutorService service = Executors.newFixedThreadPool(2);
|
||||
List<Future<?>> futures = new LinkedList<>();
|
||||
|
||||
for (boolean isClient : bools) {
|
||||
|
||||
for (Environment environment : Environment.values()) {
|
||||
futures.add(service.submit(() -> {
|
||||
try {
|
||||
logger.lifecycle(":remapping minecraft (TinyRemapper, " + (isClient ? "client" : "server") + ", srg -> official)");
|
||||
logger.lifecycle(":remapping minecraft (TinyRemapper, " + environment.side() + ", srg -> official)");
|
||||
TinyTree mappingsWithSrg = getExtension().getMappingsProvider().getMappingsWithSrg();
|
||||
|
||||
Path input = environment.patchedSrgJar.apply(this).toPath();
|
||||
Path output = environment.patchedOfficialJar.apply(this).toPath();
|
||||
|
||||
Files.deleteIfExists(output);
|
||||
|
||||
TinyRemapper remapper = TinyRemapper.newRemapper()
|
||||
.withMappings(TinyRemapperMappingsHelper.create(getExtension().getMappingsProvider().getMappingsWithSrg(), "srg", "official", true))
|
||||
.withMappings(TinyRemapperMappingsHelper.create(mappingsWithSrg, "srg", "official", true))
|
||||
.withMappings(InnerClassRemapper.of(input, mappingsWithSrg, "srg", "official"))
|
||||
.renameInvalidLocals(true)
|
||||
.rebuildSourceFilenames(true)
|
||||
.fixPackageAccess(true)
|
||||
.build();
|
||||
|
||||
Path input = (isClient ? minecraftClientPatchedSrgJar : minecraftServerPatchedSrgJar).toPath();
|
||||
Path output = (isClient ? minecraftClientPatchedJar : minecraftServerPatchedJar).toPath();
|
||||
|
||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
||||
outputConsumer.addNonClassFiles(input);
|
||||
|
||||
@@ -329,6 +349,10 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
future.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void patchJars(Logger logger) throws Exception {
|
||||
logger.lifecycle(":patching jars");
|
||||
@@ -340,7 +364,8 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
logger.lifecycle(":copying missing classes into patched jars");
|
||||
copyMissingClasses(minecraftClientSrgJar, minecraftClientPatchedSrgJar);
|
||||
copyMissingClasses(minecraftServerSrgJar, minecraftServerPatchedSrgJar);
|
||||
|
||||
|
||||
logger.lifecycle(":fixing parameter annotations for patched jars");
|
||||
fixParameterAnnotation(minecraftClientPatchedSrgJar);
|
||||
fixParameterAnnotation(minecraftServerPatchedSrgJar);
|
||||
}
|
||||
@@ -364,7 +389,7 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
private void mergeJars(Logger logger) throws IOException {
|
||||
// FIXME: Hack here: There are no server-only classes so we can just copy the client JAR.
|
||||
FileUtils.copyFile(minecraftClientPatchedJar, minecraftMergedPatchedJar);
|
||||
FileUtils.copyFile(minecraftClientPatchedOfficialJar, minecraftMergedPatchedJar);
|
||||
|
||||
logger.lifecycle(":copying resources");
|
||||
|
||||
@@ -374,13 +399,14 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
copyNonClassFiles(minecraftProvider.minecraftServerJar, minecraftMergedPatchedJar);
|
||||
}
|
||||
|
||||
private void walkFileSystems(File source, File target, Predicate<Path> filter, Function<FileSystem, Iterable<Path>> toWalk, FsPathConsumer action) throws IOException {
|
||||
private void walkFileSystems(File source, File target, Predicate<Path> filter, Function<FileSystem, Iterable<Path>> toWalk, FsPathConsumer action)
|
||||
throws IOException {
|
||||
try (FileSystem sourceFs = FileSystems.newFileSystem(new URI("jar:" + source.toURI()), ImmutableMap.of("create", false));
|
||||
FileSystem targetFs = FileSystems.newFileSystem(new URI("jar:" + target.toURI()), ImmutableMap.of("create", false))) {
|
||||
FileSystem targetFs = FileSystems.newFileSystem(new URI("jar:" + target.toURI()), ImmutableMap.of("create", false))) {
|
||||
for (Path sourceDir : toWalk.apply(sourceFs)) {
|
||||
Path dir = sourceDir.toAbsolutePath();
|
||||
java.nio.file.Files.walk(dir)
|
||||
.filter(java.nio.file.Files::isRegularFile)
|
||||
Files.walk(dir)
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(filter)
|
||||
.forEach(it -> {
|
||||
boolean root = dir.getParent() == null;
|
||||
@@ -409,14 +435,14 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
private void copyMissingClasses(File source, File target) throws IOException {
|
||||
walkFileSystems(source, target, it -> it.toString().endsWith(".class"), (sourceFs, targetFs, sourcePath, targetPath) -> {
|
||||
if (java.nio.file.Files.exists(targetPath)) return;
|
||||
if (Files.exists(targetPath)) return;
|
||||
Path parent = targetPath.getParent();
|
||||
|
||||
if (parent != null) {
|
||||
java.nio.file.Files.createDirectories(parent);
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
|
||||
java.nio.file.Files.copy(sourcePath, targetPath);
|
||||
Files.copy(sourcePath, targetPath);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -428,10 +454,10 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
Path parent = targetPath.getParent();
|
||||
|
||||
if (parent != null) {
|
||||
java.nio.file.Files.createDirectories(parent);
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
|
||||
java.nio.file.Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
private void copyUserdevFiles(File source, File target) throws IOException {
|
||||
@@ -439,10 +465,10 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
Path parent = targetPath.getParent();
|
||||
|
||||
if (parent != null) {
|
||||
java.nio.file.Files.createDirectories(parent);
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
|
||||
java.nio.file.Files.copy(sourcePath, targetPath);
|
||||
Files.copy(sourcePath, targetPath);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class AccessWidenerJarProcessor implements JarProcessor {
|
||||
//Remap accessWidener if its not named, allows for AE's to be written in intermediary
|
||||
if (!accessWidener.getNamespace().equals("named")) {
|
||||
try {
|
||||
TinyRemapper tinyRemapper = loomGradleExtension.getMinecraftMappedProvider().getTinyRemapper("official", "named");
|
||||
TinyRemapper tinyRemapper = loomGradleExtension.getMinecraftMappedProvider().getTinyRemapper(null, "official", "named");
|
||||
tinyRemapper.readClassPath(loomGradleExtension.getMinecraftMappedProvider().getRemapClasspath());
|
||||
|
||||
AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, tinyRemapper.getRemapper(), "named");
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.fabricmc.loom.util.srg;
|
||||
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class InnerClassRemapper {
|
||||
public static IMappingProvider of(Path fromJar, TinyTree mappingsWithSrg, String from, String to) throws IOException {
|
||||
Map<String, String> map = buildInnerClassRemap(fromJar, mappingsWithSrg, from, to);
|
||||
return sink -> {
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
sink.acceptClass(entry.getKey(), entry.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Map<String, String> buildInnerClassRemap(Path fromJar, TinyTree mappingsWithSrg, String from, String to) throws IOException {
|
||||
Map<String, String> remapInnerClasses = new HashMap<>();
|
||||
|
||||
try (InputStream inputStream = Files.newInputStream(fromJar)) {
|
||||
Set<String> availableClasses = mappingsWithSrg.getClasses().stream()
|
||||
.map(classDef -> classDef.getName(from))
|
||||
.collect(Collectors.toSet());
|
||||
ZipUtil.iterate(inputStream, (in, zipEntry) -> {
|
||||
if (!zipEntry.isDirectory() && zipEntry.getName().contains("$") && zipEntry.getName().endsWith(".class")) {
|
||||
String className = zipEntry.getName().substring(0, zipEntry.getName().length() - 6);
|
||||
if (!availableClasses.contains(className)) {
|
||||
String parentName = className.substring(0, className.indexOf('$'));
|
||||
String childName = className.substring(className.indexOf('$') + 1);
|
||||
String remappedParentName = mappingsWithSrg.getClasses().stream()
|
||||
.filter(classDef -> Objects.equals(classDef.getName(from), parentName))
|
||||
.findFirst()
|
||||
.map(classDef -> classDef.getName(to))
|
||||
.orElse(parentName);
|
||||
String remappedName = remappedParentName + "$" + childName;
|
||||
if (!className.equals(remappedName)) {
|
||||
remapInnerClasses.put(className, remappedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return remapInnerClasses;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user