diff --git a/build.gradle.kts b/build.gradle.kts index 2a133216..ef4cbf56 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ plugins { kotlin("jvm") version "1.8.20" + alias(libs.plugins.ksp) } group = "app.revanced" @@ -25,16 +26,17 @@ repositories { } dependencies { - implementation("app.revanced:revanced-patcher:14.2.1") - implementation("com.android.tools.smali:smali:3.0.3") - // Required because build fails without it. - // TODO: Find a way to remove this dependency. - implementation("com.google.guava:guava:32.1.2-jre") + implementation(libs.revanced.patcher) + implementation(libs.smali) + implementation(libs.revanced.patch.annotation.processor) + // TODO: Required because build fails without it. Find a way to remove this dependency. + implementation(libs.guava) // Used in JsonGenerator. - implementation("com.google.code.gson:gson:2.10.1") - // A dependency to the Android library unfortunately fails the build, - // which is why this is required for the patch change-oauth-client-id. + implementation(libs.gson) + // A dependency to the Android library unfortunately fails the build, which is why this is required. compileOnly(project("dummy")) + + ksp(libs.revanced.patch.annotation.processor) } kotlin { @@ -63,6 +65,7 @@ tasks { } } } + register("generateMeta") { description = "Generate metadata for this bundle" dependsOn(build) @@ -70,6 +73,7 @@ tasks { classpath = sourceSets["main"].runtimeClasspath mainClass.set("app.revanced.meta.PatchesFileGenerator") } + // Dummy task to fix the Gradle semantic-release plugin. // Remove this if you forked it to support building only. // Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..5673b992 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,17 @@ +[versions] +revanced-patcher = "15.0.1" +revanced-patch-annotation-processor = "15.0.1" +ksp = "1.9.0-1.0.11" +smali = "3.0.3" +guava = "32.1.2-jre" +gson = "2.10.1" + +[libraries] +revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" } +revanced-patch-annotation-processor = { module = "app.revanced:revanced-patch-annotation-processor", version.ref = "revanced-patch-annotation-processor" } +smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } +gson = { module = "com.google.code.gson:gson", version.ref = "gson" } + +[plugins] +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt index 226f4b14..0a00f5dd 100644 --- a/src/main/kotlin/app/revanced/extensions/Extensions.kt +++ b/src/main/kotlin/app/revanced/extensions/Extensions.kt @@ -2,12 +2,11 @@ package app.revanced.extensions import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch +import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction @@ -20,7 +19,7 @@ import org.w3c.dom.Node * @return The [PatchException]. */ val MethodFingerprint.exception - get() = PatchException("Failed to resolve $name") + get() = PatchException("Failed to resolve ${this.javaClass.simpleName}") /** * Find the [MutableMethod] from a given [Method] in a [MutableClass]. @@ -77,22 +76,21 @@ fun Method.findIndexForIdResource(resourceName: String): Int { * * @return the first constant instruction with the value, or -1 if not found. */ -fun Method.indexOfFirstConstantInstructionValue(constantValue: Long): Int { - return implementation?.let { - it.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue - } - } ?: -1 -} +fun Method.indexOfFirstConstantInstructionValue(constantValue: Long) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue + } +} ?: -1 + /** * Check if the method contains a constant with the given value. * * @return if the method contains a constant with the given value. */ -fun Method.containsConstantInstructionValue(constantValue: Long): Boolean { - return indexOfFirstConstantInstructionValue(constantValue) >= 0 -} +fun Method.containsConstantInstructionValue(constantValue: Long) = + indexOfFirstConstantInstructionValue(constantValue) >= 0 + /** * Traverse the class hierarchy starting from the given root class. diff --git a/src/main/kotlin/app/revanced/meta/JsonGenerator.kt b/src/main/kotlin/app/revanced/meta/JsonGenerator.kt index 3be7793f..dea128a7 100644 --- a/src/main/kotlin/app/revanced/meta/JsonGenerator.kt +++ b/src/main/kotlin/app/revanced/meta/JsonGenerator.kt @@ -1,67 +1,43 @@ package app.revanced.meta -import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages -import app.revanced.patcher.extensions.PatchExtensions.dependencies -import app.revanced.patcher.extensions.PatchExtensions.description -import app.revanced.patcher.extensions.PatchExtensions.include -import app.revanced.patcher.extensions.PatchExtensions.options -import app.revanced.patcher.extensions.PatchExtensions.patchName -import app.revanced.patcher.patch.PatchOption +import app.revanced.patcher.PatchSet +import app.revanced.patcher.patch.Patch import com.google.gson.GsonBuilder import java.io.File internal class JsonGenerator : PatchesFileGenerator { - override fun generate(bundle: PatchBundlePatches) { - val patches = bundle.map { - JsonPatch( - it.patchName, - it.description ?: "This patch has no description.", - !it.include, - it.options?.map { option -> - JsonPatch.Option( - option.key, - option.title, - option.description, - option.required, - option.let { listOption -> - if (listOption is PatchOption.ListOption<*>) { - listOption.options.toMutableList().toTypedArray() - } else null - } - ) - }?.toTypedArray() ?: emptyArray(), - it.dependencies?.map { dep -> - dep.java.patchName - }?.toTypedArray() ?: emptyArray(), - it.compatiblePackages?.map { pkg -> - JsonPatch.CompatiblePackage(pkg.name, pkg.versions) - }?.toTypedArray() ?: emptyArray() - ) - } - - val json = File("patches.json") - json.writeText(GsonBuilder().serializeNulls().create().toJson(patches)) + override fun generate(patches: PatchSet) = patches.map { + JsonPatch( + it.name!!, + it.description, + it.compatiblePackages, + it.dependencies?.map { dependency -> dependency::class.java.name }?.toSet(), + it.use, + it.requiresIntegrations, + it.options.values.map { option -> + JsonPatch.Option(option.key, option.value, option.title, option.description, option.required) + } + ) + }.let { + File("patches.json").writeText(GsonBuilder().serializeNulls().create().toJson(it)) } + @Suppress("unused") private class JsonPatch( - val name: String, - val description: String, - val excluded: Boolean, - val options: Array