Skip to content

Commit

Permalink
fix: ChatItemShowQQUin and ShowMsgAt for QQ 8.9.63, add tailMessage f…
Browse files Browse the repository at this point in the history
…or FlashPic
  • Loading branch information
klxiaoniu committed Jul 19, 2023
1 parent 63de9cb commit 74df690
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
29 changes: 21 additions & 8 deletions app/src/main/java/me/ketal/hook/ChatItemShowQQUin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ import io.github.qauxv.core.HookInstaller
import io.github.qauxv.dsl.FunctionEntryRouter
import io.github.qauxv.hook.CommonConfigFunctionHook
import io.github.qauxv.ui.CommonContextWrapper
import io.github.qauxv.util.QQVersion
import io.github.qauxv.util.Toasts
import io.github.qauxv.util.requireMinQQVersion
import kotlinx.coroutines.flow.MutableStateFlow
import me.ketal.dispacher.BaseBubbleBuilderHook
import me.ketal.dispacher.OnBubbleBuilder
import me.singleneuron.data.MsgRecordData
import xyz.nextalone.util.findHostView
import xyz.nextalone.util.method
import java.lang.reflect.Method
import java.text.SimpleDateFormat
Expand All @@ -90,8 +93,7 @@ object ChatItemShowQQUin : CommonConfigFunctionHook(), OnBubbleBuilder {
// For NT
private const val ID_ADD_LAYOUT = 0x114515
private const val ID_ADD_TEXTVIEW = 0x114516
private const val ID_BUBBLE_LAYOUT = 0x7f0a10ed
private const val ID_TAIL_LAYOUT = 0x7f0a3984
private val NAME_TAIL_LAYOUT = if (requireMinQQVersion(QQVersion.QQ_8_9_68)) "s3o" else "rzs"

override val valueState: MutableStateFlow<String?> by lazy {
MutableStateFlow(if (isEnabled) "已开启" else "禁用")
Expand Down Expand Up @@ -329,12 +331,14 @@ object ChatItemShowQQUin : CommonConfigFunctionHook(), OnBubbleBuilder {

@SuppressLint("ResourceType", "SetTextI18n")
override fun onGetViewNt(rootView: ViewGroup, chatMessage: MsgRecord, param: XC_MethodHook.MethodHookParam) {
if (!isEnabled) return
// 因为tailMessage是自己添加的,所以闪照文字也放这里处理
val isFlashPicTagNeedShow = FlashPicHook.INSTANCE.isInitializationSuccessful && isFlashPicNt(chatMessage)
if (!isEnabled && !isFlashPicTagNeedShow) return

val tailLayout = try {
rootView.findViewById(ID_TAIL_LAYOUT) ?: return
rootView.findHostView(NAME_TAIL_LAYOUT) ?: throw Exception("TailLayout not found")
} catch (_: Exception) {
val stub = rootView.findViewById<ViewStub>(ID_TAIL_LAYOUT) ?: return
val stub = rootView.findHostView<ViewStub>(NAME_TAIL_LAYOUT) ?: return
stub.inflate() as FrameLayout
}
if (!tailLayout.children.map { it.id }.contains(ID_ADD_LAYOUT)) {
Expand All @@ -343,17 +347,19 @@ object ChatItemShowQQUin : CommonConfigFunctionHook(), OnBubbleBuilder {
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply {
marginStart = XPopupUtils.dp2px(rootView.context, 12f)
marginStart = XPopupUtils.dp2px(rootView.context, 15f)
// 因为tailLayout是FrameLayout,所以继承了会和原消息tailMessage重叠的特性
}
// 灰色背景不想搞了,弄圆角麻烦
id = ID_ADD_LAYOUT
}
val textView = TextView(rootView.context).apply {
id = ID_ADD_TEXTVIEW
textSize = 12f
setOnClickListener {
// 或者不用tag,像上面mOnTailMessageClickListener一样通过view获取message
// Dialog细节没有考虑,MsgRecord里面的冗余内容很多,可考虑格式化/选择性展示
if (!mEnableDetailInfo) return@setOnClickListener
val msgRecord = it.tag as MsgRecord
FaultyDialog.show(rootView.context, Reflex.getShortClassName(msgRecord), msgRecord.toString())
}
Expand All @@ -364,8 +370,7 @@ object ChatItemShowQQUin : CommonConfigFunctionHook(), OnBubbleBuilder {

rootView.findViewById<TextView>(ID_ADD_TEXTVIEW).let {
it.tag = chatMessage
it.text = formatTailMessageNt(chatMessage)
// TODO 加上闪照信息 现在FlashPicHook了getSubMsgType之后不太好分辨是不是闪照了
it.text = (if (isFlashPicTagNeedShow) "闪照 " else "") + (if (isEnabled) formatTailMessageNt(chatMessage) else "")
}
}

Expand All @@ -374,4 +379,12 @@ object ChatItemShowQQUin : CommonConfigFunctionHook(), OnBubbleBuilder {
return (msgtype == -2000 || msgtype == -2006) &&
chatMessage.getExtInfoFromExtStr("commen_flash_pic").isNotEmpty()
}

private fun isFlashPicNt(chatMessage: MsgRecord): Boolean {
return chatMessage.javaClass.getDeclaredField("subMsgType").run {
isAccessible = true
val subMsgType = getInt(chatMessage)
subMsgType == 8194 || subMsgType == 12288
}
}
}
12 changes: 7 additions & 5 deletions app/src/main/java/me/ketal/hook/ShowMsgAt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ import io.github.qauxv.dsl.FunctionEntryRouter
import io.github.qauxv.hook.CommonSwitchFunctionHook
import io.github.qauxv.ui.CommonContextWrapper
import io.github.qauxv.util.Log
import io.github.qauxv.util.QQVersion
import io.github.qauxv.util.Toasts
import io.github.qauxv.util.isTim
import io.github.qauxv.util.requireMinQQVersion
import me.ketal.dispacher.BaseBubbleBuilderHook
import me.ketal.dispacher.OnBubbleBuilder
import me.singleneuron.data.MsgRecordData
Expand All @@ -64,6 +66,8 @@ object ShowMsgAt : CommonSwitchFunctionHook(), OnBubbleBuilder {
override val uiItemLocation = FunctionEntryRouter.Locations.Auxiliary.MESSAGE_CATEGORY
override val extraSearchKeywords: Array<String> = arrayOf("@", "艾特")

private val NAME_TEXTVIEW = if (requireMinQQVersion(QQVersion.QQ_8_9_68)) "ewl" else "ewk"

override fun initOnce(): Boolean {
return !isTim() && BaseBubbleBuilderHook.initialize()
}
Expand Down Expand Up @@ -167,11 +171,9 @@ object ShowMsgAt : CommonSwitchFunctionHook(), OnBubbleBuilder {
if (atElements.isEmpty()) {
return
}
val tv = rootView.findHostView<TextView>("ex1")
// TODO 2023-07-16 有时候 ex1 会为空
tv?.let {
setAtSpanBySearch(it, atElements)
}
val tv = rootView.findHostView<TextView>(NAME_TEXTVIEW) ?: throw Exception("TextView not found")
// TODO 2023-07-19 更稳定查找TextView
setAtSpanBySearch(tv, atElements)
}

private fun copeAtInfo(textView: TextView, atList: List<*>) {
Expand Down

0 comments on commit 74df690

Please sign in to comment.