From b3baa3ff7b1e365b04526a93d86e5b4a4dbd7d0d Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 17 Nov 2023 22:59:27 +0800 Subject: [PATCH] Apply remap to production jar --- .../plugin/ArchitecturyPluginExtension.kt | 12 ++++++ .../dev/architectury/plugin/ModLoader.kt | 10 +++++ .../architectury/plugin/TransformingTask.kt | 40 +++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt index 985686e..536d069 100644 --- a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt +++ b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt @@ -2,6 +2,7 @@ package dev.architectury.plugin +import dev.architectury.plugin.ModLoader.Companion.applyNeoForgeForgeLikeProd import dev.architectury.plugin.loom.LoomInterface import dev.architectury.plugin.utils.GradleSupport import dev.architectury.transformer.Transformer @@ -279,11 +280,17 @@ open class ArchitectPluginExtension(val project: Project) { data class CommonSettings( val loaders: MutableSet = LinkedHashSet(), val platformPackages: MutableMap = mutableMapOf(), + var isForgeLike: Boolean = false, + val extraForgeLikeToNeoForgeRemaps: MutableMap = mutableMapOf(), ) { constructor(loaders: Array) : this() { this.loaders.addAll(loaders.map { ModLoader.valueOf(it) }) } + fun remapForgeLike(remap: String, to: String) { + extraForgeLikeToNeoForgeRemaps[remap] = to + } + @Deprecated("Use add and remove directly") var forgeEnabled: Boolean get() = loaders.any { it.id == "forge" } @@ -415,6 +422,10 @@ open class ArchitectPluginExtension(val project: Project) { it.platform = loader.id loader.transformProduction(it, loom, settings) + if (settings.isForgeLike && loader.id == "neoforge") { + it.addPost(applyNeoForgeForgeLikeProd(loom, settings)) + } + it.archiveClassifier.set("transformProduction${loader.titledId}") it.input.set(jarTask.archiveFile) @@ -454,6 +465,7 @@ open class ArchitectPluginExtension(val project: Project) { fun forgeLike(action: Action) { common { clear() + isForgeLike = true action.execute(this) } } diff --git a/src/main/kotlin/dev/architectury/plugin/ModLoader.kt b/src/main/kotlin/dev/architectury/plugin/ModLoader.kt index 599d072..acab21b 100644 --- a/src/main/kotlin/dev/architectury/plugin/ModLoader.kt +++ b/src/main/kotlin/dev/architectury/plugin/ModLoader.kt @@ -2,8 +2,10 @@ package dev.architectury.plugin import dev.architectury.plugin.loom.LoomInterface import dev.architectury.plugin.transformers.AddRefmapName +import dev.architectury.transformer.Transformer import dev.architectury.transformer.shadowed.impl.com.google.gson.Gson import dev.architectury.transformer.transformers.* +import dev.architectury.transformer.transformers.base.ClassEditTransformer import dev.architectury.transformer.util.TransformerPair open class ModLoader( @@ -142,6 +144,14 @@ open class ModLoader( return listOf(TransformerPair(TransformForgeLikeToNeoForge::class.java, Gson().toJsonTree(properties).asJsonObject)) } + fun applyNeoForgeForgeLikeProd(loom: LoomInterface, settings: ArchitectPluginExtension.CommonSettings): ClassEditTransformer { + val properties = mutableMapOf() + properties[BuiltinProperties.NEOFORGE_LIKE_REMAPS] = settings.extraForgeLikeToNeoForgeRemaps + val transform = TransformForgeLikeToNeoForge() + transform.supplyProperties(Gson().toJsonTree(properties).asJsonObject) + return transform + } + val QUILT = ModLoader( id = "quilt", transformDevelopment = { diff --git a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt index 8415762..01a8748 100644 --- a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt +++ b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt @@ -3,8 +3,14 @@ package dev.architectury.plugin import dev.architectury.plugin.utils.GradleSupport import dev.architectury.transformer.Transform import dev.architectury.transformer.Transformer +import dev.architectury.transformer.input.OpenedFileAccess import dev.architectury.transformer.shadowed.impl.com.google.gson.Gson +import dev.architectury.transformer.shadowed.impl.org.objectweb.asm.ClassReader +import dev.architectury.transformer.shadowed.impl.org.objectweb.asm.ClassWriter +import dev.architectury.transformer.shadowed.impl.org.objectweb.asm.Opcodes +import dev.architectury.transformer.shadowed.impl.org.objectweb.asm.tree.ClassNode import dev.architectury.transformer.transformers.BuiltinProperties +import dev.architectury.transformer.transformers.base.ClassEditTransformer import dev.architectury.transformer.util.Logger import org.gradle.api.Project import org.gradle.api.file.RegularFileProperty @@ -14,6 +20,7 @@ import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.gradle.jvm.tasks.Jar import java.io.File +import java.nio.file.Files import java.nio.file.Path import java.util.* import java.util.function.BiConsumer @@ -27,6 +34,9 @@ open class TransformingTask : Jar() { @Internal val transformers: ListProperty = project.objects.listProperty(Transformer::class.java) + @Internal + val postTransformers: ListProperty = project.objects.listProperty(ClassEditTransformer::class.java) + @Internal var platform: String? = null @@ -47,6 +57,32 @@ open class TransformingTask : Jar() { Logger.debug("============================") Logger.debug("") Transform.runTransformers(input, output, transformers.get()) + + if (postTransformers.get().isNotEmpty()) { + val postTransformers = postTransformers.get() + val apply = { access: OpenedFileAccess -> + access.handle({ path: String -> path.endsWith(".class") }) { path: String, bytes: ByteArray -> + val reader = ClassReader(bytes) + if (reader.access and Opcodes.ACC_MODULE == 0) { + var node = ClassNode(Opcodes.ASM9) + reader.accept(node, 0) + postTransformers.forEach { node = it.doEdit(path, node) } + access.modifyFile(path, node.toByteArray()) + } + } + } + if (Files.isDirectory(output)) { + OpenedFileAccess.ofDirectory(output).use(apply) + } else { + OpenedFileAccess.ofJar(output).use(apply) + } + } + } + + private fun ClassNode.toByteArray(): ByteArray { + val writer = ClassWriter(0) + this.accept(writer) + return writer.toByteArray() } operator fun invoke(transformer: Transformer) { @@ -66,6 +102,10 @@ open class TransformingTask : Jar() { }) } + fun addPost(transformer: ClassEditTransformer) { + postTransformers.add(transformer) + } + fun add(transformer: Transformer, config: MutableMap.(file: Path) -> Unit) { add(transformer, BiConsumer { file, map -> config(map, file)