Datagen insanity, dependency, mixin & AW remapping #4

Merged
owlsys merged 6 commits from owlsys/insanity into mistress 2024-08-27 07:01:05 -04:00
6 changed files with 78 additions and 24 deletions
Showing only changes of commit 64a589abbc - Show all commits

View file

@ -1,6 +1,6 @@
#Sun May 12 17:35:40 BST 2024 #Sun May 12 17:35:40 BST 2024
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -31,7 +31,6 @@ import org.gradle.api.Project
import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Delete
import org.gradle.configurationcache.extensions.capitalized
import org.jetbrains.java.decompiler.main.Fernflower import org.jetbrains.java.decompiler.main.Fernflower
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
@ -44,6 +43,7 @@ import java.nio.file.FileSystems
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import java.util.*
import kotlin.io.path.* import kotlin.io.path.*
@ -94,7 +94,7 @@ class PhytotelmaPlugin : Plugin<Project> {
) )
ModConfigurations.configurations.forEach { conf -> ModConfigurations.configurations.forEach { conf ->
project.configurations.create("mod" + conf.name.capitalized()) { c -> project.configurations.create("mod" + conf.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }) { c ->
c.isCanBeResolved = true c.isCanBeResolved = true
c.isCanBeConsumed = false c.isCanBeConsumed = false
@ -284,7 +284,11 @@ class PhytotelmaPlugin : Plugin<Project> {
val version = ProjectStorage.get(project).minecraftVersion!! val version = ProjectStorage.get(project).minecraftVersion!!
val officialJar = VersionChecker.downloadClient(project, version) val officialJar = VersionChecker.downloadClient(project, version)
ModConfigurations.configurations.forEach { conf -> ModConfigurations.configurations.forEach { conf ->
val artifacts = project.configurations.getByName("mod" + conf.name.capitalized()) val artifacts = project.configurations.getByName("mod" + conf.name.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.getDefault()
) else it.toString()
})
.resolvedConfiguration.resolvedArtifacts .resolvedConfiguration.resolvedArtifacts
if (artifacts.isEmpty()) { if (artifacts.isEmpty()) {
return return
@ -292,17 +296,26 @@ class PhytotelmaPlugin : Plugin<Project> {
if (mojmapGameJar.notExists()) { if (mojmapGameJar.notExists()) {
Thyroxine.run(version, officialJar, mojmapGameJar, true, false) Thyroxine.run(version, officialJar, mojmapGameJar, true, false)
} }
val target = project.configurations.create("mod" + conf.name.capitalized() + "Mapped") { c -> val target = project.configurations.create("mod" + conf.name.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.getDefault()
) else it.toString()
} + "Mapped") { c ->
c.isTransitive = false c.isTransitive = false
conf.classpathNames.forEach { conf.classpathNames.forEach {
project.configurations.getByName(it).extendsFrom(c) project.configurations.getByName(it).extendsFrom(c)
} }
} }
val storage = ProjectStorage.get(project) val storage = ProjectStorage.get(project)
TinyV2Writer.write(storage.mappings!!, TinyV2Writer.write(
project.projectDir.resolve("storageMappings.tiny").writer()) storage.mappings!!,
project.projectDir.resolve("storageMappings.tiny").writer()
)
val officialStore = storage.mappings!!.forNamespaces(storage.targetNamespace!!, "official").reverse() val officialStore = storage.mappings!!.forNamespaces(storage.targetNamespace!!, "official").reverse()
TinyV2Writer.write(MappingBundle(officialStore), project.projectDir.resolve("officialStore.tiny").toPath().writer()) TinyV2Writer.write(
MappingBundle(officialStore),
project.projectDir.resolve("officialStore.tiny").toPath().writer()
)
val mojOfficial = MojmapProvider.get( val mojOfficial = MojmapProvider.get(
storage.minecraftVersion!!, storage.minecraftVersion!!,
globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt") globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
@ -362,7 +375,8 @@ class PhytotelmaPlugin : Plugin<Project> {
project.dependencies.add( project.dependencies.add(
target.name, target.name,
"dev.frogmc.phytotelma.remapped_mods:$groupname:$artifactVersion" + (classifier?.let { ":$it" } ?: "") "dev.frogmc.phytotelma.remapped_mods:$groupname:$artifactVersion" + (classifier?.let { ":$it" }
?: "")
) )
} }
Files.deleteIfExists(mojmapGameJar) Files.deleteIfExists(mojmapGameJar)

View file

@ -24,7 +24,7 @@ object ProjectStorage {
.setPrettyPrinting() .setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(ProjectData::class.java, ProjectDataTypeAdapter()) .registerTypeAdapter(ProjectData::class.java, ProjectDataTypeAdapter())
.registerTypeAdapter(MappingBundle::class.java, MappingBundleTypeAdapter()) //.registerTypeAdapter(MappingBundle::class.java, MappingBundleTypeAdapter())
.create() .create()
fun get(project: Project): ProjectData { fun get(project: Project): ProjectData {
@ -87,8 +87,8 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
out.name("local_cache_dir").value(value.localCacheDir?.absolutePathString()) out.name("local_cache_dir").value(value.localCacheDir?.absolutePathString())
out.name("minecraft_version").value(value.minecraftVersion) out.name("minecraft_version").value(value.minecraftVersion)
out.name("remapped_game_jar_path").value(value.remappedGameJarPath?.absolutePathString()) out.name("remapped_game_jar_path").value(value.remappedGameJarPath?.absolutePathString())
out.name("mappings") /*out.name("mappings")
value.mappings?.let { MappingBundleTypeAdapter().write(out, it) }?:out.nullValue() value.mappings?.let { MappingBundleTypeAdapter().write(out, it) }?:out.nullValue()*/
out.name("mappings_name").value(value.mappingsName) out.name("mappings_name").value(value.mappingsName)
out.name("target_namespace").value(value.targetNamespace) out.name("target_namespace").value(value.targetNamespace)
out.endObject() out.endObject()
@ -122,8 +122,8 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
data.targetNamespace = value data.targetNamespace = value
} }
} }
} else if (name == "mappings") { /*} else if (name == "mappings") {
data.mappings = MappingBundleTypeAdapter().read(r) data.mappings = MappingBundleTypeAdapter().read(r)*/
} else { } else {
r.skipValue() r.skipValue()
} }
@ -134,7 +134,7 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
} }
class MappingBundleTypeAdapter : TypeAdapter<MappingBundle>() { /*class MappingBundleTypeAdapter : TypeAdapter<MappingBundle>() {
override fun write(out: JsonWriter, value: MappingBundle) { override fun write(out: JsonWriter, value: MappingBundle) {
out.beginObject() out.beginObject()
out.name("data").beginArray() out.name("data").beginArray()
@ -387,4 +387,4 @@ class MappingBundleTypeAdapter : TypeAdapter<MappingBundle>() {
return MappingData(srcNs, dstNs, classes, methods, fields, parameters) return MappingData(srcNs, dstNs, classes, methods, fields, parameters)
} }
} }*/

View file

@ -5,6 +5,7 @@ import dev.frogmc.phytotelma.Constants
import org.objectweb.asm.* import org.objectweb.asm.*
import org.objectweb.asm.commons.AnnotationRemapper import org.objectweb.asm.commons.AnnotationRemapper
import org.objectweb.asm.commons.ClassRemapper import org.objectweb.asm.commons.ClassRemapper
import org.objectweb.asm.commons.FieldRemapper
import org.objectweb.asm.commons.MethodRemapper import org.objectweb.asm.commons.MethodRemapper
import org.objectweb.asm.commons.Remapper import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.ClassNode
@ -22,6 +23,17 @@ class MixinAnnotationRemapper(
private var target: String? = null private var target: String? = null
private var targetNode: ClassNode? = null private var targetNode: ClassNode? = null
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
}
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? { override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? {
if (descriptor == null || descriptor != "Lorg/spongepowered/asm/mixin/Mixin;") { if (descriptor == null || descriptor != "Lorg/spongepowered/asm/mixin/Mixin;") {
return super.visitAnnotation(descriptor, visible) return super.visitAnnotation(descriptor, visible)
@ -85,13 +97,36 @@ class MixinAnnotationRemapper(
signature: String?, signature: String?,
exceptions: Array<out String>? exceptions: Array<out String>?
): MethodVisitor? { ): MethodVisitor? {
return super.visitMethod(access, name, descriptor, signature, exceptions)?.let { val newMethodName = target?.let { mapper.mapMethodName(it, name, descriptor) }?: name
return super.visitMethod(access, newMethodName, descriptor, signature, exceptions)?.let {
if (targetNode != null) { if (targetNode != null) {
MixinMethodVisitor(it, mapper, targetNode!!) MixinMethodVisitor(it, mapper, targetNode!!)
} else it } else it
} }
} }
override fun visitField(
access: Int,
name: String?,
descriptor: String?,
signature: String?,
value: Any?
): FieldVisitor? {
val newFieldName = target?.let { mapper.mapFieldName(it, name, descriptor) }?:name
return super.visitField(access, newFieldName, descriptor, signature, value)?.let {
if (targetNode != null) {
MixinFieldVisitor(it, mapper, targetNode!!)
} else it
}
}
class MixinFieldVisitor(fv: FieldVisitor, private val mapper: Remapper, private val targetNode: ClassNode) :
FieldRemapper(Constants.ASM_VERSION, fv, mapper) {
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor {
return MixinAnnotationVisitor(super.visitAnnotation(descriptor, visible), descriptor!!, mapper, targetNode)
}
}
class MixinMethodVisitor(mv: MethodVisitor, private val mapper: Remapper, private val targetNode: ClassNode) : class MixinMethodVisitor(mv: MethodVisitor, private val mapper: Remapper, private val targetNode: ClassNode) :
MethodRemapper(Constants.ASM_VERSION, mv, mapper) { MethodRemapper(Constants.ASM_VERSION, mv, mapper) {
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor { override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor {
@ -136,6 +171,11 @@ class MixinAnnotationRemapper(
if (field != null) { if (field != null) {
newVal = mapper.mapFieldName(owner.name, value, field.desc) newVal = mapper.mapFieldName(owner.name, value, field.desc)
} }
} else if (name == "aliases") {
val field = owner.fields.find { it.name == value }
if (field != null) {
newVal = mapper.mapFieldName(owner.name, value, field.desc)
}
} else if (name == "method") { } else if (name == "method") {
val methodName = value.substringBefore("(") val methodName = value.substringBefore("(")
val desc = value.indexOf("(").takeIf { it > -1 }?.let(value::substring) val desc = value.indexOf("(").takeIf { it > -1 }?.let(value::substring)

View file

@ -23,15 +23,14 @@ object Datagen {
abstract class DatagenTask @Inject constructor(conf: DatagenExtension) : RunGameTask(Env.SERVER) { abstract class DatagenTask @Inject constructor(conf: DatagenExtension) : RunGameTask(Env.SERVER) {
init { init {
val output = project.extensions.findByType(JavaPluginExtension::class.java)?.sourceSets?.maybeCreate(
"generated"
)?.resources?.srcDirs?.first()?.toString()
jvmArguments.addAll( jvmArguments.addAll(
"-Dfrog.datagen.enabled=true", "-Dfrog.datagen.enabled=true",
"-Dfrog.datagen.modid=${Datagen.readModId(project)}", "-Dfrog.datagen.modid=${Datagen.readModId(project)}",
"-Dfrog.datagen.generator=${conf.generatorClass.get()}", "-Dfrog.datagen.generator=${conf.generatorClass.get()}",
"-Dfrog.datagen.output=${ "-Dfrog.datagen.output=${output}"
project.extensions.findByType(JavaPluginExtension::class.java)?.sourceSets?.maybeCreate(
"generated"
)?.resources?.srcDirs?.first()?.toString()
}"
) )
} }
} }

View file

@ -74,6 +74,7 @@ abstract class RunGameTask @Inject constructor(env: Env) : JavaExec() {
} }
mainClass.set("dev.frogmc.frogloader.impl.launch.${env.id}.Frog${env.pascalName}") mainClass.set("dev.frogmc.frogloader.impl.launch.${env.id}.Frog${env.pascalName}")
setStandardInput(System.`in`)
} }
private fun writeArgFile(): String { private fun writeArgFile(): String {