diff --git a/docs/api/public/ConstructorFinder.md b/docs/api/public/ConstructorFinder.md index 90341a00..39ac8f79 100644 --- a/docs/api/public/ConstructorFinder.md +++ b/docs/api/public/ConstructorFinder.md @@ -92,6 +92,8 @@ fun param(vararg paramType: Any): IndexTypeCondition 如果同时使用了 `paramCount` 则 `paramType` 的数量必须与 `paramCount` 完全匹配。 +如果 `Constructor` 中存在一些无意义又很长的类型,你可以使用 `VagueType` 来替代它。 + !> 无参 `Constructor` 请使用 `emptyParam` 设置查询条件。 !> 有参 `Constructor` 必须使用此方法设定参数或使用 `paramCount` 指定个数。 diff --git a/docs/api/public/MethodFinder.md b/docs/api/public/MethodFinder.md index 55b665f9..7b533b50 100644 --- a/docs/api/public/MethodFinder.md +++ b/docs/api/public/MethodFinder.md @@ -126,6 +126,8 @@ fun param(vararg paramType: Any): IndexTypeCondition 如果同时使用了 `paramCount` 则 `paramType` 的数量必须与 `paramCount` 完全匹配。 +如果 `Method` 中存在一些无意义又很长的类型,你可以使用 `VagueType` 来替代它。 + !> 无参 `Method` 请使用 `emptyParam` 设置查询条件。 !> 有参 `Method` 必须使用此方法设定参数或使用 `paramCount` 指定个数。 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt index c83752c6..bba63e34 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt @@ -42,6 +42,7 @@ import com.highcapable.yukihookapi.hook.factory.checkingInternal import com.highcapable.yukihookapi.hook.factory.hasExtends import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.type.defined.UndefinedType +import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.utils.IntConditions import com.highcapable.yukihookapi.hook.utils.runBlocking import com.highcapable.yukihookapi.hook.utils.unit @@ -109,6 +110,20 @@ class ConstructorFinder @PublishedApi internal constructor( * * 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配 * + * 如果 [Constructor] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它 + * + * 例如下面这个参数结构 ↓ + * + * ```java + * Foo(String var1, boolean var2, com.demo.Test var3, int var4) + * ``` + * + * 此时就可以简单地写作 ↓ + * + * ```kotlin + * param(StringType, BooleanType, VagueType, IntType) + * ``` + * * - ❗无参 [Constructor] 请使用 [emptyParam] 设置查询条件 * * - ❗有参 [Constructor] 必须使用此方法设定参数或使用 [paramCount] 指定个数 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt index de634260..5635d343 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt @@ -43,6 +43,7 @@ import com.highcapable.yukihookapi.hook.factory.checkingInternal import com.highcapable.yukihookapi.hook.factory.hasExtends import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.type.defined.UndefinedType +import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.utils.IntConditions import com.highcapable.yukihookapi.hook.utils.runBlocking import com.highcapable.yukihookapi.hook.utils.unit @@ -139,6 +140,20 @@ class MethodFinder @PublishedApi internal constructor( * * 如果同时使用了 [paramCount] 则 [paramType] 的数量必须与 [paramCount] 完全匹配 * + * 如果 [Method] 中存在一些无意义又很长的类型 - 你可以使用 [VagueType] 来替代它 + * + * 例如下面这个参数结构 ↓ + * + * ```java + * void foo(String var1, boolean var2, com.demo.Test var3, int var4) + * ``` + * + * 此时就可以简单地写作 ↓ + * + * ```kotlin + * param(StringType, BooleanType, VagueType, IntType) + * ``` + * * - ❗无参 [Method] 请使用 [emptyParam] 设置查询条件 * * - ❗有参 [Method] 必须使用此方法设定参数或使用 [paramCount] 指定个数 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt index 71789aad..347f9721 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/reflex/tools/ReflectionTool.kt @@ -36,6 +36,7 @@ import com.highcapable.yukihookapi.hook.factory.hasExtends import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.store.ReflectsCacheStore import com.highcapable.yukihookapi.hook.type.defined.UndefinedType +import com.highcapable.yukihookapi.hook.type.defined.VagueType import com.highcapable.yukihookapi.hook.type.java.NoClassDefFoundErrorClass import com.highcapable.yukihookapi.hook.type.java.NoSuchFieldErrorClass import com.highcapable.yukihookapi.hook.type.java.NoSuchMethodErrorClass @@ -170,7 +171,7 @@ internal object ReflectionTool { ?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1 val iLParamCountCds = paramCountConditions ?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1 - val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { arrayContentsEq(e, it.parameterTypes) }.lastIndex } ?: -1 + val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { paramTypesEq(e, it.parameterTypes) }.lastIndex } ?: -1 val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.filter { e == it.name }.lastIndex } ?: -1 val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 @@ -207,7 +208,7 @@ internal object ReflectionTool { }) } paramTypes?.also { - and(arrayContentsEq(it, instance.parameterTypes).let { hold -> + and(paramTypesEq(it, instance.parameterTypes).let { hold -> if (hold) iParamTypes++ hold && matchIndex.compare(iParamTypes, iLParamTypes) }) @@ -256,7 +257,7 @@ internal object ReflectionTool { ?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1 val iLParamCountCds = paramCountConditions ?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1 - val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { arrayContentsEq(e, it.parameterTypes) }.lastIndex } ?: -1 + val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { paramTypesEq(e, it.parameterTypes) }.lastIndex } ?: -1 val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 declares.forEachIndexed { index, instance -> conditions { @@ -279,7 +280,7 @@ internal object ReflectionTool { }) } paramTypes?.also { - and(arrayContentsEq(it, instance.parameterTypes).let { hold -> + and(paramTypesEq(it, instance.parameterTypes).let { hold -> if (hold) iParamTypes++ hold && matchIndex.compare(iParamTypes, iLParamTypes) }) @@ -497,21 +498,23 @@ internal object ReflectionTool { }.toString() /** - * 判断两个数组是否相等 + * 判断两个方法、构造方法类型数组是否相等 * * 复制自 [Class] 中的 [Class.arrayContentsEq] - * @param fArray 第一个数组 - * @param lArray 第二个数组 + * @param compare 用于比较的数组 + * @param original 方法、构造方法原始数组 * @return [Boolean] 是否相等 */ - private fun arrayContentsEq(fArray: Array?, lArray: Array?) = run { - if (fArray != null) when { - lArray == null -> fArray.isEmpty() - fArray.size != lArray.size -> false + private fun paramTypesEq(compare: Array?, original: Array?): Boolean { + return when { + (compare == null && original == null) || (compare?.isEmpty() == true && original?.isEmpty() == true) -> true + (compare == null && original != null) || (compare != null && original == null) || (compare?.size != original?.size) -> false else -> { - for (i in fArray.indices) if (fArray[i] !== lArray[i]) return@run false + if (compare == null || original == null) return false + if (compare.all { it == VagueType }) error("The number of VagueType must be at least less than the count of paramTypes") + for (i in compare.indices) if ((compare[i] !== VagueType) && (compare[i] !== original[i])) return false true } - } else lArray == null || lArray.isEmpty() + } } } \ No newline at end of file