remap transitive AWs if necessary and AW remapping/validation
This commit is contained in:
parent
7a2f8aefb0
commit
e54543b2b7
|
@ -7,7 +7,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "dev.frogmc"
|
||||
version = "0.0.1-alpha.15"
|
||||
version = "0.0.1-alpha.16"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
|
@ -24,7 +24,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation("dev.frogmc:thyroxine:0.0.1-alpha.9")
|
||||
implementation("dev.frogmc:thyroxine:0.0.1-alpha.10")
|
||||
implementation("org.ow2.asm:asm:9.7")
|
||||
implementation("org.ow2.asm:asm-commons:9.7")
|
||||
implementation("org.ow2.asm:asm-tree:9.7")
|
||||
|
|
|
@ -22,6 +22,7 @@ import dev.frogmc.thyroxine.RemappingStep
|
|||
import dev.frogmc.thyroxine.Thyroxine
|
||||
import dev.frogmc.thyroxine.api.Mapper
|
||||
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||
import dev.frogmc.thyroxine.api.data.MappingData
|
||||
import dev.frogmc.thyroxine.provider.MojmapProvider
|
||||
import dev.frogmc.thyroxine.writer.tiny.TinyV2Writer
|
||||
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
||||
|
@ -225,40 +226,7 @@ class PhytotelmaPlugin : Plugin<Project> {
|
|||
.get<String>("frog.extensions.accesswidener")?.let { name ->
|
||||
val aw = metadata.resolveSibling(name)
|
||||
AccessWidener.checkAW(aw, ProjectStorage.get(project).remappedGameJarPath!!)
|
||||
val mapper = Mapper(mappings) { listOf() }
|
||||
val buffer = buildString {
|
||||
aw.forEachLine {
|
||||
if (it.contains("\\t") && !it.startsWith("#")) {
|
||||
val parts = it.split("[\\t #]+".toRegex()).toMutableList()
|
||||
|
||||
if (parts.size > 2) {
|
||||
|
||||
val type = parts[1]
|
||||
when (type) {
|
||||
"class" -> {
|
||||
parts[2] = mapper.map(parts[2])
|
||||
}
|
||||
|
||||
"fields" -> {
|
||||
parts[3] = mapper.mapFieldName(parts[2], parts[3], parts[4])
|
||||
parts[4] = mapper.mapDesc(parts[4])
|
||||
parts[3] = mapper.map(parts[2])
|
||||
}
|
||||
|
||||
"methods" -> {
|
||||
parts[3] = mapper.mapMethodName(parts[2], parts[3], parts[4])
|
||||
parts[4] = mapper.mapMethodDesc(parts[4])
|
||||
parts[2] = mapper.map(parts[2])
|
||||
}
|
||||
}
|
||||
appendLine(parts.joinToString("\\t"))
|
||||
return@forEachLine
|
||||
}
|
||||
}
|
||||
appendLine(it)
|
||||
}
|
||||
}
|
||||
aw.writeText(buffer)
|
||||
remapAccesswidener(mappings, aw)
|
||||
}
|
||||
}
|
||||
Thyroxine.remap(
|
||||
|
@ -328,13 +296,11 @@ class PhytotelmaPlugin : Plugin<Project> {
|
|||
TinyV2Writer.write(storage.mappings!!,
|
||||
project.projectDir.resolve("storageMappings.tiny").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(
|
||||
storage.minecraftVersion!!,
|
||||
globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
||||
).orElseThrow().reverse().renameDstNamespace(Constants.MOJMAP_NAMESPACE).also {
|
||||
TinyV2Writer.write(it,
|
||||
project.projectDir.resolve("mojmap.tiny").writer())
|
||||
}.data[0].reverse()
|
||||
).orElseThrow().reverse().renameDstNamespace(Constants.MOJMAP_NAMESPACE).data[0].reverse()
|
||||
val targetPath = project.layout.buildDirectory.asFile.get().toPath().resolve("remappedMods")
|
||||
.resolve("dev/frogmc/phytotelma/remapped_mods")
|
||||
val remappedPaths = mutableListOf<Path>()
|
||||
|
@ -366,16 +332,28 @@ class PhytotelmaPlugin : Plugin<Project> {
|
|||
Thyroxine.remap(
|
||||
mojOfficial, artifact.file.toPath(), temp, false, defaultRemappingSteps(
|
||||
mojmapGameJar
|
||||
)
|
||||
), mojmapGameJar
|
||||
)
|
||||
Thyroxine.remap(
|
||||
officialStore, temp, remappedPath, false, defaultRemappingSteps(
|
||||
officialJar
|
||||
)
|
||||
), officialJar
|
||||
)
|
||||
Files.deleteIfExists(temp)
|
||||
NestStripper.stripJij(remappedPath)
|
||||
|
||||
FileSystems.newFileSystem(remappedPath).use { fs ->
|
||||
val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
|
||||
tomlParser.parse(metadata, FileNotFoundAction.READ_NOTHING)
|
||||
.get<String>("frog.extensions.accesswidener")?.let { name ->
|
||||
val aw = metadata.resolveSibling(name)
|
||||
remapAccesswidener(mojOfficial, aw)
|
||||
remapAccesswidener(officialStore, aw)
|
||||
|
||||
AccessWidener.checkAW(aw, ProjectStorage.get(project).remappedGameJarPath!!)
|
||||
}
|
||||
}
|
||||
|
||||
project.dependencies.add(
|
||||
target.name,
|
||||
"dev.frogmc.phytotelma.remapped_mods:$groupname:$artifactVersion" + (classifier?.let { ":$it" } ?: "")
|
||||
|
@ -386,6 +364,43 @@ class PhytotelmaPlugin : Plugin<Project> {
|
|||
System.setOut(out)
|
||||
}
|
||||
|
||||
private fun remapAccesswidener(mappings: MappingData, aw: Path) {
|
||||
val mapper = Mapper(mappings) { listOf() }
|
||||
val buffer = buildString {
|
||||
aw.forEachLine {
|
||||
if ((it.contains("\t") || it.contains(" ")) && !it.startsWith("#")) {
|
||||
val parts = it.split("[\\t #]+".toRegex()).toMutableList()
|
||||
|
||||
if (parts.size > 2) {
|
||||
|
||||
val type = parts[1]
|
||||
when (type) {
|
||||
"class" -> {
|
||||
parts[2] = mapper.map(parts[2])
|
||||
}
|
||||
|
||||
"field" -> {
|
||||
parts[3] = mapper.mapFieldName(parts[2], parts[3], parts[4])
|
||||
parts[4] = mapper.mapDesc(parts[4])
|
||||
parts[2] = mapper.map(parts[2])
|
||||
}
|
||||
|
||||
"method" -> {
|
||||
parts[3] = mapper.mapMethodName(parts[2], parts[3], parts[4])
|
||||
parts[4] = mapper.mapMethodDesc(parts[4])
|
||||
parts[2] = mapper.map(parts[2])
|
||||
}
|
||||
}
|
||||
appendLine(parts.joinToString(" "))
|
||||
return@forEachLine
|
||||
}
|
||||
}
|
||||
appendLine(it)
|
||||
}
|
||||
}
|
||||
aw.writeText(buffer)
|
||||
}
|
||||
|
||||
companion object {
|
||||
lateinit var globalCacheDir: Path
|
||||
val tomlParser = TomlParser()
|
||||
|
|
|
@ -81,7 +81,7 @@ object AccessWidener {
|
|||
}
|
||||
FileSystems.newFileSystem(gamePath).use { fs ->
|
||||
reader.lines().toList().forEachIndexed { index, line ->
|
||||
val checkString = line.substring(0, line.indexOf("#"))
|
||||
val checkString = if (line.contains("#")) line.substring(0, line.indexOf("#")) else line
|
||||
|
||||
if (checkString.isNotEmpty()) {
|
||||
val parts = checkString.split(SEPARATOR)
|
||||
|
@ -90,9 +90,10 @@ object AccessWidener {
|
|||
}
|
||||
if (parts[1] == "class") {
|
||||
val target = parts[2]
|
||||
if (fs.getPath(target).notExists()) {
|
||||
if (fs.getPath("/$target.class").notExists()) {
|
||||
error("AccessWidener validation failed in line ${index + 2}: $line (Invalid target)")
|
||||
}
|
||||
return@forEachIndexed
|
||||
}
|
||||
if (parts.size < 5) {
|
||||
error("AccessWidener validation failed in line ${index + 2}: $line (Declaration missing)")
|
||||
|
@ -102,16 +103,17 @@ object AccessWidener {
|
|||
val desc = parts[4]
|
||||
when (parts[1]) {
|
||||
"method" -> {
|
||||
val classReader = ClassReader(fs.getPath(owner).readBytes())
|
||||
val classReader = ClassReader(fs.getPath("/$owner.class").readBytes())
|
||||
val node = ClassNode()
|
||||
classReader.accept(node, 0)
|
||||
if (node.methods.none { it.name.equals(name) && it.desc.equals(desc) }) {
|
||||
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target method)")
|
||||
val similar = "\nSimilar methods:\n ${node.methods.filter { it.name.equals(name) || it.desc.equals(desc) }.joinToString("\n") { it.name+" ${it.desc}" }}"
|
||||
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target method)"+ if (node.methods.any { it.name.equals(name) || it.desc.equals(desc) }) similar else "")
|
||||
}
|
||||
}
|
||||
|
||||
"field" -> {
|
||||
val classReader = ClassReader(fs.getPath(owner).readBytes())
|
||||
val classReader = ClassReader(fs.getPath("/$owner.class").readBytes())
|
||||
val node = ClassNode()
|
||||
classReader.accept(node, 0)
|
||||
if (node.fields.none { it.name.equals(name) && it.desc.equals(desc) }) {
|
||||
|
@ -136,7 +138,8 @@ object AccessWidener {
|
|||
|
||||
private fun readTransitiveAW(path: Path): List<String> {
|
||||
return path.bufferedReader(StandardCharsets.UTF_8).takeIf { HEADER.test(it.readLine() ?: "") }?.lines()
|
||||
?.filter { it.startsWith("transitive-") }?.toList() ?: emptyList()
|
||||
?.filter { it.startsWith("transitive-") }
|
||||
?.map { it.replace("transitive-", "") }?.toList() ?: emptyList()
|
||||
}
|
||||
|
||||
private fun readAllAWs(project: Project): Stream<Entry> {
|
||||
|
|
|
@ -22,21 +22,6 @@ class MixinAnnotationRemapper(
|
|||
private var target: String? = 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 visitInnerClass(name: String?, outerName: String?, innerName: String?, access: Int) {
|
||||
super.visitInnerClass(name, outerName, innerName, access)
|
||||
}
|
||||
|
||||
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? {
|
||||
if (descriptor == null || descriptor != "Lorg/spongepowered/asm/mixin/Mixin;") {
|
||||
return super.visitAnnotation(descriptor, visible)
|
||||
|
@ -157,29 +142,26 @@ class MixinAnnotationRemapper(
|
|||
if (desc == null) {
|
||||
val method = owner.methods.find { it.name == methodName }
|
||||
if (method != null) {
|
||||
newVal = mapper.mapMethodName(
|
||||
val newName = mapper.mapMethodName(
|
||||
owner.name,
|
||||
methodName,
|
||||
method.desc
|
||||
) + mapper.mapMethodDesc(method.desc)
|
||||
println("Mapped mixin target (method) to new name: $newVal from $methodName (with found ${method.desc})")
|
||||
)
|
||||
newVal = newName + mapper.mapMethodDesc(method.desc)
|
||||
}
|
||||
} else {
|
||||
newVal = mapper.mapMethodName(
|
||||
val newName = mapper.mapMethodName(
|
||||
owner.name,
|
||||
methodName,
|
||||
desc
|
||||
) + mapper.mapMethodDesc(desc)
|
||||
)
|
||||
newVal = newName + mapper.mapMethodDesc(desc)
|
||||
}
|
||||
|
||||
} else if (name == "target") {
|
||||
newVal = remapMemberInfo(value, mapper)
|
||||
println("target remap: $value to $newVal")
|
||||
}
|
||||
}
|
||||
if (newVal != value) {
|
||||
println("new annotation value: $newVal instead of $value")
|
||||
}
|
||||
super.visit(name, newVal)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue