Update to architectury-injectables 1.0.4

This commit is contained in:
shedaniel
2021-01-12 18:55:16 +08:00
parent e298f3f937
commit 20fe7ae252
4 changed files with 104 additions and 60 deletions

View File

@@ -36,28 +36,28 @@ public class PlatformMethods {
private static String modLoader = null;
public static String getModLoader() {
try {
return (String) Class.forName("me.shedaniel.architectury.platform.Platform").getDeclaredMethod("getModLoader").invoke(null);
} catch (Throwable ignored) {
}
if (modLoader == null) {
List<String> loader = new ArrayList<>();
HashMap<String, String> MOD_LOADERS = new HashMap<>();
MOD_LOADERS.put("net.fabricmc.loader.FabricLoader", "fabric");
MOD_LOADERS.put("net.minecraftforge.fml.common.Mod", "forge");
for (Map.Entry<String, String> entry : MOD_LOADERS.entrySet()) {
try {
Class.forName(entry.getKey(), false, null);
loader.add(entry.getValue());
break;
} catch (ClassNotFoundException ignored) {
try {
modLoader = (String) Class.forName("me.shedaniel.architectury.platform.Platform").getDeclaredMethod("getModLoader").invoke(null);
} catch (Throwable ignored) {
List<String> loader = new ArrayList<>();
HashMap<String, String> MOD_LOADERS = new HashMap<>();
MOD_LOADERS.put("net.fabricmc.loader.FabricLoader", "fabric");
MOD_LOADERS.put("net.minecraftforge.fml.common.Mod", "forge");
for (Map.Entry<String, String> entry : MOD_LOADERS.entrySet()) {
try {
Class.forName(entry.getKey(), false, null);
loader.add(entry.getValue());
break;
} catch (ClassNotFoundException ignored1) {
}
}
if (loader.isEmpty())
throw new IllegalStateException("No detected mod loader!");
if (loader.size() >= 2)
System.err.println("Detected multiple mod loaders! Something is wrong on the classpath! " + String.join(", ", loader));
modLoader = loader.get(0);
}
if (loader.isEmpty())
throw new IllegalStateException("No detected mod loader!");
if (loader.size() >= 2)
System.err.println("Detected multiple mod loaders! Something is wrong on the classpath! " + String.join(", ", loader));
modLoader = loader.get(0);
}
return modLoader;
}

View File

@@ -9,6 +9,7 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask
open class ArchitectPluginExtension(val project: Project) {
var minecraft = ""
var injectInjectables = true
fun common() {
common(true)
@@ -21,8 +22,10 @@ open class ArchitectPluginExtension(val project: Project) {
}
fun common(forgeEnabled: Boolean) {
with(project.dependencies) {
add("compileOnly", "me.shedaniel:architectury-annotations:+")
if (injectInjectables) {
with(project.dependencies) {
add("compileOnly", "me.shedaniel:architectury-injectables:1.0.4")
}
}
if (forgeEnabled) {

View File

@@ -41,46 +41,46 @@ fun Project.projectUniqueIdentifier(): String {
fun transformExpectPlatform(project: Project): ClassTransformer {
val projectUniqueIdentifier by lazy { project.projectUniqueIdentifier() }
var injectedClass = false
var injectedClass = !project.extensions.getByType(ArchitectPluginExtension::class.java).injectInjectables
return { clazz, classAdder ->
if (!injectedClass) {
injectedClass = true
Transform::class.java.getResourceAsStream("/annotations-inject/injection.jar").use { stream ->
ZipUtil.iterate(stream) { input: InputStream, entry: ZipEntry ->
if (entry.name.endsWith(".class")) {
val newName = "$projectUniqueIdentifier/${
entry.name.substringBeforeLast(".class").substringAfterLast('/')
}"
classAdder(newName, input.readBytes().let {
val node = ClassNode(Opcodes.ASM8)
ClassReader(it).accept(node, ClassReader.EXPAND_FRAMES)
val writer = ClassWriter(ClassWriter.COMPUTE_MAXS)
val remapper = ClassRemapper(writer, object : Remapper() {
override fun map(internalName: String?): String {
if (internalName?.startsWith("me/shedaniel/architect/plugin/callsite") == true) {
return internalName.replace(
"me/shedaniel/architect/plugin/callsite",
projectUniqueIdentifier
)
}
return super.map(internalName)
}
})
node.apply {
name = newName
}.accept(remapper)
writer.toByteArray()
})
}
}
}
}
clazz.methods.mapNotNull { method ->
when {
method?.visibleAnnotations?.any { it.desc == expectPlatform } == true -> method to "me/shedaniel/architectury/PlatformMethods"
method?.invisibleAnnotations?.any { it.desc == expectPlatformNew } == true -> {
if (!injectedClass) {
injectedClass = true
Transform::class.java.getResourceAsStream("/annotations-inject/injection.jar").use { stream ->
ZipUtil.iterate(stream) { input: InputStream, entry: ZipEntry ->
if (entry.name.endsWith(".class")) {
val newName = "$projectUniqueIdentifier/${
entry.name.substringBeforeLast(".class").substringAfterLast('/')
}"
classAdder(newName, input.readBytes().let {
val node = ClassNode(Opcodes.ASM8)
ClassReader(it).accept(node, ClassReader.EXPAND_FRAMES)
val writer = ClassWriter(ClassWriter.COMPUTE_MAXS)
val remapper = ClassRemapper(writer, object : Remapper() {
override fun map(internalName: String?): String {
if (internalName?.startsWith("me/shedaniel/architect/plugin/callsite") == true) {
return internalName.replace(
"me/shedaniel/architect/plugin/callsite",
projectUniqueIdentifier
)
}
return super.map(internalName)
}
})
node.apply {
name = newName
}.accept(remapper)
writer.toByteArray()
})
}
}
}
}
method to "$projectUniqueIdentifier/PlatformMethods"
}
else -> null

View File

@@ -7,12 +7,12 @@ import me.shedaniel.architect.plugin.utils.Transform
import net.fabricmc.loom.LoomGradleExtension
import net.fabricmc.loom.util.LoggerFilter
import net.fabricmc.loom.util.MixinRefmapHelper
import net.fabricmc.tinyremapper.OutputConsumerPath
import net.fabricmc.tinyremapper.TinyRemapper
import net.fabricmc.tinyremapper.TinyUtils
import net.fabricmc.tinyremapper.*
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.TaskAction
import org.gradle.jvm.tasks.Jar
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
@@ -25,6 +25,7 @@ open class TransformTask : Jar() {
fun doTask() {
val input: Path = this.input.asFile.get().toPath()
val intermediate: Path = input.parent.resolve(input.toFile().nameWithoutExtension + "-intermediate.jar")
val intermediate2: Path = input.parent.resolve(input.toFile().nameWithoutExtension + "-intermediate2.jar")
val output: Path = this.archiveFile.get().asFile.toPath()
if (addRefmap) {
@@ -69,11 +70,20 @@ open class TransformTask : Jar() {
Files.copy(input, intermediate)
}
Files.deleteIfExists(intermediate2)
project.logger.lifecycle(":transforming " + input.fileName + " => " + intermediate.fileName)
Transform.transform(intermediate, output, transformExpectPlatform(project))
Transform.transform(intermediate, intermediate2, transformExpectPlatform(project))
Files.deleteIfExists(intermediate)
if (project.extensions.getByType(ArchitectPluginExtension::class.java).injectInjectables) {
transformArchitecturyInjectables(intermediate2, output)
} else {
Files.copy(intermediate2, output)
}
Files.deleteIfExists(intermediate2)
if (addRefmap) {
val loomExtension = project.extensions.getByType(LoomGradleExtension::class.java)
if (MixinRefmapHelper.addRefmapName(
@@ -86,4 +96,35 @@ open class TransformTask : Jar() {
}
}
}
private fun transformArchitecturyInjectables(intermediate2: Path, output: Path) {
val remapper = TinyRemapper.newRemapper()
.withMappings { sink ->
sink.acceptClass("me/shedaniel/architectury/targets/ArchitecturyTarget", project.projectUniqueIdentifier() + "/PlatformMethods")
sink.acceptMethod(IMappingProvider.Member(
"me/shedaniel/architectury/targets/ArchitecturyTarget",
"getCurrentTarget",
"()Ljava/lang/String;"
), "getModLoader")
}
.build()
val classpathFiles: Set<File> = LinkedHashSet(
project.configurations.getByName("compileClasspath").files
)
val classpath = classpathFiles.asSequence().map { obj: File -> obj.toPath() }
.filter { p: Path -> this.input.asFile.get().toPath() != p && Files.exists(p) }.toList().toTypedArray()
try {
OutputConsumerPath.Builder(output).build().use { outputConsumer ->
outputConsumer.addNonClassFiles(intermediate2, NonClassCopyMode.UNCHANGED, null)
remapper.readClassPath(*classpath)
remapper.readInputs(intermediate2)
remapper.apply(outputConsumer)
}
} catch (e: Exception) {
remapper.finish()
throw RuntimeException("Failed to remap $intermediate2 to $output", e)
}
}
}