Datagen insanity, dependency, mixin & AW remapping #4
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -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
|
||||||
|
|
|
@ -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!!,
|
||||||
val officialStore = storage.mappings!!.forNamespaces(storage.targetNamespace!!, "official").reverse()
|
project.projectDir.resolve("storageMappings.tiny").writer()
|
||||||
TinyV2Writer.write(MappingBundle(officialStore), project.projectDir.resolve("officialStore.tiny").toPath().writer())
|
)
|
||||||
|
val officialStore = storage.mappings!!.forNamespaces(storage.targetNamespace!!, "official").reverse()
|
||||||
|
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")
|
||||||
|
@ -334,7 +347,7 @@ class PhytotelmaPlugin : Plugin<Project> {
|
||||||
)
|
)
|
||||||
remappedPaths.add(pom)
|
remappedPaths.add(pom)
|
||||||
|
|
||||||
val temp = remappedPath.resolveSibling(remappedPath.fileName.toString()+".tmp")
|
val temp = remappedPath.resolveSibling(remappedPath.fileName.toString() + ".tmp")
|
||||||
Thyroxine.remap(
|
Thyroxine.remap(
|
||||||
mojOfficial, artifact.file.toPath(), temp, false, defaultRemappingSteps(
|
mojOfficial, artifact.file.toPath(), temp, false, defaultRemappingSteps(
|
||||||
mojmapGameJar
|
mojmapGameJar
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
|
||||||
}"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue