421 lines
14 KiB
Kotlin
421 lines
14 KiB
Kotlin
@file:OptIn(DelicateCoroutinesApi::class)
|
|
package moe.fuqiuluo.shamrock.remote.service.listener
|
|
|
|
import android.util.Log
|
|
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
|
import com.tencent.qqnt.kernel.nativeinterface.*
|
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
|
import kotlinx.coroutines.GlobalScope
|
|
import kotlinx.coroutines.launch
|
|
import moe.fuqiuluo.qqinterface.servlet.msg.toCQCode
|
|
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
|
import moe.fuqiuluo.shamrock.remote.service.api.GlobalPusher
|
|
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
|
import moe.fuqiuluo.shamrock.helper.Level
|
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
|
import java.util.ArrayList
|
|
import java.util.HashMap
|
|
|
|
internal object AioListener: IKernelMsgListener {
|
|
override fun onRecvMsg(msgList: ArrayList<MsgRecord>) {
|
|
if (msgList.isEmpty()) return
|
|
|
|
GlobalScope.launch {
|
|
msgList.forEach {
|
|
handleMsg(it)
|
|
}
|
|
}
|
|
}
|
|
|
|
private suspend fun handleMsg(record: MsgRecord) {
|
|
try {
|
|
val msgHash = MessageHelper.generateMsgIdHash(record.chatType, record.msgId)
|
|
|
|
MessageHelper.saveMsgMapping(
|
|
hash = msgHash,
|
|
qqMsgId = record.msgId,
|
|
chatType = record.chatType,
|
|
subChatType = record.chatType,
|
|
peerId = record.peerUin.toString(),
|
|
msgSeq = record.msgSeq.toInt(),
|
|
time = record.msgTime
|
|
)
|
|
|
|
val rawMsg = record.elements.toCQCode(record.chatType, record.peerUin.toString())
|
|
if (rawMsg.isEmpty()) return
|
|
|
|
when (record.chatType) {
|
|
MsgConstant.KCHATTYPEGROUP -> {
|
|
LogCenter.log("群消息(group = ${record.peerName}(${record.peerUin}), uin = ${record.senderUin}, id = $msgHash|${record.msgSeq}, msg = $rawMsg)")
|
|
ShamrockConfig.getGroupMsgRule()?.let { rule ->
|
|
if (rule.black?.contains(record.peerUin) == true) return
|
|
if (rule.white?.contains(record.peerUin) == false) return
|
|
}
|
|
|
|
GlobalPusher().forEach {
|
|
it.pushGroupMsg(record, record.elements, rawMsg, msgHash)
|
|
}
|
|
}
|
|
MsgConstant.KCHATTYPEC2C -> {
|
|
LogCenter.log("私聊消息(private = ${record.senderUin}, id = $msgHash|${record.msgSeq}, msg = $rawMsg)")
|
|
ShamrockConfig.getPrivateRule()?.let { rule ->
|
|
if (rule.black?.contains(record.peerUin) == true) return
|
|
if (rule.white?.contains(record.peerUin) == false) return
|
|
}
|
|
|
|
GlobalPusher().forEach {
|
|
it.pushPrivateMsg(record, record.elements, rawMsg, msgHash)
|
|
}
|
|
}
|
|
else -> LogCenter.log("不支持PUSH事件: ${record.chatType}")
|
|
}
|
|
} catch (e: Throwable) {
|
|
LogCenter.log(e.stackTraceToString(), Level.WARN)
|
|
}
|
|
}
|
|
|
|
override fun onAddSendMsg(record: MsgRecord) {
|
|
GlobalScope.launch {
|
|
try {
|
|
val msgHash = MessageHelper.generateMsgIdHash(record.chatType, record.msgId)
|
|
MessageHelper.saveMsgMapping(
|
|
hash = msgHash,
|
|
qqMsgId = record.msgId,
|
|
chatType = record.chatType,
|
|
subChatType = record.chatType,
|
|
peerId = record.peerUin.toString(),
|
|
msgSeq = record.msgSeq.toInt(),
|
|
time = record.msgTime
|
|
)
|
|
|
|
val rawMsg = record.elements.toCQCode(record.chatType, record.peerUin.toString())
|
|
if (rawMsg.isEmpty()) return@launch
|
|
|
|
LogCenter.log("发送消息($msgHash|${record.msgSeq}): $rawMsg")
|
|
|
|
if (!ShamrockConfig.enableSelfMsg())
|
|
return@launch
|
|
|
|
when (record.chatType) {
|
|
MsgConstant.KCHATTYPEGROUP -> {
|
|
GlobalPusher().forEach {
|
|
it.pushSelfGroupSentMsg(record, record.elements, rawMsg, msgHash)
|
|
}
|
|
}
|
|
MsgConstant.KCHATTYPEC2C -> {
|
|
GlobalPusher().forEach {
|
|
it.pushSelfPrivateSentMsg(record, record.elements, rawMsg, msgHash)
|
|
}
|
|
}
|
|
else -> LogCenter.log("不支持SELF PUSH事件: ${record.chatType}")
|
|
}
|
|
} catch (e: Throwable) {
|
|
LogCenter.log(e.stackTraceToString(), Level.WARN)
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onRecvMsgSvrRspTransInfo(
|
|
j2: Long,
|
|
contact: Contact?,
|
|
i2: Int,
|
|
i3: Int,
|
|
str: String?,
|
|
bArr: ByteArray?
|
|
) {
|
|
LogCenter.log("onRecvMsgSvrRspTransInfo($j2, $contact, $i2, $i3, $str)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onRecvS2CMsg(arrayList: ArrayList<Byte>?) {
|
|
LogCenter.log("onRecvS2CMsg(${arrayList.toString()})", Level.DEBUG)
|
|
}
|
|
|
|
override fun onRecvSysMsg(arrayList: ArrayList<Byte>?) {
|
|
LogCenter.log("onRecvSysMsg(${arrayList.toString()})", Level.DEBUG)
|
|
}
|
|
|
|
override fun onBroadcastHelperDownloadComplete(broadcastHelperTransNotifyInfo: BroadcastHelperTransNotifyInfo?) {}
|
|
|
|
override fun onBroadcastHelperProgerssUpdate(broadcastHelperTransNotifyInfo: BroadcastHelperTransNotifyInfo?) {}
|
|
|
|
override fun onChannelFreqLimitInfoUpdate(
|
|
contact: Contact?,
|
|
z: Boolean,
|
|
freqLimitInfo: FreqLimitInfo?
|
|
) {
|
|
|
|
}
|
|
|
|
override fun onContactUnreadCntUpdate(unreadMap: HashMap<Int, HashMap<String, UnreadCntInfo>>) {
|
|
// 推送未读消息数量
|
|
}
|
|
|
|
override fun onCustomWithdrawConfigUpdate(customWithdrawConfig: CustomWithdrawConfig?) {
|
|
LogCenter.log("onCustomWithdrawConfigUpdate: " + customWithdrawConfig.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onDraftUpdate(contact: Contact?, arrayList: ArrayList<MsgElement>?, j2: Long) {
|
|
LogCenter.log("onDraftUpdate: " + contact.toString() + "|" + arrayList + "|" + j2.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onEmojiDownloadComplete(emojiNotifyInfo: EmojiNotifyInfo?) {
|
|
|
|
}
|
|
|
|
override fun onEmojiResourceUpdate(emojiResourceInfo: EmojiResourceInfo?) {
|
|
|
|
}
|
|
|
|
override fun onFeedEventUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
|
|
|
}
|
|
|
|
override fun onFirstViewDirectMsgUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
|
|
|
}
|
|
|
|
override fun onFirstViewGroupGuildMapping(arrayList: ArrayList<FirstViewGroupGuildInfo>?) {
|
|
|
|
}
|
|
|
|
override fun onGrabPasswordRedBag(
|
|
i2: Int,
|
|
str: String?,
|
|
i3: Int,
|
|
recvdOrder: RecvdOrder?,
|
|
msgRecord: MsgRecord?
|
|
) {
|
|
|
|
}
|
|
|
|
override fun onKickedOffLine(kickedInfo: KickedInfo?) {
|
|
LogCenter.log("onKickedOffLine($kickedInfo)")
|
|
}
|
|
|
|
override fun onFileMsgCome(arrayList: ArrayList<MsgRecord>?) {
|
|
arrayList?.forEach { record ->
|
|
GlobalScope.launch {
|
|
when(record.chatType) {
|
|
MsgConstant.KCHATTYPEGROUP -> onGroupFileMsg(record)
|
|
MsgConstant.KCHATTYPEC2C -> onC2CFileMsg(record)
|
|
else -> LogCenter.log("不支持该来源的文件上传事件:${record}", Level.WARN)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private suspend fun onC2CFileMsg(record: MsgRecord) {
|
|
val userId = record.senderUin
|
|
val fileMsg = record.elements.firstOrNull {
|
|
it.elementType == MsgConstant.KELEMTYPEFILE
|
|
}?.fileElement ?: kotlin.run {
|
|
LogCenter.log("消息为私聊文件消息但不包含文件消息,来自:${record.peerUin}", Level.WARN)
|
|
return
|
|
}
|
|
|
|
val fileName = fileMsg.fileName
|
|
val fileSize = fileMsg.fileSize
|
|
val expireTime = fileMsg.expireTime ?: 0
|
|
val fileId = fileMsg.fileUuid
|
|
val fileSubId = fileMsg.fileSubId ?: ""
|
|
val url = RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId)
|
|
|
|
GlobalPusher().forEach {
|
|
it.pushC2CFileCome(record.msgTime, userId, fileId, fileSubId, fileName, fileSize, expireTime, url)
|
|
}
|
|
}
|
|
|
|
private suspend fun onGroupFileMsg(record: MsgRecord) {
|
|
val groupId = record.peerUin
|
|
val userId = record.senderUin
|
|
val fileMsg = record.elements.firstOrNull {
|
|
it.elementType == MsgConstant.KELEMTYPEFILE
|
|
}?.fileElement ?: kotlin.run {
|
|
LogCenter.log("消息为群聊文件消息但不包含文件消息,来自:${record.peerUin}", Level.WARN)
|
|
return
|
|
}
|
|
//val fileMd5 = fileMsg.fileMd5
|
|
val fileName = fileMsg.fileName
|
|
val fileSize = fileMsg.fileSize
|
|
val uuid = fileMsg.fileUuid
|
|
val bizId = fileMsg.fileBizId
|
|
|
|
val url = RichProtoSvc.getGroupFileDownUrl(record.peerUin, uuid, bizId)
|
|
|
|
GlobalPusher().forEach {
|
|
it.pushGroupFileCome(record.msgTime, userId, groupId, uuid, fileName, fileSize, bizId, url)
|
|
}
|
|
}
|
|
|
|
override fun onRecvOnlineFileMsg(arrayList: ArrayList<MsgRecord>?) {
|
|
LogCenter.log(("onRecvOnlineFileMsg" + arrayList?.joinToString { ", " }), Level.DEBUG)
|
|
}
|
|
|
|
override fun onRichMediaDownloadComplete(fileTransNotifyInfo: FileTransNotifyInfo) {
|
|
|
|
}
|
|
|
|
override fun onRichMediaProgerssUpdate(fileTransNotifyInfo: FileTransNotifyInfo) {
|
|
|
|
}
|
|
|
|
override fun onRichMediaUploadComplete(fileTransNotifyInfo: FileTransNotifyInfo) {
|
|
|
|
}
|
|
|
|
override fun onSearchGroupFileInfoUpdate(searchGroupFileResult: SearchGroupFileResult?) {
|
|
LogCenter.log("onSearchGroupFileInfoUpdate($searchGroupFileResult)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onGroupFileInfoAdd(groupItem: GroupItem?) {
|
|
LogCenter.log("onGroupFileInfoAdd: " + groupItem.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onGroupFileInfoUpdate(groupFileListResult: GroupFileListResult?) {
|
|
LogCenter.log("onGroupFileInfoUpdate: " + groupFileListResult.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onGroupGuildUpdate(groupGuildNotifyInfo: GroupGuildNotifyInfo?) {
|
|
LogCenter.log("onGroupGuildUpdate: " + groupGuildNotifyInfo.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onGroupTransferInfoAdd(groupItem: GroupItem?) {
|
|
LogCenter.log("onGroupTransferInfoAdd: " + groupItem.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onGroupTransferInfoUpdate(groupFileListResult: GroupFileListResult?) {
|
|
LogCenter.log("onGroupTransferInfoUpdate: " + groupFileListResult.toString(), Level.DEBUG)
|
|
}
|
|
|
|
override fun onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: DownloadRelateEmojiResultInfo?) {
|
|
|
|
}
|
|
|
|
override fun onHitEmojiKeywordResult(hitRelatedEmojiWordsResult: HitRelatedEmojiWordsResult?) {
|
|
|
|
}
|
|
|
|
override fun onHitRelatedEmojiResult(relatedWordEmojiInfo: RelatedWordEmojiInfo?) {
|
|
|
|
}
|
|
|
|
override fun onImportOldDbProgressUpdate(importOldDbMsgNotifyInfo: ImportOldDbMsgNotifyInfo?) {
|
|
|
|
}
|
|
|
|
override fun onInputStatusPush(inputStatusInfo: InputStatusInfo?) {
|
|
|
|
}
|
|
|
|
override fun onLineDev(devList: ArrayList<DevInfo>?) {
|
|
//LogCenter.log("onLineDev($arrayList)")
|
|
}
|
|
|
|
override fun onLogLevelChanged(j2: Long) {
|
|
|
|
}
|
|
|
|
override fun onMsgAbstractUpdate(arrayList: ArrayList<MsgAbstract>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgBoxChanged(arrayList: ArrayList<ContactMsgBoxInfo>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgDelete(contact: Contact?, arrayList: ArrayList<Long>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgEventListUpdate(hashMap: HashMap<String, ArrayList<Long>>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgInfoListAdd(arrayList: ArrayList<MsgRecord>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgInfoListUpdate(arrayList: ArrayList<MsgRecord>?) {
|
|
|
|
}
|
|
|
|
override fun onMsgQRCodeStatusChanged(i2: Int) {
|
|
|
|
}
|
|
|
|
override fun onMsgRecall(i2: Int, str: String?, j2: Long) {
|
|
LogCenter.log("onMsgRecall($i2, $str, $j2)")
|
|
}
|
|
|
|
override fun onMsgSecurityNotify(msgRecord: MsgRecord?) {
|
|
LogCenter.log("onMsgSecurityNotify($msgRecord)")
|
|
}
|
|
|
|
override fun onMsgSettingUpdate(msgSetting: MsgSetting?) {
|
|
|
|
}
|
|
|
|
override fun onNtFirstViewMsgSyncEnd() {
|
|
|
|
}
|
|
|
|
override fun onNtMsgSyncEnd() {
|
|
LogCenter.log("NTKernel同步消息完成", Level.DEBUG)
|
|
}
|
|
|
|
override fun onNtMsgSyncStart() {
|
|
LogCenter.log("NTKernel同步消息开始", Level.DEBUG)
|
|
}
|
|
|
|
override fun onReadFeedEventUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
|
|
|
}
|
|
|
|
override fun onRecvGroupGuildFlag(i2: Int) {
|
|
|
|
}
|
|
|
|
override fun onRecvUDCFlag(i2: Int) {
|
|
LogCenter.log("onRecvUDCFlag($i2)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onSendMsgError(j2: Long, contact: Contact?, i2: Int, str: String?) {
|
|
LogCenter.log("onSendMsgError($j2, $contact, $j2, $str)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onSysMsgNotification(i2: Int, j2: Long, j3: Long, arrayList: ArrayList<Byte>?) {
|
|
LogCenter.log("onSysMsgNotification($i2, $j2, $j3, $arrayList)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onTempChatInfoUpdate(tempChatInfo: TempChatInfo?) {
|
|
|
|
}
|
|
|
|
override fun onUnreadCntAfterFirstView(hashMap: HashMap<Int, ArrayList<UnreadCntInfo>>?) {
|
|
|
|
}
|
|
|
|
override fun onUnreadCntUpdate(hashMap: HashMap<Int, ArrayList<UnreadCntInfo>>?) {
|
|
|
|
}
|
|
|
|
override fun onUserChannelTabStatusChanged(z: Boolean) {
|
|
|
|
}
|
|
|
|
override fun onUserOnlineStatusChanged(z: Boolean) {
|
|
|
|
}
|
|
|
|
override fun onUserTabStatusChanged(arrayList: ArrayList<TabStatusInfo>?) {
|
|
LogCenter.log("onUserTabStatusChanged($arrayList)", Level.DEBUG)
|
|
}
|
|
|
|
override fun onlineStatusBigIconDownloadPush(i2: Int, j2: Long, str: String?) {
|
|
|
|
}
|
|
|
|
override fun onlineStatusSmallIconDownloadPush(i2: Int, j2: Long, str: String?) {
|
|
|
|
}
|
|
} |