1
mirror of https://github.com/revanced/revanced-patcher synced 2025-09-06 16:38:50 +02:00

Compare commits

...

23 Commits

Author SHA1 Message Date
semantic-release-bot
7e8cd3bede chore(release): 7.1.0-dev.1 [skip ci]
# [7.1.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0-dev.1) (2023-04-30)

### Features

* add appreciation message for new contributors ([d674362](d67436271d))
2023-04-30 01:16:45 +00:00
oSumAtrIX
d67436271d feat: add appreciation message for new contributors 2023-04-30 03:15:12 +02:00
oSumAtrIX
aa07f35f06 chore: bump dependencies 2023-04-03 03:04:05 +02:00
oSumAtrIX
77e0536838 build: update Kotlin to 1.8.10 2023-03-31 17:19:40 +02:00
oSumAtrIX
a49e78234b chore: remove project files
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-03-02 19:23:41 +01:00
semantic-release-bot
a3ae825e48 chore(release): 7.0.0 [skip ci]
# [7.0.0](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0) (2023-02-26)

* feat!: merge integrations only when necessary ([6e24a85](6e24a85eab))

### BREAKING CHANGES

* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:42:48 +00:00
oSumAtrIX
146c8504ed chore: merge branch dev to main (#159) 2023-02-27 00:41:27 +01:00
semantic-release-bot
2eb125ad69 chore(release): 7.0.0-dev.1 [skip ci]
# [7.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0-dev.1) (2023-02-26)

* feat!: merge integrations only when necessary ([6e24a85](6e24a85eab))

### BREAKING CHANGES

* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:24:38 +00:00
oSumAtrIX
6e24a85eab feat!: merge integrations only when necessary
BREAKING CHANGE: `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-27 00:23:27 +01:00
oSumAtrIX
e4c3e9ffc5 refactor: remove unnecessary annotations
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:18:35 +01:00
Javier Flores
4c1778a62f chore: update gradle wrapper to 8.0.1 (#160) 2023-02-26 03:46:33 +01:00
oSumAtrIX
d99261cdbb ci: fix backmerge direction
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-22 16:39:50 +01:00
oSumAtrIX
ac1c0f2773 ci: add backmerge target branch
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-22 06:45:16 +01:00
oSumAtrIX
eddd4ec7ac ci: use new semantic-release-backmerge option
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-18 21:55:40 +01:00
Palm
07a2829c65 ci: update actions (#158) 2023-02-13 22:29:20 +01:00
semantic-release-bot
3d77e299d9 chore(release): 6.4.3 [skip ci]
## [6.4.3](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3) (2023-02-10)

### Bug Fixes

* check `CONST_STRING_JUMP` instructions for matching string ([058d292](058d292ad5))
2023-02-10 04:28:15 +00:00
oSumAtrIX
f1336f89e4 chore: merge branch dev to main (#156) 2023-02-10 05:26:43 +01:00
semantic-release-bot
0502f84c20 chore(release): 6.4.3-dev.1 [skip ci]
## [6.4.3-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3-dev.1) (2023-02-10)

### Bug Fixes

* check `CONST_STRING_JUMP` instructions for matching string ([058d292](058d292ad5))
2023-02-10 04:20:46 +00:00
oSumAtrIX
058d292ad5 fix: check CONST_STRING_JUMP instructions for matching string
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:18:38 +01:00
oSumAtrIX
1029d56a52 refactor: remove dead code
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:17:36 +01:00
oSumAtrIX
709b5a0fec chore: fix typo
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:16:00 +01:00
semantic-release-bot
e1accc5041 chore(release): 6.4.2 [skip ci]
## [6.4.2](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2) (2023-01-17)

### Bug Fixes

* resolve failing builds ([a263fdf](a263fdfd41))
2023-01-17 23:29:34 +00:00
oSumAtrIX
6dbbf2e03e chore: merge branch dev to main (#153) 2023-01-18 00:14:38 +01:00
29 changed files with 774 additions and 296 deletions

2
.github/config.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
firstPRMergeComment: >
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.

View File

@@ -32,11 +32,11 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: "latest" node-version: "18"
cache: 'npm' cache: 'npm'
- name: Setup semantic-release - name: Setup semantic-release
run: npm install semantic-release@19.0.5 @saithodev/semantic-release-backmerge @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin@1.7.4 -D run: npm install
- name: Release - name: Release
env: env:
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }} GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
run: npx semantic-release run: npm exec semantic-release

6
.gitignore vendored
View File

@@ -74,6 +74,7 @@ cmake-build-*/
# IntelliJ # IntelliJ
out/ out/
.idea/
# mpeltonen/sbt-idea plugin # mpeltonen/sbt-idea plugin
.idea_modules/ .idea_modules/
@@ -117,4 +118,7 @@ gradle-app.setting
!src/test/resources/* !src/test/resources/*
# Dependency directories # Dependency directories
node_modules/ node_modules/
# Gradle props, to avoid sharing the gpr key
gradle.properties

9
.idea/.gitignore generated vendored
View File

@@ -1,9 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
/kotlinc.xml

View File

@@ -1,10 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

7
.idea/discord.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationEnabledOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
</component>
</project>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="UnusedSymbol" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

10
.idea/misc.xml generated
View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="azul-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

12
.idea/vcs.xml generated
View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CommitMessageInspectionProfile">
<profile version="1.0">
<inspection_tool class="CommitFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CommitNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -23,7 +23,7 @@
[ [
"@saithodev/semantic-release-backmerge", "@saithodev/semantic-release-backmerge",
{ {
branches: [{from: "main", to: "dev"}], backmergeBranches: [{"from": "main", "to": "dev"}],
clearWorkspace: true clearWorkspace: true
} }
], ],

View File

@@ -1,3 +1,55 @@
# [7.1.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0-dev.1) (2023-04-30)
### Features
* add appreciation message for new contributors ([d674362](https://github.com/revanced/revanced-patcher/commit/d67436271ddca9ccfe008272c1ca82c6123ae7ee))
# [7.0.0](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0) (2023-02-26)
* feat!: merge integrations only when necessary ([6e24a85](https://github.com/revanced/revanced-patcher/commit/6e24a85eabd1e7a1484fad229d5ba55c3ba1f1b4))
### BREAKING CHANGES
* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
# [7.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0-dev.1) (2023-02-26)
* feat!: merge integrations only when necessary ([6e24a85](https://github.com/revanced/revanced-patcher/commit/6e24a85eabd1e7a1484fad229d5ba55c3ba1f1b4))
### BREAKING CHANGES
* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
## [6.4.3](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3) (2023-02-10)
### Bug Fixes
* check `CONST_STRING_JUMP` instructions for matching string ([058d292](https://github.com/revanced/revanced-patcher/commit/058d292ad5e297f4c652ff543c13e77a39f7fb1b))
## [6.4.3-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3-dev.1) (2023-02-10)
### Bug Fixes
* check `CONST_STRING_JUMP` instructions for matching string ([058d292](https://github.com/revanced/revanced-patcher/commit/058d292ad5e297f4c652ff543c13e77a39f7fb1b))
## [6.4.2](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2) (2023-01-17)
### Bug Fixes
* resolve failing builds ([a263fdf](https://github.com/revanced/revanced-patcher/commit/a263fdfd413fc05098e28d4800e36ce7d313085b))
## [6.4.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2-dev.1) (2023-01-17) ## [6.4.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2-dev.1) (2023-01-17)

View File

@@ -1,5 +1,5 @@
plugins { plugins {
kotlin("jvm") version "1.7.0" kotlin("jvm") version "1.8.10"
java java
`maven-publish` `maven-publish`
} }
@@ -26,8 +26,8 @@ dependencies {
implementation("app.revanced:multidexlib2:2.5.3-a3836654") implementation("app.revanced:multidexlib2:2.5.3-a3836654")
implementation("app.revanced:apktool-lib:2.7.0") implementation("app.revanced:apktool-lib:2.7.0")
implementation(kotlin("reflect")) implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10")
testImplementation(kotlin("test")) testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.10")
} }
tasks { tasks {

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 6.4.2-dev.1 version = 7.1.0-dev.1

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

727
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,9 @@
{ {
"devDependencies": { "devDependencies": {
"@saithodev/semantic-release-backmerge": "^3.1.0",
"@semantic-release/changelog": "^6.0.2", "@semantic-release/changelog": "^6.0.2",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.7.4", "gradle-semantic-release-plugin": "^1.7.6",
"semantic-release": "^19.0.5" "semantic-release": "^20.1.0"
} }
} }

View File

@@ -1,13 +1,12 @@
package app.revanced.patcher package app.revanced.patcher
import app.revanced.patcher.data.Context import app.revanced.patcher.data.Context
import app.revanced.patcher.data.findIndexed
import app.revanced.patcher.extensions.PatchExtensions.dependencies import app.revanced.patcher.extensions.PatchExtensions.dependencies
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.extensions.PatchExtensions.requiresIntegrations
import app.revanced.patcher.extensions.nullOutputStream import app.revanced.patcher.extensions.nullOutputStream
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.* import app.revanced.patcher.patch.*
import app.revanced.patcher.util.ClassMerger.merge
import app.revanced.patcher.util.VersionReader import app.revanced.patcher.util.VersionReader
import brut.androlib.Androlib import brut.androlib.Androlib
import brut.androlib.meta.UsesFramework import brut.androlib.meta.UsesFramework
@@ -28,7 +27,7 @@ import org.jf.dexlib2.writer.io.MemoryDataStore
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
private val NAMER = BasicDexFileNamer() internal val NAMER = BasicDexFileNamer()
/** /**
* The ReVanced Patcher. * The ReVanced Patcher.
@@ -38,6 +37,7 @@ class Patcher(private val options: PatcherOptions) {
private val logger = options.logger private val logger = options.logger
private val opcodes: Opcodes private val opcodes: Opcodes
private var resourceDecodingMode = ResourceDecodingMode.MANIFEST_ONLY private var resourceDecodingMode = ResourceDecodingMode.MANIFEST_ONLY
private var mergeIntegrations = false
val context: PatcherContext val context: PatcherContext
companion object { companion object {
@@ -64,37 +64,19 @@ class Patcher(private val options: PatcherOptions) {
} }
/** /**
* Add additional dex file container to the patcher. * Add integrations to be merged by the patcher.
* @param files The dex file containers to add to the patcher. * The integrations will only be merged, if necessary.
* @param process The callback for [files] which are being added. *
* @param integrations The integrations, must be dex files or dex file container such as ZIP, APK or DEX files.
* @param callback The callback for [integrations] which are being added.
*/ */
fun addFiles( fun addIntegrations(
files: List<File>, integrations: List<File>,
process: (File) -> Unit callback: (File) -> Unit
) { ) {
with(context.bytecodeContext.classes) { context.integrations.apply integrations@{
for (file in files) { add(integrations)
process(file) this@integrations.callback = callback
for (classDef in MultiDexIO.readDexFile(true, file, NAMER, null, null).classes) {
val type = classDef.type
val result = classes.findIndexed { it.type == type }
if (result == null) {
logger.trace("Merging type $type")
classes.add(classDef)
continue
}
val (existingClass, existingClassIndex) = result
logger.trace("Type $type exists. Adding missing methods and fields.")
existingClass.merge(classDef, context, logger).let { mergedClass ->
if (mergedClass !== existingClass) // referential equality check
classes[existingClassIndex] = mergedClass
}
}
}
} }
} }
@@ -183,18 +165,29 @@ class Patcher(private val options: PatcherOptions) {
*/ */
fun addPatches(patches: Iterable<Class<out Patch<Context>>>) { fun addPatches(patches: Iterable<Class<out Patch<Context>>>) {
/** /**
* Fill the cache with the instances of the [Patch]es for later use. * Returns true if at least one patches or its dependencies matches the given predicate.
* Note: Dependencies of the [Patch] will be cached as well.
*/ */
fun Class<out Patch<Context>>.isResource() { fun Class<out Patch<Context>>.anyRecursively(predicate: (Class<out Patch<Context>>) -> Boolean): Boolean =
this.also { predicate(this) || dependencies?.any { it.java.anyRecursively(predicate) } == true
if (!ResourcePatch::class.java.isAssignableFrom(it)) return@also
// set the mode to decode all resources before running the patches
// Determine if resource patching is required.
for (patch in patches) {
if (patch.anyRecursively { ResourcePatch::class.java.isAssignableFrom(it) }) {
resourceDecodingMode = ResourceDecodingMode.FULL resourceDecodingMode = ResourceDecodingMode.FULL
}.dependencies?.forEach { it.java.isResource() } break
}
} }
context.patches.addAll(patches.onEach(Class<out Patch<Context>>::isResource)) // Determine if merging integrations is required.
for (patch in patches) {
if (patch.anyRecursively { it.requiresIntegrations }) {
mergeIntegrations = true
break
}
}
context.patches.addAll(patches)
} }
/** /**
@@ -343,6 +336,8 @@ class Patcher(private val options: PatcherOptions) {
} }
return sequence { return sequence {
if (mergeIntegrations) context.integrations.merge(logger)
// prevent from decoding the manifest twice if it is not needed // prevent from decoding the manifest twice if it is not needed
if (resourceDecodingMode == ResourceDecodingMode.FULL) decodeResources(ResourceDecodingMode.FULL) if (resourceDecodingMode == ResourceDecodingMode.FULL) decodeResources(ResourceDecodingMode.FULL)

View File

@@ -1,10 +1,9 @@
package app.revanced.patcher package app.revanced.patcher
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.*
import app.revanced.patcher.data.Context import app.revanced.patcher.logging.Logger
import app.revanced.patcher.data.PackageMetadata
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.ClassMerger.merge
import org.jf.dexlib2.iface.ClassDef import org.jf.dexlib2.iface.ClassDef
import java.io.File import java.io.File
@@ -14,6 +13,52 @@ data class PatcherContext(
) { ) {
val packageMetadata = PackageMetadata() val packageMetadata = PackageMetadata()
internal val patches = mutableListOf<Class<out Patch<Context>>>() internal val patches = mutableListOf<Class<out Patch<Context>>>()
internal val integrations = Integrations(this)
internal val bytecodeContext = BytecodeContext(classes) internal val bytecodeContext = BytecodeContext(classes)
internal val resourceContext = ResourceContext(resourceCacheDirectory) internal val resourceContext = ResourceContext(resourceCacheDirectory)
internal class Integrations(val context: PatcherContext) {
var callback: ((File) -> Unit)? = null
private val integrations: MutableList<File> = mutableListOf()
fun add(integrations: List<File>) = this@Integrations.integrations.addAll(integrations)
/**
* Merge integrations.
* @param logger A logger.
*/
fun merge(logger: Logger) {
with(context.bytecodeContext.classes) {
for (integrations in integrations) {
callback?.let { it(integrations) }
for (classDef in lanchon.multidexlib2.MultiDexIO.readDexFile(
true,
integrations,
NAMER,
null,
null
).classes) {
val type = classDef.type
val result = classes.findIndexed { it.type == type }
if (result == null) {
logger.trace("Merging type $type")
classes.add(classDef)
continue
}
val (existingClass, existingClassIndex) = result
logger.trace("Type $type exists. Adding missing methods and fields.")
existingClass.merge(classDef, context, logger).let { mergedClass ->
if (mergedClass !== existingClass) // referential equality check
classes[existingClassIndex] = mergedClass
}
}
}
}
}
}
} }

View File

@@ -7,8 +7,6 @@ import app.revanced.patcher.patch.Patch
* @param compatiblePackages A list of packages a [Patch] is compatible with. * @param compatiblePackages A list of packages a [Patch] is compatible with.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Compatibility( annotation class Compatibility(
val compatiblePackages: Array<Package>, val compatiblePackages: Array<Package>,
) )
@@ -19,8 +17,6 @@ annotation class Compatibility(
* @param versions The versions of the package the [Patch] is compatible with. * @param versions The versions of the package the [Patch] is compatible with.
*/ */
@Target() @Target()
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Package( annotation class Package(
val name: String, val name: String,
val versions: Array<String> = [], val versions: Array<String> = [],

View File

@@ -7,8 +7,6 @@ import app.revanced.patcher.patch.Patch
* @param name A suggestive name for the [Patch]. * @param name A suggestive name for the [Patch].
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Name( annotation class Name(
val name: String, val name: String,
) )
@@ -18,8 +16,6 @@ annotation class Name(
* @param description A description for the [Patch]. * @param description A description for the [Patch].
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Description( annotation class Description(
val description: String, val description: String,
) )
@@ -30,8 +26,6 @@ annotation class Description(
* @param version The version of a [Patch]. * @param version The version of a [Patch].
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Version( annotation class Version(
val version: String, val version: String,
) )

View File

@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.OptionsContainer
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchOptions import app.revanced.patcher.patch.PatchOptions
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.RequiresIntegrations
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KVisibility import kotlin.reflect.KVisibility
import kotlin.reflect.full.companionObject import kotlin.reflect.full.companionObject
@@ -58,6 +59,9 @@ object PatchExtensions {
val Class<out Patch<Context>>.compatiblePackages val Class<out Patch<Context>>.compatiblePackages
get() = findAnnotationRecursively(Compatibility::class)?.compatiblePackages get() = findAnnotationRecursively(Compatibility::class)?.compatiblePackages
internal val Class<out Patch<Context>>.requiresIntegrations
get() = findAnnotationRecursively(RequiresIntegrations::class) != null
val Class<out Patch<Context>>.options: PatchOptions? val Class<out Patch<Context>>.options: PatchOptions?
get() = kotlin.companionObject?.let { cl -> get() = kotlin.companionObject?.let { cl ->
if (cl.visibility != KVisibility.PUBLIC) return null if (cl.visibility != KVisibility.PUBLIC) return null

View File

@@ -101,7 +101,7 @@ fun MutableMethod.removeInstruction(index: Int) = this.implementation!!.removeIn
fun MutableMethod.label(index: Int) = this.implementation!!.newLabelForIndex(index) fun MutableMethod.label(index: Int) = this.implementation!!.newLabelForIndex(index)
/** /**
* Get the instruction at given index in the method's implementation. * Get the instruction at the given index in the method's implementation.
* @param index The index to get the instruction at. * @param index The index to get the instruction at.
* @return The instruction. * @return The instruction.
*/ */
@@ -227,21 +227,4 @@ internal fun parametersEqual(
internal val nullOutputStream = object : OutputStream() { internal val nullOutputStream = object : OutputStream() {
override fun write(b: Int) {} override fun write(b: Int) {}
}
/**
* Should be used to parse a list of parameters represented by their first letter,
* or in the case of arrays prefixed with an unspecified amount of '[' character.
*/
internal fun String.parseParameters(): List<String> {
val parameters = mutableListOf<String>()
var parameter = ""
for (char in this.toCharArray()) {
parameter += char
if (char == '[') continue
parameters.add(parameter)
parameter = ""
}
return parameters
} }

View File

@@ -7,7 +7,6 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
* @param threshold if [threshold] or more of the opcodes do not match, skip. * @param threshold if [threshold] or more of the opcodes do not match, skip.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class FuzzyPatternScanMethod( annotation class FuzzyPatternScanMethod(
val threshold: Int = 1 val threshold: Int = 1
) )

View File

@@ -106,7 +106,10 @@ abstract class MethodFingerprint(
val stringsList = methodFingerprint.strings.toMutableList() val stringsList = methodFingerprint.strings.toMutableList()
implementation.instructions.forEachIndexed { instructionIndex, instruction -> implementation.instructions.forEachIndexed { instructionIndex, instruction ->
if (instruction.opcode.ordinal != Opcode.CONST_STRING.ordinal) return@forEachIndexed if (
instruction.opcode != Opcode.CONST_STRING &&
instruction.opcode != Opcode.CONST_STRING_JUMBO
) return@forEachIndexed
val string = ((instruction as ReferenceInstruction).reference as StringReference).string val string = ((instruction as ReferenceInstruction).reference as StringReference).string
val index = stringsList.indexOfFirst(string::contains) val index = stringsList.indexOfFirst(string::contains)
@@ -244,7 +247,7 @@ data class MethodFingerprintResult(
* The result of scanning strings on the [MethodFingerprint]. * The result of scanning strings on the [MethodFingerprint].
* @param matches The list of strings that were matched. * @param matches The list of strings that were matched.
*/ */
data class StringsScanResult(val matches: List<StringMatch>){ data class StringsScanResult(val matches: List<StringMatch>) {
/** /**
* Represents a match for a string at an index. * Represents a match for a string at an index.
* @param string The string that was matched. * @param string The string that was matched.

View File

@@ -5,20 +5,23 @@ import app.revanced.patcher.patch.Patch
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
* Annotation to mark a Class as a patch. * Annotation to mark a class as a patch.
* @param include If false, the patch should be treated as optional by default. * @param include If false, the patch should be treated as optional by default.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Patch(val include: Boolean = true) annotation class Patch(val include: Boolean = true)
/** /**
* Annotation for dependencies of [Patch]es. * Annotation for dependencies of [Patch]es.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class DependsOn( annotation class DependsOn(
val dependencies: Array<KClass<out Patch<Context>>> = [] val dependencies: Array<KClass<out Patch<Context>>> = []
) )
/**
* Annotation to mark [Patch]es which depend on integrations.
*/
@Target(AnnotationTarget.CLASS)
annotation class RequiresIntegrations // required because integrations are decoupled from patches

View File

@@ -9,6 +9,5 @@ import app.revanced.patcher.annotation.Package
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ExampleBytecodeCompatibility internal annotation class ExampleBytecodeCompatibility

View File

@@ -9,6 +9,5 @@ import app.revanced.patcher.annotation.Package
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ExampleResourceCompatibility internal annotation class ExampleResourceCompatibility