From 1287ece86f6f1abba5025ca8c804849b371e16c6 Mon Sep 17 00:00:00 2001 From: TinyHai <34483077+TinyHai@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:47:23 +0800 Subject: [PATCH] fix: custom theme & video quality & some hookinfo (#1589) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复自定义主题 - 修复视频半屏/全屏清晰度 - 修复okio/okhttp的hookinfo --- .../me/iacn/biliroaming/BiliBiliPackage.kt | 41 ++++++++++++++----- .../iacn/biliroaming/hook/CustomThemeHook.kt | 35 +++++++++++++--- .../iacn/biliroaming/hook/VideoQualityHook.kt | 2 +- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt b/app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt index 9cff5e778d..5bd0853038 100644 --- a/app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt +++ b/app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt @@ -467,9 +467,11 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex null, null, null, - true - ).asSequence().firstNotNullOfOrNull { + false + ).asSequence().mapNotNull { dexHelper.decodeMethodIndex(it) + }.firstOrNull { + it.declaringClass?.name?.startsWith("okhttp3") == true }?.declaringClass okHttp = okHttp { val responseClass = "okhttp3.Response".from(classloader) @@ -483,9 +485,11 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex null, null, null, - true - ).asSequence().firstNotNullOfOrNull { + false + ).asSequence().mapNotNull { dexHelper.decodeMethodIndex(it) + }.firstOrNull { + it.declaringClass?.name?.startsWith("okhttp3") == true }?.declaringClass ?: return@okHttp val requestClass = "okhttp3.Request".from(classloader) ?: dexHelper.findMethodUsingString( @@ -498,9 +502,11 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex null, null, null, - true - ).asSequence().firstNotNullOfOrNull { + false + ).asSequence().mapNotNull { dexHelper.decodeMethodIndex(it) + }.firstOrNull { + it.declaringClass?.name?.startsWith("okhttp3") == true }?.declaringClass ?: return@okHttp val urlClass = "okhttp3.HttpUrl".from(classloader) ?: dexHelper.findMethodUsingString( @@ -528,9 +534,11 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex null, null, null, - true - ).asSequence().firstNotNullOfOrNull { + false + ).asSequence().mapNotNull { dexHelper.decodeMethodIndex(it) + }.firstOrNull { + it.declaringClass?.name?.startsWith("okhttp3") == true } ?: return@okHttp request = request { class_ = class_ { name = requestClass.name } @@ -1379,10 +1387,21 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex null, null, null, - true - ).asSequence().firstNotNullOfOrNull { + false + ).asSequence().mapNotNull { dexHelper.decodeMethodIndex(it) - }?.declaringClass ?: return@okIOBuffer + }.firstNotNullOfOrNull { + val method = it as? Method ?: return@firstNotNullOfOrNull null + val firstParameterType = method.parameterTypes.firstOrNull() + val returnType = method.returnType + when { + method.declaringClass?.name?.startsWith("okio") != true -> null + // https://github.com/square/okio/blob/okio-parent-2.0.0-RC1/okio/jvm/src/main/java/okio/Buffer.kt#L1717 + firstParameterType == null || firstParameterType == returnType -> it.declaringClass + // https://github.com/square/okio/blob/parent-2.10.0/okio/src/commonMain/kotlin/okio/internal/Buffer.kt#L1509 + else -> firstParameterType + } + } ?: return@okIOBuffer class_ = class_ { name = okioBufferClass.name } val okioInputStreamMethod = okioBufferClass.declaredMethods.firstOrNull { it.parameterTypes.isEmpty() && it.returnType == InputStream::class.java diff --git a/app/src/main/java/me/iacn/biliroaming/hook/CustomThemeHook.kt b/app/src/main/java/me/iacn/biliroaming/hook/CustomThemeHook.kt index 2c36d6d346..029327b80f 100644 --- a/app/src/main/java/me/iacn/biliroaming/hook/CustomThemeHook.kt +++ b/app/src/main/java/me/iacn/biliroaming/hook/CustomThemeHook.kt @@ -34,10 +34,6 @@ class CustomThemeHook(classLoader: ClassLoader) : BaseHook(classLoader) { val allThemes = instance.builtInThemesClass?.getStaticObjectFieldAs>(instance.allThemesField()) - primaryColor.toTheme()?.let { - allThemes?.put(CUSTOM_THEME_ID1.toLong(), it) - allThemes?.put(CUSTOM_THEME_ID2.toLong(), it) - } instance.skinList()?.let { "tv.danmaku.bili.ui.theme.ThemeStoreActivity".hookBeforeMethod( @@ -107,6 +103,17 @@ class CustomThemeHook(classLoader: ClassLoader) : BaseHook(classLoader) { } } + override fun lateInitHook() { + val primaryColor = customColor + + val allThemes = + instance.builtInThemesClass?.getStaticObjectFieldAs>(instance.allThemesField()) + primaryColor.toTheme()?.let { + allThemes?.put(CUSTOM_THEME_ID1.toLong(), it) + allThemes?.put(CUSTOM_THEME_ID2.toLong(), it) + } + } + fun insertColorForWebProcess() { if (!sPrefs.getBoolean("custom_theme", false)) return @@ -205,8 +212,26 @@ class CustomThemeHook(classLoader: ClassLoader) : BaseHook(classLoader) { private fun @receiver:ColorInt Int.pack() = toLong() and 0xFFFFFFFF shl 32 private fun @receiver:ColorInt Int.toTheme() = instance.themeColorsConstructor?.run { parameterTypes.let { + val garb = it[0].let { cls -> + try { + cls.new() + } catch (err: NoSuchMethodError) { + // GarbInfo in play v3.20.0 + cls.new( + 0L, // id + true, // showDarkContent + true, // isPure + "", // homePrimaryBgPath + 0L, // primary + 0L, // secondary + 0L, // background + 0L, // textTitle + 0L // actionIcon + ) + } + } newInstance( - it[0].new(), // garb + garb, // garb it[1].enumConstants[0], // currentDayNight ThemeDayNight#Day pack(), // primary !!important pack(), // secondary !!important diff --git a/app/src/main/java/me/iacn/biliroaming/hook/VideoQualityHook.kt b/app/src/main/java/me/iacn/biliroaming/hook/VideoQualityHook.kt index 88488b129b..798d62f86e 100644 --- a/app/src/main/java/me/iacn/biliroaming/hook/VideoQualityHook.kt +++ b/app/src/main/java/me/iacn/biliroaming/hook/VideoQualityHook.kt @@ -12,7 +12,7 @@ class VideoQualityHook(classLoader: ClassLoader) : BaseHook(classLoader) { if (halfScreenQuality != 0) { instance.playerPreloadHolderClass?.replaceAllMethods(instance.getPreload()) { null } instance.playerQualityServices().forEach { (clazz, getDefaultQnThumb) -> - clazz?.replaceMethod(getDefaultQnThumb) { halfScreenQuality } + clazz?.replaceAllMethods(getDefaultQnThumb) { halfScreenQuality } } } if (fullScreenQuality != 0) {