feat: load patches dynamically & use kotlinx.cli

Patches are now loaded dynamically and the CLI now links to the patches library. Also decided to use the CLI library from kotlinx, since that's friendlier than whatever we had before.
This commit is contained in:
Lucaskyy
2022-04-10 22:21:57 +02:00
parent e50071aa61
commit 4624384f28
6 changed files with 156 additions and 26 deletions

View File

@@ -0,0 +1,25 @@
package app.revanced.cli.utils
import java.io.File
import java.net.URL
import java.net.URLClassLoader
class PatchLoader {
companion object {
fun injectPatches(file: File) {
// This function will fail on Java 9 and above.
try {
val url = file.toURI().toURL()
val classLoader = Thread.currentThread().contextClassLoader as URLClassLoader
val method = URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java)
method.isAccessible = true
method.invoke(classLoader, url)
} catch (e: Exception) {
throw Exception(
"Failed to inject patches! The CLI does NOT work on Java 9 and above, please use Java 8!",
e // propagate exception
)
}
}
}
}

View File

@@ -0,0 +1,15 @@
package app.revanced.cli.utils
import app.revanced.patches.Index
class Patches {
companion object {
// You may ask yourself, "why do this?".
// We do it like this, because we don't want the Index class
// to be loaded while the dependency hasn't been injected yet.
// You can see this as "controlled class loading".
// Whenever this class is loaded (because it is invoked), all the imports
// will be loaded too. We don't want to do this until we've injected the class.
fun loadPatches() = Index.patches
}
}

View File

@@ -0,0 +1,24 @@
package app.revanced.cli.utils
import java.io.File
import java.io.FileNotFoundException
class Preconditions {
companion object {
fun isFile(path: String): File {
val f = File(path)
if (!f.exists()) {
throw FileNotFoundException(f.toString())
}
return f
}
fun isDirectory(path: String): File {
val f = isFile(path)
if (!f.isDirectory) {
throw IllegalArgumentException("$f is not a directory")
}
return f
}
}
}

View File

@@ -4,19 +4,15 @@ import app.revanced.patcher.signature.MethodSignature
import com.google.gson.JsonParser
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcodes
import java.io.File
class SignatureParser {
companion object {
fun parse(signatureJsonPath: String): List<MethodSignature> {
val json = File(signatureJsonPath).readText()
fun parse(json: String): List<MethodSignature> {
val signatures = JsonParser.parseString(json).asJsonObject.get("signatures").asJsonArray.map { sig ->
val signature = sig.asJsonObject
val returnType = signature.get("returns").asString
var accessFlags = 0
signature
.get("accessors").asJsonArray
.forEach { accessFlags = accessFlags or AccessFlags.getAccessFlag(it.asString).value }