aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-03-10 20:13:43 +0100
committernea <nea@nea.moe>2023-03-10 20:13:43 +0100
commitd0dd7dafbaccb79f1ecaa574b85dcbb648d35128 (patch)
tree156e8a2fb1cad9c89ad0f44cbc9a6bc08214b0d3
parentb8a858f0911f097eb557277d07b3568b7ec65789 (diff)
downloadmcprepack-d0dd7dafbaccb79f1ecaa574b85dcbb648d35128.tar.gz
mcprepack-d0dd7dafbaccb79f1ecaa574b85dcbb648d35128.tar.bz2
mcprepack-d0dd7dafbaccb79f1ecaa574b85dcbb648d35128.zip
Proguard log
-rw-r--r--src/main/kotlin/mcprepack/App.kt73
-rw-r--r--src/main/kotlin/mcprepack/CSVFile.kt1
-rw-r--r--src/main/kotlin/mcprepack/ParseMethodDescriptor.kt112
-rw-r--r--src/main/kotlin/mcprepack/ProguardWriter.kt35
4 files changed, 209 insertions, 12 deletions
diff --git a/src/main/kotlin/mcprepack/App.kt b/src/main/kotlin/mcprepack/App.kt
index 86764e0..688716b 100644
--- a/src/main/kotlin/mcprepack/App.kt
+++ b/src/main/kotlin/mcprepack/App.kt
@@ -110,7 +110,7 @@ fun main(): Unit = lifecycle("Repacking") {
val newTiny =
TinyFile(TinyHeader(listOf("official", "intermediary", "named"), 2, 0, mapOf()), tinyFile.classEntries.map {
TinyClass(it.classNames + listOf(it.classNames[1]), it.methods.map { method ->
- val mcpMethod = methods.map.find { it["searge"] == method.methodNames[1] }
+ val mcpMethod = methods.indexedBySearge[method.methodNames[1]]
TinyMethod(method.methodDescriptorInFirstNamespace,
method.methodNames + listOf(mcpMethod?.get("name") ?: method.methodNames[1]),
method.parameters,
@@ -118,7 +118,7 @@ fun main(): Unit = lifecycle("Repacking") {
method.comments + (mcpMethod?.get("desc")?.let { listOf(it) } ?: listOf()))
// TODO parameter names and better comments?
}, it.fields.map { field ->
- val mcpField = fields.map.find { it["searge"] == field.fieldNames[1] }
+ val mcpField = fields.indexedBySearge[field.fieldNames[1]]
TinyField(findFieldDescriptorInMergedJar(it.classNames[0], field.fieldNames[0]),
field.fieldNames + listOf(mcpField?.get("name") ?: field.fieldNames[1]),
field.comments + (mcpField?.get("desc")?.let { listOf(it) } ?: listOf()))
@@ -154,7 +154,7 @@ fun main(): Unit = lifecycle("Repacking") {
// TODO merge binpatches somehow? not sure how that would work, maybe look at essential loom
fun createBinPatchSubJar(dist: String): Path {
- val basePath = binpatchesLegacy.getPath("binpatch/client")
+ val basePath = binpatchesLegacy.getPath("binpatch/$dist")
val modernPatchJar = WorkContext.file("binpatches-modern", "jar")
modernPatchJar.deleteExisting()
val patchJarFs = FileSystems.newFileSystem(modernPatchJar, mapOf("create" to true))
@@ -180,6 +180,35 @@ fun main(): Unit = lifecycle("Repacking") {
createBinPatchSubJar("server")
}
+ val proguardLog = lifecycle("Create Proguard Obfuscation Log") {
+ val x = WorkContext.file("proguard", "txt")
+ x.bufferedWriter().use {
+ val pro = ProguardWriter(it)
+ val tinyFile = TinyV2Reader.read(tinyV2Enhanced)
+ tinyFile.classEntries.forEach { tinyClass ->
+ pro.visitClass(tinyClass.classNames[2], tinyClass.classNames[0])
+ tinyClass.fields.forEach { field ->
+ val fd = FieldDescriptor.parseFieldDescriptor(field.fieldDescriptorInFirstNamespace)
+ pro.visitField(
+ field.fieldNames[2],
+ field.fieldNames[0],
+ fd.type.mapClassName(tinyFile).toProguardString()
+ )
+ }
+ tinyClass.methods.forEach { method ->
+ val md = MethodDescriptor.parseMethodDescriptor(method.methodDescriptorInFirstNamespace)
+ pro.visitMethod(
+ method.methodNames[2], method.methodNames[0],
+ md.arguments.map { it.mapClassName(tinyFile) }
+ .map { it.toProguardString() },
+ md.returnType.mapClassName(tinyFile).toProguardString()
+ )
+ }
+ }
+ }
+ x
+ }
+
val modernForgeInstaller = lifecycle("Create Modern Forge Installer") {
val x = WorkContext.file("modern-forge-installer", "jar")
x.deleteExisting()
@@ -221,17 +250,42 @@ fun main(): Unit = lifecycle("Repacking") {
})
})
addProperty("universal", "net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9:universal@jar")
- addProperty("sources", "net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9:sources@jar")
+ addProperty("sources", "net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9:universal@jar")
addProperty("spec", 2)//Hahaha, yes, I follow the spec, so true
add("libraries", JsonArray().apply {
legacyDevJson["libraries"].asJsonArray.forEach {
add(it.asJsonObject["name"])
}
})
+ add("runs", JsonObject().apply {
+ add("client", JsonObject().apply {
+ addProperty("name", "client")
+ addProperty("main", "net.minecraft.launchwrapper.Launch")
+ add("parents", JsonArray())
+ add("args", JsonArray().apply {
+ add("--accessToken")
+ add("undefined")
+ add("--assetsIndex")
+ add("{assets_index}")
+ add("--assetsDir")
+ add("{assets_root}")
+ add("--tweakClass")
+ add("net.minecraftforge.fml.common.launcher.FMLTweaker")
+ })
+ add("jvmArgs", JsonArray())
+ addProperty("client", true)
+ addProperty("forceExit", true)
+ add("env", JsonObject())
+ add("props", JsonObject())
+ })
+ })
+ addProperty("spec", 2)
}))
userdevModern.getPath("/joined.lzma").outputStream().use {
binpatchesModernClient.inputStream().copyTo(LzmaOutputStream(it, Encoder()))
}
+ userdevModern.getPath("/META-INF").createDirectories()
+ legacyForgeUniversal.getPath("forge_at.cfg").copyTo(userdevModern.getPath("/META-INF/accesstransformer.cfg"))
userdevModern.close()
x
}
@@ -243,7 +297,7 @@ fun main(): Unit = lifecycle("Repacking") {
mcpConfigModern.getPath("config.json").writeText(gson.toJson(JsonObject().apply {
addProperty("spec", 3)
addProperty("version", "1.8.9")
- addProperty("official", false)
+ addProperty("official", true)
addProperty("encoding", "UTF-8")
add("data", JsonObject().apply {
addProperty("mappings", "config/joined.tsrg")
@@ -261,13 +315,6 @@ fun main(): Unit = lifecycle("Repacking") {
addProperty("version", "1.8.9")
addProperty("name", "rename")
})
- /*
- add(JsonObject().apply {
- addProperty("type", "rename")
- addProperty("input", "{mergeOutput}")// TODO maybe strip? honestly not sure
- addProperty("libraries", "{listLibrariesOutput}")
- addProperty("mappings", "{mappings}")
- })*/
})
for (dist in listOf("client", "server")) {
add(dist, JsonArray().apply {
@@ -361,6 +408,8 @@ fun main(): Unit = lifecycle("Repacking") {
modernForgeUserdev.copyTo(mavenFile("forge", "jar", "userdev"))
modernForgeUserdev.copyTo(mavenFile("forge", "jar"))
modernForgeInstaller.copyTo(mavenFile("forge", "jar", "installer"))
+
+ proguardLog.copyTo(mavenFile("official", "txt"))
}
}
diff --git a/src/main/kotlin/mcprepack/CSVFile.kt b/src/main/kotlin/mcprepack/CSVFile.kt
index 6463fc7..1ddc03f 100644
--- a/src/main/kotlin/mcprepack/CSVFile.kt
+++ b/src/main/kotlin/mcprepack/CSVFile.kt
@@ -2,4 +2,5 @@ package mcprepack
data class CSVFile(val headers: List<String>, val entries: List<List<String>>) {
val map = entries.map { headers.zip(it).toMap() }
+ val indexedBySearge = map.associateBy { it["searge"] }
}
diff --git a/src/main/kotlin/mcprepack/ParseMethodDescriptor.kt b/src/main/kotlin/mcprepack/ParseMethodDescriptor.kt
new file mode 100644
index 0000000..a3d5717
--- /dev/null
+++ b/src/main/kotlin/mcprepack/ParseMethodDescriptor.kt
@@ -0,0 +1,112 @@
+package mcprepack
+
+import net.fabricmc.stitch.commands.tinyv2.TinyFile
+import java.io.StringReader
+
+sealed interface TypeDescriptor {
+ fun mapClassName(tinyFile: TinyFile): TypeDescriptor {
+ return when (this) {
+ is Class ->
+ Class(tinyFile.mapClassesByFirstNamespace()[this.name]?.classNames?.get(2) ?: this.name)
+
+ else -> this
+ }
+ }
+
+ fun toProguardString(): String {
+ return when (this) {
+ is Array -> this.elementType.toProguardString() + "[]"
+ Boolean -> "boolean"
+ Byte -> "byte"
+ Char -> "char"
+ is Class -> this.name.replace("/", ".")
+ Double -> "double"
+ Float -> "float"
+ Int -> "int"
+ Long -> "long"
+ Short -> "short"
+ Void -> "void"
+ }
+ }
+
+ sealed interface FieldDescriptor : TypeDescriptor
+ object Void : TypeDescriptor
+ object Double : FieldDescriptor
+ object Boolean : FieldDescriptor
+ object Float : FieldDescriptor
+ object Int : FieldDescriptor
+ object Long : FieldDescriptor
+ object Short : FieldDescriptor
+ object Byte : FieldDescriptor
+ object Char : FieldDescriptor
+ data class Class(val name: String) : FieldDescriptor
+ data class Array(val elementType: TypeDescriptor) : FieldDescriptor
+}
+
+data class FieldDescriptor(
+ val type: TypeDescriptor.FieldDescriptor
+) {
+ companion object {
+ fun parseFieldDescriptor(descriptor: String) =
+ FieldDescriptor(readType(StringReader(descriptor)) as? TypeDescriptor.FieldDescriptor ?: error("Cannot have void as a field type"))
+ }
+}
+
+data class MethodDescriptor(
+ val arguments: List<TypeDescriptor.FieldDescriptor>,
+ val returnType: TypeDescriptor
+) {
+ companion object {
+ fun parseMethodDescriptor(descriptor: String): MethodDescriptor {
+ val reader = StringReader(descriptor)
+ require(reader.readChar() == '(')
+ val arguments = mutableListOf<TypeDescriptor.FieldDescriptor>()
+ while (reader.peek() != ')') {
+ arguments.add(
+ readType(reader) as? TypeDescriptor.FieldDescriptor ?: error("Cannot have void type as argument")
+ )
+ }
+ reader.readChar() // Consume the ')'
+ return MethodDescriptor(arguments, readType(reader))
+ }
+ }
+}
+
+fun StringReader.readChar() = CharArray(1).let {
+ if (read(it) < 0) null
+ else it[0]
+}
+
+fun StringReader.readUntil(search: Char): String? {
+ val s = StringBuilder()
+ while (true) {
+ val justRead = readChar() ?: return null
+ if (justRead == search) return s.toString()
+ s.append(justRead)
+ }
+}
+
+fun StringReader.peek(): Char? {
+ mark(0)
+ val x = readChar()
+ reset()
+ return x
+}
+
+
+fun readType(reader: StringReader): TypeDescriptor {
+ return when (reader.readChar()) {
+ 'L' -> TypeDescriptor.Class(reader.readUntil(';') ?: error("Unfinished class type descriptor"))
+ 'V' -> TypeDescriptor.Void
+ 'Z' -> TypeDescriptor.Boolean
+ 'B' -> TypeDescriptor.Byte
+ 'I' -> TypeDescriptor.Int
+ 'D' -> TypeDescriptor.Double
+ 'J' -> TypeDescriptor.Long
+ 'S' -> TypeDescriptor.Short
+ 'F' -> TypeDescriptor.Float
+ 'C' -> TypeDescriptor.Char
+ '[' -> TypeDescriptor.Array(readType(reader))
+ else -> error("Unknown or unfinished type descriptor")
+ }
+}
diff --git a/src/main/kotlin/mcprepack/ProguardWriter.kt b/src/main/kotlin/mcprepack/ProguardWriter.kt
new file mode 100644
index 0000000..64d84f8
--- /dev/null
+++ b/src/main/kotlin/mcprepack/ProguardWriter.kt
@@ -0,0 +1,35 @@
+package mcprepack
+
+import java.io.Writer
+
+data class ProguardWriter(val writer: Writer) {
+ fun visitClass(sourceName: String, targetName: String) {
+ writer.write(sourceName)
+ writer.write(" -> ")
+ writer.write(targetName)
+ writer.write(":\n")
+ }
+
+ fun visitField(sourceName: String, targetName: String, proguardType: String) {
+ writer.write(" ")
+ writer.write(proguardType)
+ writer.write(" ")
+ writer.write(sourceName)
+ writer.write(" -> ")
+ writer.write(targetName)
+ writer.write("\n")
+ }
+
+ fun visitMethod(sourceName: String, targetName: String, arguments: List<String>, returnType: String) {
+ writer.write(" ")
+ writer.write(returnType)
+ writer.write(" ")
+ writer.write(sourceName)
+ writer.write("(")
+ writer.write(arguments.joinToString(","))
+ writer.write(") -> ")
+ writer.write(targetName)
+ writer.write("\n")
+ }
+
+} \ No newline at end of file