mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2026-01-12 06:16:18 +00:00
Compare commits
6 Commits
v20.0.0-de
...
v20.0.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fc5a4708c | ||
|
|
bd434ceb33 | ||
|
|
766a73345e | ||
|
|
408e8ed81c | ||
|
|
e95fcd1c0b | ||
|
|
b8d763a66e |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,3 +1,22 @@
|
||||
# [20.0.0-dev.4](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.3...v20.0.0-dev.4) (2024-08-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Improve exception message wording ([bd434ce](https://github.com/ReVanced/revanced-patcher/commit/bd434ceb3394d1d5292e8b94e5bfd6da0e4e9c72))
|
||||
|
||||
# [20.0.0-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.2...v20.0.0-dev.3) (2024-08-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Make constructor internal as supposed ([e95fcd1](https://github.com/ReVanced/revanced-patcher/commit/e95fcd1c0b641164bbf0840ec7e562aeb3bacc3e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add ability to create options outside of a patch ([b8d763a](https://github.com/ReVanced/revanced-patcher/commit/b8d763a66e0601627dd71c8c24247726aa300146))
|
||||
|
||||
# [20.0.0-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.1...v20.0.0-dev.2) (2024-07-31)
|
||||
|
||||
|
||||
|
||||
@@ -149,7 +149,6 @@ public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revance
|
||||
}
|
||||
|
||||
public final class app/revanced/patcher/patch/BytecodePatchBuilder$InvokedFingerprint {
|
||||
public fun <init> (Lapp/revanced/patcher/Fingerprint;)V
|
||||
public final fun getValue (Ljava/lang/Void;Lkotlin/reflect/KProperty;)Lapp/revanced/patcher/Match;
|
||||
}
|
||||
|
||||
@@ -205,25 +204,43 @@ public final class app/revanced/patcher/patch/OptionException$ValueValidationExc
|
||||
|
||||
public final class app/revanced/patcher/patch/OptionKt {
|
||||
public static final fun booleanOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun booleanOption (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun booleanOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun booleanOption$default (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun booleansOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun booleansOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun booleansOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun booleansOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun floatOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun floatOption (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun floatOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun floatOption$default (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun floatsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun floatsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun intOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun intOption (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun intOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun intOption$default (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun intsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun intsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun intsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun intsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun longOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun longOption (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun longOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun longOption$default (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun longsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun longsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun longsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun longsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun stringOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun stringOption (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun stringOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun stringOption$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun stringsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static final fun stringsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun stringsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
public static synthetic fun stringsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||
}
|
||||
|
||||
public final class app/revanced/patcher/patch/Options : java/util/Map, kotlin/jvm/internal/markers/KMappedMarker {
|
||||
|
||||
@@ -36,20 +36,21 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.xpp3)
|
||||
implementation(libs.smali)
|
||||
implementation(libs.multidexlib2)
|
||||
implementation(libs.apktool.lib)
|
||||
implementation(libs.kotlin.reflect)
|
||||
|
||||
// TODO: Convert project to KMP.
|
||||
compileOnly(libs.android) {
|
||||
// Exclude, otherwise the org.w3c.dom API breaks.
|
||||
exclude(group = "xerces", module = "xmlParserAPIs")
|
||||
}
|
||||
testImplementation(libs.kotlin.test)
|
||||
|
||||
implementation(libs.apktool.lib)
|
||||
implementation(libs.kotlin.reflect)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.multidexlib2)
|
||||
implementation(libs.smali)
|
||||
implementation(libs.xpp3)
|
||||
|
||||
testImplementation(libs.mockk)
|
||||
testImplementation(libs.kotlin.test)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
@@ -149,6 +149,18 @@ The type of an option can be obtained from the `type` property of the option:
|
||||
option.type // The KType of the option.
|
||||
```
|
||||
|
||||
Options can be declared outside of a patch and added to a patch manually:
|
||||
|
||||
```kt
|
||||
val option = stringOption(key = "option")
|
||||
|
||||
bytecodePatch(name = "Patch") {
|
||||
val value by option()
|
||||
}
|
||||
```
|
||||
|
||||
This is useful when the same option is referenced in multiple patches.
|
||||
|
||||
### 🧩 Extensions
|
||||
|
||||
An extension is a precompiled DEX file merged into the patched app before a patch is executed.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
version = 20.0.0-dev.2
|
||||
version = 20.0.0-dev.4
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[versions]
|
||||
android = "4.1.1.4"
|
||||
apktool-lib = "2.9.3"
|
||||
binary-compatibility-validator = "0.15.1"
|
||||
kotlin = "2.0.0"
|
||||
kotlinx-coroutines-core = "1.8.1"
|
||||
mockk = "1.13.10"
|
||||
@@ -8,15 +9,14 @@ multidexlib2 = "3.0.3.r3"
|
||||
# Tracking https://github.com/google/smali/issues/64.
|
||||
#noinspection GradleDependency
|
||||
smali = "3.0.5"
|
||||
binary-compatibility-validator = "0.15.1"
|
||||
xpp3 = "1.1.4c"
|
||||
|
||||
[libraries]
|
||||
android = { module = "com.google.android:android", version.ref = "android" }
|
||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
||||
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructionsOrNull
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext.LookupMaps.Companion.appendParameters
|
||||
import app.revanced.patcher.patch.MethodClassPairs
|
||||
import app.revanced.patcher.util.proxy.ClassProxy
|
||||
|
||||
@@ -100,7 +100,7 @@ class Option<T> @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of [Option]s where options can be set and retrieved by key.
|
||||
* A collection of [Option]s where options can be set and retrieved by their key.
|
||||
*
|
||||
* @param options The options.
|
||||
*
|
||||
@@ -143,6 +143,39 @@ class Options internal constructor(
|
||||
override fun get(key: String) = options[key] ?: throw OptionException.OptionNotFoundException(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a string value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun stringOption(
|
||||
key: String,
|
||||
default: String? = null,
|
||||
values: Map<String, String?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<String>.(String?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a string value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -176,6 +209,39 @@ fun PatchBuilder<*>.stringOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with an integer value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun intOption(
|
||||
key: String,
|
||||
default: Int? = null,
|
||||
values: Map<String, Int?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<Int?>.(Int?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with an integer value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -209,6 +275,39 @@ fun PatchBuilder<*>.intOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a boolean value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun booleanOption(
|
||||
key: String,
|
||||
default: Boolean? = null,
|
||||
values: Map<String, Boolean?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<Boolean?>.(Boolean?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a boolean value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -242,6 +341,39 @@ fun PatchBuilder<*>.booleanOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a float value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun floatOption(
|
||||
key: String,
|
||||
default: Float? = null,
|
||||
values: Map<String, Float?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<Float?>.(Float?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a float value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -275,6 +407,39 @@ fun PatchBuilder<*>.floatOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a long value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun longOption(
|
||||
key: String,
|
||||
default: Long? = null,
|
||||
values: Map<String, Long?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<Long?>.(Long?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a long value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -308,6 +473,39 @@ fun PatchBuilder<*>.longOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a string list value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun stringsOption(
|
||||
key: String,
|
||||
default: List<String>? = null,
|
||||
values: Map<String, List<String>?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<List<String>>.(List<String>?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a string list value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -341,6 +539,39 @@ fun PatchBuilder<*>.stringsOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with an integer list value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun intsOption(
|
||||
key: String,
|
||||
default: List<Int>? = null,
|
||||
values: Map<String, List<Int>?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<List<Int>>.(List<Int>?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with an integer list value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -374,6 +605,39 @@ fun PatchBuilder<*>.intsOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a boolean list value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun booleansOption(
|
||||
key: String,
|
||||
default: List<Boolean>? = null,
|
||||
values: Map<String, List<Boolean>?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<List<Boolean>>.(List<Boolean>?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a boolean list value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -440,6 +704,39 @@ fun PatchBuilder<*>.floatsOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a long list value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
fun longsOption(
|
||||
key: String,
|
||||
default: List<Long>? = null,
|
||||
values: Map<String, List<Long>?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
validator: Option<List<Long>>.(List<Long>?) -> Boolean = { true },
|
||||
) = option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] with a long list value and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -473,6 +770,40 @@ fun PatchBuilder<*>.longsOption(
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option].
|
||||
*
|
||||
* @param key The key.
|
||||
* @param default The default value.
|
||||
* @param values Eligible option values mapped to a human-readable name.
|
||||
* @param title The title.
|
||||
* @param description A description.
|
||||
* @param required Whether the option is required.
|
||||
* @param validator The function to validate the option value.
|
||||
*
|
||||
* @return The created [Option].
|
||||
*
|
||||
* @see Option
|
||||
*/
|
||||
inline fun <reified T> option(
|
||||
key: String,
|
||||
default: T? = null,
|
||||
values: Map<String, T?>? = null,
|
||||
title: String? = null,
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
noinline validator: Option<T>.(T?) -> Boolean = { true },
|
||||
) = Option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
typeOf<T>(),
|
||||
validator,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new [Option] and add it to the current [PatchBuilder].
|
||||
*
|
||||
@@ -496,14 +827,13 @@ inline fun <reified T> PatchBuilder<*>.option(
|
||||
description: String? = null,
|
||||
required: Boolean = false,
|
||||
noinline validator: Option<T>.(T?) -> Boolean = { true },
|
||||
) = Option(
|
||||
) = app.revanced.patcher.patch.option(
|
||||
key,
|
||||
default,
|
||||
values,
|
||||
title,
|
||||
description,
|
||||
required,
|
||||
typeOf<T>(),
|
||||
validator,
|
||||
).also { it() }
|
||||
|
||||
@@ -519,30 +849,26 @@ sealed class OptionException(errorMessage: String) : Exception(errorMessage, nul
|
||||
* @param invalidType The type of the value that was passed.
|
||||
* @param expectedType The type of the value that was expected.
|
||||
*/
|
||||
class InvalidValueTypeException(invalidType: String, expectedType: String) :
|
||||
OptionException("Type $expectedType was expected but received type $invalidType")
|
||||
class InvalidValueTypeException(invalidType: String, expectedType: String) : OptionException("Type $expectedType was expected but received type $invalidType")
|
||||
|
||||
/**
|
||||
* An exception thrown when a value did not satisfy the value conditions specified by the [Option].
|
||||
*
|
||||
* @param value The value that failed validation.
|
||||
*/
|
||||
class ValueValidationException(value: Any?, option: Option<*>) :
|
||||
OptionException("The option value \"$value\" failed validation for ${option.key}")
|
||||
class ValueValidationException(value: Any?, option: Option<*>) : OptionException("The option value \"$value\" failed validation for ${option.key}")
|
||||
|
||||
/**
|
||||
* An exception thrown when a value is required but null was passed.
|
||||
*
|
||||
* @param option The [Option] that requires a value.
|
||||
*/
|
||||
class ValueRequiredException(option: Option<*>) :
|
||||
OptionException("The option ${option.key} requires a value, but null was passed")
|
||||
class ValueRequiredException(option: Option<*>) : OptionException("The option ${option.key} requires a value, but the value was null")
|
||||
|
||||
/**
|
||||
* An exception thrown when a [Option] is not found.
|
||||
*
|
||||
* @param key The key of the [Option].
|
||||
*/
|
||||
class OptionNotFoundException(key: String) :
|
||||
OptionException("No option with key $key")
|
||||
class OptionNotFoundException(key: String) : OptionException("No option with key $key")
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ sealed class Patch<C : PatchContext<*>>(
|
||||
// if a patch has a finalizing block in order to not emit it twice.
|
||||
internal var finalizeBlock: (Patch<C>.(C) -> Unit)?,
|
||||
) {
|
||||
/**
|
||||
* The options of the patch.
|
||||
*/
|
||||
val options = Options(options)
|
||||
|
||||
/**
|
||||
@@ -393,7 +396,7 @@ class BytecodePatchBuilder internal constructor(
|
||||
*/
|
||||
operator fun Fingerprint.invoke() = InvokedFingerprint(also { fingerprints.add(it) })
|
||||
|
||||
class InvokedFingerprint(private val fingerprint: Fingerprint) {
|
||||
class InvokedFingerprint internal constructor(private val fingerprint: Fingerprint) {
|
||||
// The reason getValue isn't extending the Fingerprint class is
|
||||
// because delegating makes only sense if the fingerprint was previously added to the patch by invoking it.
|
||||
// It may be likely to forget invoking it. By wrapping the fingerprint into this class,
|
||||
|
||||
@@ -7,7 +7,11 @@ import kotlin.reflect.typeOf
|
||||
import kotlin.test.*
|
||||
|
||||
internal object OptionsTest {
|
||||
private val externalOption = stringOption("external", "default")
|
||||
|
||||
private val optionsTestPatch = bytecodePatch {
|
||||
externalOption()
|
||||
|
||||
booleanOption("bool", true)
|
||||
|
||||
stringOption("required", "default", required = true)
|
||||
@@ -124,5 +128,17 @@ internal object OptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `external option should be accessible`() {
|
||||
assertDoesNotThrow {
|
||||
externalOption.value = "test"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should allow getting the external option from the patch`() {
|
||||
assertEquals(optionsTestPatch.options["external"].value, externalOption.value)
|
||||
}
|
||||
|
||||
private fun options(block: Options.() -> Unit) = optionsTestPatch.options.let(block)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user