diff --git a/.github/workflows/build_and_publish.yml b/.github/workflows/build_and_publish.yml index c1884d1..30cac39 100644 --- a/.github/workflows/build_and_publish.yml +++ b/.github/workflows/build_and_publish.yml @@ -1,10 +1,12 @@ name: Build and Publish - on: [push, pull_request, workflow_dispatch] + on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: '0' - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v3 - name: Set up JDK 17 @@ -19,7 +21,8 @@ - name: Test run: ./gradlew test check - - name: Sonar + - if: github.repository == 'FabricCompatibilityLayers/Mod-Remapping-API' + name: Sonar run: ./gradlew jacocoTestCoverageVerification jacocoTestReport sonar env: SONAR_URL: ${{ secrets.SONAR_URL }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..aa0172c --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,29 @@ + name: Build and Publish + on: [pull_request] + jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Build + run: ./gradlew build -x test + + - name: Test + run: ./gradlew test check + + - name: Store reports if any + if: failure() + uses: actions/upload-artifact@v4 + with: + name: reports + path: | + **/build/reports/ + **/build/test-results/ \ No newline at end of file diff --git a/src/main/java/fr/catcore/modremapperapi/ClassTransformer.java b/src/main/java/fr/catcore/modremapperapi/ClassTransformer.java index cf9371d..43b92c2 100644 --- a/src/main/java/fr/catcore/modremapperapi/ClassTransformer.java +++ b/src/main/java/fr/catcore/modremapperapi/ClassTransformer.java @@ -1,71 +1,34 @@ package fr.catcore.modremapperapi; -import com.google.common.collect.ImmutableSet; import fr.catcore.modremapperapi.api.IClassTransformer; -import net.mine_diver.spasm.api.transform.RawClassTransformer; -import net.mine_diver.spasm.api.transform.TransformationPhase; -import net.mine_diver.spasm.impl.SpASM; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - -public class ClassTransformer implements RawClassTransformer { - private static final Set PRE_TRANSFORMERS = new HashSet<>(); - private static final Set POST_TRANSFORMERS = new HashSet<>(); - - public static byte[] transform(String name, String transformedName, byte[] basicClass) { - Set transformers = new HashSet<>(); - - Set transformerPool = PRE_TRANSFORMERS; - - if (SpASM.getCurrentPhase() == TransformationPhase.AFTER_MIXINS) { - transformerPool = POST_TRANSFORMERS; - } - - for (IClassTransformer transformer : transformerPool) { - if (transformer.handlesClass(name, transformedName)) { - transformers.add(transformer); - } - } - - byte[] modifiedClass = basicClass; - - for (IClassTransformer transformer : transformers) { - modifiedClass = transformer.transformClass(name, transformedName, modifiedClass); - } - - return modifiedClass; - } +/** + * @deprecated Use utility methods on {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer} instead. + */ +@Deprecated +public class ClassTransformer { + /** + * @deprecated Deprecated in favor of {@link ClassTransformer#registerPreTransformer(IClassTransformer)}. + * @param transformer + */ @Deprecated public static void registerTransformer(IClassTransformer transformer) { registerPreTransformer(transformer); } + /** + * @deprecated Use {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer#registerPreTransformer(io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer)} instead. + */ + @Deprecated public static void registerPreTransformer(IClassTransformer transformer) { - PRE_TRANSFORMERS.add(transformer); + io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer.registerPreTransformer(transformer); } + /** + * @deprecated Use {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer#registerPostTransformer(io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer)} instead. + */ + @Deprecated public static void registerPostTransformer(IClassTransformer transformer) { - POST_TRANSFORMERS.add(transformer); - } - - @Override - public @NotNull Optional transform(@NotNull ClassLoader classLoader, @NotNull String className, byte @NotNull [] bytes) { - byte[] modifiedBytes = bytes; - modifiedBytes = transform(className, className, modifiedBytes); - - if (modifiedBytes != null) { - return Optional.of(modifiedBytes); - } - - return Optional.empty(); - } - - @Override - public @NotNull ImmutableSet getPhases() { - return ALL_PHASES; + io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer.registerPostTransformer(transformer); } } diff --git a/src/main/java/fr/catcore/modremapperapi/ModRemappingAPI.java b/src/main/java/fr/catcore/modremapperapi/ModRemappingAPI.java index a13ec7e..6f36cff 100644 --- a/src/main/java/fr/catcore/modremapperapi/ModRemappingAPI.java +++ b/src/main/java/fr/catcore/modremapperapi/ModRemappingAPI.java @@ -1,15 +1,9 @@ package fr.catcore.modremapperapi; -import fr.catcore.modremapperapi.api.ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl; -import net.fabricmc.loader.api.FabricLoader; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; +@Deprecated public class ModRemappingAPI { - - public static final boolean BABRIC = FabricLoader.getInstance().getModContainer("fabricloader") - .get().getMetadata().getVersion().getFriendlyString().contains("babric"); + @Deprecated + public static final boolean BABRIC = ModRemappingAPIImpl.BABRIC; } diff --git a/src/main/java/fr/catcore/modremapperapi/api/IClassTransformer.java b/src/main/java/fr/catcore/modremapperapi/api/IClassTransformer.java index 73b14f7..499422f 100644 --- a/src/main/java/fr/catcore/modremapperapi/api/IClassTransformer.java +++ b/src/main/java/fr/catcore/modremapperapi/api/IClassTransformer.java @@ -1,7 +1,10 @@ package fr.catcore.modremapperapi.api; -// Original author is gudenau. -public interface IClassTransformer { - boolean handlesClass(String name, String transformedName); - byte[] transformClass(String name, String transformedName, byte[] original); +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer; + +/** + * @deprecated Use {@link ClassTransformer} instead. + */ +@Deprecated +public interface IClassTransformer extends ClassTransformer { } diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/MapEntryType.java b/src/main/java/fr/catcore/modremapperapi/remapping/MapEntryType.java deleted file mode 100644 index a44dbbf..0000000 --- a/src/main/java/fr/catcore/modremapperapi/remapping/MapEntryType.java +++ /dev/null @@ -1,29 +0,0 @@ -package fr.catcore.modremapperapi.remapping; - -public enum MapEntryType { - CLASS("CLASS", 0, 'C'), - METHOD("METHOD", 2, 'M'), - FIELD("FIELD", 2, 'F'); - - private static final MapEntryType[] VALUES = MapEntryType.values(); - - final String name; - final char firstChar; - final int offset; - - MapEntryType(String name, int offset, char firstChar) { - this.name = name; - this.offset = offset; - this.firstChar = firstChar; - } - - public static MapEntryType getType(String name) { - char c = name.charAt(0); - for (MapEntryType type : VALUES) { - if (type.firstChar == c) { - return type; - } - } - return null; - } -} diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/RemapUtil.java b/src/main/java/fr/catcore/modremapperapi/remapping/RemapUtil.java index c2cb569..6245ae8 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/RemapUtil.java +++ b/src/main/java/fr/catcore/modremapperapi/remapping/RemapUtil.java @@ -1,228 +1,20 @@ package fr.catcore.modremapperapi.remapping; -import fr.catcore.modremapperapi.utils.Constants; -import fr.catcore.modremapperapi.utils.FileUtils; -import fr.catcore.modremapperapi.utils.MappingsUtils; -import io.github.fabriccompatibiltylayers.modremappingapi.api.MappingUtils; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingBuilderImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils; import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.mappingio.MappingVisitor; -import net.fabricmc.mappingio.MappingWriter; -import net.fabricmc.mappingio.format.MappingFormat; -import net.fabricmc.mappingio.tree.MappingTree; -import net.fabricmc.mappingio.tree.MemoryMappingTree; -import net.fabricmc.tinyremapper.*; -import net.fabricmc.tinyremapper.extension.mixin.MixinExtension; import org.jetbrains.annotations.ApiStatus; import java.io.*; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.*; -import java.util.function.Supplier; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +@Deprecated public class RemapUtil { - private static List remappers; - private static MappingTree LOADER_TREE; - private static MappingTree MINECRAFT_TREE; - private static MemoryMappingTree MODS_TREE; - - protected static final Map> MIXINED = new HashMap<>(); - - private static String defaultPackage = ""; - - public static final List MC_CLASS_NAMES = new ArrayList<>(); - - public static void init(List modRemappers) { - remappers = modRemappers; - - downloadRemappingLibs(); - - for (ModRemapper remapper : remappers) { - Optional pkg = remapper.getDefaultPackage(); - - pkg.ifPresent(s -> defaultPackage = s); - - Optional sourceNamespace = remapper.getSourceNamespace(); - - sourceNamespace.ifPresent(MappingsUtilsImpl::setSourceNamespace); - - Optional> mappings = remapper.getExtraMapping(); - - mappings.ifPresent(inputStreamSupplier -> MappingsUtilsImpl.loadExtraMappings(inputStreamSupplier.get())); - } - - MINECRAFT_TREE = MappingsUtilsImpl.getMinecraftMappings(); - - writeMcMappings(); - - LOADER_TREE = generateMappings(); - MappingsUtilsImpl.addMappingsToContext(LOADER_TREE); - - for (MappingTree.ClassMapping classView : MINECRAFT_TREE.getClasses()) { - String className = classView.getName(MappingsUtilsImpl.getSourceNamespace()); - - if (className != null) { - MC_CLASS_NAMES.add(className); - } - } - - try { - MODS_TREE = new MemoryMappingTree(); - MappingsUtilsImpl.initializeMappingTree(MODS_TREE); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static void downloadRemappingLibs() { - try { - for (ModRemapper remapper : remappers) { - List libraries = new ArrayList<>(); - - remapper.addRemapLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); - - for (RemapLibrary library : libraries) { - File libPath = new File(Constants.LIB_FOLDER, library.fileName); - - if (!libPath.exists() && !library.url.isEmpty()) { - Constants.MAIN_LOGGER.info("Downloading remapping library '" + library.fileName + "' from url '" + library.url + "'"); - try (BufferedInputStream inputStream = new BufferedInputStream(new URL(library.url).openStream())) { - try (BufferedOutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(libPath.toPath()))) { - byte[] buffer = new byte[2048]; - - // Increments file size - int length; - int downloaded = 0; - - // Looping until server finishes - while ((length = inputStream.read(buffer)) != -1) { - // Writing data - outputStream.write(buffer, 0, length); - downloaded += length; -// Constants.MAIN_LOGGER.debug("Download Status: " + (downloaded * 100) / (contentLength * 1.0) + "%"); - } - - outputStream.close(); - inputStream.close(); - } - } - - FileUtils.excludeFromZipFile(libPath, library.toExclude); - Constants.MAIN_LOGGER.info("Remapping library ready for use."); - } else if (!libPath.exists() && library.path != null) { - Constants.MAIN_LOGGER.info("Extracting remapping library '" + library.fileName + "' from mod jar."); - FileUtils.copyFile(library.path, libPath.toPath()); - Constants.MAIN_LOGGER.info("Remapping library ready for use."); - } - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static void remapMods(Map pathMap) { - Constants.MAIN_LOGGER.debug("Starting jar remapping!"); - preloadClasses(); - TinyRemapper remapper = makeRemapper(MINECRAFT_TREE, LOADER_TREE, MODS_TREE); - Constants.MAIN_LOGGER.debug("Remapper created!"); - remapFiles(remapper, pathMap); - Constants.MAIN_LOGGER.debug("Jar remapping done!"); - - MappingsUtilsImpl.writeFullMappings(); - } - - public static List makeModMappings(Path modPath) { - File path = modPath.toFile(); - List files = new ArrayList<>(); - if (path.isFile()) { - try { - FileInputStream fileinputstream = new FileInputStream(path); - ZipInputStream zipinputstream = new ZipInputStream(fileinputstream); - - while (true) { - ZipEntry zipentry = zipinputstream.getNextEntry(); - if (zipentry == null) { - zipinputstream.close(); - fileinputstream.close(); - break; - } - - String s1 = zipentry.getName(); - if (!zipentry.isDirectory()) { - files.add(s1.replace("\\", "/")); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } else if (path.isDirectory()) { - files.addAll(generateFolderMappings(path.listFiles())); - } - - List classes = new ArrayList<>(); - - for (String file : files) { - if (file.endsWith(".class")) { - String clName = file.replace(".class", ""); - classes.add(clName); - } - } - - io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder mappingBuilder = new MappingBuilderImpl(MODS_TREE); - - classes.forEach(cl -> mappingBuilder.addMapping(cl, (cl.contains("/") ? "" : defaultPackage) + cl)); - - return files; - } - - public static void generateModMappings() { - try { - MODS_TREE.visitEnd(); - - MappingWriter writer = MappingWriter.create(Constants.REMAPPED_MAPPINGS_FILE.toPath(), MappingFormat.TINY_2_FILE); - MODS_TREE.accept(writer); - } catch (IOException e) { - throw new RuntimeException("Error while generating mods mappings", e); - } - - MappingsUtilsImpl.addMappingsToContext(MODS_TREE); - } - - public static void writeMcMappings() { - try { - MappingWriter writer = MappingWriter.create(Constants.MC_MAPPINGS_FILE.toPath(), MappingFormat.TINY_2_FILE); - MINECRAFT_TREE.accept(writer); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static List generateFolderMappings(File[] files) { - List list = new ArrayList<>(); - - for (File file : files) { - if (file.isFile()) list.add(file.getName()); - else if (file.isDirectory()) { - String name = file.getName(); - - for (String fileName : generateFolderMappings(file.listFiles())) { - list.add(name + "/" + fileName); - } - } - } - - return list; - } + @Deprecated + public static final List MC_CLASS_NAMES = MappingsRegistry.VANILLA_CLASS_LIST; @Deprecated public static class MappingList extends ArrayList { @@ -250,394 +42,6 @@ public void accept(MappingVisitor visitor) throws IOException { } } - private static MappingTree generateMappings() { - MemoryMappingTree mappingTree = new MemoryMappingTree(); - - try { - MappingsUtilsImpl.initializeMappingTree(mappingTree); - - io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder builder = new MappingBuilderImpl(mappingTree); - - for (ModRemapper remapper : remappers) { - remapper.registerMappings(builder); - } - - mappingTree.visitEnd(); - - MappingWriter mappingWriter = MappingWriter.create(Constants.EXTRA_MAPPINGS_FILE.toPath(), MappingFormat.TINY_2_FILE); - mappingTree.accept(mappingWriter); - } catch (IOException e) { - throw new RuntimeException("Error while generating remappers mappings", e); - } - - return mappingTree; - } - - private static String getLibClassName(String lib, String string) { - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - return "net.fabricmc." + lib + "." + string; - } - - return "fr.catcore.modremapperapi.impl.lib." + lib + "." + string; - } - - private static void preloadClasses() { - for (String clazz : new String[]{ - "java.io.IOException", - "java.net.URI", - "java.net.URISyntaxException", - "java.nio.file.FileSystem", - "java.nio.file.FileVisitResult", - "java.nio.file.Files", - "java.nio.file.Path", - "java.nio.file.SimpleFileVisitor", - "java.nio.file.attribute.BasicFileAttributes", - "java.util.ArrayDeque", - "java.util.ArrayList", - "java.util.Collection", - "java.util.Collections", - "java.util.HashMap", - "java.util.HashSet", - "java.util.IdentityHashMap", - "java.util.List", - "java.util.Map", - "java.util.Objects", - "java.util.Optional", - "java.util.Queue", - "java.util.Set", - "java.util.concurrent.CompletableFuture", - "java.util.concurrent.ConcurrentHashMap", - "java.util.concurrent.ExecutionException", - "java.util.concurrent.ExecutorService", - "java.util.concurrent.Executors", - "java.util.concurrent.Future", - "java.util.concurrent.TimeUnit", - "java.util.concurrent.atomic.AtomicReference", - "java.util.function.BiConsumer", - "java.util.function.Supplier", - "java.util.regex.Pattern", - "java.util.stream.Collectors", - "java.util.zip.ZipError", - - "org.objectweb.asm.ClassReader", - "org.objectweb.asm.ClassVisitor", - "org.objectweb.asm.ClassWriter", - "org.objectweb.asm.FieldVisitor", - "org.objectweb.asm.MethodVisitor", - "org.objectweb.asm.Opcodes", - "org.objectweb.asm.commons.Remapper", - "org.objectweb.asm.util.CheckClassAdapter", - - "fr.catcore.modremapperapi.api.RemapLibrary", - "fr.catcore.modremapperapi.api.ModRemapper", - "fr.catcore.modremapperapi.utils.BArrayList", - "fr.catcore.modremapperapi.utils.CollectionUtils", - "fr.catcore.modremapperapi.utils.Constants", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModEntry", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper", - "fr.catcore.modremapperapi.utils.FileUtils", - "fr.catcore.modremapperapi.utils.MappingsUtils", - "fr.catcore.modremapperapi.utils.MixinUtils", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModDiscoverer", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModDiscoverer$1", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModEntry", - "fr.catcore.modremapperapi.utils.RefmapJson", - "fr.catcore.modremapperapi.remapping.MapEntryType", - "fr.catcore.modremapperapi.remapping.MappingBuilder", - "fr.catcore.modremapperapi.remapping.MappingBuilder$Entry", - "fr.catcore.modremapperapi.remapping.MappingBuilder$Type", - "fr.catcore.modremapperapi.remapping.MixinPostApplyVisitor", - "fr.catcore.modremapperapi.remapping.MRAClassVisitor", - "fr.catcore.modremapperapi.remapping.MRAMethodVisitor", - "fr.catcore.modremapperapi.remapping.MRAApplyVisitor", - "fr.catcore.modremapperapi.remapping.RefmapRemapper", - "fr.catcore.modremapperapi.remapping.RemapUtil", - "fr.catcore.modremapperapi.remapping.RemapUtil$MappingList", - "fr.catcore.modremapperapi.remapping.VisitorInfos", - "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodNamed", - "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodValue", - "fr.catcore.modremapperapi.remapping.VisitorInfos$Type", - "net.fabricmc.loader.impl.launch.FabricLauncher", - "net.fabricmc.loader.impl.launch.FabricLauncherBase", - "net.fabricmc.loader.api.ObjectShare", - - getLibClassName("tinyremapper", "AsmClassRemapper"), - getLibClassName("tinyremapper", "AsmClassRemapper$AsmAnnotationRemapper"), - getLibClassName("tinyremapper", "AsmClassRemapper$AsmAnnotationRemapper$AsmArrayAttributeAnnotationRemapper"), - getLibClassName("tinyremapper", "AsmClassRemapper$AsmFieldRemapper"), - getLibClassName("tinyremapper", "AsmClassRemapper$AsmMethodRemapper"), - getLibClassName("tinyremapper", "AsmClassRemapper$AsmRecordComponentRemapper"), - getLibClassName("tinyremapper", "AsmRemapper"), - getLibClassName("tinyremapper", "BridgeHandler"), - getLibClassName("tinyremapper", "ClassInstance"), - getLibClassName("tinyremapper", "FileSystemReference"), - getLibClassName("tinyremapper", "IMappingProvider"), - getLibClassName("tinyremapper", "IMappingProvider$MappingAcceptor"), - getLibClassName("tinyremapper", "IMappingProvider$Member"), - getLibClassName("tinyremapper", "InputTag"), - getLibClassName("tinyremapper", "MemberInstance"), - getLibClassName("tinyremapper", "MetaInfFixer"), - getLibClassName("tinyremapper", "MetaInfRemover"), - getLibClassName("tinyremapper", "NonClassCopyMode"), - getLibClassName("tinyremapper", "OutputConsumerPath"), - getLibClassName("tinyremapper", "OutputConsumerPath$1"), - getLibClassName("tinyremapper", "OutputConsumerPath$Builder"), - getLibClassName("tinyremapper", "OutputConsumerPath$ResourceRemapper"), - getLibClassName("tinyremapper", "PackageAccessChecker"), - getLibClassName("tinyremapper", "Propagator"), - getLibClassName("tinyremapper", "TinyRemapper"), - getLibClassName("tinyremapper", "TinyRemapper$1"), - getLibClassName("tinyremapper", "TinyRemapper$1$1"), - getLibClassName("tinyremapper", "TinyRemapper$2"), - getLibClassName("tinyremapper", "TinyRemapper$3"), - getLibClassName("tinyremapper", "TinyRemapper$4"), - getLibClassName("tinyremapper", "TinyRemapper$5"), - getLibClassName("tinyremapper", "TinyRemapper$AnalyzeVisitorProvider"), - getLibClassName("tinyremapper", "TinyRemapper$ApplyVisitorProvider"), - getLibClassName("tinyremapper", "TinyRemapper$Builder"), - getLibClassName("tinyremapper", "TinyRemapper$CLIExtensionProvider"), - getLibClassName("tinyremapper", "TinyRemapper$Direction"), - getLibClassName("tinyremapper", "TinyRemapper$Extension"), - getLibClassName("tinyremapper", "TinyRemapper$LinkedMethodPropagation"), - getLibClassName("tinyremapper", "TinyRemapper$MrjState"), - getLibClassName("tinyremapper", "TinyRemapper$Propagation"), - getLibClassName("tinyremapper", "TinyRemapper$StateProcessor"), - getLibClassName("tinyremapper", "TinyUtils"), - getLibClassName("tinyremapper", "TinyUtils$MappingAdapter"), - getLibClassName("tinyremapper", "VisitTrackingClassRemapper"), - getLibClassName("tinyremapper", "VisitTrackingClassRemapper$VisitKind"), - getLibClassName("tinyremapper", "extension.mixin.common.IMappable"), - getLibClassName("tinyremapper", "extension.mixin.common.MapUtility"), - getLibClassName("tinyremapper", "extension.mixin.common.ResolveUtility"), - getLibClassName("tinyremapper", "extension.mixin.common.StringUtility"), - getLibClassName("tinyremapper", "extension.mixin.common.data.Annotation"), - getLibClassName("tinyremapper", "extension.mixin.common.data.AnnotationElement"), - getLibClassName("tinyremapper", "extension.mixin.common.data.CommonData"), - getLibClassName("tinyremapper", "extension.mixin.common.data.Constant"), - getLibClassName("tinyremapper", "extension.mixin.common.data.Message"), - getLibClassName("tinyremapper", "extension.mixin.common.data.MxClass"), - getLibClassName("tinyremapper", "extension.mixin.common.data.MxMember"), - getLibClassName("tinyremapper", "extension.mixin.common.data.Pair"), - getLibClassName("tinyremapper", "extension.mixin.soft.SoftTargetMixinClassVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.SoftTargetMixinMethodVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.AccessorAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.InvokerAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.MixinAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtConstructorMappable"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtSecondPassAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtSecondPassAnnotationVisitor$1"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.CommonInjectionAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.CommonInjectionAnnotationVisitor$InjectMethodMappable"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionAnnotationVisitor$MemberRemappingVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionsAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionsAnnotationVisitor$DefinitionRemappingVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DescAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.InjectAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyArgAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyArgsAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyConstantAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyExpressionValueAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyReceiverAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyReturnValueAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyVariableAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.RedirectAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.SliceAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapMethodAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapOperationAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapWithConditionAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapWithConditionV2AnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.soft.data.MemberInfo"), - getLibClassName("tinyremapper", "extension.mixin.soft.util.NamedMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinClassVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinFieldVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinMethodVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$1"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$InterfaceAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$SoftImplementsMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor$1"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor$2"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.OverwriteAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.OverwriteAnnotationVisitor$OverwriteMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ShadowAnnotationVisitor"), - getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ShadowAnnotationVisitor$ShadowPrefixMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.data.SoftInterface"), - getLibClassName("tinyremapper", "extension.mixin.hard.data.SoftInterface$Remap"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.CamelPrefixString"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.ConvertibleMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.HardTargetMappable"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.IConvertibleString"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.IdentityString"), - getLibClassName("tinyremapper", "extension.mixin.hard.util.PrefixString"), - getLibClassName("tinyremapper", "extension.mixin.MixinExtension"), - getLibClassName("tinyremapper", "extension.mixin.MixinExtension$AnalyzeVisitorProvider"), - getLibClassName("tinyremapper", "extension.mixin.MixinExtension$AnnotationTarget"), - getLibClassName("tinyremapper", "extension.mixin.MixinExtension$CLIProvider"), - getLibClassName("tinyremapper", "extension.mixin.MixinExtension$PreApplyVisitorProvider"), - getLibClassName("tinyremapper", "api.TrClass"), - getLibClassName("tinyremapper", "api.TrEnvironment"), - getLibClassName("tinyremapper", "api.TrField"), - getLibClassName("tinyremapper", "api.TrLogger"), - getLibClassName("tinyremapper", "api.TrLogger$Level"), - getLibClassName("tinyremapper", "api.TrMember"), - getLibClassName("tinyremapper", "api.TrMember$MemberType"), - getLibClassName("tinyremapper", "api.TrMethod"), - getLibClassName("tinyremapper", "api.TrRemapper"), - - getLibClassName("mappingio", "MappingReader"), - getLibClassName("mappingio", "MappingReader$1"), - getLibClassName("mappingio", "FlatMappingVisitor"), - getLibClassName("mappingio", "MappedElementKind"), - getLibClassName("mappingio", "MappingFlag"), - getLibClassName("mappingio", "MappingUtil"), - getLibClassName("mappingio", "MappingVisitor"), - getLibClassName("mappingio", "MappingWriter"), - getLibClassName("mappingio", "MappingWriter$1") - }) { - try { - Constants.MAIN_LOGGER.debug("Preloading class: " + clazz); - Class.forName(clazz); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - } - - /** - * Will create remapper with specified trees. - */ - private static TinyRemapper makeRemapper(MappingTree... trees) { - TinyRemapper.Builder builder = TinyRemapper - .newRemapper() - .renameInvalidLocals(true) - .ignoreFieldDesc(false) - .propagatePrivate(true) - .ignoreConflicts(true); - - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - builder.fixPackageAccess(true); - } - - for (MappingTree tree : trees) { - builder.withMappings(MappingsUtilsImpl.createProvider(tree, MappingsUtilsImpl.getSourceNamespace(), MappingsUtils.getTargetNamespace())); - } - - MRAApplyVisitor preApplyVisitor = new MRAApplyVisitor(); - MRAApplyVisitor postApplyVisitor = new MRAApplyVisitor(); - MixinPostApplyVisitor mixinPostApplyVisitor = new MixinPostApplyVisitor(); - - VisitorInfosImpl preInfos = new VisitorInfosImpl(); - VisitorInfosImpl postInfos = new VisitorInfosImpl(); - - for (ModRemapper modRemapper : remappers) { - modRemapper.registerPreVisitors(preInfos); - modRemapper.registerPostVisitors(postInfos); - } - - preApplyVisitor.setInfos(preInfos); - postApplyVisitor.setInfos(postInfos); - - builder.extraPreApplyVisitor(preApplyVisitor); - builder.extraPostApplyVisitor(postApplyVisitor); - builder.extraPostApplyVisitor(mixinPostApplyVisitor); - - builder.extension(new MixinExtension(EnumSet.of(MixinExtension.AnnotationTarget.HARD))); - - TinyRemapper remapper = builder.build(); - - try { - MappingsUtils.addMinecraftJar(remapper); - } catch (IOException e) { - throw new RuntimeException(e); - } - - for (ModRemapper modRemapper : remappers) { - List libraries = new ArrayList<>(); - - modRemapper.addRemapLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); - - for (RemapLibrary library : libraries) { - File libPath = new File(Constants.LIB_FOLDER, library.fileName); - - if (libPath.exists()) { - remapper.readClassPathAsync(libPath.toPath()); - } else { - Constants.MAIN_LOGGER.info("Library " + libPath.toPath() + " does not exist."); - } - } - } - - return remapper; - } - - /** - * Will remap file with specified remapper and store it into output. - * - * @param remapper {@link TinyRemapper} to remap with. - */ - private static void remapFiles(TinyRemapper remapper, Map paths) { - List outputConsumerPaths = new ArrayList<>(); - - List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); - resourceRemappers.add(new RefmapRemapper()); - - applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, true, MappingsUtilsImpl.getSourceNamespace(), MappingsUtils.getTargetNamespace()); - } - - @ApiStatus.Internal - public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) { - try { - Map tagMap = new HashMap<>(); - - Constants.MAIN_LOGGER.debug("Creating InputTags!"); - for (Path input : paths.keySet()) { - InputTag tag = remapper.createInputTag(); - tagMap.put(input, tag); - remapper.readInputsAsync(tag, input); - } - - Constants.MAIN_LOGGER.debug("Initializing remapping!"); - for (Map.Entry entry : paths.entrySet()) { - Constants.MAIN_LOGGER.debug("Starting remapping " + entry.getKey().toString() + " to " + entry.getValue().toString()); - OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(entry.getValue()).build(); - - outputConsumerPaths.add(outputConsumer); - - Constants.MAIN_LOGGER.debug("Apply remapper!"); - remapper.apply(outputConsumer, tagMap.get(entry.getKey())); - - Constants.MAIN_LOGGER.debug("Add input as non class file!"); - outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourceRemappers); - - Constants.MAIN_LOGGER.debug("Done 1!"); - } - - if (analyzeMapping) MappingsUtilsImpl.completeMappingsFromTr(remapper.getEnvironment(), srcNamespace); - } catch (Exception e) { - remapper.finish(); - outputConsumerPaths.forEach(o -> { - try { - o.close(); - } catch (IOException e2) { - e2.printStackTrace(); - } - }); - throw new RuntimeException("Failed to remap jar", e); - } finally { - remapper.finish(); - outputConsumerPaths.forEach(o -> { - try { - o.close(); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - } - @Deprecated public static String getRemappedFieldName(Class owner, String fieldName) { return MappingUtils.mapField(owner, fieldName).name; @@ -658,6 +62,6 @@ public static EnvType getEnvironment() { @Deprecated public static String getNativeNamespace() { - return MappingsUtils.getNativeNamespace(); + return MappingsUtilsImpl.getNativeNamespace(); } } diff --git a/src/main/java/fr/catcore/modremapperapi/utils/Constants.java b/src/main/java/fr/catcore/modremapperapi/utils/Constants.java index 5bc7e8e..e92f42e 100644 --- a/src/main/java/fr/catcore/modremapperapi/utils/Constants.java +++ b/src/main/java/fr/catcore/modremapperapi/utils/Constants.java @@ -1,28 +1,19 @@ package fr.catcore.modremapperapi.utils; -import net.fabricmc.loader.api.FabricLoader; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; import net.legacyfabric.fabric.api.logger.v1.Logger; import java.io.File; public class Constants { - public static final File MAIN_FOLDER = new File(FabricLoader.getInstance().getGameDir().toFile(), "mod-remapping-api"); - public static final File VERSIONED_FOLDER = new File( - new File(MAIN_FOLDER, - FabricLoader.getInstance().getModContainer("minecraft").get().getMetadata().getVersion().getFriendlyString() - ), FabricLoader.getInstance().getModContainer("mod-remapping-api").get().getMetadata().getVersion().getFriendlyString() - ); - public static final File EXTRA_MAPPINGS_FILE = new File(VERSIONED_FOLDER, "extra_mappings.tiny"); - public static final File REMAPPED_MAPPINGS_FILE = new File(VERSIONED_FOLDER, "remapped_mappings.tiny"); - public static final File MC_MAPPINGS_FILE = new File(VERSIONED_FOLDER, "mc_mappings.tiny"); - public static final File FULL_MAPPINGS_FILE = new File(VERSIONED_FOLDER, "full_mappings.tiny"); + public static final File MAIN_FOLDER = CacheUtils.BASE_FOLDER.toFile(); + public static final File VERSIONED_FOLDER = CacheUtils.MAIN_FOLDER.toFile(); + public static final File LIB_FOLDER = CacheUtils.LIBRARY_FOLDER.toFile(); - public static final File LIB_FOLDER = new File(VERSIONED_FOLDER, "libs"); - public static final Logger MAIN_LOGGER = Logger.get("ModRemappingAPI"); + public static final File EXTRA_MAPPINGS_FILE = CacheUtils.getCachePath("extra_mappings.tiny").toFile(); + public static final File REMAPPED_MAPPINGS_FILE = CacheUtils.getCachePath("remapped_mappings.tiny").toFile(); + public static final File MC_MAPPINGS_FILE = CacheUtils.getCachePath("mc_mappings.tiny").toFile(); + public static final File FULL_MAPPINGS_FILE = CacheUtils.getCachePath("full_mappings.tiny").toFile(); - static { - MAIN_FOLDER.mkdirs(); - VERSIONED_FOLDER.mkdirs(); - LIB_FOLDER.mkdirs(); - } + public static final Logger MAIN_LOGGER = Logger.get("ModRemappingAPI"); } diff --git a/src/main/java/fr/catcore/modremapperapi/utils/FileUtils.java b/src/main/java/fr/catcore/modremapperapi/utils/FileUtils.java index 2a213e0..23d958e 100644 --- a/src/main/java/fr/catcore/modremapperapi/utils/FileUtils.java +++ b/src/main/java/fr/catcore/modremapperapi/utils/FileUtils.java @@ -3,17 +3,15 @@ import net.fabricmc.loader.impl.launch.FabricLauncherBase; import java.io.*; -import java.nio.file.Files; +import java.net.URISyntaxException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; +@Deprecated public class FileUtils { - + @Deprecated public static void writeTextFile(Collection lines, File file) { file.getParentFile().mkdirs(); try { @@ -30,6 +28,7 @@ public static void writeTextFile(Collection lines, File file) { } } + @Deprecated public static List readTextSource(String path) { List result = new ArrayList<>(); try { @@ -50,72 +49,17 @@ public static List readTextSource(String path) { return result; } + @Deprecated public static void excludeFromZipFile(File file, List excluded) throws IOException { - File tempFile = new File(file.getAbsolutePath() + ".tmp"); - tempFile.delete(); - tempFile.deleteOnExit(); - - boolean renameOk = file.renameTo(tempFile); - if (!renameOk) { - throw new RuntimeException("could not rename the file " + file.getAbsolutePath() + " to " + tempFile.getAbsolutePath()); - } - - ZipInputStream zin = new ZipInputStream(Files.newInputStream(tempFile.toPath())); - ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(file.toPath())); - - ZipEntry entry = zin.getNextEntry(); - byte[] buf = new byte[1024]; - - while (entry != null) { - String zipEntryName = entry.getName(); - boolean toBeDeleted = excluded.contains(zipEntryName); - - if (!toBeDeleted) { - zout.putNextEntry(new ZipEntry(zipEntryName)); - // Transfer bytes from the ZIP file to the output file - int len; - while ((len = zin.read(buf)) > 0) { - zout.write(buf, 0, len); - } - } - - entry = zin.getNextEntry(); + try { + io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils.removeEntriesFromZip(file.toPath(), excluded); + } catch (URISyntaxException e) { + throw new RuntimeException(e); } - - // Close the streams - zin.close(); - // Compress the files - // Complete the ZIP file - zout.close(); - tempFile.delete(); } + @Deprecated public static void copyFile(Path original, Path copy) throws IOException { - copy.toFile().delete(); - - ZipInputStream zin = new ZipInputStream(Files.newInputStream(original)); - ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(copy)); - - ZipEntry entry = zin.getNextEntry(); - byte[] buf = new byte[1024]; - - while (entry != null) { - String zipEntryName = entry.getName(); - - zout.putNextEntry(new ZipEntry(zipEntryName)); - // Transfer bytes from the ZIP file to the output file - int len; - while ((len = zin.read(buf)) > 0) { - zout.write(buf, 0, len); - } - - entry = zin.getNextEntry(); - } - - // Close the streams - zin.close(); - // Compress the files - // Complete the ZIP file - zout.close(); + io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils.copyZipFile(original, copy); } } diff --git a/src/main/java/fr/catcore/modremapperapi/utils/MappingsUtils.java b/src/main/java/fr/catcore/modremapperapi/utils/MappingsUtils.java index f030d01..d30feb8 100644 --- a/src/main/java/fr/catcore/modremapperapi/utils/MappingsUtils.java +++ b/src/main/java/fr/catcore/modremapperapi/utils/MappingsUtils.java @@ -1,149 +1,30 @@ package fr.catcore.modremapperapi.utils; -import fr.catcore.modremapperapi.ModRemappingAPI; -import fr.catcore.modremapperapi.remapping.RemapUtil; import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.RemapUtils; -import net.fabricmc.api.EnvType; -import net.fabricmc.loader.api.*; -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.MappingVisitor; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import net.fabricmc.mappingio.tree.MappingTree; -import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.tinyremapper.*; -import org.jetbrains.annotations.ApiStatus; - -import java.io.*; -import java.nio.file.Path; -import java.util.*; - -import static io.github.fabriccompatibiltylayers.modremappingapi.impl.RemapUtils.getRemapClasspath; +@Deprecated public class MappingsUtils { @Deprecated public static String getNativeNamespace() { - if (ModRemappingAPI.BABRIC) { - return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT ? "client" : "server"; - } - - return "official"; + return MappingsUtilsImpl.getNativeNamespace(); } + @Deprecated public static String getTargetNamespace() { - return FabricLoader.getInstance().getMappingResolver().getCurrentRuntimeNamespace(); - } - - public static MappingTree loadMappings(Reader reader) { - MemoryMappingTree tree = new MemoryMappingTree(); - try { - loadMappings(reader, tree); - } catch (IOException e) { - e.printStackTrace(); - } - return tree; + return MappingsUtilsImpl.getTargetNamespace(); } - public static void loadMappings(Reader reader, MappingVisitor tree) throws IOException { - MappingReader.read(reader, tree); - } - - /** - * @deprecated Use {@link MappingsUtilsImpl#getVanillaMappings()} instead for the same behavior. - */ @Deprecated public static MappingTree getMinecraftMappings() { - return MappingsUtilsImpl.getVanillaMappings(); + return MappingsRegistry.VANILLA; } @Deprecated public static IMappingProvider createProvider(MappingTree mappings) { - return MappingsUtilsImpl.createProvider(mappings, getNativeNamespace(), getTargetNamespace()); - } - - private static Path[] getMinecraftJar(List sourcePaths, String src, String target) throws IOException { - Path[] originalClassPath = sourcePaths.toArray(new Path[0]); - - Map paths = new HashMap<>(); - - for (Path path : - originalClassPath) { - Constants.MAIN_LOGGER.debug(path.toString()); - paths.put(path, new File( - new File(Constants.LIB_FOLDER, target), - path.toFile().getName()).toPath() - ); - paths.get(path).toFile().delete(); - } - - TinyRemapper.Builder builder = TinyRemapper - .newRemapper() - .renameInvalidLocals(true) - .ignoreFieldDesc(false) - .propagatePrivate(true) - .ignoreConflicts(true) - .fixPackageAccess(true) - .withMappings( - MappingsUtilsImpl.createProvider(MappingsUtilsImpl.getMinecraftMappings(), src, target) - ); - - TinyRemapper remapper = builder.build(); - - Constants.MAIN_LOGGER.info("Remapping minecraft jar from " + src + " to " + target + "!"); - - List outputConsumerPaths = new ArrayList<>(); - - List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); - - RemapUtil.applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, true, src, target); - - Constants.MAIN_LOGGER.info("MC jar remapped successfully!"); - - return paths.values().toArray(new Path[0]); - } - - @ApiStatus.Internal - public static void addMinecraftJar(TinyRemapper remapper) throws IOException { - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - try { - Path[] classPath = getMinecraftJar( - Arrays.asList( - getMinecraftJar( - getRemapClasspath(), - getTargetNamespace(), - "intermediary" - ) - ), - "intermediary", - "official" - ); - - if (!MappingsUtilsImpl.isSourceNamespaceObf()) { - classPath = getMinecraftJar( - Arrays.asList( - classPath - ), - "official", - MappingsUtilsImpl.getSourceNamespace() - ); - } - - remapper.readClassPathAsync(classPath); - } catch (IOException e) { - throw new RuntimeException("Failed to populate default remap classpath", e); - } - } else { - List list = RemapUtils.getClassPathFromObjectShare(); - - Path[] classPath = list.toArray(new Path[0]); - - if (!MappingsUtilsImpl.isSourceNamespaceObf()) { - classPath = getMinecraftJar(list, "official", MappingsUtilsImpl.getSourceNamespace()); - } - - for (Path path : classPath) { - Constants.MAIN_LOGGER.debug("Appending '%s' to remapper classpath", path); - remapper.readClassPathAsync(path); - } - } + return MappingTreeHelper.createMappingProvider(mappings, getNativeNamespace(), getTargetNamespace()); } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/MappingUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/MappingUtils.java index 3fe9635..d10b203 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/MappingUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/MappingUtils.java @@ -4,95 +4,119 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils} + */ +@Deprecated public interface MappingUtils { /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapClass(String)} * @param className original class name * @return remapped class name */ + @Deprecated static String mapClass(String className) { - return MappingsUtilsImpl.mapClass(className); + return io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils.mapClass(className); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#unmapClass(String)} * @param className remapped class name * @return original class name */ + @Deprecated static String unmapClass(String className) { - return MappingsUtilsImpl.unmapClass(className); + return io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils.unmapClass(className); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapField(String, String, String)} * @param className original class name * @param fieldName * @param fieldDesc * @return */ + @Deprecated static MappingUtils.ClassMember mapField(String className, String fieldName, @Nullable String fieldDesc) { return MappingsUtilsImpl.mapField(className, fieldName, fieldDesc); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapFieldFromRemappedClass(String, String, String)} * @param className remapped class name * @param fieldName * @param fieldDesc * @return */ + @Deprecated static MappingUtils.ClassMember mapFieldFromRemappedClass(String className, String fieldName, @Nullable String fieldDesc) { return MappingsUtilsImpl.mapFieldFromRemappedClass(className, fieldName, fieldDesc); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapMethod(String, String, String)} * @param className original class name * @param methodName * @param methodDesc * @return */ + @Deprecated static MappingUtils.ClassMember mapMethod(String className, String methodName, String methodDesc) { return MappingsUtilsImpl.mapMethod(className, methodName, methodDesc); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapMethodFromRemappedClass(String, String, String)} * @param className remapped class name * @param methodName * @param methodDesc * @return */ + @Deprecated static MappingUtils.ClassMember mapMethodFromRemappedClass(String className, String methodName, String methodDesc) { return MappingsUtilsImpl.mapMethodFromRemappedClass(className, methodName, methodDesc); } + /** + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapField(Class, String)} + * @param owner + * @param fieldName + * @return + */ + @Deprecated static MappingUtils.ClassMember mapField(Class owner, String fieldName) { return MappingsUtilsImpl.mapField(owner, fieldName); } + /** + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapMethod(Class, String, Class[])} + * @param owner + * @param methodName + * @param parameterTypes + * @return + */ + @Deprecated static MappingUtils.ClassMember mapMethod(Class owner, String methodName, Class[] parameterTypes) { return MappingsUtilsImpl.mapMethod(owner, methodName, parameterTypes); } /** - * + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils#mapDescriptor(String)} * @param desc original descriptor * @return remapped descriptor */ + @Deprecated static String mapDescriptor(String desc) { - return MappingsUtilsImpl.mapDescriptor(desc); + return io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils.mapDescriptor(desc); } - class ClassMember { - public final @NotNull String name; - public final @Nullable String desc; - + /** + * @deprecated Deprecated in favor of {@link io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils.ClassMember} + */ + @Deprecated + class ClassMember extends io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingUtils.ClassMember { public ClassMember(@NotNull String name, @Nullable String desc) { - assert name != null; - - this.name = name; - this.desc = desc; + super(name, desc); } } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ClassTransformer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ClassTransformer.java new file mode 100644 index 0000000..c1bc5af --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ClassTransformer.java @@ -0,0 +1,17 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.api.v1; + +import io.github.fabriccompatibiltylayers.modremappingapi.impl.TransformerRegistry; + +// Original author is gudenau. +public interface ClassTransformer { + boolean handlesClass(String name, String transformedName); + byte[] transformClass(String name, String transformedName, byte[] original); + + static void registerPreTransformer(ClassTransformer transformer) { + TransformerRegistry.registerPreTransformer(transformer); + } + + static void registerPostTransformer(ClassTransformer transformer) { + TransformerRegistry.registerPostTransformer(transformer); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java new file mode 100644 index 0000000..7becc3a --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java @@ -0,0 +1,98 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.api.v1; + +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface MappingUtils { + /** + * + * @param className original class name + * @return remapped class name + */ + static String mapClass(String className) { + return MappingsUtilsImpl.mapClass(className); + } + + /** + * + * @param className remapped class name + * @return original class name + */ + static String unmapClass(String className) { + return MappingsUtilsImpl.unmapClass(className); + } + + /** + * + * @param className original class name + * @param fieldName + * @param fieldDesc + * @return + */ + static ClassMember mapField(String className, String fieldName, @Nullable String fieldDesc) { + return MappingsUtilsImpl.mapField(className, fieldName, fieldDesc); + } + + /** + * + * @param className remapped class name + * @param fieldName + * @param fieldDesc + * @return + */ + static ClassMember mapFieldFromRemappedClass(String className, String fieldName, @Nullable String fieldDesc) { + return MappingsUtilsImpl.mapFieldFromRemappedClass(className, fieldName, fieldDesc); + } + + /** + * + * @param className original class name + * @param methodName + * @param methodDesc + * @return + */ + static ClassMember mapMethod(String className, String methodName, String methodDesc) { + return MappingsUtilsImpl.mapMethod(className, methodName, methodDesc); + } + + /** + * + * @param className remapped class name + * @param methodName + * @param methodDesc + * @return + */ + static ClassMember mapMethodFromRemappedClass(String className, String methodName, String methodDesc) { + return MappingsUtilsImpl.mapMethodFromRemappedClass(className, methodName, methodDesc); + } + + static ClassMember mapField(Class owner, String fieldName) { + return MappingsUtilsImpl.mapField(owner, fieldName); + } + + static ClassMember mapMethod(Class owner, String methodName, Class[] parameterTypes) { + return MappingsUtilsImpl.mapMethod(owner, methodName, parameterTypes); + } + + /** + * + * @param desc original descriptor + * @return remapped descriptor + */ + static String mapDescriptor(String desc) { + return MappingsUtilsImpl.mapDescriptor(desc); + } + + class ClassMember { + public final @NotNull String name; + public final @Nullable String desc; + + public ClassMember(@NotNull String name, @Nullable String desc) { + assert name != null; + + this.name = name; + this.desc = desc; + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModEntry.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModEntry.java index d72b631..21e539a 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModEntry.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModEntry.java @@ -1,9 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; -import java.io.File; +import java.nio.file.Path; public class DefaultModEntry extends ModEntry { - protected DefaultModEntry(String modName, File file, File original) { + protected DefaultModEntry(String modName, Path file, Path original) { super(modName, modName, file, original); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java new file mode 100644 index 0000000..0b23642 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java @@ -0,0 +1,66 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl; + +import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.tinyremapper.TinyRemapper; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LibraryHandler { + private static final Map remapLibraries = new HashMap<>(); + + public static void gatherRemapLibraries(List remappers) { + try { + for (ModRemapper remapper : remappers) { + List libraries = new ArrayList<>(); + + remapper.addRemapLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); + + Map temp = CacheUtils.computeExtraLibraryPaths(libraries, MappingsUtilsImpl.getSourceNamespace()); + + for (Map.Entry entry : temp.entrySet()) { + RemapLibrary library = entry.getKey(); + Path path = entry.getValue(); + + if (Files.exists(path)) continue; + + if (!library.url.isEmpty()) { + Constants.MAIN_LOGGER.info("Downloading remapping library '" + library.fileName + "' from url '" + library.url + "'"); + FileUtils.downloadFile(library.url, path); + FileUtils.removeEntriesFromZip(path, library.toExclude); + Constants.MAIN_LOGGER.info("Remapping library ready for use."); + } else if (library.path != null) { + Constants.MAIN_LOGGER.info("Extracting remapping library '" + library.fileName + "' from mod jar."); + FileUtils.copyZipFile(library.path, path); + Constants.MAIN_LOGGER.info("Remapping library ready for use."); + } + } + + remapLibraries.putAll(temp); + } + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + public static void addLibrariesToRemapClasspath(TinyRemapper remapper) { + for (Path libPath : remapLibraries.values()) { + if (Files.exists(libPath)) { + remapper.readClassPathAsync(libPath); + } else { + Constants.MAIN_LOGGER.info("Library " + libPath + " does not exist."); + } + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java index 58922be..50e030b 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java @@ -1,27 +1,13 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; import fr.catcore.modremapperapi.utils.Constants; -import fr.catcore.modremapperapi.utils.MappingsUtils; -import fr.catcore.wfvaio.WhichFabricVariantAmIOn; import io.github.fabriccompatibiltylayers.modremappingapi.api.MappingUtils; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.MappingTreeHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.impl.launch.MappingConfiguration; -import net.fabricmc.loader.impl.util.log.Log; -import net.fabricmc.loader.impl.util.log.LogCategory; import net.fabricmc.mappingio.MappedElementKind; -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.MappingVisitor; -import net.fabricmc.mappingio.MappingWriter; -import net.fabricmc.mappingio.adapter.MappingDstNsReorder; -import net.fabricmc.mappingio.adapter.MappingNsRenamer; -import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; -import net.fabricmc.mappingio.format.MappingFormat; -import net.fabricmc.mappingio.format.tiny.Tiny1FileReader; -import net.fabricmc.mappingio.format.tiny.Tiny2FileReader; import net.fabricmc.mappingio.tree.*; -import net.fabricmc.tinyremapper.IMappingProvider; -import net.fabricmc.tinyremapper.TinyUtils; import net.fabricmc.tinyremapper.api.TrClass; import net.fabricmc.tinyremapper.api.TrEnvironment; import net.fabricmc.tinyremapper.api.TrMethod; @@ -30,42 +16,14 @@ import org.jetbrains.annotations.Nullable; import org.objectweb.asm.Type; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; import java.util.*; import java.util.stream.Collectors; -import java.util.zip.ZipError; - -import static fr.catcore.modremapperapi.utils.MappingsUtils.getTargetNamespace; @ApiStatus.Internal public class MappingsUtilsImpl { - private static boolean initialized = false; - private static MappingTree VANILLA_MAPPINGS; - private static VisitableMappingTree MINECRAFT_MAPPINGS; - private static VisitableMappingTree FULL_MAPPINGS = new MemoryMappingTree(); - private static String sourceNamespace = "official"; - - private static MappingTree EXTRA_MAPPINGS; - - @ApiStatus.Internal - public static MappingTree getVanillaMappings() { - loadMappings(); - - return VANILLA_MAPPINGS; - } - - @ApiStatus.Internal - public static MappingTree getMinecraftMappings() { - loadMappings(); - - return MINECRAFT_MAPPINGS; - } + private static String defaultPackage = ""; @ApiStatus.Internal public static String getSourceNamespace() { @@ -77,183 +35,46 @@ public static void setSourceNamespace(String sourceNamespace) { MappingsUtilsImpl.sourceNamespace = sourceNamespace; } - @ApiStatus.Internal - public static void loadExtraMappings(InputStream stream) { - try { - EXTRA_MAPPINGS = loadMappings(stream); - } catch (IOException e) { - throw new RuntimeException(e); - } + public static String getDefaultPackage() { + return defaultPackage; } - public static boolean isSourceNamespaceObf() { - return Objects.equals(sourceNamespace, "official"); + public static void setDefaultPackage(String defaultPackage) { + MappingsUtilsImpl.defaultPackage = defaultPackage; } - @ApiStatus.Internal - public static MemoryMappingTree loadMappings(InputStream stream) throws IOException { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { - long time = System.currentTimeMillis(); - MemoryMappingTree mappingTree = new MemoryMappingTree(); - - // We will only ever need to read tiny here - // so to strip the other formats from the included copy of mapping IO, don't use MappingReader.read() - reader.mark(4096); - final MappingFormat format = MappingReader.detectFormat(reader); - reader.reset(); - - switch (format) { - case TINY_FILE: - Tiny1FileReader.read(reader, mappingTree); - break; - case TINY_2_FILE: - Tiny2FileReader.read(reader, mappingTree); - break; - default: - throw new UnsupportedOperationException("Unsupported mapping format: " + format); - } - - Log.debug(LogCategory.MAPPINGS, "Loading mappings took %d ms", System.currentTimeMillis() - time); - - return mappingTree; - } - } - - private static void loadMappings() { - if (initialized) return; - - URL url = MappingConfiguration.class.getClassLoader().getResource("mappings/mappings.tiny"); - - if (url != null) { - try { - URLConnection connection = url.openConnection(); - - VANILLA_MAPPINGS = loadMappings(connection.getInputStream()); - } catch (IOException | ZipError e) { - throw new RuntimeException("Error reading "+url, e); - } - } - - adaptVanillaMappings(); - - if (VANILLA_MAPPINGS == null) { - Log.info(LogCategory.MAPPINGS, "Mappings not present!"); - VANILLA_MAPPINGS = new MemoryMappingTree(); - } - - try { - MINECRAFT_MAPPINGS.accept(FULL_MAPPINGS); - } catch (IOException e) { - e.printStackTrace(); - } - - initialized = true; + public static boolean isSourceNamespaceObf() { + return Objects.equals(sourceNamespace, "official"); } - private static void adaptVanillaMappings() { - MINECRAFT_MAPPINGS = new MemoryMappingTree(); - - if (VANILLA_MAPPINGS == null) { - return; - } - - Map renames = new HashMap<>(); - boolean switchNamespace = false; - - switch (WhichFabricVariantAmIOn.getVariant()) { - case BABRIC: - renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH), "official"); - switchNamespace = true; - break; - case ORNITHE_V2: - Boolean merged = VersionHelper.predicate(">=1.3"); - if (merged != null && !merged) { - renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH) + "Official", "official"); - switchNamespace = true; - } - break; - case BABRIC_NEW_FORMAT: - renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH) + "Official", "official"); - switchNamespace = true; - break; - default: - break; - } - - MemoryMappingTree tempTree = new MemoryMappingTree(); - MappingVisitor visitor = getMappingVisitor(tempTree, switchNamespace, renames); - - try { - VANILLA_MAPPINGS.accept(visitor); - - if (EXTRA_MAPPINGS == null) { - tempTree.accept(MINECRAFT_MAPPINGS); - } else { - MappingTreeHelper.mergeIntoNew(MINECRAFT_MAPPINGS, tempTree, EXTRA_MAPPINGS); - } - } catch (IOException e) { - e.printStackTrace(); - } + public static String getTargetNamespace() { + return FabricLoader.getInstance().getMappingResolver().getCurrentRuntimeNamespace(); } - private static @NotNull MappingVisitor getMappingVisitor(MemoryMappingTree tempTree, boolean switchNamespace, Map renames) { - List targetNamespace = new ArrayList<>(); - targetNamespace.add("intermediary"); - - if (VANILLA_MAPPINGS.getDstNamespaces().contains("named")) targetNamespace.add("named"); - - MappingVisitor visitor = tempTree; - - if (switchNamespace) { - visitor = new MappingSourceNsSwitch( - new MappingDstNsReorder( - visitor, - targetNamespace - ), - "official" - ); + public static String getNativeNamespace() { + if (ModRemappingAPIImpl.BABRIC) { + return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT ? "client" : "server"; } - visitor = new MappingNsRenamer(visitor, renames); - return visitor; - } - - @ApiStatus.Internal - public static IMappingProvider createProvider(MappingTree mappings, String from, String to) { - return TinyUtils.createMappingProvider(mappings, from, to); - } - - @ApiStatus.Internal - public static void initializeMappingTree(MappingVisitor mappingVisitor) throws IOException { - initializeMappingTree(mappingVisitor, getSourceNamespace(), MappingsUtils.getTargetNamespace()); - } - - @ApiStatus.Internal - public static void initializeMappingTree(MappingVisitor mappingVisitor, String src, String target) throws IOException { - mappingVisitor.visitHeader(); - - List namespaces = new ArrayList<>(); - namespaces.add(target); - - mappingVisitor.visitNamespaces(src, namespaces); + return "official"; } @ApiStatus.Internal public static void addMappingsToContext(MappingTree mappingTreeView) { try { - MappingTreeHelper.merge(FULL_MAPPINGS, mappingTreeView); + MappingTreeHelper.merge(MappingsRegistry.FULL, mappingTreeView); } catch (IOException e) { e.printStackTrace(); } } public static void completeMappingsFromTr(TrEnvironment trEnvironment, String src) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(src); - int trueSrcNamespace = FULL_MAPPINGS.getNamespaceId(FULL_MAPPINGS.getSrcNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(src); + int trueSrcNamespace = MappingsRegistry.FULL.getNamespaceId(MappingsRegistry.FULL.getSrcNamespace()); Map> classMembers = new HashMap<>(); - for (MappingTree.ClassMapping classMapping : FULL_MAPPINGS.getClasses()) { + for (MappingTree.ClassMapping classMapping : MappingsRegistry.FULL.getClasses()) { String className = classMapping.getName(srcNamespace); TrClass trClass = trEnvironment.getClass(className); @@ -283,9 +104,9 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr int propagated = 0; try { - FULL_MAPPINGS.visitHeader(); - FULL_MAPPINGS.visitNamespaces(FULL_MAPPINGS.getSrcNamespace(), FULL_MAPPINGS.getDstNamespaces()); - FULL_MAPPINGS.visitContent(); + MappingsRegistry.FULL.visitHeader(); + MappingsRegistry.FULL.visitNamespaces(MappingsRegistry.FULL.getSrcNamespace(), MappingsRegistry.FULL.getDstNamespaces()); + MappingsRegistry.FULL.visitContent(); } catch (IOException e) { throw new RuntimeException(e); } @@ -298,17 +119,13 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr TrClass trClass = trEnvironment.getClass(child); if (trClass == null) continue; - try { - if (srcNamespace == trueSrcNamespace) { - FULL_MAPPINGS.visitClass(child); - } else { - FULL_MAPPINGS.visitClass(FULL_MAPPINGS.mapClassName(child, srcNamespace, trueSrcNamespace)); - } - } catch (IOException e) { - e.printStackTrace(); + if (srcNamespace == trueSrcNamespace) { + MappingsRegistry.FULL.visitClass(child); + } else { + MappingsRegistry.FULL.visitClass(MappingsRegistry.FULL.mapClassName(child, srcNamespace, trueSrcNamespace)); } - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(child, srcNamespace); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(child, srcNamespace); if (classMapping == null) continue; @@ -317,26 +134,26 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr try { if (srcNamespace == trueSrcNamespace) { - FULL_MAPPINGS.visitMethod(member.name, member.desc); + MappingsRegistry.FULL.visitMethod(member.name, member.desc); } else { - MappingTree.MemberMapping memberMapping = FULL_MAPPINGS.getMethod(member.owner, member.name, member.desc, srcNamespace); + MappingTree.MemberMapping memberMapping = MappingsRegistry.FULL.getMethod(member.owner, member.name, member.desc, srcNamespace); if (memberMapping == null) continue; - FULL_MAPPINGS.visitMethod(memberMapping.getSrcName(), memberMapping.getSrcDesc()); + MappingsRegistry.FULL.visitMethod(memberMapping.getSrcName(), memberMapping.getSrcDesc()); - FULL_MAPPINGS.visitDstName(MappedElementKind.METHOD, srcNamespace, member.name); - FULL_MAPPINGS.visitDstDesc(MappedElementKind.METHOD, srcNamespace, member.desc); + MappingsRegistry.FULL.visitDstName(MappedElementKind.METHOD, srcNamespace, member.name); + MappingsRegistry.FULL.visitDstDesc(MappedElementKind.METHOD, srcNamespace, member.desc); } - MappingTree.MethodMapping methodMapping = FULL_MAPPINGS.getMethod(member.owner, member.name, member.desc, srcNamespace); + MappingTree.MethodMapping methodMapping = MappingsRegistry.FULL.getMethod(member.owner, member.name, member.desc, srcNamespace); if (methodMapping == null) continue; MappingTree.MethodMapping newMethodMapping = classMapping.getMethod(member.name, member.desc, srcNamespace); boolean actualPropagated = false; - for (String namespace : FULL_MAPPINGS.getDstNamespaces()) { - int targetNamespace = FULL_MAPPINGS.getNamespaceId(namespace); + for (String namespace : MappingsRegistry.FULL.getDstNamespaces()) { + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(namespace); if (targetNamespace == srcNamespace) continue; @@ -344,7 +161,7 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr String targetName = methodMapping.getName(targetNamespace); if (targetName != null) { - FULL_MAPPINGS.visitDstName(MappedElementKind.METHOD, targetNamespace, targetName); + MappingsRegistry.FULL.visitDstName(MappedElementKind.METHOD, targetNamespace, targetName); actualPropagated = true; } } @@ -353,7 +170,7 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr String targetDesc = methodMapping.getDesc(targetNamespace); if (targetDesc != null) { - FULL_MAPPINGS.visitDstDesc(MappedElementKind.METHOD, targetNamespace, targetDesc); + MappingsRegistry.FULL.visitDstDesc(MappedElementKind.METHOD, targetNamespace, targetDesc); actualPropagated = true; } } @@ -373,8 +190,7 @@ public static void completeMappingsFromTr(TrEnvironment trEnvironment, String sr public static void writeFullMappings() { try { - MappingWriter writer = MappingWriter.create(Constants.FULL_MAPPINGS_FILE.toPath(), MappingFormat.TINY_2_FILE); - FULL_MAPPINGS.accept(writer); + MappingTreeHelper.exportMappings(MappingsRegistry.FULL, Constants.FULL_MAPPINGS_FILE.toPath()); } catch (IOException e) { throw new RuntimeException(e); } @@ -409,33 +225,33 @@ public ExtendedClassMember(String name, @Nullable String desc, String owner) { } public static String mapClass(String className) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - return FULL_MAPPINGS.mapClassName(className, srcNamespace, targetNamespace); + return MappingsRegistry.FULL.mapClassName(className, srcNamespace, targetNamespace); } public static String unmapClass(String className) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); - return FULL_MAPPINGS.mapClassName(className, srcNamespace, targetNamespace); + return MappingsRegistry.FULL.mapClassName(className, srcNamespace, targetNamespace); } public static MappingUtils.ClassMember mapField(String className, String fieldName, @Nullable String fieldDesc) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - MappingTree.FieldMapping fieldMapping = FULL_MAPPINGS.getField(className, fieldName, fieldDesc, srcNamespace); + MappingTree.FieldMapping fieldMapping = MappingsRegistry.FULL.getField(className, fieldName, fieldDesc, srcNamespace); return mapMember(fieldName, fieldDesc, targetNamespace, fieldMapping); } public static MappingUtils.ClassMember mapFieldFromRemappedClass(String className, String fieldName, @Nullable String fieldDesc) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(className, targetNamespace); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(className, targetNamespace); if (classMapping == null) return new MappingUtils.ClassMember(fieldName, fieldDesc); MappingTree.FieldMapping fieldMapping = classMapping.getField(fieldName, fieldDesc, srcNamespace); @@ -443,13 +259,13 @@ public static MappingUtils.ClassMember mapFieldFromRemappedClass(String classNam } public static MappingUtils.ClassMember mapMethod(String className, String methodName, String methodDesc) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - MappingTree.MethodMapping methodMapping = FULL_MAPPINGS.getMethod(className, methodName, methodDesc, srcNamespace); + MappingTree.MethodMapping methodMapping = MappingsRegistry.FULL.getMethod(className, methodName, methodDesc, srcNamespace); if (methodMapping == null) { - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(className, srcNamespace); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(className, srcNamespace); if (classMapping != null) methodMapping = mapMethodWithPartialDesc(classMapping, methodName, methodDesc, srcNamespace); } @@ -457,10 +273,10 @@ public static MappingUtils.ClassMember mapMethod(String className, String method } public static MappingUtils.ClassMember mapMethodFromRemappedClass(String className, String methodName, String methodDesc) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(className, targetNamespace); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(className, targetNamespace); if (classMapping == null) return new MappingUtils.ClassMember(methodName, methodDesc); MappingTree.MethodMapping methodMapping = classMapping.getMethod(methodName, methodDesc, srcNamespace); @@ -497,9 +313,9 @@ private static MappingUtils.ClassMember mapMember(String memberName, @Nullable S } public static MappingUtils.ClassMember mapField(Class owner, String fieldName) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(owner.getName().replace(".", "/"), targetNamespace); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(owner.getName().replace(".", "/"), targetNamespace); if (classMapping != null) { MappingTree.FieldMapping fieldMapping = classMapping.getField(fieldName, null, srcNamespace); @@ -519,9 +335,9 @@ public static MappingUtils.ClassMember mapField(Class owner, String fieldName public static MappingUtils.ClassMember mapMethod(Class owner, String methodName, Class[] parameterTypes) { String argDesc = classTypeToDescriptor(parameterTypes); - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); - MappingTree.ClassMapping classMapping = FULL_MAPPINGS.getClass(owner.getName().replace(".", "/"), targetNamespace); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); + MappingTree.ClassMapping classMapping = MappingsRegistry.FULL.getClass(owner.getName().replace(".", "/"), targetNamespace); if (classMapping != null) { for (MappingTree.MethodMapping methodDef : classMapping.getMethods()) { @@ -558,9 +374,9 @@ private static String classTypeToDescriptor(Class[] classTypes) { } public static String mapDescriptor(String desc) { - int srcNamespace = FULL_MAPPINGS.getNamespaceId(getSourceNamespace()); - int targetNamespace = FULL_MAPPINGS.getNamespaceId(getTargetNamespace()); + int srcNamespace = MappingsRegistry.FULL.getNamespaceId(getSourceNamespace()); + int targetNamespace = MappingsRegistry.FULL.getNamespaceId(getTargetNamespace()); - return FULL_MAPPINGS.mapDesc(desc, srcNamespace, targetNamespace); + return MappingsRegistry.FULL.mapDesc(desc, srcNamespace, targetNamespace); } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModDiscoverer.java index 25032e8..2d28bf8 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModDiscoverer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModDiscoverer.java @@ -1,33 +1,30 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; import fr.catcore.modremapperapi.utils.Constants; -import fr.catcore.modremapperapi.utils.FileUtils; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; -import fr.catcore.modremapperapi.remapping.RemapUtil; import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.impl.launch.FabricLauncherBase; +import org.jetbrains.annotations.NotNull; import org.spongepowered.include.com.google.common.collect.ImmutableList; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; public class ModDiscoverer { private static final Map> EXCLUDED = new HashMap<>(); protected static void init(List modRemappers, boolean remapClassEdits) { - RemapUtil.init(modRemappers); + ModRemapperContext context = new ModRemapperContext(modRemappers); + + context.init(); List mods = new ArrayList<>(); @@ -39,158 +36,86 @@ protected static void init(List modRemappers, boolean remapClassEdi for (ModRemapper remapper : modRemappers) { for (String jarFolder : remapper.getJarFolders()) { - File mcSubFolder = new File(FabricLoader.getInstance().getGameDir().toFile(), jarFolder); - File cacheFolder = new File(Constants.VERSIONED_FOLDER, jarFolder); - - if (!mcSubFolder.exists()) mcSubFolder.mkdirs(); - if (!cacheFolder.exists()) cacheFolder.mkdirs(); + Path mcSubFolder = FabricLoader.getInstance().getGameDir().resolve(jarFolder); + Path cacheFolder = CacheUtils.getCachePath(jarFolder); - emptyDir(cacheFolder); + try { + if (!Files.exists(mcSubFolder)) Files.createDirectories(mcSubFolder); + if (!Files.exists(cacheFolder)) Files.createDirectories(cacheFolder); + else FileUtils.emptyDir(cacheFolder); - mods.addAll(discoverModsInFolder(mcSubFolder, cacheFolder)); + mods.addAll(discoverModsInFolder(mcSubFolder, cacheFolder)); + } catch (IOException | URISyntaxException e) { + e.printStackTrace(); + } } } - File mainTempDir = new File(Constants.VERSIONED_FOLDER, "temp"); - if (mainTempDir.exists()) { - emptyDir(mainTempDir); - } - - Map modPaths = mods.stream() - .filter(entry -> entry.original != null) - .collect(Collectors.toMap(entry -> entry.original.toPath(), entry -> entry.file.toPath())); + Path mainTempDir = CacheUtils.getCachePath("temp"); - if (!remapClassEdits) { - modPaths = excludeClassEdits(modPaths); - } - - for (Path path : modPaths.keySet()) { - RemapUtil.makeModMappings(path); + if (Files.exists(mainTempDir)) { + FileUtils.emptyDir(mainTempDir); } - RemapUtil.generateModMappings(); - - RemapUtil.remapMods(modPaths); - - modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); - } - - private static void emptyDir(File mainTempDir) { try { - Files.walkFileTree(mainTempDir.toPath(), new FileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) { - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); + Files.createDirectory(mainTempDir); } catch (IOException e) { throw new RuntimeException(e); } - } - - private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut, boolean root) throws IOException { - if (fileToZip.isHidden()) { - return; - } - - if (fileToZip.isDirectory()) { - if (!root) { - if (fileName.endsWith("/")) { - zipOut.putNextEntry(new ZipEntry(fileName)); - zipOut.closeEntry(); - } else { - zipOut.putNextEntry(new ZipEntry(fileName + "/")); - zipOut.closeEntry(); - } - } - File[] children = fileToZip.listFiles(); + Map modPaths = mods.stream() + .filter(entry -> Files.exists(entry.original)) + .collect(Collectors.groupingBy(entry -> entry.modId)) + .entrySet().stream() + .collect(Collectors.toMap(entry -> entry.getValue().get(0).original, entry -> entry.getValue().get(0).file)); - for (File childFile : children) { - zipFile(childFile, (root ? "" : fileName + "/") + childFile.getName(), zipOut, false); - } + if (!remapClassEdits) { + modPaths = excludeClassEdits(modPaths, mainTempDir); + } - return; + for (Path path : modPaths.keySet()) { + MappingsRegistry.addModMappings(path); } - FileInputStream fis = new FileInputStream(fileToZip); - ZipEntry zipEntry = new ZipEntry(fileName); - zipOut.putNextEntry(zipEntry); - byte[] bytes = new byte[1024]; - int length; + MappingsRegistry.generateModMappings(); - while ((length = fis.read(bytes)) >= 0) { - zipOut.write(bytes, 0, length); - } + context.remapMods(modPaths); - zipOut.closeEntry(); + modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); } - private static Map excludeClassEdits(Map modPaths) { + private static Map excludeClassEdits(Map modPaths, Path tempFolder) { Map map = new HashMap<>(); Map convertMap = new HashMap<>(); - File mainTempDir = new File(Constants.VERSIONED_FOLDER, "temp"); - mainTempDir.mkdirs(); - - for (Map.Entry entry : modPaths.entrySet()) { - File tempDir = new File(mainTempDir, entry.getValue().toFile().getParentFile().getName()); - if (!tempDir.exists()) tempDir.mkdir(); + Path tempDir = tempFolder.resolve(entry.getValue().getParent().getFileName().toString()); + + if (!Files.exists(tempDir)) { + try { + Files.createDirectory(tempDir); + } catch (IOException e) { + e.printStackTrace(); + continue; + } + } - File tempFile = new File(tempDir, entry.getValue().toFile().getName()); - map.put(tempFile.toPath(), entry.getValue()); - convertMap.put(entry.getKey(), tempFile.toPath()); + Path tempFile = tempDir.resolve(entry.getValue().getFileName().toString()); + map.put(tempFile, entry.getValue()); + convertMap.put(entry.getKey(), tempFile); } List errored = new ArrayList<>(); for (Map.Entry entry : convertMap.entrySet()) { try { - if (entry.getKey().toFile().isDirectory()) { - FileOutputStream fos = new FileOutputStream(entry.getValue().toFile()); - ZipOutputStream zipOut = new ZipOutputStream(fos); - - File fileToZip = entry.getKey().toFile(); - zipFile(fileToZip, fileToZip.getName(), zipOut, true); - zipOut.close(); + if (Files.isDirectory(entry.getKey())) { + FileUtils.zipFolder(entry.getKey(), entry.getValue()); } else { Files.copy(entry.getKey(), entry.getValue(), StandardCopyOption.REPLACE_EXISTING); } - /* Define ZIP File System Properies in HashMap */ - Map zip_properties = new HashMap<>(); - /* We want to read an existing ZIP File, so we set this to False */ - zip_properties.put("create", "false"); - /* Specify the encoding as UTF -8 */ - zip_properties.put("encoding", "UTF-8"); - - try (FileSystem zipfs = FileSystems.newFileSystem(new URI("jar:" + entry.getValue().toUri()), zip_properties)) { - for (String clName : RemapUtil.MC_CLASS_NAMES) { - Path classPath = zipfs.getPath("/" + clName + ".class"); - - if (Files.exists(classPath)) { - Files.delete(classPath); - } - } - } + FileUtils.removeEntriesFromZip(entry.getValue(), MappingsRegistry.VANILLA_CLASS_LIST); } catch (IOException | URISyntaxException e) { e.printStackTrace(); errored.add(entry.getValue()); @@ -202,97 +127,96 @@ private static Map excludeClassEdits(Map modPaths) { return map; } - private static List discoverModsInFolder(File folder, File destination) { - List mods = new ArrayList<>(); + private static Optional discoverFolderMod(Path folder, Path destinationFolder) throws IOException { + String name = folder.getFileName().toString().replace(" ", "_"); + Path destination = destinationFolder.resolve(name + ".zip"); - File[] folderFiles = folder.listFiles(); - if (!folder.isDirectory() || folderFiles == null) return ImmutableList.of(); + final boolean[] hasClasses = {false}; - for (File file : folderFiles) { - String name = file.getName().replace(" ", "_"); - if (file.isDirectory() || (file.isFile() && (name.endsWith(".jar") || name.endsWith(".zip")))) { - File remappedFile = new File(destination, name); + Files.walkFileTree(folder, new SimpleFileVisitor() { + @Override + public @NotNull FileVisitResult visitFile(Path file, @NotNull BasicFileAttributes attrs) throws IOException { + if (file.toString().endsWith(".class")) { + hasClasses[0] = true; + return FileVisitResult.TERMINATE; + } - List modName = new ArrayList<>(); + return super.visitFile(file, attrs); + } + }); + + if (hasClasses[0]) { + return Optional.of( + new DefaultModEntry( + name, + destination, + folder + ) + ); + } - boolean hasClass = false; - boolean fabric = false; + return Optional.empty(); + } - File[] fileFiles = file.listFiles(); + private static Optional discoverFileMod(Path file, Path destinationFolder) throws IOException { + String fileName = file.getFileName().toString().replace(" ", "_"); + String modName = fileName.replace(".jar", "").replace(".zip", ""); - if (file.isDirectory() && fileFiles != null) { - remappedFile = new File(destination, name + ".zip"); - for (File subFile : fileFiles) { - String subName = subFile.getName(); - if (subFile.isFile()) { - if (subName.endsWith(".class")) { - hasClass = true; - } - } - } + List entries = FileUtils.listZipContent(file); - if (/* modName.isEmpty() && */ hasClass) { - modName.add(new DefaultModEntry( - name.replace(".zip", "").replace(".jar", ""), - remappedFile, - file - )); - } + boolean found = false; - if (!modName.isEmpty() && EXCLUDED.containsKey(modName.get(0).modName)) { - for (String excluded : - EXCLUDED.get(modName.get(0).modName)) { - File excludedFile = new File(file, excluded); - if (excludedFile.delete()) { - Constants.MAIN_LOGGER.debug("File deleted: " + excludedFile.getName()); - } - } - } - } else { - try { - FileInputStream fileinputstream = new FileInputStream(file); - ZipInputStream zipinputstream = new ZipInputStream(fileinputstream); - while (true) { - ZipEntry zipentry = zipinputstream.getNextEntry(); - if (zipentry == null) { - zipinputstream.close(); - fileinputstream.close(); - break; - } - - String s1 = zipentry.getName(); - String[] ss = s1.split("/"); - String s2 = ss[ss.length - 1]; - if (!zipentry.isDirectory()) { - if (s2.equals("fabric.mod.json")) { -// modName.clear(); - fabric = true; - break; - } else if (s2.endsWith(".class")) { - hasClass = true; - } - } - } + for (String entry : entries) { + if (entry.contains("fabric.mod.json")) return Optional.empty(); - if (/* modName.isEmpty() && */ hasClass && !fabric) { - modName.add(new DefaultModEntry( - name.replace(".zip", "").replace(".jar", ""), - remappedFile, - file - )); - } + if (entry.endsWith(".class")) { + found = true; + } + } + + if (found) { + return Optional.of( + new DefaultModEntry( + modName, + destinationFolder.resolve(fileName), + file + ) + ); + } + + return Optional.empty(); + } + + private static List discoverModsInFolder(Path folder, Path destination) throws IOException, URISyntaxException { + List mods = new ArrayList<>(); + + if (!Files.isDirectory(folder)) return ImmutableList.of(); + + try (DirectoryStream stream = Files.newDirectoryStream(folder)) { + for (Path path : stream) { + String name = path.getFileName().toString(); - if (!modName.isEmpty()) { - if (EXCLUDED.containsKey(modName.get(0).modName)) { - FileUtils.excludeFromZipFile(file, EXCLUDED.get(modName.get(0).modName)); - } + if (Files.isDirectory(path)) { + discoverFolderMod(path, destination) + .ifPresent(mods::add); + } else if (Files.exists(path) && (name.endsWith(".jar") || name.endsWith(".zip"))) { + discoverFileMod(path, destination) + .ifPresent(mods::add); + } + } + } + + for (ModEntry modEntry : mods) { + if (EXCLUDED.containsKey(modEntry.modId)) { + if (Files.isDirectory(modEntry.file)) { + for (String excluded : EXCLUDED.get(modEntry.modId)) { + if (Files.deleteIfExists(modEntry.file.resolve(excluded))) { + Constants.MAIN_LOGGER.debug("File deleted: " + modEntry.file.resolve(excluded)); } - } catch (IOException e) { - throw new RuntimeException(e); } + } else { + FileUtils.removeEntriesFromZip(modEntry.file, EXCLUDED.get(modEntry.modId)); } - - mods.addAll(modName); } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModEntry.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModEntry.java index 68899bf..90644c8 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModEntry.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModEntry.java @@ -1,15 +1,15 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; -import java.io.File; +import java.nio.file.Path; public abstract class ModEntry { public final String modName; public final String modId; - public final File file; - public final File original; + public final Path file; + public final Path original; - protected ModEntry(String modName, String modId, File file, File original) { + protected ModEntry(String modName, String modId, Path file, Path original) { this.modName = modName; this.modId = modId; this.file = file; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemapperContext.java new file mode 100644 index 0000000..27608ab --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemapperContext.java @@ -0,0 +1,81 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl; + +import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import net.fabricmc.tinyremapper.TinyRemapper; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; + +public class ModRemapperContext { + private final List remappers; + + public ModRemapperContext(List remappers) { + this.remappers = remappers; + } + + public void init() { + for (ModRemapper remapper : remappers) { + Optional pkg = remapper.getDefaultPackage(); + + pkg.ifPresent(MappingsUtilsImpl::setDefaultPackage); + + Optional sourceNamespace = remapper.getSourceNamespace(); + + sourceNamespace.ifPresent(MappingsUtilsImpl::setSourceNamespace); + + Optional> mappings = remapper.getExtraMapping(); + + mappings.ifPresent(inputStreamSupplier -> { + try { + MappingsRegistry.generateFormattedMappings(inputStreamSupplier.get()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + if (!MappingsRegistry.generated) { + try { + MappingsRegistry.generateFormattedMappings(null); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + Path sourceLibraryPath = CacheUtils.getLibraryPath(MappingsUtilsImpl.getSourceNamespace()); + + if (!Files.exists(sourceLibraryPath)) { + try { + Files.createDirectories(sourceLibraryPath); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + LibraryHandler.gatherRemapLibraries(remappers); + + MappingsRegistry.registerAdditionalMappings(remappers); + } + + public void remapMods(Map pathMap) { + Constants.MAIN_LOGGER.debug("Starting jar remapping!"); + SoftLockFixer.preloadClasses(); + TinyRemapper remapper = ModTrRemapper.makeRemapper(remappers); + Constants.MAIN_LOGGER.debug("Remapper created!"); + ModTrRemapper.remapMods(remapper, pathMap); + Constants.MAIN_LOGGER.debug("Jar remapping done!"); + + MappingsUtilsImpl.writeFullMappings(); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/TransformerRegistry.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/TransformerRegistry.java new file mode 100644 index 0000000..cd4b458 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/TransformerRegistry.java @@ -0,0 +1,71 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl; + +import com.google.common.collect.ImmutableSet; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ClassTransformer; +import net.mine_diver.spasm.api.transform.RawClassTransformer; +import net.mine_diver.spasm.api.transform.TransformationPhase; +import net.mine_diver.spasm.impl.SpASM; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +@ApiStatus.Internal +public class TransformerRegistry implements RawClassTransformer { + private static final Set PRE_TRANSFORMERS = new HashSet<>(); + private static final Set POST_TRANSFORMERS = new HashSet<>(); + + @ApiStatus.Internal + public static byte[] transform(String name, String transformedName, byte[] basicClass) { + Set transformers = new HashSet<>(); + + Set transformerPool = PRE_TRANSFORMERS; + + if (SpASM.getCurrentPhase() == TransformationPhase.AFTER_MIXINS) { + transformerPool = POST_TRANSFORMERS; + } + + for (ClassTransformer transformer : transformerPool) { + if (transformer.handlesClass(name, transformedName)) { + transformers.add(transformer); + } + } + + byte[] modifiedClass = basicClass; + + for (ClassTransformer transformer : transformers) { + modifiedClass = transformer.transformClass(name, transformedName, modifiedClass); + } + + return modifiedClass; + } + + @ApiStatus.Internal + public static void registerPreTransformer(ClassTransformer transformer) { + PRE_TRANSFORMERS.add(transformer); + } + + @ApiStatus.Internal + public static void registerPostTransformer(ClassTransformer transformer) { + POST_TRANSFORMERS.add(transformer); + } + + @Override + public @NotNull Optional transform(@NotNull ClassLoader classLoader, @NotNull String className, byte @NotNull [] bytes) { + byte[] modifiedBytes = bytes; + modifiedBytes = transform(className, className, modifiedBytes); + + if (modifiedBytes != null) { + return Optional.of(modifiedBytes); + } + + return Optional.empty(); + } + + @Override + public @NotNull ImmutableSet getPhases() { + return ALL_PHASES; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V0ModRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V0ModRemapper.java index d778bc3..f980d5d 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V0ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V0ModRemapper.java @@ -7,7 +7,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; import net.fabricmc.api.EnvType; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; @@ -107,13 +107,13 @@ public void afterRemap() { * @return */ private MemoryMappingTree convertMappingList(RemapUtil.MappingList mappingList) { - MemoryMappingTree mappingTree = new MemoryMappingTree(); + MemoryMappingTree mappingTree; try { if (BABRIC) { - MappingsUtilsImpl.initializeMappingTree(mappingTree, "intermediary", "official"); + mappingTree = MappingTreeHelper.createMappingTree("intermediary", "official"); } else { - MappingsUtilsImpl.initializeMappingTree(mappingTree); + mappingTree = MappingTreeHelper.createMappingTree(); } mappingList.accept(mappingTree); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingTreeHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingTreeHelper.java new file mode 100644 index 0000000..0bba6a3 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingTreeHelper.java @@ -0,0 +1,170 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings; + +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.impl.util.log.Log; +import net.fabricmc.loader.impl.util.log.LogCategory; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.adapter.MappingDstNsReorder; +import net.fabricmc.mappingio.adapter.MappingNsRenamer; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.MappingFormat; +import net.fabricmc.mappingio.format.tiny.Tiny1FileReader; +import net.fabricmc.mappingio.format.tiny.Tiny2FileReader; +import net.fabricmc.mappingio.tree.*; +import net.fabricmc.tinyremapper.IMappingProvider; +import net.fabricmc.tinyremapper.TinyUtils; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@ApiStatus.Internal +public class MappingTreeHelper { + + @ApiStatus.Internal + public static void mergeIntoNew(VisitableMappingTree result, MappingTree left, MappingTree right) throws IOException { + if (!Objects.equals(left.getSrcNamespace(), right.getSrcNamespace())) { + throw new RuntimeException("Source namespace mismatch!"); + } + + result.visitHeader(); + + List dstNamespaces = new ArrayList<>(left.getDstNamespaces()); + + for (String dstNamespace : right.getDstNamespaces()) { + if (!dstNamespaces.contains(dstNamespace)) { + dstNamespaces.add(dstNamespace); + } + } + + result.visitNamespaces(left.getSrcNamespace(), dstNamespaces); + result.visitEnd(); + + MemoryMappingTree reorderedLeft = new MemoryMappingTree(); + left.accept(new MappingDstNsReorder(reorderedLeft, dstNamespaces)); + MemoryMappingTree reorderedRight = new MemoryMappingTree(); + right.accept(new MappingDstNsReorder(reorderedRight, dstNamespaces)); + + reorderedLeft.accept(result, VisitOrder.createByName()); + reorderedRight.accept(result, VisitOrder.createByName()); + } + + @ApiStatus.Internal + public static void merge(VisitableMappingTree main, MappingTree additional) throws IOException { + if (!Objects.equals(additional.getSrcNamespace(), main.getSrcNamespace())) { + MemoryMappingTree reorder = new MemoryMappingTree(); + + MappingVisitor visitor = new MappingSourceNsSwitch(reorder, main.getSrcNamespace()); + + if (!additional.getDstNamespaces().contains(main.getSrcNamespace())) { + List dstNamespaces = new ArrayList<>(additional.getDstNamespaces()); + dstNamespaces.add(main.getSrcNamespace()); + + visitor = new MappingDstNsReorder(reorder, dstNamespaces); + } + + additional.accept(visitor); + + additional = reorder; + } + + MemoryMappingTree reordered = new MemoryMappingTree(); + + additional.accept(new MappingDstNsReorder(reordered, main.getDstNamespaces())); + + reordered.accept(main, VisitOrder.createByInputOrder()); + } + + @ApiStatus.Internal + public static MemoryMappingTree readMappings(InputStream stream) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { + long time = System.currentTimeMillis(); + MemoryMappingTree mappingTree = new MemoryMappingTree(); + + // We will only ever need to read tiny here + // so to strip the other formats from the included copy of mapping IO, don't use MappingReader.read() + reader.mark(4096); + final MappingFormat format = MappingReader.detectFormat(reader); + reader.reset(); + + switch (format) { + case TINY_FILE: + Tiny1FileReader.read(reader, mappingTree); + break; + case TINY_2_FILE: + Tiny2FileReader.read(reader, mappingTree); + break; + default: + throw new UnsupportedOperationException("Unsupported mapping format: " + format); + } + + Log.debug(LogCategory.MAPPINGS, "Loading mappings took %d ms", System.currentTimeMillis() - time); + + return mappingTree; + } + } + + @ApiStatus.Internal + public static IMappingProvider createMappingProvider(MappingTree mappings, String from, String to) { + return TinyUtils.createMappingProvider(mappings, from, to); + } + + @ApiStatus.Internal + public static MemoryMappingTree createMappingTree() throws IOException { + return createMappingTree(MappingsUtilsImpl.getSourceNamespace(), MappingsUtilsImpl.getTargetNamespace()); + } + + @ApiStatus.Internal + public static MemoryMappingTree createMappingTree(String src, String target) throws IOException { + MemoryMappingTree mappingTree = new MemoryMappingTree(); + + mappingTree.visitHeader(); + + List namespaces = new ArrayList<>(); + namespaces.add(target); + + mappingTree.visitNamespaces(src, namespaces); + + return mappingTree; + } + + @ApiStatus.Internal + public static void exportMappings(MappingTreeView mappingTreeView, Path outputPath) throws IOException { + try (MappingWriter writer = MappingWriter.create(outputPath, MappingFormat.TINY_2_FILE)) { + mappingTreeView.accept(writer); + } + } + + public static @NotNull MappingVisitor getNsReorderingVisitor(MemoryMappingTree tempTree, boolean switchNamespace, Map renames) { + List targetNamespace = new ArrayList<>(); + targetNamespace.add("intermediary"); + + if (FabricLoader.getInstance().getMappingResolver().getNamespaces().contains("named")) targetNamespace.add("named"); + + MappingVisitor visitor = tempTree; + + if (switchNamespace) { + visitor = new MappingSourceNsSwitch( + new MappingDstNsReorder( + visitor, + targetNamespace + ), + "official" + ); + } + + visitor = new MappingNsRenamer(visitor, renames); + return visitor; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java new file mode 100644 index 0000000..5952a0f --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java @@ -0,0 +1,168 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings; + +import fr.catcore.modremapperapi.utils.Constants; +import fr.catcore.wfvaio.WhichFabricVariantAmIOn; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingBuilderImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.VersionHelper; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.impl.launch.MappingConfiguration; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.tree.MappingTree; +import net.fabricmc.mappingio.tree.MemoryMappingTree; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Path; +import java.util.*; +import java.util.zip.ZipError; + +@ApiStatus.Internal +public class MappingsRegistry { + public static List VANILLA_CLASS_LIST = new ArrayList<>(); + + public static final MemoryMappingTree VANILLA; + public static MemoryMappingTree FORMATTED = new MemoryMappingTree(); + public static boolean generated = false; + + public static MemoryMappingTree MODS; + public static MemoryMappingTree ADDITIONAL; + + static { + try { + MODS = MappingTreeHelper.createMappingTree(); + ADDITIONAL = MappingTreeHelper.createMappingTree(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static MemoryMappingTree FULL = new MemoryMappingTree(); + + static { + URL url = MappingConfiguration.class.getClassLoader().getResource("mappings/mappings.tiny"); + + if (url != null) { + try { + URLConnection connection = url.openConnection(); + + VANILLA = MappingTreeHelper.readMappings(connection.getInputStream()); + } catch (IOException | ZipError e) { + throw new RuntimeException("Error reading "+url, e); + } + } else { + VANILLA = null; + } + } + + public static void generateFormattedMappings(@Nullable InputStream extraStream) throws IOException { + generated = true; + + Map renames = new HashMap<>(); + boolean switchNamespace = false; + + switch (WhichFabricVariantAmIOn.getVariant()) { + case BABRIC: + renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH), "official"); + switchNamespace = true; + break; + case ORNITHE_V2: + Boolean merged = VersionHelper.predicate(">=1.3"); + if (merged != null && !merged) { + renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH) + "Official", "official"); + switchNamespace = true; + } + break; + case BABRIC_NEW_FORMAT: + renames.put(FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH) + "Official", "official"); + switchNamespace = true; + break; + default: + break; + } + + MemoryMappingTree tempTree = new MemoryMappingTree(); + MappingVisitor visitor = MappingTreeHelper.getNsReorderingVisitor(tempTree, switchNamespace, renames); + + VANILLA.accept(visitor); + + if (extraStream == null) { + tempTree.accept(FORMATTED); + } else { + MappingTree extra = MappingTreeHelper.readMappings(extraStream); + + MappingTreeHelper.mergeIntoNew( + FORMATTED, + tempTree, + extra + ); + } + + FORMATTED.accept(FULL); + + for (MappingTree.ClassMapping classView : FORMATTED.getClasses()) { + String className = classView.getName(MappingsUtilsImpl.getSourceNamespace()); + + if (className != null) { + VANILLA_CLASS_LIST.add("/" + className + ".class"); + } + } + + try { + MappingTreeHelper.exportMappings(MappingsRegistry.FORMATTED, Constants.MC_MAPPINGS_FILE.toPath()); + } catch (IOException e) { + throw new RuntimeException("Error while writing formatted mappings", e); + } + } + + public static void addModMappings(Path path) { + MappingBuilder mappingBuilder = new MappingBuilderImpl(MODS); + + try { + FileUtils.listPathContent(path) + .stream() + .filter(file -> file.endsWith(".class")) + .map(file -> file.replace(".class", "")) + .forEach(cl -> mappingBuilder.addMapping(cl, (cl.contains("/") ? "" : MappingsUtilsImpl.getDefaultPackage()) + cl)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void generateModMappings() { + try { + MODS.visitEnd(); + + MappingTreeHelper.exportMappings(MODS, Constants.REMAPPED_MAPPINGS_FILE.toPath()); + } catch (IOException e) { + throw new RuntimeException("Error while generating mods mappings", e); + } + + MappingsUtilsImpl.addMappingsToContext(MODS); + } + + public static void registerAdditionalMappings(List remappers) { + MappingBuilder builder = new MappingBuilderImpl(ADDITIONAL); + + for (ModRemapper remapper : remappers) { + remapper.registerMappings(builder); + } + + ADDITIONAL.visitEnd(); + + try { + MappingTreeHelper.exportMappings(ADDITIONAL, Constants.EXTRA_MAPPINGS_FILE.toPath()); + } catch (IOException e) { + throw new RuntimeException("Error while generating remappers mappings", e); + } + + MappingsUtilsImpl.addMappingsToContext(ADDITIONAL); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/MixinRemappingHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/MixinRemappingHelper.java new file mode 100644 index 0000000..99b973e --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/MixinRemappingHelper.java @@ -0,0 +1,12 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; + +import org.jetbrains.annotations.ApiStatus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ApiStatus.Internal +public class MixinRemappingHelper { + public static final Map> MIXIN2TARGETMAP = new HashMap<>(); +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java new file mode 100644 index 0000000..6b7a278 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java @@ -0,0 +1,87 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; + +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft.MinecraftRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.mappingio.tree.MappingTree; +import net.fabricmc.tinyremapper.NonClassCopyMode; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; +import net.fabricmc.tinyremapper.extension.mixin.MixinExtension; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; + +@ApiStatus.Internal +public class ModTrRemapper { + public static TinyRemapper makeRemapper(List remappers) { + List trees = Arrays.asList(MappingsRegistry.FORMATTED, MappingsRegistry.ADDITIONAL, MappingsRegistry.MODS); + + TinyRemapper.Builder builder = TinyRemapper + .newRemapper() + .renameInvalidLocals(true) + .ignoreFieldDesc(false) + .propagatePrivate(true) + .ignoreConflicts(true); + + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + builder.fixPackageAccess(true); + } + + for (MappingTree tree : trees) { + builder.withMappings(MappingTreeHelper.createMappingProvider(tree, MappingsUtilsImpl.getSourceNamespace(), MappingsUtilsImpl.getTargetNamespace())); + } + + MRAApplyVisitor preApplyVisitor = new MRAApplyVisitor(); + MRAApplyVisitor postApplyVisitor = new MRAApplyVisitor(); + MixinPostApplyVisitor mixinPostApplyVisitor = new MixinPostApplyVisitor(); + + VisitorInfosImpl preInfos = new VisitorInfosImpl(); + VisitorInfosImpl postInfos = new VisitorInfosImpl(); + + for (ModRemapper modRemapper : remappers) { + modRemapper.registerPreVisitors(preInfos); + modRemapper.registerPostVisitors(postInfos); + } + + preApplyVisitor.setInfos(preInfos); + postApplyVisitor.setInfos(postInfos); + + builder.extraPreApplyVisitor(preApplyVisitor); + builder.extraPostApplyVisitor(postApplyVisitor); + builder.extraPostApplyVisitor(mixinPostApplyVisitor); + + builder.extension(new MixinExtension(EnumSet.of(MixinExtension.AnnotationTarget.HARD))); + + TinyRemapper remapper = builder.build(); + + try { + MinecraftRemapper.addMinecraftJar(remapper); + } catch (IOException e) { + throw new RuntimeException(e); + } + + LibraryHandler.addLibrariesToRemapClasspath(remapper); + + return remapper; + } + + public static void remapMods(TinyRemapper remapper, Map paths) { + List outputConsumerPaths = new ArrayList<>(); + + List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); + resourceRemappers.add(new RefmapRemapper()); + + TrRemapperHelper.applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, true, MappingsUtilsImpl.getSourceNamespace(), MappingsUtilsImpl.getTargetNamespace()); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java new file mode 100644 index 0000000..3d08f27 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java @@ -0,0 +1,244 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; + +import fr.catcore.modremapperapi.utils.Constants; +import net.fabricmc.loader.api.FabricLoader; + +public class SoftLockFixer { + public static void preloadClasses() { + for (String clazz : new String[]{ + "java.io.IOException", + "java.net.URI", + "java.net.URISyntaxException", + "java.nio.file.FileSystem", + "java.nio.file.FileVisitResult", + "java.nio.file.Files", + "java.nio.file.Path", + "java.nio.file.SimpleFileVisitor", + "java.nio.file.attribute.BasicFileAttributes", + "java.util.ArrayDeque", + "java.util.ArrayList", + "java.util.Collection", + "java.util.Collections", + "java.util.HashMap", + "java.util.HashSet", + "java.util.IdentityHashMap", + "java.util.List", + "java.util.Map", + "java.util.Objects", + "java.util.Optional", + "java.util.Queue", + "java.util.Set", + "java.util.concurrent.CompletableFuture", + "java.util.concurrent.ConcurrentHashMap", + "java.util.concurrent.ExecutionException", + "java.util.concurrent.ExecutorService", + "java.util.concurrent.Executors", + "java.util.concurrent.Future", + "java.util.concurrent.TimeUnit", + "java.util.concurrent.atomic.AtomicReference", + "java.util.function.BiConsumer", + "java.util.function.Supplier", + "java.util.regex.Pattern", + "java.util.stream.Collectors", + "java.util.zip.ZipError", + + "org.objectweb.asm.ClassReader", + "org.objectweb.asm.ClassVisitor", + "org.objectweb.asm.ClassWriter", + "org.objectweb.asm.FieldVisitor", + "org.objectweb.asm.MethodVisitor", + "org.objectweb.asm.Opcodes", + "org.objectweb.asm.commons.Remapper", + "org.objectweb.asm.util.CheckClassAdapter", + + "fr.catcore.modremapperapi.api.RemapLibrary", + "fr.catcore.modremapperapi.api.ModRemapper", + "fr.catcore.modremapperapi.utils.BArrayList", + "fr.catcore.modremapperapi.utils.CollectionUtils", + "fr.catcore.modremapperapi.utils.Constants", + "fr.catcore.modremapperapi.utils.FileUtils", + "fr.catcore.modremapperapi.utils.MappingsUtils", + "fr.catcore.modremapperapi.utils.MixinUtils", + "fr.catcore.modremapperapi.remapping.MappingBuilder", + "fr.catcore.modremapperapi.remapping.MappingBuilder$Entry", + "fr.catcore.modremapperapi.remapping.MappingBuilder$Type", + "fr.catcore.modremapperapi.remapping.RemapUtil", + "fr.catcore.modremapperapi.remapping.RemapUtil$MappingList", + "fr.catcore.modremapperapi.remapping.VisitorInfos", + "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodNamed", + "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodValue", + "fr.catcore.modremapperapi.remapping.VisitorInfos$Type", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModEntry", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModDiscoverer", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModDiscoverer$1", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.ModEntry", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAClassVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAMethodVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.MixinRemappingHelper", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.TrRemapperHelper", + + "net.fabricmc.loader.impl.launch.FabricLauncher", + "net.fabricmc.loader.impl.launch.FabricLauncherBase", + "net.fabricmc.loader.api.ObjectShare", + + getLibClassName("tinyremapper", "AsmClassRemapper"), + getLibClassName("tinyremapper", "AsmClassRemapper$AsmAnnotationRemapper"), + getLibClassName("tinyremapper", "AsmClassRemapper$AsmAnnotationRemapper$AsmArrayAttributeAnnotationRemapper"), + getLibClassName("tinyremapper", "AsmClassRemapper$AsmFieldRemapper"), + getLibClassName("tinyremapper", "AsmClassRemapper$AsmMethodRemapper"), + getLibClassName("tinyremapper", "AsmClassRemapper$AsmRecordComponentRemapper"), + getLibClassName("tinyremapper", "AsmRemapper"), + getLibClassName("tinyremapper", "BridgeHandler"), + getLibClassName("tinyremapper", "ClassInstance"), + getLibClassName("tinyremapper", "FileSystemReference"), + getLibClassName("tinyremapper", "IMappingProvider"), + getLibClassName("tinyremapper", "IMappingProvider$MappingAcceptor"), + getLibClassName("tinyremapper", "IMappingProvider$Member"), + getLibClassName("tinyremapper", "InputTag"), + getLibClassName("tinyremapper", "MemberInstance"), + getLibClassName("tinyremapper", "MetaInfFixer"), + getLibClassName("tinyremapper", "MetaInfRemover"), + getLibClassName("tinyremapper", "NonClassCopyMode"), + getLibClassName("tinyremapper", "OutputConsumerPath"), + getLibClassName("tinyremapper", "OutputConsumerPath$1"), + getLibClassName("tinyremapper", "OutputConsumerPath$Builder"), + getLibClassName("tinyremapper", "OutputConsumerPath$ResourceRemapper"), + getLibClassName("tinyremapper", "PackageAccessChecker"), + getLibClassName("tinyremapper", "Propagator"), + getLibClassName("tinyremapper", "TinyRemapper"), + getLibClassName("tinyremapper", "TinyRemapper$1"), + getLibClassName("tinyremapper", "TinyRemapper$1$1"), + getLibClassName("tinyremapper", "TinyRemapper$2"), + getLibClassName("tinyremapper", "TinyRemapper$3"), + getLibClassName("tinyremapper", "TinyRemapper$4"), + getLibClassName("tinyremapper", "TinyRemapper$5"), + getLibClassName("tinyremapper", "TinyRemapper$AnalyzeVisitorProvider"), + getLibClassName("tinyremapper", "TinyRemapper$ApplyVisitorProvider"), + getLibClassName("tinyremapper", "TinyRemapper$Builder"), + getLibClassName("tinyremapper", "TinyRemapper$CLIExtensionProvider"), + getLibClassName("tinyremapper", "TinyRemapper$Direction"), + getLibClassName("tinyremapper", "TinyRemapper$Extension"), + getLibClassName("tinyremapper", "TinyRemapper$LinkedMethodPropagation"), + getLibClassName("tinyremapper", "TinyRemapper$MrjState"), + getLibClassName("tinyremapper", "TinyRemapper$Propagation"), + getLibClassName("tinyremapper", "TinyRemapper$StateProcessor"), + getLibClassName("tinyremapper", "TinyUtils"), + getLibClassName("tinyremapper", "TinyUtils$MappingAdapter"), + getLibClassName("tinyremapper", "VisitTrackingClassRemapper"), + getLibClassName("tinyremapper", "VisitTrackingClassRemapper$VisitKind"), + getLibClassName("tinyremapper", "extension.mixin.common.IMappable"), + getLibClassName("tinyremapper", "extension.mixin.common.MapUtility"), + getLibClassName("tinyremapper", "extension.mixin.common.ResolveUtility"), + getLibClassName("tinyremapper", "extension.mixin.common.StringUtility"), + getLibClassName("tinyremapper", "extension.mixin.common.data.Annotation"), + getLibClassName("tinyremapper", "extension.mixin.common.data.AnnotationElement"), + getLibClassName("tinyremapper", "extension.mixin.common.data.CommonData"), + getLibClassName("tinyremapper", "extension.mixin.common.data.Constant"), + getLibClassName("tinyremapper", "extension.mixin.common.data.Message"), + getLibClassName("tinyremapper", "extension.mixin.common.data.MxClass"), + getLibClassName("tinyremapper", "extension.mixin.common.data.MxMember"), + getLibClassName("tinyremapper", "extension.mixin.common.data.Pair"), + getLibClassName("tinyremapper", "extension.mixin.soft.SoftTargetMixinClassVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.SoftTargetMixinMethodVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.AccessorAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.InvokerAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.MixinAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtConstructorMappable"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtSecondPassAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.AtAnnotationVisitor$AtSecondPassAnnotationVisitor$1"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.CommonInjectionAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.CommonInjectionAnnotationVisitor$InjectMethodMappable"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionAnnotationVisitor$MemberRemappingVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionsAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DefinitionsAnnotationVisitor$DefinitionRemappingVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.DescAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.InjectAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyArgAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyArgsAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyConstantAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyExpressionValueAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyReceiverAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyReturnValueAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.ModifyVariableAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.RedirectAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.SliceAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapMethodAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapOperationAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapWithConditionAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.annotation.injection.WrapWithConditionV2AnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.soft.data.MemberInfo"), + getLibClassName("tinyremapper", "extension.mixin.soft.util.NamedMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinClassVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinFieldVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.HardTargetMixinMethodVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$1"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$InterfaceAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ImplementsAnnotationVisitor$SoftImplementsMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor$1"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.MixinAnnotationVisitor$2"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.OverwriteAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.OverwriteAnnotationVisitor$OverwriteMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ShadowAnnotationVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.annotation.ShadowAnnotationVisitor$ShadowPrefixMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.data.SoftInterface"), + getLibClassName("tinyremapper", "extension.mixin.hard.data.SoftInterface$Remap"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.CamelPrefixString"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.ConvertibleMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.HardTargetMappable"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.IConvertibleString"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.IdentityString"), + getLibClassName("tinyremapper", "extension.mixin.hard.util.PrefixString"), + getLibClassName("tinyremapper", "extension.mixin.MixinExtension"), + getLibClassName("tinyremapper", "extension.mixin.MixinExtension$AnalyzeVisitorProvider"), + getLibClassName("tinyremapper", "extension.mixin.MixinExtension$AnnotationTarget"), + getLibClassName("tinyremapper", "extension.mixin.MixinExtension$CLIProvider"), + getLibClassName("tinyremapper", "extension.mixin.MixinExtension$PreApplyVisitorProvider"), + getLibClassName("tinyremapper", "api.TrClass"), + getLibClassName("tinyremapper", "api.TrEnvironment"), + getLibClassName("tinyremapper", "api.TrField"), + getLibClassName("tinyremapper", "api.TrLogger"), + getLibClassName("tinyremapper", "api.TrLogger$Level"), + getLibClassName("tinyremapper", "api.TrMember"), + getLibClassName("tinyremapper", "api.TrMember$MemberType"), + getLibClassName("tinyremapper", "api.TrMethod"), + getLibClassName("tinyremapper", "api.TrRemapper"), + + getLibClassName("mappingio", "MappingReader"), + getLibClassName("mappingio", "MappingReader$1"), + getLibClassName("mappingio", "FlatMappingVisitor"), + getLibClassName("mappingio", "MappedElementKind"), + getLibClassName("mappingio", "MappingFlag"), + getLibClassName("mappingio", "MappingUtil"), + getLibClassName("mappingio", "MappingVisitor"), + getLibClassName("mappingio", "MappingWriter"), + getLibClassName("mappingio", "MappingWriter$1") + }) { + try { + Constants.MAIN_LOGGER.debug("Preloading class: " + clazz); + Class.forName(clazz); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + } + + private static String getLibClassName(String lib, String string) { + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + return "net.fabricmc." + lib + "." + string; + } + + return "fr.catcore.modremapperapi.impl.lib." + lib + "." + string; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java new file mode 100644 index 0000000..afbd2b9 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java @@ -0,0 +1,67 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; + +import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import net.fabricmc.tinyremapper.InputTag; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ApiStatus.Internal +public class TrRemapperHelper { + public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) { + try { + Map tagMap = new HashMap<>(); + + Constants.MAIN_LOGGER.debug("Creating InputTags!"); + for (Path input : paths.keySet()) { + InputTag tag = remapper.createInputTag(); + tagMap.put(input, tag); + remapper.readInputsAsync(tag, input); + } + + Constants.MAIN_LOGGER.debug("Initializing remapping!"); + for (Map.Entry entry : paths.entrySet()) { + Constants.MAIN_LOGGER.debug("Starting remapping " + entry.getKey().toString() + " to " + entry.getValue().toString()); + OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(entry.getValue()).build(); + + outputConsumerPaths.add(outputConsumer); + + Constants.MAIN_LOGGER.debug("Apply remapper!"); + remapper.apply(outputConsumer, tagMap.get(entry.getKey())); + + Constants.MAIN_LOGGER.debug("Add input as non class file!"); + outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourceRemappers); + + Constants.MAIN_LOGGER.debug("Done 1!"); + } + + if (analyzeMapping) MappingsUtilsImpl.completeMappingsFromTr(remapper.getEnvironment(), srcNamespace); + } catch (Exception e) { + remapper.finish(); + outputConsumerPaths.forEach(o -> { + try { + o.close(); + } catch (IOException e2) { + e2.printStackTrace(); + } + }); + throw new RuntimeException("Failed to remap jar", e); + } finally { + remapper.finish(); + outputConsumerPaths.forEach(o -> { + try { + o.close(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + } +} diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/MRAClassVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAClassVisitor.java similarity index 89% rename from src/main/java/fr/catcore/modremapperapi/remapping/MRAClassVisitor.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAClassVisitor.java index 0f2588c..d955387 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/MRAClassVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAClassVisitor.java @@ -1,4 +1,4 @@ -package fr.catcore.modremapperapi.remapping; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm; import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; import org.objectweb.asm.*; @@ -7,7 +7,7 @@ public class MRAClassVisitor extends ClassVisitor { private final VisitorInfosImpl infos; private final String className; - protected MRAClassVisitor(ClassVisitor classVisitor, VisitorInfosImpl infos, String className) { + public MRAClassVisitor(ClassVisitor classVisitor, VisitorInfosImpl infos, String className) { super(Opcodes.ASM9, classVisitor); this.infos = infos; this.className = className; diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/MRAMethodVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java similarity index 98% rename from src/main/java/fr/catcore/modremapperapi/remapping/MRAMethodVisitor.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java index dc826b6..1a9600a 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/MRAMethodVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java @@ -1,4 +1,4 @@ -package fr.catcore.modremapperapi.remapping; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos; import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java new file mode 100644 index 0000000..9995326 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java @@ -0,0 +1,95 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft; + +import fr.catcore.modremapperapi.remapping.RemapUtil; +import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.RemapUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.TrRemapperHelper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.tinyremapper.NonClassCopyMode; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +@ApiStatus.Internal +public class MinecraftRemapper { + private static Collection getMinecraftJar(Collection sourcePaths, String src, String target) throws IOException { + Path targetFolder = CacheUtils.getLibraryPath(target); + + if (!Files.exists(targetFolder)) { + Files.createDirectories(targetFolder); + } + + Map paths = CacheUtils.computeLibraryPaths(sourcePaths, target); + + if (FileUtils.exist(paths.values())) return paths.values(); + + FileUtils.delete(paths.values()); + + TinyRemapper.Builder builder = TinyRemapper + .newRemapper() + .renameInvalidLocals(true) + .ignoreFieldDesc(false) + .propagatePrivate(true) + .ignoreConflicts(true) + .fixPackageAccess(true) + .withMappings( + MappingTreeHelper.createMappingProvider(MappingsRegistry.FORMATTED, src, target) + ); + + TinyRemapper remapper = builder.build(); + + Constants.MAIN_LOGGER.info("Remapping minecraft jar from " + src + " to " + target + "!"); + + List outputConsumerPaths = new ArrayList<>(); + + List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); + + TrRemapperHelper.applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, true, src, target); + + Constants.MAIN_LOGGER.info("MC jar remapped successfully!"); + + return paths.values(); + } + + @ApiStatus.Internal + public static void addMinecraftJar(TinyRemapper remapper) throws IOException { + Collection classPath; + + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + try { + classPath = getMinecraftJar( + getMinecraftJar(RemapUtils.getRemapClasspath(), MappingsUtilsImpl.getTargetNamespace(), "intermediary"), + "intermediary", + "official" + ); + + if (!MappingsUtilsImpl.isSourceNamespaceObf()) { + classPath = getMinecraftJar(classPath, "official", MappingsUtilsImpl.getSourceNamespace()); + } + } catch (IOException e) { + throw new RuntimeException("Failed to populate default remap classpath", e); + } + } else { + classPath = RemapUtils.getClassPathFromObjectShare(); + + if (!MappingsUtilsImpl.isSourceNamespaceObf()) { + classPath = getMinecraftJar(classPath, "official", MappingsUtilsImpl.getSourceNamespace()); + } + } + + for (Path path : classPath) { + Constants.MAIN_LOGGER.debug("Appending '%s' to remapper classpath", path); + remapper.readClassPathAsync(path); + } + } +} diff --git a/src/main/java/fr/catcore/modremapperapi/utils/RefmapJson.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java similarity index 88% rename from src/main/java/fr/catcore/modremapperapi/utils/RefmapJson.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java index c29503e..b09f442 100644 --- a/src/main/java/fr/catcore/modremapperapi/utils/RefmapJson.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java @@ -1,6 +1,5 @@ -package fr.catcore.modremapperapi.utils; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource; -import fr.catcore.modremapperapi.remapping.RefmapRemapper; import net.fabricmc.tinyremapper.TinyRemapper; import java.util.HashMap; diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/RefmapRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java similarity index 96% rename from src/main/java/fr/catcore/modremapperapi/remapping/RefmapRemapper.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java index 75cc69d..22d12a5 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/RefmapRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java @@ -1,7 +1,7 @@ -package fr.catcore.modremapperapi.remapping; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource; import com.google.gson.Gson; -import fr.catcore.modremapperapi.utils.RefmapJson; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.MixinRemappingHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.api.TrRemapper; @@ -40,7 +40,7 @@ public void transform(Path destinationDirectory, Path relativePath, InputStream public String mapRefMapEntry(String mixinClass, String old, TinyRemapper remapper) { TrRemapper trRemapper = remapper.getEnvironment().getRemapper(); - List supers = RemapUtil.MIXINED.get(mixinClass); + List supers = MixinRemappingHelper.MIXIN2TARGETMAP.get(mixinClass); // format is: // owner + name + quantifier + (desc == null || desc.startsWith("(") ? "" : ":") + desc + (tail != null ? " -> " : "") + tail String owner; // can be "" diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/MRAApplyVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MRAApplyVisitor.java similarity index 78% rename from src/main/java/fr/catcore/modremapperapi/remapping/MRAApplyVisitor.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MRAApplyVisitor.java index dd60eba..8272855 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/MRAApplyVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MRAApplyVisitor.java @@ -1,6 +1,7 @@ -package fr.catcore.modremapperapi.remapping; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor; import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAClassVisitor; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.api.TrClass; import org.objectweb.asm.ClassVisitor; diff --git a/src/main/java/fr/catcore/modremapperapi/remapping/MixinPostApplyVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java similarity index 88% rename from src/main/java/fr/catcore/modremapperapi/remapping/MixinPostApplyVisitor.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java index 5d934b4..e78e0fd 100644 --- a/src/main/java/fr/catcore/modremapperapi/remapping/MixinPostApplyVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java @@ -1,7 +1,7 @@ -package fr.catcore.modremapperapi.remapping; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor; import fr.catcore.modremapperapi.utils.Constants; -import net.fabricmc.mappingio.tree.MappingTree; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.MixinRemappingHelper; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.api.TrClass; import org.objectweb.asm.ClassReader; @@ -54,7 +54,7 @@ public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { }); } - RemapUtil.MIXINED.put(cls.getName().replace(".", "/"), supers); + MixinRemappingHelper.MIXIN2TARGETMAP.put(cls.getName().replace(".", "/"), supers); return next; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java new file mode 100644 index 0000000..04b4350 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java @@ -0,0 +1,47 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.utils; + +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; +import net.fabricmc.loader.api.FabricLoader; +import org.jetbrains.annotations.ApiStatus; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +@ApiStatus.Internal +public class CacheUtils { + public static final Path BASE_FOLDER = FabricLoader.getInstance().getGameDir().resolve("mod-remapping-api"); + public static final Path MAIN_FOLDER = BASE_FOLDER + .resolve(VersionHelper.MINECRAFT_VERSION) + .resolve(VersionHelper.MOD_VERSION); + public static final Path LIBRARY_FOLDER = MAIN_FOLDER.resolve("libs"); + + public static Path getCachePath(String pathName) { + return MAIN_FOLDER.resolve(pathName); + } + + public static Path getLibraryPath(String pathName) { + return LIBRARY_FOLDER.resolve(pathName); + } + + @ApiStatus.Internal + public static Map computeLibraryPaths(Collection sourcePaths, String target) { + return sourcePaths.stream().collect(Collectors.toMap(p -> p, + p -> CacheUtils.getLibraryPath(target).resolve(p.toFile().getName()))); + } + + @ApiStatus.Internal + public static Map computeExtraLibraryPaths(Collection sourcePaths, String target) { + return sourcePaths.stream() + .collect(Collectors.toMap(p -> p, + p -> CacheUtils.getLibraryPath(target).resolve(p.fileName))); + } + + static { + BASE_FOLDER.toFile().mkdirs(); + MAIN_FOLDER.toFile().mkdirs(); + LIBRARY_FOLDER.toFile().mkdirs(); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java new file mode 100644 index 0000000..5eb36eb --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java @@ -0,0 +1,248 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.utils; + +import org.jetbrains.annotations.ApiStatus; + +import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +@ApiStatus.Internal +public class FileUtils { + + @ApiStatus.Internal + public static boolean exist(Collection paths) { + for (Path path : paths) { + if (!Files.exists(path)) return false; + } + + return true; + } + + @ApiStatus.Internal + public static void delete(Collection paths) { + for (Path path : paths) { + try { + Files.deleteIfExists(path); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @ApiStatus.Internal + public static void downloadFile(String url, Path target) throws IOException { + try (BufferedInputStream inputStream = new BufferedInputStream(new URL(url).openStream())) { + try (BufferedOutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(target))) { + byte[] buffer = new byte[2048]; + + // Increments file size + int length; + int downloaded = 0; + + // Looping until server finishes + while ((length = inputStream.read(buffer)) != -1) { + // Writing data + outputStream.write(buffer, 0, length); + downloaded += length; +// Constants.MAIN_LOGGER.debug("Download Status: " + (downloaded * 100) / (contentLength * 1.0) + "%"); + } + + outputStream.close(); + inputStream.close(); + } + } + } + + @ApiStatus.Internal + public static void copyZipFile(Path original, Path target) throws IOException { + target.toFile().delete(); + + ZipInputStream zin = new ZipInputStream(Files.newInputStream(original)); + ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(target)); + + ZipEntry entry = zin.getNextEntry(); + byte[] buf = new byte[1024]; + + while (entry != null) { + String zipEntryName = entry.getName(); + + zout.putNextEntry(new ZipEntry(zipEntryName)); + // Transfer bytes from the ZIP file to the output file + int len; + while ((len = zin.read(buf)) > 0) { + zout.write(buf, 0, len); + } + + entry = zin.getNextEntry(); + } + + // Close the streams + zin.close(); + // Compress the files + // Complete the ZIP file + zout.close(); + } + + @ApiStatus.Internal + public static List listZipContent(Path path) throws IOException { + List files = new ArrayList<>(); + + try (ZipInputStream zin = new ZipInputStream(Files.newInputStream(path))) { + while (true) { + ZipEntry entry = zin.getNextEntry(); + if (entry == null) { + break; + } + + String name = entry.getName(); + if (!entry.isDirectory()) { + files.add(name.replace("\\", "/")); + } + } + } + + return files; + } + + @ApiStatus.Internal + public static List listDirectoryContent(File[] files) { + List list = new ArrayList<>(); + + for (File file : files) { + if (file.isDirectory()) { + String name = file.getName(); + + for (String fileName : listDirectoryContent(file.listFiles())) { + list.add(name + "/" + fileName); + } + } else if (file.isFile()) { + list.add(file.getName()); + } + } + + return list; + } + + @ApiStatus.Internal + public static List listPathContent(Path path) throws IOException { + File file = path.toFile(); + + if (file.isDirectory()) { + return listDirectoryContent(file.listFiles()); + } else if (file.isFile()) { + return listZipContent(path); + } + + return new ArrayList<>(); + } + + @ApiStatus.Internal + public static void emptyDir(Path dir) { + try { + Files.walkFileTree(dir, new FileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @ApiStatus.Internal + public static void zipFolder(Path input, Path output) throws IOException { + try (ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(output))) { + File fileToZip = input.toFile(); + + zipFile(fileToZip, fileToZip.getName(), zout, true); + } + } + + private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut, boolean root) throws IOException { + if (fileToZip.isHidden()) { + return; + } + + if (fileToZip.isDirectory()) { + if (!root) { + if (fileName.endsWith("/")) { + zipOut.putNextEntry(new ZipEntry(fileName)); + zipOut.closeEntry(); + } else { + zipOut.putNextEntry(new ZipEntry(fileName + "/")); + zipOut.closeEntry(); + } + } + + File[] children = fileToZip.listFiles(); + + for (File childFile : children) { + zipFile(childFile, (root ? "" : fileName + "/") + childFile.getName(), zipOut, false); + } + + return; + } + + ZipEntry zipEntry = new ZipEntry(fileName); + zipOut.putNextEntry(zipEntry); + + try (FileInputStream fis = new FileInputStream(fileToZip)) { + byte[] bytes = new byte[1024]; + int length; + + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); + } + } + + zipOut.closeEntry(); + } + + /* Define ZIP File System Properies in HashMap */ + private static final Map ZIP_PROPERTIES = new HashMap<>(); + + static { + /* We want to read an existing ZIP File, so we set this to False */ + ZIP_PROPERTIES.put("create", "false"); + /* Specify the encoding as UTF-8 */ + ZIP_PROPERTIES.put("encoding", "UTF-8"); + } + + @ApiStatus.Internal + public static void removeEntriesFromZip(Path zipPath, List entries) throws IOException, URISyntaxException { + try (FileSystem zipfs = FileSystems.newFileSystem(new URI("jar:" + zipPath.toUri()), ZIP_PROPERTIES)) { + for (String entryName : entries) { + Path entryPath = zipfs.getPath(entryName); + + if (Files.exists(entryPath)) { + Files.delete(entryPath); + } + } + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/MappingTreeHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/MappingTreeHelper.java deleted file mode 100644 index becc080..0000000 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/MappingTreeHelper.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl.utils; - -import net.fabricmc.mappingio.MappingVisitor; -import net.fabricmc.mappingio.adapter.MappingDstNsReorder; -import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; -import net.fabricmc.mappingio.tree.MappingTree; -import net.fabricmc.mappingio.tree.MemoryMappingTree; -import net.fabricmc.mappingio.tree.VisitOrder; -import net.fabricmc.mappingio.tree.VisitableMappingTree; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MappingTreeHelper { - public static void mergeIntoNew(VisitableMappingTree result, MappingTree left, MappingTree right) throws IOException { - assert Objects.equals(left.getSrcNamespace(), right.getSrcNamespace()); - - result.visitHeader(); - - List dstNamespaces = new ArrayList<>(left.getDstNamespaces()); - - for (String dstNamespace : right.getDstNamespaces()) { - if (!dstNamespaces.contains(dstNamespace)) { - dstNamespaces.add(dstNamespace); - } - } - - result.visitNamespaces(left.getSrcNamespace(), dstNamespaces); - result.visitEnd(); - - MemoryMappingTree reorderedLeft = new MemoryMappingTree(); - left.accept(new MappingDstNsReorder(reorderedLeft, dstNamespaces)); - MemoryMappingTree reorderedRight = new MemoryMappingTree(); - right.accept(new MappingDstNsReorder(reorderedRight, dstNamespaces)); - - reorderedLeft.accept(result, VisitOrder.createByName()); - reorderedRight.accept(result, VisitOrder.createByName()); - } - - public static void merge(VisitableMappingTree main, MappingTree additional) throws IOException { - if (!Objects.equals(additional.getSrcNamespace(), main.getSrcNamespace())) { - MemoryMappingTree reorder = new MemoryMappingTree(); - - MappingVisitor visitor = new MappingSourceNsSwitch(reorder, main.getSrcNamespace()); - - if (!additional.getDstNamespaces().contains(main.getSrcNamespace())) { - List dstNamespaces = new ArrayList<>(additional.getDstNamespaces()); - dstNamespaces.add(main.getSrcNamespace()); - - visitor = new MappingDstNsReorder(reorder, dstNamespaces); - } - - additional.accept(visitor); - - additional = reorder; - } - - MemoryMappingTree reordered = new MemoryMappingTree(); - - additional.accept(new MappingDstNsReorder(reordered, main.getDstNamespaces())); - - reordered.accept(main, VisitOrder.createByInputOrder()); - } -} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VersionHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/VersionHelper.java similarity index 68% rename from src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VersionHelper.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/VersionHelper.java index f2a80c0..9017f89 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VersionHelper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/VersionHelper.java @@ -1,4 +1,4 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.utils; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.Version; @@ -11,6 +11,9 @@ public class VersionHelper { private static final Version MC_VERSION = FabricLoader.getInstance().getModContainer("minecraft") .get().getMetadata().getVersion(); + public static final String MINECRAFT_VERSION = MC_VERSION.getFriendlyString(); + public static final String MOD_VERSION = FabricLoader.getInstance().getModContainer("mod-remapping-api").get().getMetadata().getVersion().getFriendlyString(); + public static Boolean predicate(String predicate) { try { return VersionPredicate.parse(predicate).test(MC_VERSION); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 0c8c05b..f44c180 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,7 +26,7 @@ "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper" ], "spasm:raw_transformer": [ - "fr.catcore.modremapperapi.ClassTransformer" + "io.github.fabriccompatibiltylayers.modremappingapi.impl.TransformerRegistry" ] }, "depends": {