From c924fc6746da586df889caeeccdeefde74fbdf58 Mon Sep 17 00:00:00 2001 From: klxiaoniu Date: Fri, 21 Jul 2023 10:08:54 +0800 Subject: [PATCH] fix: ChatWordsCount display for QQNT --- .../java/io/github/qauxv/tlb/QQConfigTable.kt | 4 ++++ .../github/qauxv/util/dexkit/DexKitTarget.kt | 11 +++++++--- .../java/xyz/nextalone/hook/ChatWordsCount.kt | 20 +++++++++++-------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/github/qauxv/tlb/QQConfigTable.kt b/app/src/main/java/io/github/qauxv/tlb/QQConfigTable.kt index b53721b9e0..d8a0046ff3 100644 --- a/app/src/main/java/io/github/qauxv/tlb/QQConfigTable.kt +++ b/app/src/main/java/io/github/qauxv/tlb/QQConfigTable.kt @@ -58,6 +58,7 @@ import io.github.qauxv.util.QQVersion.QQ_8_9_2 import io.github.qauxv.util.QQVersion.QQ_8_9_25 import io.github.qauxv.util.QQVersion.QQ_8_9_28 import io.github.qauxv.util.QQVersion.QQ_8_9_3 +import io.github.qauxv.util.QQVersion.QQ_8_9_63 import io.github.qauxv.util.QQVersion.QQ_8_9_68 import io.github.qauxv.util.QQVersion.QQ_8_9_8 import me.ketal.hook.SortAtPanel @@ -96,6 +97,9 @@ class QQConfigTable : ConfigTableInterface { QQ_8_8_68 to "nm7", QQ_8_8_80 to "nmx", QQ_8_8_83 to "nnl", + // NT begin + QQ_8_9_63 to "nxj", + QQ_8_9_68 to "nyb", ), //中间部分(QQ会员 我的钱包等) diff --git a/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt b/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt index b919234370..47bc9aefe9 100644 --- a/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt +++ b/app/src/main/java/io/github/qauxv/util/dexkit/DexKitTarget.kt @@ -380,6 +380,7 @@ data object AbstractQQCustomMenuItem : DexKitTarget.UsingStr() { override val traitString = arrayOf("QQCustomMenuItem{title='") override val filter = DexKitFilter.strInClsName("com/tencent/qqnt/aio/menu/ui") } + data object Guild_Emo_Btn_Create_QQNT : DexKitTarget.UsingStr() { override val findMethod: Boolean = true override val traitString = arrayOf("mEmojiLayout.findViewByI…id.guild_aio_emoji_image)") @@ -482,7 +483,10 @@ data object NQQSettingMe_onResume : DexKitTarget.UsingStr() { override val findMethod: Boolean = true override val declaringClass = "com.tencent.mobileqq.activity.QQSettingMe" override val traitString = arrayOf("-->onResume!") - override val filter = DexKitFilter.strInClsName("QQSettingMe") + override val filter = filter@{ it: DexMethodDescriptor -> + it.declaringClass.contains("QQSettingMe") && !it.declaringClass.contains("V9") + // 暂不支持V9侧滑栏,排除 + } } data object NVipUtils_getPrivilegeFlags : DexKitTarget.UsingStr() { @@ -614,6 +618,7 @@ data object NCustomWidgetUtil_updateCustomNoteTxt : DexKitTarget.UsingStr() { && m.parameterTypes[0] == TextView::class.java && m.paramCount == 6 } } + data object CCustomWidgetUtil_updateCustomNoteTxt_NT : DexKitTarget.UsingStr() { // guess override val declaringClass = "com.tencent.widget.CustomWidgetUtil" @@ -708,7 +713,7 @@ data object EmoMsgUtils_isSingleLottie_QQNT : DexKitTarget.UsingStr() { override val traitString = arrayOf("is Valid EmojiFaceId") override val declaringClass = "" override val filter = DexKitFilter.strInClsName("com/tencent/mobileqq/aio/utils") - // "com/tencent/guild/aio/util" 是频道的 + // "com/tencent/guild/aio/util" 是频道的 } data object Reply_At_QQNT : DexKitTarget.UsingStr() { @@ -730,7 +735,7 @@ data object TroopEnterEffect_QQNT : DexKitTarget.UsingStr() { override val traitString = arrayOf("playAnimaions: isSimpleUISwitch = true") override val declaringClass = "" override val filter = DexKitFilter.allowAll - // 理论上非NT也能用,但祖法不可变 + // 理论上非NT也能用,但祖法不可变 } data object NQZMoment_EntranceEnabled : DexKitTarget.UsingStr() { diff --git a/app/src/main/java/xyz/nextalone/hook/ChatWordsCount.kt b/app/src/main/java/xyz/nextalone/hook/ChatWordsCount.kt index f1bd182f17..b2a7c726ea 100644 --- a/app/src/main/java/xyz/nextalone/hook/ChatWordsCount.kt +++ b/app/src/main/java/xyz/nextalone/hook/ChatWordsCount.kt @@ -21,6 +21,7 @@ */ package xyz.nextalone.hook +import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.content.DialogInterface @@ -37,16 +38,19 @@ import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.view.children +import cc.hicore.QApp.QAppUtils +import cc.hicore.ReflectUtil.MField import cc.ioctl.util.HostInfo import cc.ioctl.util.LayoutHelper import cc.ioctl.util.LayoutHelper.newLinearLayoutParams -import cc.hicore.ReflectUtil.MField import io.github.qauxv.base.IUiItemAgent import io.github.qauxv.base.annotation.FunctionHookEntry import io.github.qauxv.base.annotation.UiItemAgentEntry +import io.github.qauxv.config.ConfigManager.getExFriendCfg import io.github.qauxv.dsl.FunctionEntryRouter import io.github.qauxv.hook.CommonConfigFunctionHook import io.github.qauxv.tlb.ConfigTable.getConfig +import io.github.qauxv.ui.CommonContextWrapper import io.github.qauxv.util.Initiator import io.github.qauxv.util.QQVersion import io.github.qauxv.util.Toasts @@ -55,8 +59,6 @@ import io.github.qauxv.util.dexkit.NChatActivityFacade_sendMsgButton import io.github.qauxv.util.dexkit.NQQSettingMe_onResume import io.github.qauxv.util.requireMinQQVersion import kotlinx.coroutines.flow.MutableStateFlow -import io.github.qauxv.config.ConfigManager.getExFriendCfg -import io.github.qauxv.ui.CommonContextWrapper import xyz.nextalone.util.clazz import xyz.nextalone.util.findHostView import xyz.nextalone.util.get @@ -108,12 +110,13 @@ object ChatWordsCount : CommonConfigFunctionHook("na_chat_words_count_kt", array val kQQSettingMeView: Class<*> = if (requireMinQQVersion(QQVersion.QQ_8_9_25)) Initiator.loadClass("com.tencent.mobileqq.activity.QQSettingMeView") else Initiator.loadClass("com.tencent.mobileqq.activity.QQSettingMe") - val ctor = kQQSettingMeView.constructors.asSequence().first { it.parameterTypes.size > 2 } + // From QQ 8.9.68 the constructor of QQSettingMeView has 2 parameters + val ctor = kQQSettingMeView.constructors.asSequence().first { it.parameterTypes.size >= 2 } // select a method to get view - if (ViewGroup::class.java.isAssignableFrom(ctor.parameterTypes[2])) { + if (ViewGroup::class.java.isAssignableFrom(ctor.parameterTypes.last())) { // for after QQ 8.8.20 kQQSettingMeView.hookBeforeAllConstructors { - val viewGroup = it.args[2] as ViewGroup + val viewGroup = it.args.last() as ViewGroup updateChatWordView(viewGroup) } } @@ -162,7 +165,7 @@ object ChatWordsCount : CommonConfigFunctionHook("na_chat_words_count_kt", array private fun updateChatWordView(viewGroup: ViewGroup) { val relativeLayout: RelativeLayout = - if (HostInfo.requireMinQQVersion(QQVersion.QQ_8_8_80)) { + if (HostInfo.requireMinQQVersion(QQVersion.QQ_8_8_80) && !QAppUtils.isQQnt()) { val getId = MField.GetStaticField("com.tencent.mobileqq.R\$id".clazz, "drawer_top_sig_layout") viewGroup.findViewById(getId) } else { @@ -183,7 +186,7 @@ object ChatWordsCount : CommonConfigFunctionHook("na_chat_words_count_kt", array private fun injectChatWordView(context: Context, viewGroup: ViewGroup) { val relativeLayout: RelativeLayout = - if (HostInfo.requireMinQQVersion(QQVersion.QQ_8_8_80)) { + if (HostInfo.requireMinQQVersion(QQVersion.QQ_8_8_80) && !QAppUtils.isQQnt()) { val getId = MField.GetStaticField("com.tencent.mobileqq.R\$id".clazz, "drawer_top_sig_layout") viewGroup.findViewById(getId) } else { @@ -250,6 +253,7 @@ object ChatWordsCount : CommonConfigFunctionHook("na_chat_words_count_kt", array override val isAvailable: Boolean get() = requireMinQQVersion(QQVersion.QQ_8_5_0) + @SuppressLint("SetTextI18n") private fun showChatWordsCountDialog(activity: Context) { val dialog = AlertDialog.Builder(CommonContextWrapper.createAppCompatContext(activity)) val ctx = dialog.context