From 873279e0a844e5dc679b4394a8a67277980797db Mon Sep 17 00:00:00 2001 From: lliioollzh Date: Thu, 30 Nov 2023 20:07:17 +0800 Subject: [PATCH] feat: add AntiNickBlock --- .../main/java/cc/ioctl/util/MsgRecordUtil.kt | 25 +++++ .../java/cn/lliiooll/hook/AntiNickBlock.kt | 91 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 app/src/main/java/cn/lliiooll/hook/AntiNickBlock.kt diff --git a/app/src/main/java/cc/ioctl/util/MsgRecordUtil.kt b/app/src/main/java/cc/ioctl/util/MsgRecordUtil.kt index c43cbd1ce2..f550bcba20 100644 --- a/app/src/main/java/cc/ioctl/util/MsgRecordUtil.kt +++ b/app/src/main/java/cc/ioctl/util/MsgRecordUtil.kt @@ -271,6 +271,21 @@ object MsgRecordUtil { } } + val NICK_BLOCKS = object : HashBiMap() { + init { + put("VIP图标", "AIOVipIconProcessor") + put("额外VIP图标", "AIOVipIconExProcessor") + put("游戏图标", "AIOGameIconProcessor") + put("昵称", "MainNickNameBlock") + put("机器人图标", "NickNameRobotBlock") + put("群等级图标", "AIOTroopMemberLevelBlock") + put("群数字等级图标", "AIOTroopMemberGradeLevelBlock") + put("群荣耀图标", "AIOTroopHonorNickBlock") + put("群匿名图标", "AIOTroopAnonymousNickBlock") + put("群QQ圈图标", "QCircleTroopIconProcessor") + } + } + val MSG_WITH_DESC = object : HashBiMap() { init { MSG.forEach { @@ -341,4 +356,14 @@ object MsgRecordUtil { map[cache]!! } else cache } + + fun parseNickBlocks(activeItems: List): List { + val items: MutableList = ArrayList() + for (item in activeItems) { + if (NICK_BLOCKS.containsKey(item)) { + items.add(NICK_BLOCKS[item]!!) + } + } + return items + } } diff --git a/app/src/main/java/cn/lliiooll/hook/AntiNickBlock.kt b/app/src/main/java/cn/lliiooll/hook/AntiNickBlock.kt new file mode 100644 index 0000000000..56f2a493bd --- /dev/null +++ b/app/src/main/java/cn/lliiooll/hook/AntiNickBlock.kt @@ -0,0 +1,91 @@ +/* + * QAuxiliary - An Xposed module for QQ/TIM + * Copyright (C) 2019-2023 QAuxiliary developers + * https://github.com/cinit/QAuxiliary + * + * This software is non-free but opensource software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either + * version 3 of the License, or any later version and our eula as published + * by QAuxiliary contributors. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * and eula along with this software. If not, see + * + * . + */ + +package cn.lliiooll.hook + +import cc.ioctl.util.HookUtils +import cc.ioctl.util.MsgRecordUtil +import com.github.kyuubiran.ezxhelper.utils.findMethod +import com.github.kyuubiran.ezxhelper.utils.loadClass +import com.github.kyuubiran.ezxhelper.utils.paramCount +import io.github.qauxv.base.annotation.FunctionHookEntry +import io.github.qauxv.base.annotation.UiItemAgentEntry +import io.github.qauxv.dsl.FunctionEntryRouter.Locations.Simplify +import io.github.qauxv.util.QQVersion +import io.github.qauxv.util.requireMinQQVersion +import me.ketal.util.hookMethod +import xyz.nextalone.base.MultiItemDelayableHook +import java.text.Collator +import java.util.Locale + +@FunctionHookEntry +@UiItemAgentEntry +object AntiNickBlock : MultiItemDelayableHook("ll_anti_nickblock") { + override var allItems = setOf() + override val defaultItems = setOf() + override var items: MutableList = MsgRecordUtil.NICK_BLOCKS.keys.sortedWith(chineseSorter).toMutableList() + override val preferenceTitle: String = "屏蔽群昵称图标" + override val dialogDesc = "屏蔽群昵称图标" + override val enableCustom = false + override val uiItemLocation = Simplify.UI_CHAT_MSG + + + override fun initOnce(): Boolean { + val providerList = arrayOf( + "com.tencent.mobileqq.vas.vipicon.g", + "com.tencent.qqnt.aio.nick.f", + "com.tencent.mobileqq.aio.msglist.holder.component.nick.block.f", + "com.tencent.mobileqq.activity.qcircle.c", + ) + val callBack = HookUtils.afterIfEnabled(this) { param -> + if (param.result != null) { + val modified = (param.result as List<*>).toMutableList() + val sources = (param.result as List<*>).toMutableList() + modified.clear() + val items: List = MsgRecordUtil.parseNickBlocks(activeItems) + for (i in 0 until sources.size) { + if (!items.contains(sources[i]?.javaClass?.simpleName)) { + modified.add(sources[i]) + } + } + param.result = modified.toList() + } + } + + providerList.forEach { provider -> + loadClass(provider).findMethod { + //protected List a(@NotNull Context context, @NotNull LinearLayout rootView) + paramCount == 2 + }.hookMethod(callBack) + } + return true + } + + override var isEnabled: Boolean + get() = true + set(value) {} + + override val isAvailable = requireMinQQVersion(QQVersion.QQ_8_9_80) + +} + +val chineseSorter = Comparator(Collator.getInstance(Locale.CHINA)::compare)