mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 17:55:24 +08:00
Added more function in MethodFinder, ConstructorFinder, FieldFinder
This commit is contained in:
@@ -16,6 +16,8 @@ class ConstructorFinder internal constructor(override val hookInstance: YukiMemb
|
||||
|
||||
> `Constructor` 查找类。
|
||||
|
||||
可通过指定类型查找指定构造方法或一组构造方法。
|
||||
|
||||
### paramCount [field]
|
||||
|
||||
```kotlin
|
||||
@@ -112,6 +114,24 @@ fun paramCount(num: Int): IndexTypeCondition
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
### paramCount [method]
|
||||
|
||||
```kotlin
|
||||
fun paramCount(numRange: IntRange): IndexTypeCondition
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置 `Constructor` 参数个数范围。
|
||||
|
||||
你可以不使用 `param` 指定参数类型而是仅使用此方法指定参数个数范围。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
### superClass [method]
|
||||
|
||||
```kotlin
|
||||
@@ -160,7 +180,7 @@ inline fun constructor(initiate: ConstructorFinder.() -> Unit)
|
||||
|
||||
> 创建需要重新查找的 `Constructor`。
|
||||
|
||||
你可以添加多个备选构造方法,直到成功为止,若最后依然失败,将停止查找并输出错误日志。
|
||||
你可以添加多个备选 `Constructor`,直到成功为止,若最后依然失败,将停止查找并输出错误日志。
|
||||
|
||||
#### Result [class]
|
||||
|
||||
@@ -179,13 +199,17 @@ inner class Result internal constructor()
|
||||
##### onFind [method]
|
||||
|
||||
```kotlin
|
||||
fun onFind(initiate: Constructor<*>.() -> Unit)
|
||||
fun onFind(initiate: HashSet<Constructor<*>>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.1` `新增`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
`initiate` 参数 `Constructor` 变为 `HashSet<Constructor>`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 当在 `RemedyPlan` 中找到结果时。
|
||||
@@ -207,13 +231,17 @@ constructor {
|
||||
### Result [class]
|
||||
|
||||
```kotlin
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, internal val e: Throwable?)
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, internal val throwable: Throwable?) : BaseResult
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0` `添加`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
继承到接口 `BaseResult`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Constructor` 查找结果实现类。
|
||||
@@ -247,6 +275,7 @@ constructor {
|
||||
// Your code here.
|
||||
}.result {
|
||||
get().call()
|
||||
all()
|
||||
remedys {}
|
||||
onNoSuchConstructor {}
|
||||
}
|
||||
@@ -266,6 +295,8 @@ fun get(): Instance
|
||||
|
||||
> 获得 `Constructor` 实例处理类。
|
||||
|
||||
若有多个 `Constructor` 结果只会返回第一个。
|
||||
|
||||
!> 若你设置了 `remedys` 请使用 `wait` 回调结果方法。
|
||||
|
||||
**功能示例**
|
||||
@@ -300,6 +331,36 @@ constructor {
|
||||
}.get().newInstance<TestClass>("param1", "param2")
|
||||
```
|
||||
|
||||
#### all [method]
|
||||
|
||||
```kotlin
|
||||
fun all(): ArrayList<Instance>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Constructor` 实例处理类数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Constructor` 实例结果并在 `isBindToHooker` 时设置到 `hookInstance`。
|
||||
|
||||
**功能示例**
|
||||
|
||||
你可以通过此方法来获得当前条件结果中匹配的全部 `Constructor`。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
constructor {
|
||||
// Your code here.
|
||||
}.all().forEach { instance ->
|
||||
instance.call(...)
|
||||
}
|
||||
```
|
||||
|
||||
#### give [method]
|
||||
|
||||
```kotlin
|
||||
@@ -314,6 +375,28 @@ fun give(): Constructor<*>?
|
||||
|
||||
> 得到构造方法本身。
|
||||
|
||||
若有多个 `Constructor` 结果只会返回第一个。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回 `null`。
|
||||
|
||||
#### giveAll [method]
|
||||
|
||||
```kotlin
|
||||
fun giveAll(): HashSet<Constructor<*>>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到 `Constructor` 本身数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Constructor` 实例。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回空的 `HashSet`。
|
||||
|
||||
#### wait [method]
|
||||
|
||||
```kotlin
|
||||
@@ -328,6 +411,28 @@ fun wait(initiate: Instance.() -> Unit)
|
||||
|
||||
> 获得 `Constructor` 实例处理类,配合 `RemedyPlan` 使用。
|
||||
|
||||
若有多个 `Constructor` 结果只会返回第一个。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
|
||||
#### waitAll [method]
|
||||
|
||||
```kotlin
|
||||
fun waitAll(initiate: ArrayList<Instance>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Constructor` 实例处理类数组,配合 `RemedyPlan` 使用。
|
||||
|
||||
返回全部查询条件匹配的多个 `Constructor` 实例结果。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
@@ -348,11 +453,11 @@ inline fun remedys(initiate: RemedyPlan.() -> Unit): Result
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 创建构造方法重查找功能。
|
||||
> 创建 `Constructor` 重查找功能。
|
||||
|
||||
**功能示例**
|
||||
|
||||
当你遇到一种构造方法可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchConstructor` 捕获异常二次查找构造方法。
|
||||
当你遇到一种 `Constructor` 可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchConstructor` 捕获异常二次查找 `Constructor`。
|
||||
|
||||
若第一次查找失败了,你还可以在这里继续添加此方法体直到成功为止。
|
||||
|
||||
@@ -387,7 +492,7 @@ inline fun onNoSuchConstructor(result: (Throwable) -> Unit): Result
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 监听找不到构造方法时。
|
||||
> 监听找不到 `Constructor` 时。
|
||||
|
||||
只会返回第一次的错误信息,不会返回 `RemedyPlan` 的错误信息。
|
||||
|
||||
@@ -410,13 +515,17 @@ fun ignoredError(): Result
|
||||
#### Instance [class]
|
||||
|
||||
```kotlin
|
||||
inner class Instance internal constructor()
|
||||
inner class Instance internal constructor(private val constructor: Constructor<*>?)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.2` `新增`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
新增 `constructor` 参数
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Constructor` 实例处理类。
|
||||
@@ -433,7 +542,7 @@ fun call(vararg param: Any?): Any?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 执行构造方法创建目标实例,不指定目标实例类型。
|
||||
> 执行 `Constructor` 创建目标实例,不指定目标实例类型。
|
||||
|
||||
##### newInstance [method]
|
||||
|
||||
@@ -447,4 +556,4 @@ fun <T> newInstance(vararg param: Any?): T?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 执行构造方法创建目标实例 ,指定 `T` 目标实例类型。
|
||||
> 执行 `Constructor` 创建目标实例 ,指定 `T` 目标实例类型。
|
@@ -16,6 +16,8 @@ class FieldFinder internal constructor(override val hookInstance: YukiMemberHook
|
||||
|
||||
> `Field` 查找类。
|
||||
|
||||
可通过指定类型查找指定变量或一组变量。
|
||||
|
||||
### ~~classSet [field]~~ <!-- {docsify-ignore} -->
|
||||
|
||||
**变更记录**
|
||||
@@ -58,7 +60,7 @@ var type: Any?
|
||||
|
||||
> 设置 `Field` 类型。
|
||||
|
||||
可不填写类型,默认模糊查找并取第一个匹配的 `Field`。
|
||||
可不填写类型。
|
||||
|
||||
### modifiers [method]
|
||||
|
||||
@@ -78,7 +80,7 @@ inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition
|
||||
|
||||
> 设置 `Field` 标识符筛选条件。
|
||||
|
||||
可不设置筛选条件,默认模糊查找并取第一个匹配的 `Field`。
|
||||
可不设置筛选条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -110,7 +112,7 @@ fun name(value: String): IndexTypeCondition
|
||||
|
||||
> 设置 `Field` 名称。
|
||||
|
||||
!> 若不填写名称则必须存在一个其它条件,默认模糊查找并取第一个匹配的 `Field`。
|
||||
!> 若不填写名称则必须存在一个其它条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -128,7 +130,7 @@ inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition
|
||||
|
||||
> 设置 `Field` 名称条件。
|
||||
|
||||
!> 若不填写名称则必须存在一个其它条件,默认模糊查找并取第一个匹配的 `Field`。
|
||||
!> 若不填写名称则必须存在一个其它条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -146,7 +148,7 @@ fun type(value: Any): IndexTypeCondition
|
||||
|
||||
> 设置 `Field` 类型。
|
||||
|
||||
!> 可不填写类型,默认模糊查找并取第一个匹配的 `Field`。
|
||||
!> 可不填写类型。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -166,16 +168,92 @@ fun superClass(isOnlySuperClass: Boolean)
|
||||
|
||||
!> 若当前 `classSet` 的父类较多可能会耗时,API 会自动循环到父类继承是 `Any` 前的最后一个类。
|
||||
|
||||
### RemedyPlan [class]
|
||||
|
||||
```kotlin
|
||||
inner class RemedyPlan internal constructor()
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Field` 重查找实现类,可累计失败次数直到查找成功。
|
||||
|
||||
#### field [method]
|
||||
|
||||
```kotlin
|
||||
inline fun field(initiate: FieldFinder.() -> Unit): Result
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 创建需要重新查找的 `Field`。
|
||||
|
||||
你可以添加多个备选 `Field`,直到成功为止,若最后依然失败,将停止查找并输出错误日志。
|
||||
|
||||
#### Result [class]
|
||||
|
||||
```kotlin
|
||||
inner class Result internal constructor()
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `RemedyPlan` 结果实现类。
|
||||
|
||||
##### onFind [method]
|
||||
|
||||
```kotlin
|
||||
fun onFind(initiate: HashSet<Field>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 当在 `RemedyPlan` 中找到结果时。
|
||||
|
||||
**功能示例**
|
||||
|
||||
你可以方便地对重查找的 `Field` 实现 `onFind` 方法。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
field {
|
||||
// Your code here.
|
||||
}.onFind {
|
||||
// Your code here.
|
||||
}
|
||||
```
|
||||
|
||||
### Result [class]
|
||||
|
||||
```kotlin
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, private val e: Throwable?)
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, private val throwable: Throwable?) : BaseResult
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0` `添加`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
继承到接口 `BaseResult`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Field` 查找结果实现类。
|
||||
@@ -212,22 +290,28 @@ field {
|
||||
get(instance).string()
|
||||
get(instance).cast<CustomClass>()
|
||||
get().boolean()
|
||||
all(instance)
|
||||
give()
|
||||
giveAll()
|
||||
onNoSuchField {}
|
||||
}
|
||||
```
|
||||
|
||||
#### get [method]
|
||||
|
||||
```kotlin
|
||||
fun get(instance: Any?): Instance
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0` `添加`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量实例处理类。
|
||||
> 获得 `Field` 实例处理类。
|
||||
|
||||
若有多个 `Field` 结果只会返回第一个。
|
||||
|
||||
**功能示例**
|
||||
|
||||
@@ -251,6 +335,36 @@ field {
|
||||
}.get().set("something")
|
||||
```
|
||||
|
||||
#### all [method]
|
||||
|
||||
```kotlin
|
||||
fun all(instance: Any?): ArrayList<Instance>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Field` 实例处理类数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Field` 实例结果。
|
||||
|
||||
**功能示例**
|
||||
|
||||
你可以通过此方法来获得当前条件结果中匹配的全部 `Field`,其变量所在实例用法与 `get` 相同。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
field {
|
||||
// Your code here.
|
||||
}.all(instance).forEach { instance ->
|
||||
instance.self
|
||||
}
|
||||
```
|
||||
|
||||
#### give [method]
|
||||
|
||||
```kotlin
|
||||
@@ -263,7 +377,104 @@ fun give(): Field?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量本身。
|
||||
> 得到 `Field` 本身。
|
||||
|
||||
若有多个 Field 结果只会返回第一个。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回 `null`。
|
||||
|
||||
#### giveAll [method]
|
||||
|
||||
```kotlin
|
||||
fun giveAll(): HashSet<Field>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到 `Field` 本身数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Field` 实例。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回空的 `HashSet`。
|
||||
|
||||
#### wait [method]
|
||||
|
||||
```kotlin
|
||||
fun wait(instance: Any?, initiate: Instance.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Field` 实例处理类,配合 `RemedyPlan` 使用。
|
||||
|
||||
若有多个 `Field` 结果只会返回第一个。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
|
||||
#### waitAll [method]
|
||||
|
||||
```kotlin
|
||||
fun waitAll(instance: Any?, initiate: ArrayList<Instance>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Field` 实例处理类数组,配合 `RemedyPlan` 使用。
|
||||
|
||||
返回全部查询条件匹配的多个 `Field` 实例结果。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
|
||||
#### remedys [method]
|
||||
|
||||
```kotlin
|
||||
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 创建 `Field` 重查找功能。
|
||||
|
||||
**功能示例**
|
||||
|
||||
当你遇到一种 `Field` 可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchField` 捕获异常二次查找 `Field`。
|
||||
|
||||
若第一次查找失败了,你还可以在这里继续添加此方法体直到成功为止。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
field {
|
||||
// Your code here.
|
||||
}.remedys {
|
||||
field {
|
||||
// Your code here.
|
||||
}
|
||||
field {
|
||||
// Your code here.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### onNoSuchField [method]
|
||||
|
||||
@@ -277,7 +488,7 @@ fun onNoSuchField(result: (Throwable) -> Unit): Result
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 监听找不到变量时。
|
||||
> 监听找不到 `Field` 时。
|
||||
|
||||
#### ignoredError [method]
|
||||
|
||||
@@ -298,17 +509,37 @@ fun ignoredError(): Result
|
||||
#### Instance [class]
|
||||
|
||||
```kotlin
|
||||
inner class Instance internal constructor(private val instance: Any?, val self: Any?)
|
||||
inner class Instance internal constructor(private val instance: Any?, private val field: Field?)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0` `添加`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
新增 `field` 参数
|
||||
|
||||
移动 `self` 参数到类变量
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Field` 实例变量处理类。
|
||||
|
||||
##### self [field]
|
||||
|
||||
```kotlin
|
||||
val self: Any?
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获取当前 `Field` 自身的实例化对象。
|
||||
|
||||
##### cast [method]
|
||||
|
||||
```kotlin
|
||||
@@ -327,7 +558,7 @@ fun <T> cast(): T?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量实例。
|
||||
> 得到当前 `Field` 实例。
|
||||
|
||||
##### byte [method]
|
||||
|
||||
@@ -341,7 +572,7 @@ fun byte(): Byte?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Byte 实例。
|
||||
> 得到当前 `Field` Byte 实例。
|
||||
|
||||
##### int [method]
|
||||
|
||||
@@ -361,7 +592,7 @@ fun int(): Int
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Int 实例。
|
||||
> 得到当前 `Field` Int 实例。
|
||||
|
||||
##### long [method]
|
||||
|
||||
@@ -381,7 +612,7 @@ fun long(): Long
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Long 实例。
|
||||
> 得到当前 `Field` Long 实例。
|
||||
|
||||
##### short [method]
|
||||
|
||||
@@ -400,7 +631,7 @@ fun short(): Short
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Short 实例。
|
||||
> 得到当前 `Field` Short 实例。
|
||||
|
||||
##### double [method]
|
||||
|
||||
@@ -420,7 +651,7 @@ fun double(): Double
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Double 实例。
|
||||
> 得到当前 `Field` Double 实例。
|
||||
|
||||
##### float [method]
|
||||
|
||||
@@ -439,7 +670,7 @@ fun float(): Float
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Float 实例。
|
||||
> 得到当前 `Field` Float 实例。
|
||||
|
||||
##### string [method]
|
||||
|
||||
@@ -459,7 +690,7 @@ fun string(): String
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 String 实例。
|
||||
> 得到当前 `Field` String 实例。
|
||||
|
||||
##### char [method]
|
||||
|
||||
@@ -473,7 +704,7 @@ fun char(): Char
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Char 实例。
|
||||
> 得到当前 `Field` Char 实例。
|
||||
|
||||
##### boolean [method]
|
||||
|
||||
@@ -493,7 +724,7 @@ fun boolean(): Boolean
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Boolean 实例。
|
||||
> 得到当前 `Field` Boolean 实例。
|
||||
|
||||
##### any [method]
|
||||
|
||||
@@ -512,7 +743,7 @@ fun any(): Any?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Any 实例。
|
||||
> 得到当前 `Field` Any 实例。
|
||||
|
||||
##### array [method]
|
||||
|
||||
@@ -526,7 +757,7 @@ inline fun <reified T> array(): Array<T>
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 Array 实例。
|
||||
> 得到当前 `Field` Array 实例。
|
||||
|
||||
##### list [method]
|
||||
|
||||
@@ -540,7 +771,7 @@ inline fun <reified T> list(): List<T>
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到变量 List 实例。
|
||||
> 得到当前 `Field` List 实例。
|
||||
|
||||
##### set [method]
|
||||
|
||||
@@ -554,7 +785,7 @@ fun set(any: Any?)
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置变量实例。
|
||||
> 设置当前 `Field` 实例。
|
||||
|
||||
##### setTrue [method]
|
||||
|
||||
@@ -567,7 +798,7 @@ fun setTrue()
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置变量实例为 `true`。
|
||||
> 设置当前 `Field` 实例为 `true`。
|
||||
|
||||
!> 请确保实例对象类型为 `Boolean`。
|
||||
|
||||
@@ -583,7 +814,7 @@ fun setFalse()
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置变量实例为 `false`。
|
||||
> 设置当前 `Field` 实例为 `false`。
|
||||
|
||||
!> 请确保实例对象类型为 `Boolean`。
|
||||
|
||||
@@ -599,4 +830,4 @@ fun setNull()
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置变量实例为 `null`。
|
||||
> 设置当前 `Field` 实例为 `null`。
|
@@ -16,6 +16,8 @@ class MethodFinder internal constructor(override val hookInstance: YukiMemberHoo
|
||||
|
||||
> `Method` 查找类。
|
||||
|
||||
可通过指定类型查找指定方法或一组方法。
|
||||
|
||||
### name [field]
|
||||
|
||||
```kotlin
|
||||
@@ -66,7 +68,7 @@ var returnType: Any?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置 `Method` 返回值,可不填写返回值,默认模糊查找并取第一个匹配的 `Method`。
|
||||
> 设置 `Method` 返回值,可不填写返回值。
|
||||
|
||||
### modifiers [method]
|
||||
|
||||
@@ -86,7 +88,7 @@ inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition
|
||||
|
||||
> 设置 `Method` 标识符筛选条件。
|
||||
|
||||
可不设置筛选条件,默认模糊查找并取第一个匹配的 `Method`。
|
||||
可不设置筛选条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -154,7 +156,7 @@ fun name(value: String): IndexTypeCondition
|
||||
|
||||
> 设置 `Method` 名称。
|
||||
|
||||
!> 若不填写名称则必须存在一个其它条件,默认模糊查找并取第一个匹配的 `Method`。
|
||||
!> 若不填写名称则必须存在一个其它条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -172,7 +174,7 @@ inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition
|
||||
|
||||
> 设置 `Method` 名称条件。
|
||||
|
||||
!> 若不填写名称则必须存在一个其它条件,默认模糊查找并取第一个匹配的 `Method`。
|
||||
!> 若不填写名称则必须存在一个其它条件。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -196,6 +198,24 @@ fun paramCount(num: Int): IndexTypeCondition
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
### paramCount [method]
|
||||
|
||||
```kotlin
|
||||
fun paramCount(numRange: IntRange): IndexTypeCondition
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置 `Method` 参数个数范围。
|
||||
|
||||
你可以不使用 `param` 指定参数类型而是仅使用此方法指定参数个数范围。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
### returnType [method]
|
||||
|
||||
```kotlin
|
||||
@@ -210,7 +230,7 @@ fun returnType(value: Any): IndexTypeCondition
|
||||
|
||||
> 设置 `Method` 返回值。
|
||||
|
||||
可不填写返回值,默认模糊查找并取第一个匹配的 `Method`。
|
||||
可不填写返回值。
|
||||
|
||||
!> 存在多个 `IndexTypeCondition` 时除了 `order` 只会生效最后一个。
|
||||
|
||||
@@ -262,7 +282,7 @@ inline fun method(initiate: MethodFinder.() -> Unit): Result
|
||||
|
||||
> 创建需要重新查找的 `Method`。
|
||||
|
||||
你可以添加多个备选方法,直到成功为止,若最后依然失败,将停止查找并输出错误日志。
|
||||
你可以添加多个备选 `Method`,直到成功为止,若最后依然失败,将停止查找并输出错误日志。
|
||||
|
||||
#### Result [class]
|
||||
|
||||
@@ -281,13 +301,17 @@ inner class Result internal constructor()
|
||||
##### onFind [method]
|
||||
|
||||
```kotlin
|
||||
fun onFind(initiate: Method.() -> Unit)
|
||||
fun onFind(initiate: HashSet<Method>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.1` `新增`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
`initiate` 参数 `Method` 变为 `HashSet<Method>`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 当在 `RemedyPlan` 中找到结果时。
|
||||
@@ -309,13 +333,17 @@ method {
|
||||
### Result [class]
|
||||
|
||||
```kotlin
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, private val e: Throwable?)
|
||||
inner class Result internal constructor(internal val isNoSuch: Boolean, private val throwable: Throwable?) : BaseResult
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0` `添加`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
继承到接口 `BaseResult`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Method` 查找结果实现类。
|
||||
@@ -349,6 +377,7 @@ method {
|
||||
// Your code here.
|
||||
}.result {
|
||||
get(instance).call()
|
||||
all(instance)
|
||||
remedys {}
|
||||
onNoSuchMethod {}
|
||||
}
|
||||
@@ -368,6 +397,8 @@ fun get(instance: Any?): Instance
|
||||
|
||||
> 获得 `Method` 实例处理类。
|
||||
|
||||
若有多个 `Method` 结果只会返回第一个。
|
||||
|
||||
!> 若你设置了 `remedys` 请使用 `wait` 回调结果方法。
|
||||
|
||||
**功能示例**
|
||||
@@ -392,6 +423,36 @@ method {
|
||||
}.get().call()
|
||||
```
|
||||
|
||||
#### all [method]
|
||||
|
||||
```kotlin
|
||||
fun all(instance: Any?): ArrayList<Instance>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Method` 实例处理类数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Method` 实例结果并在 `isBindToHooker` 时设置到 `hookInstance`。
|
||||
|
||||
**功能示例**
|
||||
|
||||
你可以通过此方法来获得当前条件结果中匹配的全部 `Method`,其方法所在实例用法与 `get` 相同。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
method {
|
||||
// Your code here.
|
||||
}.all(instance).forEach { instance ->
|
||||
instance.call(...)
|
||||
}
|
||||
```
|
||||
|
||||
#### give [method]
|
||||
|
||||
```kotlin
|
||||
@@ -404,7 +465,29 @@ fun give(): Method?
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到方法本身。
|
||||
> 得到 `Method` 本身。
|
||||
|
||||
若有多个 `Method` 结果只会返回第一个。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回 `null`。
|
||||
|
||||
#### giveAll [method]
|
||||
|
||||
```kotlin
|
||||
fun giveAll(): HashSet<Method>
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 得到 `Method` 本身数组。
|
||||
|
||||
返回全部查询条件匹配的多个 `Method` 实例。
|
||||
|
||||
在查询条件找不到任何结果的时候将返回空的 `HashSet`。
|
||||
|
||||
#### wait [method]
|
||||
|
||||
@@ -420,6 +503,28 @@ fun wait(instance: Any?, initiate: Instance.() -> Unit)
|
||||
|
||||
> 获得 `Method` 实例处理类,配合 `RemedyPlan` 使用。
|
||||
|
||||
若有多个 `Method` 结果只会返回第一个。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
|
||||
#### waitAll [method]
|
||||
|
||||
```kotlin
|
||||
fun waitAll(instance: Any?, initiate: ArrayList<Instance>.() -> Unit)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获得 `Method` 实例处理类数组,配合 `RemedyPlan` 使用。
|
||||
|
||||
返回全部查询条件匹配的多个 `Method` 实例结果。
|
||||
|
||||
!> 若你设置了 `remedys` 必须使用此方法才能获得结果。
|
||||
|
||||
!> 若你没有设置 `remedys` 此方法将不会被回调。
|
||||
@@ -440,11 +545,11 @@ inline fun remedys(initiate: RemedyPlan.() -> Unit): Result
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 创建方法重查找功能。
|
||||
> 创建 `Method` 重查找功能。
|
||||
|
||||
**功能示例**
|
||||
|
||||
当你遇到一种方法可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchMethod` 捕获异常二次查找方法。
|
||||
当你遇到一种 `Method` 可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchMethod` 捕获异常二次查找 `Method`。
|
||||
|
||||
若第一次查找失败了,你还可以在这里继续添加此方法体直到成功为止。
|
||||
|
||||
@@ -479,7 +584,7 @@ inline fun onNoSuchMethod(result: (Throwable) -> Unit): Result
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 监听找不到方法时。
|
||||
> 监听找不到 `Method` 时。
|
||||
|
||||
只会返回第一次的错误信息,不会返回 `RemedyPlan` 的错误信息。
|
||||
|
||||
@@ -502,13 +607,17 @@ fun ignoredError(): Result
|
||||
#### Instance [class]
|
||||
|
||||
```kotlin
|
||||
inner class Instance internal constructor(private val instance: Any?)
|
||||
inner class Instance internal constructor(private val instance: Any?, private val method: Method?)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.2` `新增`
|
||||
|
||||
`v1.0.93` `修改`
|
||||
|
||||
新增 `method` 参数
|
||||
|
||||
**功能描述**
|
||||
|
||||
> `Method` 实例处理类。
|
||||
|
@@ -325,6 +325,58 @@ Test::class.java.method {
|
||||
|
||||
更多用法可参考 [NameConditions](api/document?id=nameconditions-class)。
|
||||
|
||||
### 多重查询
|
||||
|
||||
有些时候,我们可能需要查询一个 `Class` 中具有相同特征的一组方法、构造方法、变量,这个时候,我们就可以利用相对条件匹配来完成。
|
||||
|
||||
在查询条件结果的基础上,我们只需要把 `get` 换为 `all` 即可得到匹配条件的全部字节码。
|
||||
|
||||
假设这次我们要得到 `Class` 中方法参数个数范围在 `1..3` 的全部方法,可以使用如下实现。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
// 假设这就是这个 Class 的实例
|
||||
val instance = Test()
|
||||
// 使用 YukiHookAPI 调用并执行
|
||||
Test::class.java.method {
|
||||
paramCount(1..3)
|
||||
}.all(instance).forEach { instance ->
|
||||
// 调用执行每个方法
|
||||
instance.call(...)
|
||||
}
|
||||
```
|
||||
|
||||
上述示例可完美匹配到如下 3 个方法。
|
||||
|
||||
`private void doTask(String taskName)`
|
||||
|
||||
`private void release(Release release, Function<boolean, String> function, Task task)`
|
||||
|
||||
`private void b(String a)`
|
||||
|
||||
通过观察 `Class` 中有两个名称为 `b` 的方法,可以使用如下实现。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
// 假设这就是这个 Class 的实例
|
||||
val instance = Test()
|
||||
// 使用 YukiHookAPI 调用并执行
|
||||
Test::class.java.method {
|
||||
name = "b"
|
||||
}.all(instance).forEach { instance ->
|
||||
// 调用执行每个方法
|
||||
instance.call(...)
|
||||
}
|
||||
```
|
||||
|
||||
上述示例可完美匹配到如下 2 个方法。
|
||||
|
||||
`private void b()`
|
||||
|
||||
`private void b(String a)`
|
||||
|
||||
### 静态字节码
|
||||
|
||||
有些方法和变量在 `Class` 中是静态的实现,这个时候,我们不需要传入实例就可以调用它们。
|
||||
@@ -625,7 +677,7 @@ Test::class.java.method {
|
||||
|
||||
!> 特别注意使用了 `RemedyPlan` 的方法查询结果不能再使用 `get` 的方式得到方法实例,应当使用 `wait` 方法。
|
||||
|
||||
更多用法可参考 [Method RemedyPlan](api/document?id=remedyplan-class) 以及 [Constructor RemedyPlan](api/document?id=remedyplan-class-1)。
|
||||
更多用法可参考 [Method RemedyPlan](api/document?id=remedyplan-class)、[Constructor RemedyPlan](api/document?id=remedyplan-class-1)、[Field RemedyPlan](api/document?id=remedyplan-class-2)。
|
||||
|
||||
### 相对匹配
|
||||
|
||||
|
@@ -44,8 +44,8 @@ import java.lang.reflect.Constructor
|
||||
/**
|
||||
* [Constructor] 查找类
|
||||
*
|
||||
* 可通过指定类型查找指定构造方法
|
||||
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiMemberHookCreater.MemberHookCreater.member]
|
||||
* 可通过指定类型查找指定构造方法或一组构造方法
|
||||
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiMemberHookCreater.MemberHookCreater.members]
|
||||
* @param classSet 当前需要查找的 [Class] 实例
|
||||
*/
|
||||
class ConstructorFinder @PublishedApi internal constructor(
|
||||
@@ -67,6 +67,9 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
/** [Constructor] 参数数组 */
|
||||
private var paramTypes: Array<out Class<*>>? = null
|
||||
|
||||
/** [Constructor] 参数个数范围 */
|
||||
private var paramCountRange = IntRange.EMPTY
|
||||
|
||||
/** [ModifierRules] 实例 */
|
||||
@PublishedApi
|
||||
internal var modifiers: ModifierRules? = null
|
||||
@@ -140,6 +143,20 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
return IndexTypeCondition(IndexConfigType.MATCH)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 [Constructor] 参数个数范围
|
||||
*
|
||||
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param numRange 个数范围
|
||||
* @return [BaseFinder.IndexTypeCondition]
|
||||
*/
|
||||
fun paramCount(numRange: IntRange): IndexTypeCondition {
|
||||
paramCountRange = numRange
|
||||
return IndexTypeCondition(IndexConfigType.MATCH)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置在 [classSet] 的所有父类中查找当前 [Constructor]
|
||||
*
|
||||
@@ -152,30 +169,35 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到构造方法
|
||||
* @return [Constructor]
|
||||
* 得到构造方法或一组构造方法
|
||||
* @return [HashSet]<[Constructor]>
|
||||
* @throws NoSuchMethodError 如果找不到构造方法
|
||||
*/
|
||||
private val result
|
||||
get() = ReflectionTool.findConstructor(
|
||||
get() = ReflectionTool.findConstructors(
|
||||
usedClassSet, orderIndex, matchIndex, modifiers,
|
||||
paramCount, paramTypes, isFindInSuperClass
|
||||
paramCount, paramCountRange, paramTypes, isFindInSuperClass
|
||||
)
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
* @param constructor 当前找到的 [Constructor]
|
||||
* @param constructors 当前找到的 [Constructor] 数组
|
||||
*/
|
||||
private fun setInstance(isBind: Boolean, constructor: Constructor<*>) {
|
||||
memberInstance = constructor
|
||||
if (isBind) hookInstance?.member = constructor
|
||||
private fun setInstance(isBind: Boolean, constructors: HashSet<Constructor<*>>) {
|
||||
memberInstances.clear()
|
||||
val result = constructors.takeIf { it.isNotEmpty() }?.onEach { memberInstances.add(it) }?.first()
|
||||
if (isBind) hookInstance?.members?.apply {
|
||||
clear()
|
||||
result?.also { add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到构造方法结果
|
||||
* 得到 [Constructor] 结果
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
* @return [Result]
|
||||
*/
|
||||
@YukiPrivateApi
|
||||
@@ -184,7 +206,9 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
runBlocking {
|
||||
isBindToHooker = isBind
|
||||
setInstance(isBind, result)
|
||||
}.result { onHookLogMsg(msg = "Find Constructor [${memberInstance}] takes ${it}ms [${hookTag}]") }
|
||||
}.result { ms ->
|
||||
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onHookLogMsg(msg = "Find Constructor [$it] takes ${ms}ms [${hookTag}]") }
|
||||
}
|
||||
Result()
|
||||
} else Result(isNoSuch = true, Throwable("classSet is null"))
|
||||
} catch (e: Throwable) {
|
||||
@@ -216,7 +240,7 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 创建需要重新查找的 [Constructor]
|
||||
*
|
||||
* 你可以添加多个备选构造方法 - 直到成功为止
|
||||
* 你可以添加多个备选 [Constructor] - 直到成功为止
|
||||
*
|
||||
* 若最后依然失败 - 将停止查找并输出错误日志
|
||||
* @param initiate 方法体
|
||||
@@ -235,13 +259,15 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
runCatching {
|
||||
runBlocking {
|
||||
setInstance(isBindToHooker, it.first.result)
|
||||
}.result {
|
||||
onHookLogMsg(msg = "Find Constructor [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||
}.result { ms ->
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Find Constructor [$it] takes ${ms}ms [${hookTag}]") }
|
||||
}
|
||||
isFindSuccess = true
|
||||
it.second.onFindCallback?.invoke(memberInstance as Constructor<*>)
|
||||
it.second.onFindCallback?.invoke(memberInstances.constructors())
|
||||
remedyPlansCallback?.invoke()
|
||||
onHookLogMsg(msg = "Constructor [${memberInstance}] trying ${p + 1} times success by RemedyPlan [${hookTag}]")
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Constructor [$it] trying ${p + 1} times success by RemedyPlan [${hookTag}]") }
|
||||
return@run
|
||||
}.onFailure {
|
||||
lastError = it
|
||||
@@ -267,13 +293,13 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
inner class Result @PublishedApi internal constructor() {
|
||||
|
||||
/** 找到结果时的回调 */
|
||||
internal var onFindCallback: (Constructor<*>.() -> Unit)? = null
|
||||
internal var onFindCallback: (HashSet<Constructor<*>>.() -> Unit)? = null
|
||||
|
||||
/**
|
||||
* 当找到结果时
|
||||
* @param initiate 回调
|
||||
*/
|
||||
fun onFind(initiate: Constructor<*>.() -> Unit) {
|
||||
fun onFind(initiate: HashSet<Constructor<*>>.() -> Unit) {
|
||||
onFindCallback = initiate
|
||||
}
|
||||
}
|
||||
@@ -282,12 +308,12 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* [Constructor] 查找结果实现类
|
||||
* @param isNoSuch 是否没有找到构造方法 - 默认否
|
||||
* @param e 错误信息
|
||||
* @param throwable 错误信息
|
||||
*/
|
||||
inner class Result internal constructor(
|
||||
@PublishedApi internal val isNoSuch: Boolean = false,
|
||||
@PublishedApi internal val e: Throwable? = null
|
||||
) {
|
||||
@PublishedApi internal val throwable: Throwable? = null
|
||||
) : BaseResult {
|
||||
|
||||
/**
|
||||
* 创建监听结果事件方法体
|
||||
@@ -299,38 +325,89 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 获得 [Constructor] 实例处理类
|
||||
*
|
||||
* - ❗在 [memberInstance] 结果为空时使用此方法将无法获得对象
|
||||
* - 若有多个 [Constructor] 结果只会返回第一个
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
|
||||
* @return [Instance]
|
||||
*/
|
||||
fun get() = Instance()
|
||||
fun get() = Instance(give())
|
||||
|
||||
/**
|
||||
* 得到构造方法本身
|
||||
* 获得 [Constructor] 实例处理类数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Constructor] 实例结果并在 [isBindToHooker] 时设置到 [hookInstance]
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
|
||||
* @return [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun all(): ArrayList<Instance> {
|
||||
if (isBindToHooker) memberInstances.takeIf { it.isNotEmpty() }?.apply {
|
||||
hookInstance?.members?.clear()
|
||||
forEach { hookInstance?.members?.add(it) }
|
||||
}
|
||||
return arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(it)) } }
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到 [Constructor] 本身
|
||||
*
|
||||
* - 若有多个 [Constructor] 结果只会返回第一个
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回 null
|
||||
* @return [Constructor] or null
|
||||
*/
|
||||
fun give() = memberInstance as? Constructor<*>?
|
||||
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
|
||||
|
||||
/**
|
||||
* 得到 [Constructor] 本身数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Constructor] 实例
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回空的 [HashSet]
|
||||
* @return [HashSet]<[Constructor]>
|
||||
*/
|
||||
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.constructors() ?: HashSet()
|
||||
|
||||
/**
|
||||
* 获得 [Constructor] 实例处理类
|
||||
*
|
||||
* - 若有多个 [Constructor] 结果只会返回第一个
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
* @param initiate 回调 [Instance]
|
||||
*/
|
||||
fun wait(initiate: Instance.() -> Unit) {
|
||||
if (memberInstance != null) initiate(get())
|
||||
if (memberInstances.isNotEmpty()) initiate(get())
|
||||
else remedyPlansCallback = { initiate(get()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建构造方法重查找功能
|
||||
* 获得 [Constructor] 实例处理类数组
|
||||
*
|
||||
* 当你遇到一种构造方法可能存在不同形式的存在时
|
||||
* - 返回全部查询条件匹配的多个 [Constructor] 实例结果
|
||||
*
|
||||
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchConstructor] 捕获异常二次查找构造方法
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
* @param initiate 回调 [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun waitAll(initiate: ArrayList<Instance>.() -> Unit) {
|
||||
if (memberInstances.isNotEmpty()) initiate(all())
|
||||
else remedyPlansCallback = { initiate(all()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 [Constructor] 重查找功能
|
||||
*
|
||||
* 当你遇到一种 [Constructor] 可能存在不同形式的存在时
|
||||
*
|
||||
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchConstructor] 捕获异常二次查找 [Constructor]
|
||||
* @param initiate 方法体
|
||||
* @return [Result] 可继续向下监听
|
||||
*/
|
||||
@@ -341,14 +418,14 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听找不到构造方法时
|
||||
* 监听找不到 [Constructor] 时
|
||||
*
|
||||
* 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||
* @param result 回调错误
|
||||
* @return [Result] 可继续向下监听
|
||||
*/
|
||||
inline fun onNoSuchConstructor(result: (Throwable) -> Unit): Result {
|
||||
if (isNoSuch) result(e ?: Throwable())
|
||||
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -368,32 +445,33 @@ class ConstructorFinder @PublishedApi internal constructor(
|
||||
*
|
||||
* 调用与创建目标实例类对象
|
||||
*
|
||||
* - ❗请使用 [get] 或 [wait] 方法来获取 [Instance]
|
||||
* - ❗请使用 [get]、[wait]、[all]、[waitAll] 方法来获取 [Instance]
|
||||
* @param constructor 当前 [Constructor] 实例对象
|
||||
*/
|
||||
inner class Instance internal constructor() {
|
||||
inner class Instance internal constructor(private val constructor: Constructor<*>?) {
|
||||
|
||||
/**
|
||||
* 执行构造方法创建目标实例
|
||||
* 执行 [Constructor] 创建目标实例
|
||||
* @param param 构造方法参数
|
||||
* @return [Any] or null
|
||||
*/
|
||||
private fun baseCall(vararg param: Any?) = (memberInstance as? Constructor<*>?)?.newInstance(*param)
|
||||
private fun baseCall(vararg param: Any?) = constructor?.newInstance(*param)
|
||||
|
||||
/**
|
||||
* 执行构造方法创建目标实例 - 不指定目标实例类型
|
||||
* 执行 [Constructor] 创建目标实例 - 不指定目标实例类型
|
||||
* @param param 构造方法参数
|
||||
* @return [Any] or null
|
||||
*/
|
||||
fun call(vararg param: Any?) = baseCall(*param)
|
||||
|
||||
/**
|
||||
* 执行构造方法创建目标实例 - 指定 [T] 目标实例类型
|
||||
* 执行 [Constructor] 创建目标实例 - 指定 [T] 目标实例类型
|
||||
* @param param 构造方法参数
|
||||
* @return [T] or null
|
||||
*/
|
||||
fun <T> newInstance(vararg param: Any?) = baseCall(*param) as? T?
|
||||
|
||||
override fun toString() = "[${(memberInstance as? Constructor<*>?)?.name ?: "<empty>"}]"
|
||||
override fun toString() = "[${constructor?.name ?: "<empty>"}]"
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,13 +38,14 @@ import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
||||
import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions
|
||||
import com.highcapable.yukihookapi.hook.core.reflex.tools.ReflectionTool
|
||||
import com.highcapable.yukihookapi.hook.factory.hasExtends
|
||||
import com.highcapable.yukihookapi.hook.log.yLoggerW
|
||||
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* Field 查找类
|
||||
*
|
||||
* 可通过执行类型查找指定变量
|
||||
* 可通过指定类型查找指定变量或一组变量
|
||||
* @param hookInstance 当前 Hook 实例
|
||||
* @param classSet 当前需要查找的 [Class] 实例
|
||||
*/
|
||||
@@ -61,6 +62,9 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
/** 是否在未找到后继续在当前 [classSet] 的父类中查找 */
|
||||
private var isFindInSuperClass = false
|
||||
|
||||
/** 当前重查找结果回调 */
|
||||
private var remedyPlansCallback: (() -> Unit)? = null
|
||||
|
||||
/** [ModifierRules] 实例 */
|
||||
@PublishedApi
|
||||
internal var modifiers: ModifierRules? = null
|
||||
@@ -72,7 +76,7 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Field] 名称
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*/
|
||||
var name = ""
|
||||
|
||||
@@ -81,14 +85,14 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
*
|
||||
* - ❗只能是 [Class]、[String]、[VariousClass]
|
||||
*
|
||||
* - 可不填写类型 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - 可不填写类型
|
||||
*/
|
||||
var type: Any? = null
|
||||
|
||||
/**
|
||||
* 设置 [Field] 标识符筛选条件
|
||||
*
|
||||
* 可不设置筛选条件 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - 可不设置筛选条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param initiate 方法体
|
||||
@@ -108,7 +112,7 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Field] 名称
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param value 名称
|
||||
@@ -122,7 +126,7 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Field] 名称条件
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param initiate 方法体
|
||||
@@ -136,7 +140,7 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Field] 类型
|
||||
*
|
||||
* - 可不填写类型 - 默认模糊查找并取第一个匹配的 [Field]
|
||||
* - 可不填写类型
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param value 类型 - ❗只能是 [Class]、[String]、[VariousClass]
|
||||
@@ -159,7 +163,29 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到变量处理结果
|
||||
* 得到变量或一组变量
|
||||
* @return [HashSet]<[Field]>
|
||||
* @throws NoSuchFieldError 如果找不到变量
|
||||
*/
|
||||
private val result
|
||||
get() = ReflectionTool.findFields(
|
||||
usedClassSet, orderIndex,
|
||||
matchIndex, name,
|
||||
modifiers, nameConditions,
|
||||
type.compat(), isFindInSuperClass
|
||||
)
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
* @param fields 当前找到的 [Field] 数组
|
||||
*/
|
||||
private fun setInstance(fields: HashSet<Field>) {
|
||||
memberInstances.clear()
|
||||
fields.takeIf { it.isNotEmpty() }?.forEach { memberInstances.add(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到 [Field] 处理结果
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
@@ -170,13 +196,10 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
override fun build(isBind: Boolean) = try {
|
||||
if (classSet != null) {
|
||||
runBlocking {
|
||||
memberInstance = ReflectionTool.findField(
|
||||
usedClassSet, orderIndex,
|
||||
matchIndex, name,
|
||||
modifiers, nameConditions,
|
||||
type.compat(), isFindInSuperClass
|
||||
)
|
||||
}.result { onHookLogMsg(msg = "Find Field [${memberInstance}] takes ${it}ms [${hookTag}]") }
|
||||
setInstance(result)
|
||||
}.result {
|
||||
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onHookLogMsg(msg = "Find Field [$it] takes ${it}ms [${hookTag}]") }
|
||||
}
|
||||
Result()
|
||||
} else Result(isNoSuch = true, Throwable("classSet is null"))
|
||||
} catch (e: Throwable) {
|
||||
@@ -198,13 +221,96 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
@YukiPrivateApi
|
||||
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
||||
|
||||
/**
|
||||
* [Field] 重查找实现类
|
||||
*
|
||||
* 可累计失败次数直到查找成功
|
||||
*/
|
||||
inner class RemedyPlan @PublishedApi internal constructor() {
|
||||
|
||||
/** 失败尝试次数数组 */
|
||||
@PublishedApi
|
||||
internal val remedyPlans = HashSet<Pair<FieldFinder, Result>>()
|
||||
|
||||
/**
|
||||
* 创建需要重新查找的 [Field]
|
||||
*
|
||||
* 你可以添加多个备选 [Field] - 直到成功为止
|
||||
*
|
||||
* 若最后依然失败 - 将停止查找并输出错误日志
|
||||
* @param initiate 方法体
|
||||
* @return [Result] 结果
|
||||
*/
|
||||
inline fun field(initiate: FieldFinder.() -> Unit) =
|
||||
Result().apply { remedyPlans.add(Pair(FieldFinder(hookInstance, classSet).apply(initiate), this)) }
|
||||
|
||||
/** 开始重查找 */
|
||||
@PublishedApi
|
||||
internal fun build() {
|
||||
if (classSet == null) return
|
||||
if (remedyPlans.isNotEmpty()) run {
|
||||
var isFindSuccess = false
|
||||
var lastError: Throwable? = null
|
||||
remedyPlans.forEachIndexed { p, it ->
|
||||
runCatching {
|
||||
runBlocking {
|
||||
setInstance(it.first.result)
|
||||
}.result { ms ->
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Find Field [$it] takes ${ms}ms [${hookTag}]") }
|
||||
}
|
||||
isFindSuccess = true
|
||||
it.second.onFindCallback?.invoke(memberInstances.fields())
|
||||
remedyPlansCallback?.invoke()
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Field [$it] trying ${p + 1} times success by RemedyPlan [${hookTag}]") }
|
||||
return@run
|
||||
}.onFailure {
|
||||
lastError = it
|
||||
onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true)
|
||||
}
|
||||
}
|
||||
if (isFindSuccess.not()) {
|
||||
onFailureMsg(
|
||||
msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan",
|
||||
throwable = lastError,
|
||||
isAlwaysPrint = true
|
||||
)
|
||||
remedyPlans.clear()
|
||||
}
|
||||
} else yLoggerW(msg = "RemedyPlan is empty, forgot it? [${hookTag}]")
|
||||
}
|
||||
|
||||
/**
|
||||
* [RemedyPlan] 结果实现类
|
||||
*
|
||||
* 可在这里处理是否成功的回调
|
||||
*/
|
||||
inner class Result @PublishedApi internal constructor() {
|
||||
|
||||
/** 找到结果时的回调 */
|
||||
internal var onFindCallback: (HashSet<Field>.() -> Unit)? = null
|
||||
|
||||
/**
|
||||
* 当找到结果时
|
||||
* @param initiate 回调
|
||||
*/
|
||||
fun onFind(initiate: HashSet<Field>.() -> Unit) {
|
||||
onFindCallback = initiate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Field] 查找结果实现类
|
||||
*
|
||||
* @param isNoSuch 是否没有找到变量 - 默认否
|
||||
* @param e 错误信息
|
||||
* @param throwable 错误信息
|
||||
*/
|
||||
inner class Result internal constructor(@PublishedApi internal val isNoSuch: Boolean = false, private val e: Throwable? = null) {
|
||||
inner class Result internal constructor(
|
||||
@PublishedApi internal val isNoSuch: Boolean = false,
|
||||
private val throwable: Throwable? = null
|
||||
) : BaseResult {
|
||||
|
||||
/**
|
||||
* 创建监听结果事件方法体
|
||||
@@ -214,32 +320,114 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||
|
||||
/**
|
||||
* 得到变量实例处理类
|
||||
* 获得 [Field] 实例处理类
|
||||
*
|
||||
* - 若有多个 [Field] 结果只会返回第一个
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗如果目标对象不是静态 - 你必须设置 [instance]
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
|
||||
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
|
||||
* @return [Instance]
|
||||
*/
|
||||
fun get(instance: Any? = null) = try {
|
||||
Instance(instance, give()?.get(instance))
|
||||
} catch (e: Throwable) {
|
||||
onFailureMsg(msg = "Try to get field instance failed", throwable = e)
|
||||
Instance(instance, self = null)
|
||||
fun get(instance: Any? = null) = Instance(instance, give())
|
||||
|
||||
/**
|
||||
* 获得 [Field] 实例处理类数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Field] 实例结果
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗如果目标对象不是静态 - 你必须设置 [instance]
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
|
||||
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
|
||||
* @return [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun all(instance: Any? = null) =
|
||||
arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(instance, it)) } }
|
||||
|
||||
/**
|
||||
* 得到 [Field] 本身
|
||||
*
|
||||
* - 若有多个 [Field] 结果只会返回第一个
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回 null
|
||||
* @return [Field] or null
|
||||
*/
|
||||
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
|
||||
|
||||
/**
|
||||
* 得到 [Field] 本身数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Field] 实例
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回空的 [HashSet]
|
||||
* @return [HashSet]<[Field]>
|
||||
*/
|
||||
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.fields() ?: HashSet()
|
||||
|
||||
/**
|
||||
* 获得 [Field] 实例处理类
|
||||
*
|
||||
* - 若有多个 [Field] 结果只会返回第一个
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
* @param instance 所在实例
|
||||
* @param initiate 回调 [Instance]
|
||||
*/
|
||||
fun wait(instance: Any? = null, initiate: Instance.() -> Unit) {
|
||||
if (memberInstances.isNotEmpty()) initiate(get(instance))
|
||||
else remedyPlansCallback = { initiate(get(instance)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到变量本身
|
||||
* @return [Field] or null
|
||||
* 获得 [Field] 实例处理类数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Field] 实例结果
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
* @param instance 所在实例
|
||||
* @param initiate 回调 [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun give() = memberInstance as? Field?
|
||||
fun waitAll(instance: Any? = null, initiate: ArrayList<Instance>.() -> Unit) {
|
||||
if (memberInstances.isNotEmpty()) initiate(all(instance))
|
||||
else remedyPlansCallback = { initiate(all(instance)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听找不到变量时
|
||||
* 创建 [Field] 重查找功能
|
||||
*
|
||||
* 当你遇到一种方法可能存在不同形式的存在时
|
||||
*
|
||||
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchField] 捕获异常二次查找 [Field]
|
||||
*
|
||||
* 若第一次查找失败了 - 你还可以在这里继续添加此方法体直到成功为止
|
||||
* @param initiate 方法体
|
||||
* @return [Result] 可继续向下监听
|
||||
*/
|
||||
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
|
||||
isUsingRemedyPlan = true
|
||||
if (isNoSuch) RemedyPlan().apply(initiate).build()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听找不到 [Field] 时
|
||||
*
|
||||
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||
* @param result 回调错误
|
||||
* @return [Result] 可继续向下监听
|
||||
*/
|
||||
fun onNoSuchField(result: (Throwable) -> Unit): Result {
|
||||
if (isNoSuch) result(e ?: Throwable())
|
||||
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -255,135 +443,141 @@ class FieldFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* [Field] 实例变量处理类
|
||||
* [Field] 实例处理类
|
||||
*
|
||||
* - ❗请使用 [get] 方法来获取 [Instance]
|
||||
* - ❗请使用 [get]、[all] 方法来获取 [Instance]
|
||||
* @param instance 当前 [Field] 所在类的实例对象
|
||||
* @param self 当前 [Field] 自身的实例对象
|
||||
* @param field 当前 [Field] 实例对象
|
||||
*/
|
||||
inner class Instance internal constructor(private val instance: Any?, val self: Any?) {
|
||||
inner class Instance internal constructor(private val instance: Any?, private val field: Field?) {
|
||||
|
||||
/**
|
||||
* 得到变量实例
|
||||
* 获取当前 [Field] 自身的实例化对象
|
||||
* @return [Any] or null
|
||||
*/
|
||||
val self get() = field?.get(instance)
|
||||
|
||||
/**
|
||||
* 得到当前 [Field] 实例
|
||||
* @return [T] or null
|
||||
*/
|
||||
fun <T> cast() = self as? T?
|
||||
|
||||
/**
|
||||
* 得到变量的 [Byte] 实例
|
||||
* 得到当前 [Field] 的 [Byte] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回 null
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回 null
|
||||
* @return [Byte] or null
|
||||
*/
|
||||
fun byte() = cast<Byte?>()
|
||||
|
||||
/**
|
||||
* 得到变量的 [Int] 实例
|
||||
* 得到当前 [Field] 的 [Int] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Int] 取不到返回 0
|
||||
*/
|
||||
fun int() = cast() ?: 0
|
||||
|
||||
/**
|
||||
* 得到变量的 [Long] 实例
|
||||
* 得到当前 [Field] 的 [Long] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Long] 取不到返回 0L
|
||||
*/
|
||||
fun long() = cast() ?: 0L
|
||||
|
||||
/**
|
||||
* 得到变量的 [Short] 实例
|
||||
* 得到当前 [Field] 的 [Short] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Short] 取不到返回 0
|
||||
*/
|
||||
fun short() = cast<Short?>() ?: 0
|
||||
|
||||
/**
|
||||
* 得到变量的 [Double] 实例
|
||||
* 得到当前 [Field] 的 [Double] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Double] 取不到返回 0.0
|
||||
*/
|
||||
fun double() = cast() ?: 0.0
|
||||
|
||||
/**
|
||||
* 得到变量的 [Float] 实例
|
||||
* 得到当前 [Field] 的 [Float] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Float] 取不到返回 0f
|
||||
*/
|
||||
fun float() = cast() ?: 0f
|
||||
|
||||
/**
|
||||
* 得到变量的 [String] 实例
|
||||
* 得到当前 [Field] 的 [String] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [String] 取不到返回 ""
|
||||
*/
|
||||
fun string() = cast() ?: ""
|
||||
|
||||
/**
|
||||
* 得到变量的 [Char] 实例
|
||||
* 得到当前 [Field] 的 [Char] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Char] 取不到返回 ' '
|
||||
*/
|
||||
fun char() = cast() ?: ' '
|
||||
|
||||
/**
|
||||
* 得到变量的 [Boolean] 实例
|
||||
* 得到当前 [Field] 的 [Boolean] 实例
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回默认值
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回默认值
|
||||
* @return [Boolean] 取不到返回 false
|
||||
*/
|
||||
fun boolean() = cast() ?: false
|
||||
|
||||
/**
|
||||
* 得到变量的 [Any] 实例
|
||||
* 得到当前 [Field] 的 [Any] 实例
|
||||
* @return [Any] or null
|
||||
*/
|
||||
fun any() = cast<Any?>()
|
||||
|
||||
/**
|
||||
* 得到变量的 [Array] 实例 - 每项类型 [T]
|
||||
* 得到当前 [Field] 的 [Array] 实例 - 每项类型 [T]
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回空数组
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回空数组
|
||||
* @return [Array] 取不到返回空数组
|
||||
*/
|
||||
inline fun <reified T> array() = cast() ?: arrayOf<T>()
|
||||
|
||||
/**
|
||||
* 得到变量的 [List] 实例 - 每项类型 [T]
|
||||
* 得到当前 [Field] 的 [List] 实例 - 每项类型 [T]
|
||||
*
|
||||
* - ❗请确认目标变量的类型 - 发生错误会返回空数组
|
||||
* - ❗请确认目标 [Field] 的类型 - 发生错误会返回空数组
|
||||
* @return [List] 取不到返回空数组
|
||||
*/
|
||||
inline fun <reified T> list() = cast() ?: listOf<T>()
|
||||
|
||||
/**
|
||||
* 设置变量实例
|
||||
* 设置当前 [Field] 实例
|
||||
* @param any 设置的实例内容
|
||||
*/
|
||||
fun set(any: Any?) = give()?.set(instance, any)
|
||||
fun set(any: Any?) = field?.set(instance, any)
|
||||
|
||||
/**
|
||||
* 设置变量实例为 true
|
||||
* 设置当前 [Field] 实例为 true
|
||||
*
|
||||
* - ❗请确保示例对象类型为 [Boolean]
|
||||
*/
|
||||
fun setTrue() = set(true)
|
||||
|
||||
/**
|
||||
* 设置变量实例为 true
|
||||
* 设置当前 [Field] 实例为 true
|
||||
*
|
||||
* - ❗请确保示例对象类型为 [Boolean]
|
||||
*/
|
||||
fun setFalse() = set(false)
|
||||
|
||||
/** 设置变量实例为 null */
|
||||
/** 设置当前 [Field] 实例为 null */
|
||||
fun setNull() = set(null)
|
||||
|
||||
override fun toString() =
|
||||
|
@@ -46,8 +46,8 @@ import java.lang.reflect.Method
|
||||
/**
|
||||
* [Method] 查找类
|
||||
*
|
||||
* 可通过指定类型查找指定方法
|
||||
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiMemberHookCreater.MemberHookCreater.member]
|
||||
* 可通过指定类型查找指定方法或一组方法
|
||||
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiMemberHookCreater.MemberHookCreater.members]
|
||||
* @param classSet 当前需要查找的 [Class] 实例
|
||||
*/
|
||||
class MethodFinder @PublishedApi internal constructor(
|
||||
@@ -69,6 +69,9 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/** [Method] 参数数组 */
|
||||
private var paramTypes: Array<out Class<*>>? = null
|
||||
|
||||
/** [Method] 参数个数范围 */
|
||||
private var paramCountRange = IntRange.EMPTY
|
||||
|
||||
/** [ModifierRules] 实例 */
|
||||
@PublishedApi
|
||||
internal var modifiers: ModifierRules? = null
|
||||
@@ -80,7 +83,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Method] 名称
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*/
|
||||
var name = ""
|
||||
|
||||
@@ -98,14 +101,14 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
*
|
||||
* - ❗只能是 [Class]、[String]、[VariousClass]
|
||||
*
|
||||
* - 可不填写返回值 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - 可不填写返回值
|
||||
*/
|
||||
var returnType: Any? = null
|
||||
|
||||
/**
|
||||
* 设置 [Method] 标识符筛选条件
|
||||
*
|
||||
* 可不设置筛选条件 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - 可不设置筛选条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param initiate 方法体
|
||||
@@ -151,7 +154,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Method] 名称
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param value 名称
|
||||
@@ -165,7 +168,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 设置 [Method] 名称条件
|
||||
*
|
||||
* - ❗若不填写名称则必须存在一个其它条件 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - ❗若不填写名称则必须存在一个其它条件
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param initiate 方法体
|
||||
@@ -192,10 +195,24 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
return IndexTypeCondition(IndexConfigType.MATCH)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 [Method] 参数个数范围
|
||||
*
|
||||
* 你可以不使用 [param] 指定参数类型而是仅使用此方法指定参数个数范围
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param numRange 个数范围
|
||||
* @return [BaseFinder.IndexTypeCondition]
|
||||
*/
|
||||
fun paramCount(numRange: IntRange): IndexTypeCondition {
|
||||
paramCountRange = numRange
|
||||
return IndexTypeCondition(IndexConfigType.MATCH)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 [Method] 返回值
|
||||
*
|
||||
* 可不填写返回值 - 默认模糊查找并取第一个匹配的 [Method]
|
||||
* - 可不填写返回值
|
||||
*
|
||||
* - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个
|
||||
* @param value 个数
|
||||
@@ -218,29 +235,33 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到方法
|
||||
* @return [Method]
|
||||
* 得到方法或一组方法
|
||||
* @return [HashSet]<[Method]>
|
||||
* @throws NoSuchMethodError 如果找不到方法
|
||||
*/
|
||||
private val result
|
||||
get() = ReflectionTool.findMethod(
|
||||
get() = ReflectionTool.findMethods(
|
||||
usedClassSet, orderIndex, matchIndex, name,
|
||||
modifiers, nameConditions, returnType.compat(),
|
||||
paramCount, paramTypes, isFindInSuperClass
|
||||
paramCount, paramCountRange, paramTypes, isFindInSuperClass
|
||||
)
|
||||
|
||||
/**
|
||||
* 设置实例
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
* @param method 当前找到的 [Method]
|
||||
* @param methods 当前找到的 [Method] 数组
|
||||
*/
|
||||
private fun setInstance(isBind: Boolean, method: Method) {
|
||||
memberInstance = method
|
||||
if (isBind) hookInstance?.member = method
|
||||
private fun setInstance(isBind: Boolean, methods: HashSet<Method>) {
|
||||
memberInstances.clear()
|
||||
val result = methods.takeIf { it.isNotEmpty() }?.onEach { memberInstances.add(it) }?.first()
|
||||
if (isBind) hookInstance?.members?.apply {
|
||||
clear()
|
||||
result?.also { add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到方法结果
|
||||
* 得到 [Method] 结果
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
@@ -252,7 +273,9 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
runBlocking {
|
||||
isBindToHooker = isBind
|
||||
setInstance(isBind, result)
|
||||
}.result { onHookLogMsg(msg = "Find Method [${memberInstance}] takes ${it}ms [${hookTag}]") }
|
||||
}.result { ms ->
|
||||
memberInstances.takeIf { it.isNotEmpty() }?.forEach { onHookLogMsg(msg = "Find Method [$it] takes ${ms}ms [${hookTag}]") }
|
||||
}
|
||||
Result()
|
||||
} else Result(isNoSuch = true, Throwable("classSet is null"))
|
||||
} catch (e: Throwable) {
|
||||
@@ -284,7 +307,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 创建需要重新查找的 [Method]
|
||||
*
|
||||
* 你可以添加多个备选方法 - 直到成功为止
|
||||
* 你可以添加多个备选 [Method] - 直到成功为止
|
||||
*
|
||||
* 若最后依然失败 - 将停止查找并输出错误日志
|
||||
* @param initiate 方法体
|
||||
@@ -304,13 +327,15 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
runCatching {
|
||||
runBlocking {
|
||||
setInstance(isBindToHooker, it.first.result)
|
||||
}.result {
|
||||
onHookLogMsg(msg = "Find Method [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||
}.result { ms ->
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Find Method [$it] takes ${ms}ms [${hookTag}]") }
|
||||
}
|
||||
isFindSuccess = true
|
||||
it.second.onFindCallback?.invoke(memberInstance as Method)
|
||||
it.second.onFindCallback?.invoke(memberInstances.methods())
|
||||
remedyPlansCallback?.invoke()
|
||||
onHookLogMsg(msg = "Method [${memberInstance}] trying ${p + 1} times success by RemedyPlan [${hookTag}]")
|
||||
memberInstances.takeIf { it.isNotEmpty() }
|
||||
?.forEach { onHookLogMsg(msg = "Method [$it] trying ${p + 1} times success by RemedyPlan [${hookTag}]") }
|
||||
return@run
|
||||
}.onFailure {
|
||||
lastError = it
|
||||
@@ -336,13 +361,13 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
inner class Result @PublishedApi internal constructor() {
|
||||
|
||||
/** 找到结果时的回调 */
|
||||
internal var onFindCallback: (Method.() -> Unit)? = null
|
||||
internal var onFindCallback: (HashSet<Method>.() -> Unit)? = null
|
||||
|
||||
/**
|
||||
* 当找到结果时
|
||||
* @param initiate 回调
|
||||
*/
|
||||
fun onFind(initiate: Method.() -> Unit) {
|
||||
fun onFind(initiate: HashSet<Method>.() -> Unit) {
|
||||
onFindCallback = initiate
|
||||
}
|
||||
}
|
||||
@@ -351,12 +376,12 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* [Method] 查找结果实现类
|
||||
* @param isNoSuch 是否没有找到方法 - 默认否
|
||||
* @param e 错误信息
|
||||
* @param throwable 错误信息
|
||||
*/
|
||||
inner class Result internal constructor(
|
||||
@PublishedApi internal val isNoSuch: Boolean = false,
|
||||
@PublishedApi internal val e: Throwable? = null
|
||||
) {
|
||||
@PublishedApi internal val throwable: Throwable? = null
|
||||
) : BaseResult {
|
||||
|
||||
/**
|
||||
* 创建监听结果事件方法体
|
||||
@@ -368,23 +393,60 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* 获得 [Method] 实例处理类
|
||||
*
|
||||
* - ❗在 [memberInstance] 结果为空时使用此方法将无法获得对象
|
||||
* - 若有多个 [Method] 结果只会返回第一个
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
|
||||
* @param instance 所在实例
|
||||
* @return [Instance]
|
||||
*/
|
||||
fun get(instance: Any? = null) = Instance(instance)
|
||||
fun get(instance: Any? = null) = Instance(instance, give())
|
||||
|
||||
/**
|
||||
* 得到方法本身
|
||||
* 获得 [Method] 实例处理类数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Method] 实例结果并在 [isBindToHooker] 时设置到 [hookInstance]
|
||||
*
|
||||
* - ❗在 [memberInstances] 结果为空时使用此方法将无法获得对象
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 请使用 [waitAll] 回调结果方法
|
||||
* @param instance 所在实例
|
||||
* @return [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun all(instance: Any? = null): ArrayList<Instance> {
|
||||
if (isBindToHooker) memberInstances.takeIf { it.isNotEmpty() }?.apply {
|
||||
hookInstance?.members?.clear()
|
||||
forEach { hookInstance?.members?.add(it) }
|
||||
}
|
||||
return arrayListOf<Instance>().apply { giveAll().takeIf { it.isNotEmpty() }?.forEach { add(Instance(instance, it)) } }
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到 [Method] 本身
|
||||
*
|
||||
* - 若有多个 [Method] 结果只会返回第一个
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回 null
|
||||
* @return [Method] or null
|
||||
*/
|
||||
fun give() = memberInstance as? Method?
|
||||
fun give() = giveAll().takeIf { it.isNotEmpty() }?.first()
|
||||
|
||||
/**
|
||||
* 得到 [Method] 本身数组
|
||||
*
|
||||
* - 返回全部查询条件匹配的多个 [Method] 实例
|
||||
*
|
||||
* - 在查询条件找不到任何结果的时候将返回空的 [HashSet]
|
||||
* @return [HashSet]<[Method]>
|
||||
*/
|
||||
fun giveAll() = memberInstances.takeIf { it.isNotEmpty() }?.methods() ?: HashSet()
|
||||
|
||||
/**
|
||||
* 获得 [Method] 实例处理类
|
||||
*
|
||||
* - 若有多个 [Method] 结果只会返回第一个
|
||||
*
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
@@ -392,16 +454,32 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
* @param initiate 回调 [Instance]
|
||||
*/
|
||||
fun wait(instance: Any? = null, initiate: Instance.() -> Unit) {
|
||||
if (memberInstance != null) initiate(get(instance))
|
||||
if (memberInstances.isNotEmpty()) initiate(get(instance))
|
||||
else remedyPlansCallback = { initiate(get(instance)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建方法重查找功能
|
||||
* 获得 [Method] 实例处理类数组
|
||||
*
|
||||
* 当你遇到一种方法可能存在不同形式的存在时
|
||||
* - 返回全部查询条件匹配的多个 [Method] 实例结果
|
||||
*
|
||||
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchMethod] 捕获异常二次查找方法
|
||||
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||
*
|
||||
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||
* @param instance 所在实例
|
||||
* @param initiate 回调 [ArrayList]<[Instance]>
|
||||
*/
|
||||
fun waitAll(instance: Any? = null, initiate: ArrayList<Instance>.() -> Unit) {
|
||||
if (memberInstances.isNotEmpty()) initiate(all(instance))
|
||||
else remedyPlansCallback = { initiate(all(instance)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 [Method] 重查找功能
|
||||
*
|
||||
* 当你遇到一种 [Method] 可能存在不同形式的存在时
|
||||
*
|
||||
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchMethod] 捕获异常二次查找 [Method]
|
||||
*
|
||||
* 若第一次查找失败了 - 你还可以在这里继续添加此方法体直到成功为止
|
||||
* @param initiate 方法体
|
||||
@@ -414,14 +492,14 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听找不到方法时
|
||||
* 监听找不到 [Method] 时
|
||||
*
|
||||
* 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||
* - 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||
* @param result 回调错误
|
||||
* @return [Result] 可继续向下监听
|
||||
*/
|
||||
inline fun onNoSuchMethod(result: (Throwable) -> Unit): Result {
|
||||
if (isNoSuch) result(e ?: Throwable("Initialization Error"))
|
||||
if (isNoSuch) result(throwable ?: Throwable("Initialization Error"))
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -439,10 +517,11 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
/**
|
||||
* [Method] 实例处理类
|
||||
*
|
||||
* - ❗请使用 [get] 或 [wait] 方法来获取 [Instance]
|
||||
* - ❗请使用 [get]、[wait]、[all]、[waitAll] 方法来获取 [Instance]
|
||||
* @param instance 当前 [Method] 所在类的实例对象
|
||||
* @param method 当前 [Method] 实例对象
|
||||
*/
|
||||
inner class Instance internal constructor(private val instance: Any?) {
|
||||
inner class Instance internal constructor(private val instance: Any?, private val method: Method?) {
|
||||
|
||||
/** 标识需要调用当前 [Method] 未经 Hook 的原始方法 */
|
||||
private var isCallOriginal = false
|
||||
@@ -465,11 +544,10 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
* @param param 方法参数
|
||||
* @return [Any] or null
|
||||
*/
|
||||
private fun baseCall(vararg param: Any?) = (memberInstance as? Method?)?.let {
|
||||
private fun baseCall(vararg param: Any?) =
|
||||
if (isCallOriginal)
|
||||
YukiHookHelper.invokeOriginalMember(it, instance, *param) ?: it.invoke(instance, *param)
|
||||
else it.invoke(instance, *param)
|
||||
}
|
||||
method?.let { YukiHookHelper.invokeOriginalMember(it, instance, *param) ?: it.invoke(instance, *param) }
|
||||
else method?.invoke(instance, *param)
|
||||
|
||||
/**
|
||||
* 执行方法 - 不指定返回值类型
|
||||
@@ -578,8 +656,7 @@ class MethodFinder @PublishedApi internal constructor(
|
||||
*/
|
||||
inline fun <reified T> list(vararg param: Any?) = invoke(*param) ?: listOf<T>()
|
||||
|
||||
override fun toString() =
|
||||
"[${(memberInstance as? Method?)?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}]"
|
||||
override fun toString() = "[${method?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}]"
|
||||
}
|
||||
}
|
||||
}
|
@@ -37,7 +37,10 @@ import com.highcapable.yukihookapi.hook.log.yLoggerE
|
||||
import com.highcapable.yukihookapi.hook.log.yLoggerI
|
||||
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
@@ -46,7 +49,7 @@ import kotlin.math.abs
|
||||
* @param hookInstance 当前 Hook 实例
|
||||
* @param classSet 当前需要查找的 [Class] 实例
|
||||
*/
|
||||
abstract class BaseFinder(
|
||||
abstract class BaseFinder internal constructor(
|
||||
private val tag: String,
|
||||
open val hookInstance: YukiMemberHookCreater.MemberHookCreater? = null,
|
||||
open val classSet: Class<*>? = null
|
||||
@@ -127,8 +130,8 @@ abstract class BaseFinder(
|
||||
/** 是否开启忽略错误警告功能 */
|
||||
internal var isShutErrorPrinting = false
|
||||
|
||||
/** 当前找到的 [Member] */
|
||||
internal var memberInstance: Member? = null
|
||||
/** 当前找到的 [Member] 数组 */
|
||||
internal var memberInstances = HashSet<Member>()
|
||||
|
||||
/**
|
||||
* 获取当前使用的 TAG
|
||||
@@ -145,6 +148,27 @@ abstract class BaseFinder(
|
||||
/** 需要输出的日志内容 */
|
||||
private var loggingContent: Pair<String, Throwable?>? = null
|
||||
|
||||
/**
|
||||
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Field]>
|
||||
* @return [HashSet]<[Field]>
|
||||
*/
|
||||
internal fun HashSet<Member>.fields() =
|
||||
hashSetOf<Field>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Field?)?.also { f -> it.add(f) } } }
|
||||
|
||||
/**
|
||||
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Method]>
|
||||
* @return [HashSet]<[Method]>
|
||||
*/
|
||||
internal fun HashSet<Member>.methods() =
|
||||
hashSetOf<Method>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Method?)?.also { m -> it.add(m) } } }
|
||||
|
||||
/**
|
||||
* 将 [HashSet]<[Member]> 转换为 [HashSet]<[Constructor]>
|
||||
* @return [HashSet]<[Constructor]>
|
||||
*/
|
||||
internal fun HashSet<Member>.constructors() =
|
||||
hashSetOf<Constructor<*>>().also { takeIf { e -> e.isNotEmpty() }?.forEach { e -> (e as? Constructor<*>?)?.also { c -> it.add(c) } } }
|
||||
|
||||
/**
|
||||
* 将目标类型转换为可识别的兼容类型
|
||||
* @return [Class] or null
|
||||
@@ -208,18 +232,26 @@ abstract class BaseFinder(
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @param isBind 是否将结果设置到目标 [YukiMemberHookCreater.MemberHookCreater]
|
||||
* @return [Any]
|
||||
* @return [BaseResult]
|
||||
*/
|
||||
@YukiPrivateApi
|
||||
abstract fun build(isBind: Boolean = false): Any
|
||||
abstract fun build(isBind: Boolean = false): BaseResult
|
||||
|
||||
/**
|
||||
* 创建一个异常结果
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @param throwable 异常
|
||||
* @return [Any]
|
||||
* @return [BaseResult]
|
||||
*/
|
||||
@YukiPrivateApi
|
||||
abstract fun failure(throwable: Throwable?): Any
|
||||
abstract fun failure(throwable: Throwable?): BaseResult
|
||||
|
||||
/**
|
||||
* 查找结果实现类接口
|
||||
*
|
||||
* - ❗此功能交由方法体自动完成 - 你不应该手动继承此接口
|
||||
*/
|
||||
@YukiPrivateApi
|
||||
interface BaseResult
|
||||
}
|
@@ -47,7 +47,7 @@ internal object ReflectionTool {
|
||||
private const val TAG = "YukiHookAPI#ReflectionTool"
|
||||
|
||||
/**
|
||||
* 查找任意变量
|
||||
* 查找任意变量或一组变量
|
||||
* @param classSet 变量所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
@@ -56,11 +56,11 @@ internal object ReflectionTool {
|
||||
* @param nameConditions 名称查找条件
|
||||
* @param type 变量类型
|
||||
* @param isFindInSuperClass 是否在未找到后继续在当前 [classSet] 的父类中查找
|
||||
* @return [Field]
|
||||
* @return [HashSet]<[Field]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [type] 目标类不存在
|
||||
* @throws NoSuchFieldError 如果找不到变量
|
||||
*/
|
||||
internal fun findField(
|
||||
internal fun findFields(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
@@ -69,13 +69,13 @@ internal object ReflectionTool {
|
||||
nameConditions: NameConditions?,
|
||||
type: Class<*>?,
|
||||
isFindInSuperClass: Boolean
|
||||
): Field {
|
||||
): HashSet<Field> {
|
||||
if (type == UndefinedType) error("Field match type class is not found")
|
||||
if (orderIndex == null && matchIndex == null && name.isBlank() && modifiers == null && type == null)
|
||||
error("You must set a condition when finding a Field")
|
||||
val hashCode = ("[$orderIndex][$matchIndex][$name][$type][$modifiers][$classSet]").hashCode()
|
||||
return MemberCacheStore.findField(hashCode) ?: let {
|
||||
var field: Field? = null
|
||||
return MemberCacheStore.findFields(hashCode) ?: let {
|
||||
val fields = HashSet<Field>()
|
||||
classSet?.declaredFields?.apply {
|
||||
var typeIndex = -1
|
||||
var nameIndex = -1
|
||||
@@ -132,15 +132,12 @@ internal object ReflectionTool {
|
||||
(conditions && ((orderIndex.first >= 0 && orderIndex.first == p && orderIndex.second) ||
|
||||
(orderIndex.first < 0 && abs(orderIndex.first) == (lastIndex - p) && orderIndex.second) ||
|
||||
(lastIndex == p && orderIndex.second.not()))).also { isMatched = true }
|
||||
if (conditions && isMatched) {
|
||||
field = it.apply { isAccessible = true }
|
||||
return@apply
|
||||
}
|
||||
if (conditions && isMatched) fields.add(it.apply { isAccessible = true })
|
||||
}
|
||||
} ?: error("Can't find this Field [$name] because classSet is null")
|
||||
field?.also { MemberCacheStore.putField(hashCode, field) }
|
||||
fields.takeIf { it.isNotEmpty() }?.also { MemberCacheStore.putFields(hashCode, fields) }
|
||||
?: if (isFindInSuperClass && classSet.hasExtends)
|
||||
findField(
|
||||
findFields(
|
||||
classSet.superclass,
|
||||
orderIndex, matchIndex,
|
||||
name, modifiers, nameConditions,
|
||||
@@ -165,14 +162,14 @@ internal object ReflectionTool {
|
||||
"name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"type:[${type ?: "unspecified"}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in Class [$classSet] " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找任意方法
|
||||
* 查找任意方法或一组方法
|
||||
* @param classSet 方法所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
@@ -181,13 +178,14 @@ internal object ReflectionTool {
|
||||
* @param nameConditions 名称查找条件
|
||||
* @param returnType 方法返回值
|
||||
* @param paramCount 方法参数个数
|
||||
* @param paramCountRange 方法参数个数范围
|
||||
* @param paramTypes 方法参数类型
|
||||
* @param isFindInSuperClass 是否在未找到后继续在当前 [classSet] 的父类中查找
|
||||
* @return [Method]
|
||||
* @return [HashSet]<[Method]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [paramTypes] 以及 [returnType] 目标类不存在
|
||||
* @throws NoSuchMethodError 如果找不到方法
|
||||
*/
|
||||
internal fun findMethod(
|
||||
internal fun findMethods(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
@@ -196,22 +194,27 @@ internal object ReflectionTool {
|
||||
nameConditions: NameConditions?,
|
||||
returnType: Class<*>?,
|
||||
paramCount: Int,
|
||||
paramCountRange: IntRange,
|
||||
paramTypes: Array<out Class<*>>?,
|
||||
isFindInSuperClass: Boolean
|
||||
): Method {
|
||||
): HashSet<Method> {
|
||||
if (returnType == UndefinedType) error("Method match returnType class is not found")
|
||||
paramTypes?.takeIf { it.isNotEmpty() }
|
||||
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Method match paramType[$p] class is not found") }
|
||||
if (orderIndex == null && matchIndex == null && name.isBlank() && modifiers == null && paramCount < 0 && paramTypes == null && returnType == null)
|
||||
error("You must set a condition when finding a Method")
|
||||
if (orderIndex == null && matchIndex == null &&
|
||||
name.isBlank() && modifiers == null &&
|
||||
paramCount < 0 && paramCountRange.isEmpty() &&
|
||||
paramTypes == null && returnType == null
|
||||
) error("You must set a condition when finding a Method")
|
||||
val hashCode =
|
||||
("[$orderIndex][$matchIndex][$name][$paramCount][${paramTypes.typeOfString()}][$returnType][$modifiers][$classSet]").hashCode()
|
||||
return MemberCacheStore.findMethod(hashCode) ?: let {
|
||||
var method: Method? = null
|
||||
return MemberCacheStore.findMethods(hashCode) ?: let {
|
||||
val methods = HashSet<Method>()
|
||||
classSet?.declaredMethods?.apply {
|
||||
var returnTypeIndex = -1
|
||||
var paramTypeIndex = -1
|
||||
var paramCountIndex = -1
|
||||
var paramCountRangeIndex = -1
|
||||
var nameIndex = -1
|
||||
var modifyIndex = -1
|
||||
var nameCdsIndex = -1
|
||||
@@ -219,6 +222,8 @@ internal object ReflectionTool {
|
||||
if (returnType != null && matchIndex != null) filter { returnType == it.returnType }.lastIndex else -1
|
||||
val paramCountLastIndex =
|
||||
if (paramCount >= 0 && matchIndex != null) filter { paramCount == it.parameterTypes.size }.lastIndex else -1
|
||||
val paramCountRangeLastIndex = if (paramCountRange.isEmpty().not() && matchIndex != null)
|
||||
filter { it.parameterTypes.size in paramCountRange }.lastIndex else -1
|
||||
val paramTypeLastIndex =
|
||||
if (paramTypes != null && matchIndex != null) filter { arrayContentsEq(paramTypes, it.parameterTypes) }.lastIndex else -1
|
||||
val nameLastIndex = if (name.isNotBlank() && matchIndex != null) filter { name == it.name }.lastIndex else -1
|
||||
@@ -257,6 +262,16 @@ internal object ReflectionTool {
|
||||
abs(matchIndex.first) == (paramCountLastIndex - paramCountIndex) && matchIndex.second) ||
|
||||
(paramCountLastIndex == paramCountIndex && matchIndex.second.not()))
|
||||
}
|
||||
if (paramCountRange.isEmpty().not())
|
||||
conditions = (conditions && it.parameterTypes.size in paramCountRange).let {
|
||||
if (it) paramCountRangeIndex++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountRangeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountRangeLastIndex - paramCountRangeIndex) && matchIndex.second) ||
|
||||
(paramCountRangeLastIndex == paramCountRangeIndex && matchIndex.second.not()))
|
||||
}
|
||||
if (paramTypes != null)
|
||||
conditions = (conditions && arrayContentsEq(paramTypes, it.parameterTypes)).let {
|
||||
if (it) paramTypeIndex++
|
||||
@@ -291,19 +306,16 @@ internal object ReflectionTool {
|
||||
(conditions && ((orderIndex.first >= 0 && orderIndex.first == p && orderIndex.second) ||
|
||||
(orderIndex.first < 0 && abs(orderIndex.first) == (lastIndex - p) && orderIndex.second) ||
|
||||
(lastIndex == p && orderIndex.second.not()))).also { isMatched = true }
|
||||
if (conditions && isMatched) {
|
||||
method = it.apply { isAccessible = true }
|
||||
return@apply
|
||||
}
|
||||
if (conditions && isMatched) methods.add(it.apply { isAccessible = true })
|
||||
}
|
||||
} ?: error("Can't find this Method [$name] because classSet is null")
|
||||
method?.also { MemberCacheStore.putMethod(hashCode, method) }
|
||||
methods.takeIf { it.isNotEmpty() }?.also { MemberCacheStore.putMethods(hashCode, methods) }
|
||||
?: if (isFindInSuperClass && classSet.hasExtends)
|
||||
findMethod(
|
||||
findMethods(
|
||||
classSet.superclass,
|
||||
orderIndex, matchIndex,
|
||||
name, modifiers, nameConditions,
|
||||
returnType, paramCount,
|
||||
returnType, paramCount, paramCountRange,
|
||||
paramTypes, isFindInSuperClass = true
|
||||
)
|
||||
else throw NoSuchMethodError(
|
||||
@@ -324,50 +336,58 @@ internal object ReflectionTool {
|
||||
} +
|
||||
"name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}] " +
|
||||
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${paramTypes.typeOfString()}] " +
|
||||
"returnType:[${returnType ?: "unspecified"}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in Class [$classSet] " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找任意构造方法
|
||||
* 查找任意构造方法或一组构造方法
|
||||
* @param classSet 构造方法所在类
|
||||
* @param orderIndex 字节码顺序下标
|
||||
* @param matchIndex 字节码筛选下标
|
||||
* @param modifiers 构造方法描述
|
||||
* @param paramCount 构造方法参数个数
|
||||
* @param paramCountRange 构造方法参数个数范围
|
||||
* @param paramTypes 构造方法参数类型
|
||||
* @param isFindInSuperClass 是否在未找到后继续在当前 [classSet] 的父类中查找
|
||||
* @return [Constructor]
|
||||
* @return [HashSet]<[Constructor]>
|
||||
* @throws IllegalStateException 如果 [classSet] 为 null 或未设置任何条件或 [paramTypes] 目标类不存在
|
||||
* @throws NoSuchMethodError 如果找不到构造方法
|
||||
*/
|
||||
internal fun findConstructor(
|
||||
internal fun findConstructors(
|
||||
classSet: Class<*>?,
|
||||
orderIndex: Pair<Int, Boolean>?,
|
||||
matchIndex: Pair<Int, Boolean>?,
|
||||
modifiers: ModifierRules?,
|
||||
paramCount: Int,
|
||||
paramCountRange: IntRange,
|
||||
paramTypes: Array<out Class<*>>?,
|
||||
isFindInSuperClass: Boolean
|
||||
): Constructor<*> {
|
||||
): HashSet<Constructor<*>> {
|
||||
paramTypes?.takeIf { it.isNotEmpty() }
|
||||
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Constructor match paramType[$p] class is not found") }
|
||||
val paramCountR =
|
||||
if (orderIndex == null && matchIndex == null && paramCount < 0 && paramTypes == null && modifiers == null) 0 else paramCount
|
||||
val hashCode = ("[$orderIndex][$matchIndex][$paramCountR][${paramTypes.typeOfString()}][$modifiers][$classSet]").hashCode()
|
||||
return MemberCacheStore.findConstructor(hashCode) ?: let {
|
||||
var constructor: Constructor<*>? = null
|
||||
if (orderIndex == null && matchIndex == null &&
|
||||
modifiers == null && paramCount < 0 &&
|
||||
paramCountRange.isEmpty() && paramTypes == null
|
||||
) error("You must set a condition when finding a Constructor")
|
||||
val hashCode = ("[$orderIndex][$matchIndex][$paramCount][${paramTypes.typeOfString()}][$modifiers][$classSet]").hashCode()
|
||||
return MemberCacheStore.findConstructors(hashCode) ?: let {
|
||||
val constructors = HashSet<Constructor<*>>()
|
||||
classSet?.declaredConstructors?.apply {
|
||||
var paramTypeIndex = -1
|
||||
var paramCountIndex = -1
|
||||
var paramCountRangeIndex = -1
|
||||
var modifyIndex = -1
|
||||
val paramCountLastIndex =
|
||||
if (paramCountR >= 0 && matchIndex != null) filter { paramCountR == it.parameterTypes.size }.lastIndex else -1
|
||||
if (paramCount >= 0 && matchIndex != null) filter { paramCount == it.parameterTypes.size }.lastIndex else -1
|
||||
val paramCountRangeLastIndex = if (paramCountRange.isEmpty().not() && matchIndex != null)
|
||||
filter { it.parameterTypes.size in paramCountRange }.lastIndex else -1
|
||||
val paramTypeLastIndex =
|
||||
if (paramTypes != null && matchIndex != null) filter { arrayContentsEq(paramTypes, it.parameterTypes) }.lastIndex else -1
|
||||
val modifyLastIndex = if (modifiers != null && matchIndex != null) filter { modifiers.contains(it) }.lastIndex else -1
|
||||
@@ -375,7 +395,7 @@ internal object ReflectionTool {
|
||||
var isMatched = false
|
||||
var conditions = true
|
||||
if (paramCount >= 0)
|
||||
conditions = (it.parameterTypes.size == paramCountR).let {
|
||||
conditions = (it.parameterTypes.size == paramCount).let {
|
||||
if (it) paramCountIndex++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
@@ -384,6 +404,16 @@ internal object ReflectionTool {
|
||||
abs(matchIndex.first) == (paramCountLastIndex - paramCountIndex) && matchIndex.second) ||
|
||||
(paramCountLastIndex == paramCountIndex && matchIndex.second.not()))
|
||||
}
|
||||
if (paramCountRange.isEmpty().not())
|
||||
conditions = (conditions && it.parameterTypes.size in paramCountRange).let {
|
||||
if (it) paramCountRangeIndex++
|
||||
isMatched = true
|
||||
it && (matchIndex == null ||
|
||||
(matchIndex.first >= 0 && matchIndex.first == paramCountRangeIndex && matchIndex.second) ||
|
||||
(matchIndex.first < 0 &&
|
||||
abs(matchIndex.first) == (paramCountRangeLastIndex - paramCountRangeIndex) && matchIndex.second) ||
|
||||
(paramCountRangeLastIndex == paramCountRangeIndex && matchIndex.second.not()))
|
||||
}
|
||||
if (paramTypes != null)
|
||||
conditions = (conditions && arrayContentsEq(paramTypes, it.parameterTypes)).let {
|
||||
if (it) paramTypeIndex++
|
||||
@@ -408,18 +438,15 @@ internal object ReflectionTool {
|
||||
(conditions && ((orderIndex.first >= 0 && orderIndex.first == p && orderIndex.second) ||
|
||||
(orderIndex.first < 0 && abs(orderIndex.first) == (lastIndex - p) && orderIndex.second) ||
|
||||
(lastIndex == p && orderIndex.second.not()))).also { isMatched = true }
|
||||
if (conditions && isMatched) {
|
||||
constructor = it.apply { isAccessible = true }
|
||||
return@apply
|
||||
}
|
||||
if (conditions && isMatched) constructors.add(it.apply { isAccessible = true })
|
||||
}
|
||||
} ?: error("Can't find this Constructor because classSet is null")
|
||||
return constructor?.also { MemberCacheStore.putConstructor(hashCode, constructor) }
|
||||
return constructors.takeIf { it.isNotEmpty() }?.also { MemberCacheStore.putConstructors(hashCode, constructors) }
|
||||
?: if (isFindInSuperClass && classSet.hasExtends)
|
||||
findConstructor(
|
||||
findConstructors(
|
||||
classSet.superclass,
|
||||
orderIndex, matchIndex,
|
||||
modifiers, paramCount,
|
||||
modifiers, paramCount, paramCountRange,
|
||||
paramTypes, isFindInSuperClass = true
|
||||
)
|
||||
else throw NoSuchMethodError(
|
||||
@@ -434,13 +461,11 @@ internal object ReflectionTool {
|
||||
matchIndex.second.not() -> "matchIndex:[last] "
|
||||
else -> "matchIndex:[${matchIndex.first}] "
|
||||
} +
|
||||
"paramCount:[${
|
||||
paramCountR.takeIf { it >= 0 || it == -2 }
|
||||
?.toString()?.replace(oldValue = "-2", newValue = "last") ?: "unspecified"
|
||||
}] " +
|
||||
"paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}] " +
|
||||
"paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}] " +
|
||||
"paramTypes:[${paramTypes.typeOfString()}] " +
|
||||
"modifiers:${modifiers ?: "[]"} " +
|
||||
"in Class [$classSet] " +
|
||||
"in [$classSet] " +
|
||||
"by $TAG"
|
||||
)
|
||||
}
|
||||
|
@@ -45,14 +45,14 @@ internal object MemberCacheStore {
|
||||
/** 缓存的 [Class] */
|
||||
private val classCacheDatas = HashMap<Int, Class<*>?>()
|
||||
|
||||
/** 缓存的 [Method] */
|
||||
private val methodCacheDatas = HashMap<Int, Method?>()
|
||||
/** 缓存的 [Method] 数组 */
|
||||
private val methodsCacheDatas = HashMap<Int, HashSet<Method>>()
|
||||
|
||||
/** 缓存的 [Constructor] */
|
||||
private val constructorCacheDatas = HashMap<Int, Constructor<*>?>()
|
||||
/** 缓存的 [Constructor] 数组 */
|
||||
private val constructorsCacheDatas = HashMap<Int, HashSet<Constructor<*>>>()
|
||||
|
||||
/** 缓存的 [Field] */
|
||||
private val fieldCacheDatas = HashMap<Int, Field?>()
|
||||
/** 缓存的 [Field] 数组 */
|
||||
private val fieldsCacheDatas = HashMap<Int, HashSet<Field>>()
|
||||
|
||||
/**
|
||||
* 查找缓存中的 [Class]
|
||||
@@ -62,25 +62,25 @@ internal object MemberCacheStore {
|
||||
internal fun findClass(hashCode: Int) = classCacheDatas[hashCode]
|
||||
|
||||
/**
|
||||
* 查找缓存中的 [Method]
|
||||
* 查找缓存中的 [Method] 数组
|
||||
* @param hashCode 标识符
|
||||
* @return [Method] or null
|
||||
* @return [HashSet]<[Method]>
|
||||
*/
|
||||
internal fun findMethod(hashCode: Int) = methodCacheDatas[hashCode]
|
||||
internal fun findMethods(hashCode: Int) = methodsCacheDatas[hashCode]
|
||||
|
||||
/**
|
||||
* 查找缓存中的 [Constructor]
|
||||
* 查找缓存中的 [Constructor] 数组
|
||||
* @param hashCode 标识符
|
||||
* @return [Constructor] or null
|
||||
* @return [HashSet]<[Constructor]>
|
||||
*/
|
||||
internal fun findConstructor(hashCode: Int) = constructorCacheDatas[hashCode]
|
||||
internal fun findConstructors(hashCode: Int) = constructorsCacheDatas[hashCode]
|
||||
|
||||
/**
|
||||
* 查找缓存中的 [Field]
|
||||
* 查找缓存中的 [Field] 数组
|
||||
* @param hashCode 标识符
|
||||
* @return [Field] or null
|
||||
* @return [HashSet]<[Field]>
|
||||
*/
|
||||
internal fun findField(hashCode: Int) = fieldCacheDatas[hashCode]
|
||||
internal fun findFields(hashCode: Int) = fieldsCacheDatas[hashCode]
|
||||
|
||||
/**
|
||||
* 写入 [Class] 到缓存
|
||||
@@ -93,32 +93,32 @@ internal object MemberCacheStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 [Method] 到缓存
|
||||
* 写入 [Method] 数组到缓存
|
||||
* @param hashCode 标识符
|
||||
* @param instance 实例
|
||||
* @param instances 实例数组
|
||||
*/
|
||||
internal fun putMethod(hashCode: Int, instance: Method?) {
|
||||
internal fun putMethods(hashCode: Int, instances: HashSet<Method>) {
|
||||
if (YukiHookAPI.Configs.isEnableMemberCache.not()) return
|
||||
methodCacheDatas[hashCode] = instance
|
||||
methodsCacheDatas[hashCode] = instances
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 [Constructor] 到缓存
|
||||
* 写入 [Constructor] 数组到缓存
|
||||
* @param hashCode 标识符
|
||||
* @param instance 实例
|
||||
* @param instances 实例数组
|
||||
*/
|
||||
internal fun putConstructor(hashCode: Int, instance: Constructor<*>?) {
|
||||
internal fun putConstructors(hashCode: Int, instances: HashSet<Constructor<*>>) {
|
||||
if (YukiHookAPI.Configs.isEnableMemberCache.not()) return
|
||||
constructorCacheDatas[hashCode] = instance
|
||||
constructorsCacheDatas[hashCode] = instances
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 [Field] 到缓存
|
||||
* 写入 [Field] 数组到缓存
|
||||
* @param hashCode 标识符
|
||||
* @param instance 实例
|
||||
* @param instances 实例数组
|
||||
*/
|
||||
internal fun putField(hashCode: Int, instance: Field?) {
|
||||
internal fun putFields(hashCode: Int, instances: HashSet<Field>) {
|
||||
if (YukiHookAPI.Configs.isEnableMemberCache.not()) return
|
||||
fieldCacheDatas[hashCode] = instance
|
||||
fieldsCacheDatas[hashCode] = instances
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user