mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 实现事件推送
Signed-off-by: 白池 <whitechi73@outlook.com>
This commit is contained in:
parent
a95d8d85e8
commit
3a07116093
@ -1,28 +1,41 @@
|
||||
package kritor.service
|
||||
|
||||
import io.grpc.Status
|
||||
import io.grpc.StatusRuntimeException
|
||||
import io.kritor.event.EventRequest
|
||||
import io.kritor.event.EventServiceGrpcKt
|
||||
import io.kritor.event.EventStructure
|
||||
import io.kritor.event.EventType
|
||||
import io.kritor.event.RequestPushEvent
|
||||
import io.kritor.event.eventStructure
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
||||
|
||||
object EventService: EventServiceGrpcKt.EventServiceCoroutineImplBase() {
|
||||
override fun registerActiveListener(request: EventRequest): Flow<EventStructure> {
|
||||
override fun registerActiveListener(request: RequestPushEvent): Flow<EventStructure> {
|
||||
return channelFlow {
|
||||
when(request.type!!) {
|
||||
EventType.CORE_EVENT -> TODO()
|
||||
EventType.MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
||||
EventType.EVENT_TYPE_CORE_EVENT -> {}
|
||||
EventType.EVENT_TYPE_MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
||||
send(eventStructure {
|
||||
this.type = EventType.MESSAGE
|
||||
this.type = EventType.EVENT_TYPE_MESSAGE
|
||||
this.message = it.second
|
||||
})
|
||||
}
|
||||
EventType.NOTICE -> TODO()
|
||||
EventType.REQUEST -> TODO()
|
||||
EventType.UNRECOGNIZED -> TODO()
|
||||
EventType.EVENT_TYPE_NOTICE -> GlobalEventTransmitter.onRequestEvent {
|
||||
send(eventStructure {
|
||||
this.type = EventType.EVENT_TYPE_NOTICE
|
||||
this.request = it
|
||||
})
|
||||
}
|
||||
EventType.EVENT_TYPE_REQUEST -> GlobalEventTransmitter.onNoticeEvent {
|
||||
send(eventStructure {
|
||||
this.type = EventType.EVENT_TYPE_NOTICE
|
||||
this.notice = it
|
||||
})
|
||||
}
|
||||
EventType.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,17 +4,42 @@ package moe.fuqiuluo.shamrock.internals
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||
import io.kritor.event.GroupApplyType
|
||||
import io.kritor.event.GroupMemberBanType
|
||||
import io.kritor.event.GroupMemberDecreasedType
|
||||
import io.kritor.event.GroupMemberIncreasedType
|
||||
import io.kritor.event.MessageEvent
|
||||
import io.kritor.event.NoticeEvent
|
||||
import io.kritor.event.NoticeType
|
||||
import io.kritor.event.RequestType
|
||||
import io.kritor.event.RequestsEvent
|
||||
import io.kritor.event.Scene
|
||||
import io.kritor.event.contact
|
||||
import io.kritor.event.essenceMessageNotice
|
||||
import io.kritor.event.friendApplyRequest
|
||||
import io.kritor.event.friendFileComeNotice
|
||||
import io.kritor.event.friendPokeNotice
|
||||
import io.kritor.event.friendRecallNotice
|
||||
import io.kritor.event.groupAdminChangedNotice
|
||||
import io.kritor.event.groupApplyRequest
|
||||
import io.kritor.event.groupFileComeNotice
|
||||
import io.kritor.event.groupMemberBannedNotice
|
||||
import io.kritor.event.groupMemberDecreasedNotice
|
||||
import io.kritor.event.groupMemberIncreasedNotice
|
||||
import io.kritor.event.groupPokeNotice
|
||||
import io.kritor.event.groupRecallNotice
|
||||
import io.kritor.event.groupSignNotice
|
||||
import io.kritor.event.groupUniqueTitleChangedNotice
|
||||
import io.kritor.event.groupWholeBanNotice
|
||||
import io.kritor.event.messageEvent
|
||||
import io.kritor.event.noticeEvent
|
||||
import io.kritor.event.requestsEvent
|
||||
import io.kritor.event.sender
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.io.core.BytePacketBuilder
|
||||
import qq.service.QQInterfaces
|
||||
import qq.service.msg.toKritorMessages
|
||||
|
||||
@ -22,16 +47,16 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
private val messageEventFlow by lazy {
|
||||
MutableSharedFlow<Pair<MsgRecord, MessageEvent>>()
|
||||
}
|
||||
//private val noticeEventFlow by lazy {
|
||||
// MutableSharedFlow<NoticeEvent>()
|
||||
//}
|
||||
//private val requestEventFlow by lazy {
|
||||
// MutableSharedFlow<RequestEvent>()
|
||||
//}
|
||||
private val noticeEventFlow by lazy {
|
||||
MutableSharedFlow<NoticeEvent>()
|
||||
}
|
||||
private val requestEventFlow by lazy {
|
||||
MutableSharedFlow<RequestsEvent>()
|
||||
}
|
||||
|
||||
//private suspend fun pushNotice(noticeEvent: NoticeEvent) = noticeEventFlow.emit(noticeEvent)
|
||||
private suspend fun pushNotice(noticeEvent: NoticeEvent) = noticeEventFlow.emit(noticeEvent)
|
||||
|
||||
//private suspend fun pushRequest(requestEvent: RequestEvent) = requestEventFlow.emit(requestEvent)
|
||||
private suspend fun pushRequest(requestEvent: RequestsEvent) = requestEventFlow.emit(requestEvent)
|
||||
|
||||
private suspend fun transMessageEvent(record: MsgRecord, message: MessageEvent) = messageEventFlow.emit(record to message)
|
||||
|
||||
@ -135,10 +160,9 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* 文件通知 通知器
|
||||
*/
|
||||
**/
|
||||
object FileNoticeTransmitter {
|
||||
/**
|
||||
* 推送私聊文件事件
|
||||
@ -153,23 +177,19 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
expireTime: Long,
|
||||
url: String
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = msgTime,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.PrivateUpload,
|
||||
operatorId = userId,
|
||||
userId = userId,
|
||||
senderId = userId,
|
||||
privateFile = PrivateFileMsg(
|
||||
id = fileId,
|
||||
name = fileName,
|
||||
size = fileSize,
|
||||
url = url,
|
||||
subId = fileSubId,
|
||||
expire = expireTime
|
||||
)
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.FRIEND_FILE_COME
|
||||
this.time = msgTime.toInt()
|
||||
this.friendFileCome = friendFileComeNotice {
|
||||
this.fileId = fileId
|
||||
this.fileName = fileName
|
||||
this.operator = userId
|
||||
this.fileSize = fileSize
|
||||
this.expireTime = expireTime.toInt()
|
||||
this.fileSubId = fileSubId
|
||||
this.url = url
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -186,22 +206,19 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
bizId: Int,
|
||||
url: String
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = msgTime,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupUpload,
|
||||
operatorId = userId,
|
||||
userId = userId,
|
||||
groupId = groupId,
|
||||
file = GroupFileMsg(
|
||||
id = uuid,
|
||||
name = fileName,
|
||||
size = fileSize,
|
||||
busid = bizId.toLong(),
|
||||
url = url
|
||||
)
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_FILE_COME
|
||||
this.time = msgTime.toInt()
|
||||
this.groupFileCome = groupFileComeNotice {
|
||||
this.groupId = groupId
|
||||
this.operator = userId
|
||||
this.fileId = uuid
|
||||
this.fileName = fileName
|
||||
this.fileSize = fileSize
|
||||
this.biz = bizId
|
||||
this.url = url
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -211,68 +228,80 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
*/
|
||||
object GroupNoticeTransmitter {
|
||||
suspend fun transGroupSign(time: Long, target: Long, action: String?, rankImg: String?, groupCode: Long): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.Notify,
|
||||
subType = NoticeSubType.Sign,
|
||||
userId = target,
|
||||
groupId = groupCode,
|
||||
target = target,
|
||||
signDetail = SignDetail(
|
||||
rankImg = rankImg,
|
||||
action = action
|
||||
)
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_SIGN
|
||||
this.time = time.toInt()
|
||||
this.groupSign = groupSignNotice {
|
||||
this.groupId = groupCode
|
||||
this.targetUin = target
|
||||
this.action = action ?: ""
|
||||
this.suffix = ""
|
||||
this.rankImage = rankImg ?: ""
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupPoke(time: Long, operation: Long, target: Long, action: String?, suffix: String?, actionImg: String?, groupCode: Long): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.Notify,
|
||||
subType = NoticeSubType.Poke,
|
||||
operatorId = operation,
|
||||
userId = operation,
|
||||
groupId = groupCode,
|
||||
target = target,
|
||||
pokeDetail = PokeDetail(
|
||||
action = action,
|
||||
suffix = suffix,
|
||||
actionImg = actionImg
|
||||
)
|
||||
))
|
||||
suspend fun transGroupPoke(time: Long, operator: Long, target: Long, action: String?, suffix: String?, actionImg: String?, groupCode: Long): Boolean {
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_POKE
|
||||
this.time = time.toInt()
|
||||
this.groupPoke = groupPokeNotice {
|
||||
this.action = action ?: ""
|
||||
this.target = target
|
||||
this.operator = operator
|
||||
this.suffix = suffix ?: ""
|
||||
this.actionImage = actionImg ?: ""
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupMemberNumChanged(
|
||||
suspend fun transGroupMemberNumIncreased(
|
||||
time: Long,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
noticeType: NoticeType,
|
||||
noticeSubType: NoticeSubType
|
||||
type: GroupMemberIncreasedType
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = noticeType,
|
||||
subType = noticeSubType,
|
||||
operatorId = operator,
|
||||
userId = target,
|
||||
senderId = operator,
|
||||
target = target,
|
||||
groupId = groupCode,
|
||||
targetUid = targetUid,
|
||||
operatorUid = operatorUid,
|
||||
userUid = targetUid
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
||||
this.time = time.toInt()
|
||||
this.groupMemberIncrease = groupMemberIncreasedNotice {
|
||||
this.groupId = groupCode
|
||||
this.operatorUid = operatorUid
|
||||
this.operatorUin = operator
|
||||
this.targetUid = targetUid
|
||||
this.targetUin = target
|
||||
this.type = type
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupMemberNumDecreased(
|
||||
time: Long,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
type: GroupMemberDecreasedType
|
||||
): Boolean {
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
||||
this.time = time.toInt()
|
||||
this.groupMemberDecrease = groupMemberDecreasedNotice {
|
||||
this.groupId = groupCode
|
||||
this.operatorUid = operatorUid
|
||||
this.operatorUin = operator
|
||||
this.targetUid = targetUid
|
||||
this.targetUin = target
|
||||
this.type = type
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -283,25 +312,39 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
groupCode: Long,
|
||||
setAdmin: Boolean
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = msgTime,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupAdminChange,
|
||||
subType = if (setAdmin) NoticeSubType.Set else NoticeSubType.UnSet,
|
||||
operatorId = 0,
|
||||
userId = target,
|
||||
userUid = targetUid,
|
||||
target = target,
|
||||
targetUid = targetUid,
|
||||
groupId = groupCode
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_ADMIN_CHANGED
|
||||
this.time = msgTime.toInt()
|
||||
this.groupAdminChanged = groupAdminChangedNotice {
|
||||
this.groupId = groupCode
|
||||
this.targetUid = targetUid
|
||||
this.targetUin = target
|
||||
this.isAdmin = setAdmin
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupWholeBan(
|
||||
msgTime: Long,
|
||||
operator: Long,
|
||||
groupCode: Long,
|
||||
isOpen: Boolean
|
||||
): Boolean {
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_WHOLE_BAN
|
||||
this.time = msgTime.toInt()
|
||||
this.groupWholeBan = groupWholeBanNotice {
|
||||
this.groupId = groupCode
|
||||
this.isWholeBan = isOpen
|
||||
this.operator = operator
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupBan(
|
||||
msgTime: Long,
|
||||
subType: NoticeSubType,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
target: Long,
|
||||
@ -309,43 +352,46 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
groupCode: Long,
|
||||
duration: Int
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = msgTime,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupBan,
|
||||
subType = subType,
|
||||
operatorId = operator,
|
||||
userId = target,
|
||||
senderId = operator,
|
||||
target = target,
|
||||
groupId = groupCode,
|
||||
duration = duration,
|
||||
operatorUid = operatorUid,
|
||||
targetUid = targetUid
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_MEMBER_BANNED
|
||||
this.time = msgTime.toInt()
|
||||
this.groupMemberBanned = groupMemberBannedNotice {
|
||||
this.groupId = groupCode
|
||||
this.operatorUid = operatorUid
|
||||
this.operatorUin = operator
|
||||
this.targetUid = targetUid
|
||||
this.targetUin = target
|
||||
this.duration = duration
|
||||
this.type = if (duration > 0) GroupMemberBanType.BAN
|
||||
else GroupMemberBanType.LIFT_BAN
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transGroupMsgRecall(
|
||||
time: Long,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
msgHash: Int,
|
||||
msgId: Long,
|
||||
tipText: String
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupRecall,
|
||||
operatorId = operator,
|
||||
userId = target,
|
||||
msgId = msgHash,
|
||||
tip = tipText,
|
||||
groupId = groupCode
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_RECALL
|
||||
this.time = time.toInt()
|
||||
this.groupRecall = groupRecallNotice {
|
||||
this.groupId = groupCode
|
||||
this.operatorUid = operatorUid
|
||||
this.operatorUin = operator
|
||||
this.targetUid = targetUid
|
||||
this.targetUin = target
|
||||
this.messageId = msgId
|
||||
this.tipText = tipText
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -356,16 +402,7 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
newCard: String,
|
||||
groupId: Long
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupCard,
|
||||
userId = targetId,
|
||||
cardNew = newCard,
|
||||
cardOld = oldCard,
|
||||
groupId = groupId
|
||||
))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -375,16 +412,15 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
title: String,
|
||||
groupId: Long
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.Notify,
|
||||
userId = targetId,
|
||||
groupId = groupId,
|
||||
title = title,
|
||||
subType = NoticeSubType.Title
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_MEMBER_UNIQUE_TITLE_CHANGED
|
||||
this.time = time.toInt()
|
||||
this.groupMemberUniqueTitleChanged = groupUniqueTitleChangedNotice {
|
||||
this.groupId = groupId
|
||||
this.target = targetId
|
||||
this.title = title
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -392,21 +428,21 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
time: Long,
|
||||
senderUin: Long,
|
||||
operatorUin: Long,
|
||||
msgId: Int,
|
||||
msgId: Long,
|
||||
groupId: Long,
|
||||
subType: NoticeSubType
|
||||
subType: UInt
|
||||
): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.Essence,
|
||||
senderId = senderUin,
|
||||
groupId = groupId,
|
||||
operatorId = operatorUin,
|
||||
msgId = msgId,
|
||||
subType = subType
|
||||
))
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.GROUP_ESSENCE_CHANGED
|
||||
this.time = time.toInt()
|
||||
this.groupEssenceChanged = essenceMessageNotice {
|
||||
this.groupId = groupId
|
||||
this.messageId = msgId
|
||||
this.sender = senderUin
|
||||
this.operator = operatorUin
|
||||
this.subType = subType.toInt()
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -415,37 +451,31 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
* 私聊通知 通知器
|
||||
*/
|
||||
object PrivateNoticeTransmitter {
|
||||
suspend fun transPrivatePoke(msgTime: Long, operation: Long, target: Long, action: String?, suffix: String?, actionImg: String?): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = msgTime,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.Notify,
|
||||
subType = NoticeSubType.Poke,
|
||||
operatorId = operation,
|
||||
userId = operation,
|
||||
senderId = operation,
|
||||
target = target,
|
||||
pokeDetail = PokeDetail(
|
||||
actionImg = actionImg,
|
||||
action = action,
|
||||
suffix = suffix
|
||||
)
|
||||
))
|
||||
suspend fun transPrivatePoke(msgTime: Long, operator: Long, target: Long, action: String?, suffix: String?, actionImg: String?): Boolean {
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.FRIEND_POKE
|
||||
this.time = msgTime.toInt()
|
||||
this.friendPoke = friendPokeNotice {
|
||||
this.action = action ?: ""
|
||||
this.target = target
|
||||
this.operator = operator
|
||||
this.suffix = suffix ?: ""
|
||||
this.actionImage = actionImg ?: ""
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun transPrivateRecall(time: Long, operation: Long, msgHashId: Int, tipText: String): Boolean {
|
||||
pushNotice(NoticeEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.FriendRecall,
|
||||
operatorId = operation,
|
||||
userId = operation,
|
||||
msgId = msgHashId,
|
||||
tip = tipText
|
||||
))
|
||||
suspend fun transPrivateRecall(time: Long, operator: Long, msgId: Long, tipText: String): Boolean {
|
||||
pushNotice(noticeEvent {
|
||||
this.type = NoticeType.FRIEND_RECALL
|
||||
this.time = time.toInt()
|
||||
this.friendRecall = friendRecallNotice {
|
||||
this.operator = operator
|
||||
this.messageId = msgId
|
||||
this.tipText = tipText
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -455,16 +485,16 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
* 请求 通知器
|
||||
*/
|
||||
object RequestTransmitter {
|
||||
suspend fun transFriendApp(time: Long, operation: Long, tipText: String, flag: String): Boolean {
|
||||
pushRequest(RequestEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Request,
|
||||
type = RequestType.Friend,
|
||||
userId = operation,
|
||||
comment = tipText,
|
||||
flag = flag
|
||||
))
|
||||
suspend fun transFriendApp(time: Long, operator: Long, tipText: String, flag: String): Boolean {
|
||||
pushRequest(requestsEvent {
|
||||
this.type = RequestType.FRIEND_APPLY
|
||||
this.time = time.toInt()
|
||||
this.friendApply = friendApplyRequest {
|
||||
this.applierUin = operator
|
||||
this.message = tipText
|
||||
this.flag = flag
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -475,23 +505,23 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
reason: String,
|
||||
groupCode: Long,
|
||||
flag: String,
|
||||
subType: RequestSubType
|
||||
type: GroupApplyType
|
||||
): Boolean {
|
||||
pushRequest(RequestEvent(
|
||||
time = time,
|
||||
selfId = app.longAccountUin,
|
||||
postType = PostType.Request,
|
||||
type = RequestType.Group,
|
||||
userId = applier,
|
||||
userUid = applierUid,
|
||||
comment = reason,
|
||||
groupId = groupCode,
|
||||
subType = subType,
|
||||
flag = flag
|
||||
))
|
||||
pushRequest(requestsEvent {
|
||||
this.type = RequestType.GROUP_APPLY
|
||||
this.time = time.toInt()
|
||||
this.groupApply = groupApplyRequest {
|
||||
this.applierUid = applierUid
|
||||
this.applierUin = applier
|
||||
this.groupId = groupCode
|
||||
this.reason = reason
|
||||
this.flag = flag
|
||||
this.type = type
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
suspend inline fun onMessageEvent(collector: FlowCollector<Pair<MsgRecord, MessageEvent>>) {
|
||||
messageEventFlow.collect {
|
||||
@ -501,7 +531,6 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
suspend inline fun onNoticeEvent(collector: FlowCollector<NoticeEvent>) {
|
||||
noticeEventFlow.collect {
|
||||
GlobalScope.launch {
|
||||
@ -510,11 +539,11 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
||||
}
|
||||
}
|
||||
|
||||
suspend inline fun onRequestEvent(collector: FlowCollector<RequestEvent>) {
|
||||
suspend inline fun onRequestEvent(collector: FlowCollector<RequestsEvent>) {
|
||||
requestEventFlow.collect {
|
||||
GlobalScope.launch {
|
||||
collector.emit(it)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
@ -3,11 +3,15 @@ package qq.service.friend
|
||||
import com.tencent.mobileqq.data.Friends
|
||||
import com.tencent.mobileqq.friend.api.IFriendDataService
|
||||
import com.tencent.mobileqq.friend.api.IFriendHandlerService
|
||||
import com.tencent.mobileqq.qroute.QRoute
|
||||
import com.tencent.mobileqq.relation.api.IAddFriendTempApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import qq.service.QQInterfaces
|
||||
import tencent.mobileim.structmsg.structmsg
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
internal object FriendHelper: QQInterfaces() {
|
||||
@ -21,6 +25,69 @@ internal object FriendHelper: QQInterfaces() {
|
||||
return Result.success(service.allFriends)
|
||||
}
|
||||
|
||||
// ProfileService.Pb.ReqSystemMsgAction.Friend
|
||||
fun requestFriendRequest(msgSeq: Long, uin: Long, remark: String = "", approve: Boolean? = true, notSee: Boolean? = false) {
|
||||
val service = QRoute.api(IAddFriendTempApi::class.java)
|
||||
val action = structmsg.SystemMsgActionInfo()
|
||||
action.type.set(if (approve != false) 2 else 3)
|
||||
action.group_id.set(0)
|
||||
action.remark.set(remark)
|
||||
val snInfo = structmsg.AddFrdSNInfo()
|
||||
snInfo.uint32_not_see_dynamic.set(if (notSee != false) 1 else 0)
|
||||
snInfo.uint32_set_sn.set(0)
|
||||
action.addFrdSNInfo.set(snInfo)
|
||||
service.sendFriendSystemMsgAction(1, msgSeq, uin, 1, 2004, 11, 0, action, 0, structmsg.StructMsg(), false, app)
|
||||
}
|
||||
|
||||
suspend fun requestFriendSystemMsgNew(msgNum: Int, latestFriendSeq: Long = 0, latestGroupSeq: Long = 0, retryCnt: Int = 3): List<structmsg.StructMsg>? {
|
||||
if (retryCnt < 0) {
|
||||
return ArrayList()
|
||||
}
|
||||
val req = structmsg.ReqSystemMsgNew()
|
||||
req.msg_num.set(msgNum)
|
||||
req.latest_friend_seq.set(latestFriendSeq)
|
||||
req.latest_group_seq.set(latestGroupSeq)
|
||||
req.version.set(1000)
|
||||
req.checktype.set(2)
|
||||
val flag = structmsg.FlagInfo()
|
||||
// flag.GrpMsg_Kick_Admin.set(1)
|
||||
// flag.GrpMsg_HiddenGrp.set(1)
|
||||
// flag.GrpMsg_WordingDown.set(1)
|
||||
flag.FrdMsg_GetBusiCard.set(1)
|
||||
// flag.GrpMsg_GetOfficialAccount.set(1)
|
||||
// flag.GrpMsg_GetPayInGroup.set(1)
|
||||
flag.FrdMsg_Discuss2ManyChat.set(1)
|
||||
// flag.GrpMsg_NotAllowJoinGrp_InviteNotFrd.set(1)
|
||||
flag.FrdMsg_NeedWaitingMsg.set(1)
|
||||
flag.FrdMsg_uint32_need_all_unread_msg.set(1)
|
||||
// flag.GrpMsg_NeedAutoAdminWording.set(1)
|
||||
// flag.GrpMsg_get_transfer_group_msg_flag.set(1)
|
||||
// flag.GrpMsg_get_quit_pay_group_msg_flag.set(1)
|
||||
// flag.GrpMsg_support_invite_auto_join.set(1)
|
||||
// flag.GrpMsg_mask_invite_auto_join.set(1)
|
||||
// flag.GrpMsg_GetDisbandedByAdmin.set(1)
|
||||
flag.GrpMsg_GetC2cInviteJoinGroup.set(1)
|
||||
req.flag.set(flag)
|
||||
req.is_get_frd_ribbon.set(false)
|
||||
req.is_get_grp_ribbon.set(false)
|
||||
req.friend_msg_type_flag.set(1)
|
||||
req.uint32_req_msg_type.set(1)
|
||||
req.uint32_need_uid.set(1)
|
||||
val fromServiceMsg = sendBufferAW("ProfileService.Pb.ReqSystemMsgNew.Friend", true, req.toByteArray())
|
||||
return if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
|
||||
ArrayList()
|
||||
} else {
|
||||
try {
|
||||
val msg = structmsg.RspSystemMsgNew()
|
||||
msg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
|
||||
return msg.friendmsgs.get()
|
||||
} catch (err: Throwable) {
|
||||
requestFriendSystemMsgNew(msgNum, latestFriendSeq, latestGroupSeq, retryCnt - 1)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun requestFriendList(dataService: IFriendDataService): Boolean {
|
||||
val service = app.getRuntimeService(IFriendHandlerService::class.java, "all")
|
||||
service.requestFriendList(true, 0)
|
||||
|
@ -37,6 +37,7 @@ import tencent.im.oidb.cmd0x8fc.Oidb_0x8fc
|
||||
import tencent.im.oidb.cmd0xed3.oidb_cmd0xed3
|
||||
import tencent.im.oidb.oidb_sso
|
||||
import tencent.im.troop.honor.troop_honor
|
||||
import tencent.mobileim.structmsg.structmsg
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
import java.nio.ByteBuffer
|
||||
@ -217,6 +218,106 @@ internal object GroupHelper: QQInterfaces() {
|
||||
sendOidb("OidbSvc.0x55c_1", 1372, 1, array)
|
||||
}
|
||||
|
||||
// ProfileService.Pb.ReqSystemMsgAction.Group
|
||||
suspend fun requestGroupRequest(
|
||||
msgSeq: Long,
|
||||
uin: Long,
|
||||
gid: Long,
|
||||
msg: String? = "",
|
||||
approve: Boolean? = true,
|
||||
notSee: Boolean? = false,
|
||||
subType: String
|
||||
): Result<String>{
|
||||
val req = structmsg.ReqSystemMsgAction().apply {
|
||||
if (subType == "invite") {
|
||||
msg_type.set(1)
|
||||
src_id.set(3)
|
||||
sub_src_id.set(10016)
|
||||
group_msg_type.set(2)
|
||||
} else {
|
||||
msg_type.set(2)
|
||||
src_id.set(2)
|
||||
sub_src_id.set(30024)
|
||||
group_msg_type.set(1)
|
||||
}
|
||||
msg_seq.set(msgSeq)
|
||||
req_uin.set(uin)
|
||||
sub_type.set(1)
|
||||
action_info.set(structmsg.SystemMsgActionInfo().apply {
|
||||
type.set(if (approve != false) 11 else 12)
|
||||
group_code.set(gid)
|
||||
if (subType == "add") {
|
||||
this.msg.set(msg)
|
||||
this.blacklist.set(notSee != false)
|
||||
}
|
||||
})
|
||||
language.set(1000)
|
||||
}
|
||||
val fromServiceMsg = sendBufferAW("ProfileService.Pb.ReqSystemMsgAction.Group", true, req.toByteArray())
|
||||
?: return Result.failure(Exception("ReqSystemMsgAction.Group: No Response"))
|
||||
if (fromServiceMsg.wupBuffer == null) {
|
||||
return Result.failure(Exception("ReqSystemMsgAction.Group: No WupBuffer"))
|
||||
}
|
||||
val rsp = structmsg.RspSystemMsgAction().mergeFrom(fromServiceMsg.wupBuffer.slice(4))
|
||||
return if (rsp.head.result.has()) {
|
||||
if (rsp.head.result.get() == 0) {
|
||||
Result.success(rsp.msg_detail.get())
|
||||
} else {
|
||||
Result.failure(Exception(rsp.head.msg_fail.get()))
|
||||
}
|
||||
} else {
|
||||
Result.failure(Exception("操作失败"))
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun requestGroupSystemMsgNew(msgNum: Int, reqMsgType: Int = 1, latestFriendSeq: Long = 0, latestGroupSeq: Long = 0, retryCnt: Int = 5): List<structmsg.StructMsg> {
|
||||
if (retryCnt < 0) {
|
||||
return ArrayList()
|
||||
}
|
||||
val req = structmsg.ReqSystemMsgNew()
|
||||
req.msg_num.set(msgNum)
|
||||
req.latest_friend_seq.set(latestFriendSeq)
|
||||
req.latest_group_seq.set(latestGroupSeq)
|
||||
req.version.set(1000)
|
||||
req.checktype.set(3)
|
||||
val flag = structmsg.FlagInfo()
|
||||
flag.GrpMsg_Kick_Admin.set(1)
|
||||
flag.GrpMsg_HiddenGrp.set(1)
|
||||
flag.GrpMsg_WordingDown.set(1)
|
||||
// flag.FrdMsg_GetBusiCard.set(1)
|
||||
flag.GrpMsg_GetOfficialAccount.set(1)
|
||||
flag.GrpMsg_GetPayInGroup.set(1)
|
||||
flag.FrdMsg_Discuss2ManyChat.set(1)
|
||||
flag.GrpMsg_NotAllowJoinGrp_InviteNotFrd.set(1)
|
||||
flag.FrdMsg_NeedWaitingMsg.set(1)
|
||||
// flag.FrdMsg_uint32_need_all_unread_msg.set(1)
|
||||
flag.GrpMsg_NeedAutoAdminWording.set(1)
|
||||
flag.GrpMsg_get_transfer_group_msg_flag.set(1)
|
||||
flag.GrpMsg_get_quit_pay_group_msg_flag.set(1)
|
||||
flag.GrpMsg_support_invite_auto_join.set(1)
|
||||
flag.GrpMsg_mask_invite_auto_join.set(1)
|
||||
flag.GrpMsg_GetDisbandedByAdmin.set(1)
|
||||
flag.GrpMsg_GetC2cInviteJoinGroup.set(1)
|
||||
req.flag.set(flag)
|
||||
req.is_get_frd_ribbon.set(false)
|
||||
req.is_get_grp_ribbon.set(false)
|
||||
req.friend_msg_type_flag.set(1)
|
||||
req.uint32_req_msg_type.set(reqMsgType)
|
||||
req.uint32_need_uid.set(1)
|
||||
val fromServiceMsg = sendBufferAW("ProfileService.Pb.ReqSystemMsgNew.Group", true, req.toByteArray())
|
||||
return if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
|
||||
ArrayList()
|
||||
} else {
|
||||
try {
|
||||
val msg = structmsg.RspSystemMsgNew()
|
||||
msg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
|
||||
return msg.groupmsgs.get().orEmpty()
|
||||
} catch (err: Throwable) {
|
||||
requestGroupSystemMsgNew(msgNum, reqMsgType, latestFriendSeq, latestGroupSeq, retryCnt - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setGroupUniqueTitle(groupId: Long, userId: Long, title: String) {
|
||||
val localMemberInfo = getTroopMemberInfoByUin(groupId, userId, true).getOrThrow()
|
||||
val req = Oidb_0x8fc.ReqBody()
|
||||
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.launch
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
||||
import qq.service.bdh.RichProtoSvc
|
||||
import qq.service.kernel.SimpleKernelMsgListener
|
||||
import qq.service.msg.MessageHelper
|
||||
|
||||
@ -29,6 +30,8 @@ object AioListener: SimpleKernelMsgListener() {
|
||||
private suspend fun onMsg(record: MsgRecord) {
|
||||
when (record.chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> {
|
||||
if (record.senderUin == 0L) return
|
||||
|
||||
LogCenter.log("群消息(group = ${record.peerName}(${record.peerUin}), uin = ${record.senderUin}, id = ${record.msgId})")
|
||||
|
||||
if (!GlobalEventTransmitter.MessageTransmitter.transGroupMessage(record, record.elements)) {
|
||||
@ -75,4 +78,63 @@ object AioListener: SimpleKernelMsgListener() {
|
||||
else -> LogCenter.log("不支持PUSH事件: ${record.chatType}")
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if (!GlobalEventTransmitter.FileNoticeTransmitter
|
||||
.transPrivateFileEvent(record.msgTime, userId, fileId, fileSubId, fileName, fileSize, expireTime, url)
|
||||
) {
|
||||
LogCenter.log("私聊文件消息推送失败 -> FileNoticeTransmitter", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if (!GlobalEventTransmitter.FileNoticeTransmitter
|
||||
.transGroupFileEvent(record.msgTime, userId, groupId, uuid, fileName, fileSize, bizId, url)
|
||||
) {
|
||||
LogCenter.log("群聊文件消息推送失败 -> FileNoticeTransmitter", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
@ -52,8 +52,12 @@ internal object MSFHandler {
|
||||
|
||||
fun onPush(fromServiceMsg: FromServiceMsg) {
|
||||
val cmd = fromServiceMsg.serviceCmd
|
||||
val push = mPushHandlers[cmd]
|
||||
push?.invoke(fromServiceMsg)
|
||||
if (cmd == "trpc.msg.olpush.OlPushService.MsgPush") {
|
||||
PrimitiveListener.onPush(fromServiceMsg)
|
||||
} else {
|
||||
val push = mPushHandlers[cmd]
|
||||
push?.invoke(fromServiceMsg)
|
||||
}
|
||||
}
|
||||
|
||||
fun onResp(toServiceMsg: ToServiceMsg, fromServiceMsg: FromServiceMsg) {
|
||||
|
668
xposed/src/main/java/qq/service/internals/PrimitiveListener.kt
Normal file
668
xposed/src/main/java/qq/service/internals/PrimitiveListener.kt
Normal file
@ -0,0 +1,668 @@
|
||||
@file:OptIn(DelicateCoroutinesApi::class)
|
||||
package qq.service.internals
|
||||
|
||||
import com.tencent.mobileqq.qroute.QRoute
|
||||
import com.tencent.qphone.base.remote.FromServiceMsg
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.msg.api.IMsgService
|
||||
import io.kritor.event.GroupApplyType
|
||||
import io.kritor.event.GroupMemberDecreasedType
|
||||
import io.kritor.event.GroupMemberIncreasedType
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
||||
import moe.fuqiuluo.shamrock.tools.asJsonObject
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import moe.fuqiuluo.shamrock.tools.readBuf32Long
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||
import protobuf.message.ContentHead
|
||||
import protobuf.message.MsgBody
|
||||
import protobuf.message.ResponseHead
|
||||
import protobuf.push.C2CCommonTipsEvent
|
||||
import protobuf.push.C2CRecallEvent
|
||||
import protobuf.push.FriendApplyEvent
|
||||
import protobuf.push.GroupAdminChangeEvent
|
||||
import protobuf.push.GroupApplyEvent
|
||||
import protobuf.push.GroupBanEvent
|
||||
import protobuf.push.GroupCommonTipsEvent
|
||||
import protobuf.push.GroupInviteEvent
|
||||
import protobuf.push.GroupInvitedApplyEvent
|
||||
import protobuf.push.GroupListChangeEvent
|
||||
import protobuf.push.MessagePush
|
||||
import protobuf.push.MessagePushClientInfo
|
||||
import qq.service.QQInterfaces
|
||||
import qq.service.contact.ContactHelper
|
||||
import qq.service.friend.FriendHelper.requestFriendSystemMsgNew
|
||||
import qq.service.group.GroupHelper
|
||||
import qq.service.group.GroupHelper.requestGroupSystemMsgNew
|
||||
import qq.service.msg.MessageHelper
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
internal object PrimitiveListener {
|
||||
|
||||
fun onPush(fromServiceMsg: FromServiceMsg) {
|
||||
if (fromServiceMsg.wupBuffer == null) return
|
||||
try {
|
||||
val push = fromServiceMsg.wupBuffer.slice(4)
|
||||
.decodeProtobuf<MessagePush>()
|
||||
GlobalScope.launch {
|
||||
onMsgPush(push)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LogCenter.log(e.stackTraceToString(), Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onMsgPush(push: MessagePush) {
|
||||
if (
|
||||
push.msgBody == null ||
|
||||
push.msgBody!!.contentHead == null ||
|
||||
push.msgBody!!.body == null ||
|
||||
push.msgBody!!.contentHead!!.msgTime == null
|
||||
) return
|
||||
val msgBody = push.msgBody!!
|
||||
val contentHead = msgBody.contentHead!!
|
||||
val msgType = contentHead.msgType
|
||||
val subType = contentHead.msgSubType
|
||||
val msgTime = contentHead.msgTime!!
|
||||
val body = msgBody.body!!
|
||||
try {
|
||||
when (msgType) {
|
||||
33 -> onGroupMemIncreased(msgTime, body)
|
||||
34 -> onGroupMemberDecreased(msgTime, body)
|
||||
44 -> onGroupAdminChange(msgTime, body)
|
||||
82 -> onGroupMessage(msgTime, body)
|
||||
84 -> onGroupApply(msgTime, contentHead, body)
|
||||
87 -> onInviteGroup(msgTime, msgBody.msgHead!!, body)
|
||||
528 -> when (subType) {
|
||||
35 -> onFriendApply(msgTime, push.clientInfo!!, body)
|
||||
39 -> onCardChange(msgTime, body)
|
||||
68 -> onGroupApply(msgTime, contentHead, body)
|
||||
138 -> onC2CRecall(msgTime, body)
|
||||
290 -> onC2CPoke(msgTime, body)
|
||||
}
|
||||
|
||||
732 -> when (subType) {
|
||||
12 -> onGroupBan(msgTime, body)
|
||||
16 -> onGroupUniqueTitleChange(msgTime, body)
|
||||
17 -> onGroupRecall(msgTime, body)
|
||||
20 -> onGroupCommonTips(msgTime, body)
|
||||
21 -> onEssenceMessage(msgTime, push.clientInfo, body)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LogCenter.log("onMsgPush(msgType: $msgType, subType: $subType): " + e.stackTraceToString(), Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onGroupMessage(msgTime: Long, body: MsgBody) {
|
||||
|
||||
}
|
||||
|
||||
private suspend fun onC2CPoke(msgTime: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<C2CCommonTipsEvent>()
|
||||
if (event.params == null) return
|
||||
|
||||
val params = event.params!!.associate {
|
||||
it.key to it.value
|
||||
}
|
||||
|
||||
val target = params["uin_str2"] ?: return
|
||||
val operation = params["uin_str1"] ?: return
|
||||
val suffix = params["suffix_str"] ?: ""
|
||||
val actionImg = params["action_img_url"] ?: ""
|
||||
val action = params["alt_str1"] ?: ""
|
||||
|
||||
LogCenter.log("私聊戳一戳: $operation $action $target $suffix")
|
||||
|
||||
if (!GlobalEventTransmitter.PrivateNoticeTransmitter
|
||||
.transPrivatePoke(msgTime, operation.toLong(), target.toLong(), action, suffix, actionImg)
|
||||
) {
|
||||
LogCenter.log("私聊戳一戳推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onFriendApply(
|
||||
msgTime: Long,
|
||||
clientInfo: MessagePushClientInfo,
|
||||
body: MsgBody
|
||||
) {
|
||||
val event = body.msgContent!!.decodeProtobuf<FriendApplyEvent>()
|
||||
if (event.head == null) return
|
||||
val head = event.head!!
|
||||
val applierUid = head.applierUid
|
||||
val msg = head.applyMsg ?: ""
|
||||
val source = head.source ?: ""
|
||||
var applier = ContactHelper.getUinByUidAsync(applierUid).toLong()
|
||||
if (applier == 0L) {
|
||||
applier = clientInfo.liteHead?.sender?.toLong() ?: 0
|
||||
}
|
||||
val src = head.srcId
|
||||
val subSrc = head.subSrc
|
||||
val flag: String = try {
|
||||
val reqs = requestFriendSystemMsgNew(20, 0, 0)
|
||||
val req = reqs?.first {
|
||||
it.msg_time.get() == msgTime
|
||||
}
|
||||
val seq = req?.msg_seq?.get()
|
||||
"$seq;$src;$subSrc;$applier"
|
||||
} catch (err: Throwable) {
|
||||
"$msgTime;$src;$subSrc;$applier"
|
||||
}
|
||||
LogCenter.log("来自$applier 的好友申请:$msg ($source)")
|
||||
if (!GlobalEventTransmitter.RequestTransmitter
|
||||
.transFriendApp(msgTime, applier, msg, flag)
|
||||
) {
|
||||
LogCenter.log("好友申请推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private suspend fun onCardChange(msgTime: Long, body: MsgBody) {
|
||||
// val event = runCatching {
|
||||
// body.msgContent!!.decodeProtobuf<GroupCardChangeEvent>()
|
||||
// }.getOrElse {
|
||||
// val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
// readPacket.readBuf32Long()
|
||||
// readPacket.discardExact(1)
|
||||
//
|
||||
// readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
// readPacket.release()
|
||||
// }.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
// }
|
||||
//
|
||||
// val targetId = detail[1, 13, 2].asUtf8String
|
||||
// val newCardList = detail[1, 13, 3].asList
|
||||
// var newCard = ""
|
||||
// newCardList
|
||||
// .value
|
||||
// .forEach {
|
||||
// if (it[1].asInt == 1) {
|
||||
// newCard = it[2].asUtf8String
|
||||
// }
|
||||
// }
|
||||
// val groupId = detail[1, 13, 4].asLong
|
||||
// var oldCard = ""
|
||||
// val targetQQ = ContactHelper.getUinByUidAsync(targetId).toLong()
|
||||
// LogCenter.log("群组[$groupId]成员$targetQQ 群名片变动 -> $newCard")
|
||||
// // oldCard暂时获取不到
|
||||
// if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
// .transCardChange(msgTime, targetQQ, oldCard, newCard, groupId)
|
||||
// ) {
|
||||
// LogCenter.log("群名片变动推送失败!", Level.WARN)
|
||||
// }
|
||||
}
|
||||
|
||||
private suspend fun onGroupUniqueTitleChange(msgTime: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.readBuf32Long()
|
||||
readPacket.discardExact(1)
|
||||
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.release()
|
||||
}.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}
|
||||
val groupId = event.groupCode.toLong()
|
||||
val detail = event.uniqueTitleChangeDetail!!.first()
|
||||
|
||||
//detail = if (detail[5] is ProtoList) {
|
||||
// (detail[5] as ProtoList).value[0]
|
||||
//} else {
|
||||
// detail[5]
|
||||
// }
|
||||
|
||||
val targetUin = detail.targetUin.toLong()
|
||||
|
||||
// 恭喜<{\"cmd\":5,\"data\":\"qq\",\"text}\":\"nickname\"}>获得群主授予的<{\"cmd\":1,\"data\":\"https://qun.qq.com/qqweb/m/qun/medal/detail.html?_wv=16777223&bid=2504&gc=gid&isnew=1&medal=302&uin=uin\",\"text\":\"title\",\"url\":\"https://qun.qq.com/qqweb/m/qun/medal/detail.html?_wv=16777223&bid=2504&gc=gid&isnew=1&medal=302&uin=uin\"}>头衔
|
||||
val titleChangeInfo = detail.wording
|
||||
if (titleChangeInfo.indexOf("群主授予") == -1) {
|
||||
return
|
||||
}
|
||||
val titleJson = titleChangeInfo.split("获得群主授予的<")[1].replace(">头衔", "")
|
||||
val titleJsonObj = Json.decodeFromString<JsonElement>(titleJson).asJsonObject
|
||||
val title = titleJsonObj["text"].asString
|
||||
|
||||
LogCenter.log("群组[$groupId]成员$targetUin 获得群头衔 -> $title")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transTitleChange(msgTime, targetUin, title, groupId)
|
||||
) {
|
||||
LogCenter.log("群头衔变动推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onEssenceMessage(
|
||||
msgTime: Long,
|
||||
clientInfo: MessagePushClientInfo?,
|
||||
body: MsgBody
|
||||
) {
|
||||
if (clientInfo == null) return
|
||||
val event = runCatching {
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.readBuf32Long()
|
||||
readPacket.discardExact(1)
|
||||
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.release()
|
||||
}.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}
|
||||
val groupId = event.groupCode.toLong()
|
||||
val detail = event.essenceMsgInfo!!.first()
|
||||
|
||||
val msgSeq = event.msgSeq.toLong()
|
||||
val senderUin = detail.sender.toLong()
|
||||
val operatorUin = detail.operator.toLong()
|
||||
|
||||
when (val type = detail.type) {
|
||||
1u -> {
|
||||
LogCenter.log("群设精消息(groupId=$groupId, sender=$senderUin, msgSeq=$msgSeq, operator=$operatorUin)")
|
||||
}
|
||||
2u -> {
|
||||
LogCenter.log("群撤精消息(groupId=$groupId, sender=$senderUin, msgId=$msgSeq, operator=$operatorUin)")
|
||||
}
|
||||
else -> error("onEssenceMessage unknown type: $type")
|
||||
}
|
||||
|
||||
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId.toString())
|
||||
val sourceRecord = withTimeoutOrNull(3000) {
|
||||
suspendCancellableCoroutine {
|
||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||
it.resume(records)
|
||||
}
|
||||
}
|
||||
}?.firstOrNull()
|
||||
|
||||
if (sourceRecord == null) {
|
||||
LogCenter.log("无法获取源消息记录,无法推送精华消息变动!", Level.WARN)
|
||||
return
|
||||
}
|
||||
|
||||
val msgId = sourceRecord.msgId
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transEssenceChange(msgTime, senderUin, operatorUin, msgId, groupId, detail.type)
|
||||
) {
|
||||
LogCenter.log("精华消息变动推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private suspend fun onGroupCommonTips(time: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.discardExact(4)
|
||||
readPacket.discardExact(1)
|
||||
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.release()
|
||||
}.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}
|
||||
val groupId = event.groupCode.toLong()
|
||||
val detail = event.baseTips!!.first()
|
||||
|
||||
val params = detail.params!!.associate {
|
||||
it.key to it.value
|
||||
}
|
||||
|
||||
val target = params["uin_str2"] ?: params["mqq_uin"] ?: return
|
||||
val operation = params["uin_str1"] ?: return
|
||||
val suffix = params["suffix_str"] ?: ""
|
||||
val actionImg = params["action_img_url"] ?: ""
|
||||
val action = params["alt_str1"]
|
||||
?: params["action_str"]
|
||||
?: params["user_sign"]
|
||||
?: ""
|
||||
val rankImg = params["rank_img"] ?: ""
|
||||
|
||||
when (detail.type) {
|
||||
1061u -> {
|
||||
LogCenter.log("群戳一戳($groupId): $operation $action $target $suffix")
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupPoke(time, operation.toLong(), target.toLong(), action, suffix, actionImg, groupId)
|
||||
) {
|
||||
LogCenter.log("群戳一戳推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
1068u -> {
|
||||
LogCenter.log("群打卡($groupId): $action $target")
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupSign(time, target.toLong(), action, rankImg, groupId)
|
||||
) {
|
||||
LogCenter.log("群打卡推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
LogCenter.log("onGroupPokeAndGroupSign unknown type ${detail.type}", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onC2CRecall(time: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<C2CRecallEvent>()
|
||||
val head = event.head!!
|
||||
|
||||
val operationUid = head.operator!!
|
||||
val operator = ContactHelper.getUinByUidAsync(operationUid).toLong()
|
||||
|
||||
val msgSeq = head.msgSeq
|
||||
val tipText = head.wording?.wording ?: ""
|
||||
|
||||
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, operationUid)
|
||||
val sourceRecord = withTimeoutOrNull(3000) {
|
||||
suspendCancellableCoroutine {
|
||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||
it.resume(records)
|
||||
}
|
||||
}
|
||||
}?.firstOrNull()
|
||||
|
||||
if (sourceRecord == null) {
|
||||
LogCenter.log("无法获取源消息记录,无法推送撤回消息!", Level.WARN)
|
||||
return
|
||||
}
|
||||
|
||||
val msgId = sourceRecord.msgId
|
||||
|
||||
LogCenter.log("私聊消息撤回: $operator, seq = $msgSeq, msgId = ${msgId}, tip = $tipText")
|
||||
|
||||
if (!GlobalEventTransmitter.PrivateNoticeTransmitter
|
||||
.transPrivateRecall(time, operator, msgId, tipText)
|
||||
) {
|
||||
LogCenter.log("私聊消息撤回推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupMemIncreased(time: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupListChangeEvent>()
|
||||
val groupCode = event.groupCode
|
||||
val targetUid = event.memberUid
|
||||
val type = event.type
|
||||
|
||||
GroupHelper.getGroupMemberList(groupCode.toString(), true).onFailure {
|
||||
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
|
||||
}.onSuccess {
|
||||
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
|
||||
}
|
||||
|
||||
val operatorUid = event.operatorUid
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
LogCenter.log("群成员增加($groupCode): $target, type = $type")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumIncreased(
|
||||
time,
|
||||
target,
|
||||
targetUid,
|
||||
groupCode,
|
||||
operator,
|
||||
operatorUid,
|
||||
when (type) {
|
||||
130 -> GroupMemberIncreasedType.APPROVE
|
||||
131 -> GroupMemberIncreasedType.INVITE
|
||||
else -> GroupMemberIncreasedType.APPROVE
|
||||
}
|
||||
)
|
||||
) {
|
||||
LogCenter.log("群成员增加推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupMemberDecreased(time: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupListChangeEvent>()
|
||||
val groupCode = event.groupCode
|
||||
val targetUid = event.memberUid
|
||||
val type = event.type
|
||||
val operatorUid = event.operatorUid
|
||||
|
||||
GroupHelper.getGroupMemberList(groupCode.toString(), true).onFailure {
|
||||
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
|
||||
}.onSuccess {
|
||||
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
|
||||
}
|
||||
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
val subtype = when (type) {
|
||||
130 -> GroupMemberDecreasedType.LEAVE
|
||||
131 -> GroupMemberDecreasedType.KICK
|
||||
3 -> GroupMemberDecreasedType.KICK_ME
|
||||
else -> GroupMemberDecreasedType.KICK
|
||||
}
|
||||
|
||||
LogCenter.log("群成员减少($groupCode): $target, type = $subtype ($type)")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumDecreased(
|
||||
time,
|
||||
target,
|
||||
targetUid,
|
||||
groupCode,
|
||||
operator,
|
||||
operatorUid,
|
||||
subtype
|
||||
)
|
||||
) {
|
||||
LogCenter.log("群成员减少推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupAdminChange(msgTime: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupAdminChangeEvent>()
|
||||
val groupCode = event.groupCode
|
||||
if (event.operation == null) return
|
||||
val operation = event.operation!!
|
||||
if (operation.setInfo == null && operation.unsetInfo == null) return
|
||||
|
||||
val isSetAdmin: Boolean
|
||||
val targetUid: String
|
||||
if (operation.setInfo == null) {
|
||||
isSetAdmin = false
|
||||
targetUid = operation.unsetInfo!!.targetUid!!
|
||||
} else {
|
||||
isSetAdmin = true
|
||||
targetUid = operation.setInfo!!.targetUid!!
|
||||
}
|
||||
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
LogCenter.log("群管理员变动($groupCode): $target, isSetAdmin = $isSetAdmin")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupAdminChanged(msgTime, target, targetUid, groupCode, isSetAdmin)
|
||||
) {
|
||||
LogCenter.log("群管理员变动推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupBan(msgTime: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupBanEvent>()
|
||||
val groupCode = event.groupCode.toLong()
|
||||
val operatorUid = event.operatorUid
|
||||
val wholeBan = event.target?.target?.targetUid == null
|
||||
val targetUid = event.target?.target?.targetUid ?: ""
|
||||
val rawDuration = event.target?.target?.rawDuration?.toInt() ?: 0
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val duration = if (wholeBan) -1 else rawDuration
|
||||
val target = if (wholeBan) 0 else ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
|
||||
if (wholeBan) {
|
||||
LogCenter.log("群全员禁言($groupCode): $operator -> ${if (rawDuration != 0) "开启" else "关闭"}")
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupWholeBan(msgTime, groupCode, operator, rawDuration != 0)
|
||||
) {
|
||||
LogCenter.log("群禁言推送失败!", Level.WARN)
|
||||
}
|
||||
} else {
|
||||
LogCenter.log("群禁言($groupCode): $operator -> $target, 时长 = ${duration}s")
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupBan(msgTime, operator, operatorUid, target, targetUid, groupCode, duration)
|
||||
) {
|
||||
LogCenter.log("群禁言推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupRecall(time: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.discardExact(4)
|
||||
readPacket.discardExact(1)
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.release()
|
||||
}.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}
|
||||
val groupCode = event.groupCode.toLong()
|
||||
val detail = event.recallDetails!!
|
||||
val operatorUid = detail.operatorUid
|
||||
val targetUid = detail.msgInfo!!.senderUid
|
||||
val msgSeq = detail.msgInfo!!.msgSeq.toLong()
|
||||
val tipText = detail.wording?.wording ?: ""
|
||||
|
||||
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupCode.toString())
|
||||
val sourceRecord = withTimeoutOrNull(3000) {
|
||||
suspendCancellableCoroutine {
|
||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||
it.resume(records)
|
||||
}
|
||||
}
|
||||
}?.firstOrNull()
|
||||
|
||||
if (sourceRecord == null) {
|
||||
LogCenter.log("无法获取源消息记录,无法推送撤回消息!", Level.WARN)
|
||||
return
|
||||
}
|
||||
|
||||
val msgId = sourceRecord.msgId
|
||||
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
LogCenter.log("群消息撤回($groupCode): $operator -> $target, seq = $msgSeq, id = $msgId, tip = $tipText")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMsgRecall(time, operator, operatorUid, target, targetUid, groupCode, msgId, tipText)
|
||||
) {
|
||||
LogCenter.log("群消息撤回推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupApply(time: Long, contentHead: ContentHead, body: MsgBody) {
|
||||
when (contentHead.msgType) {
|
||||
84 -> {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupApplyEvent>()
|
||||
val groupCode = event.groupCode
|
||||
val applierUid = event.applierUid
|
||||
val reason = event.applyMsg ?: ""
|
||||
var applier = ContactHelper.getUinByUidAsync(applierUid).toLong()
|
||||
if (applier == QQInterfaces.app.longAccountUin) {
|
||||
return
|
||||
}
|
||||
val msgSeq = contentHead.msgSeq
|
||||
val flag = try {
|
||||
var reqs = requestGroupSystemMsgNew(10, 1)
|
||||
val riskReqs = requestGroupSystemMsgNew(5, 2)
|
||||
reqs = reqs + riskReqs
|
||||
val req = reqs.firstOrNull {
|
||||
it.msg_time.get() == time && it.msg?.group_code?.get() == groupCode
|
||||
}
|
||||
val seq = req?.msg_seq?.get() ?: time
|
||||
if (applier == 0L) {
|
||||
applier = req?.req_uin?.get() ?: 0L
|
||||
}
|
||||
"$seq;$groupCode;$applier"
|
||||
} catch (err: Throwable) {
|
||||
"$time;$groupCode;$applier"
|
||||
}
|
||||
LogCenter.log("入群申请($groupCode) $applier: \"$reason\", seq: $msgSeq")
|
||||
if (!GlobalEventTransmitter.RequestTransmitter
|
||||
.transGroupApply(time, applier, applierUid, reason, groupCode, flag, GroupApplyType.GROUP_APPLY_ADD)
|
||||
) {
|
||||
LogCenter.log("入群申请推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
528 -> {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupInvitedApplyEvent>()
|
||||
val groupCode = event.applyInfo?.groupCode ?: return
|
||||
val applierUid = event.applyInfo?.applierUid ?: return
|
||||
var applier = ContactHelper.getUinByUidAsync(applierUid).toLong()
|
||||
if (applier == QQInterfaces.app.longAccountUin) {
|
||||
return
|
||||
}
|
||||
if ((event.applyInfo?.type ?: return) < 3) {
|
||||
// todo
|
||||
return
|
||||
}
|
||||
val flag = try {
|
||||
var reqs = requestGroupSystemMsgNew(10, 1)
|
||||
val riskReqs = requestGroupSystemMsgNew(5, 2)
|
||||
reqs = reqs + riskReqs
|
||||
val req = reqs.firstOrNull() {
|
||||
it.msg_time.get() == time
|
||||
}
|
||||
val seq = req?.msg_seq?.get() ?: time
|
||||
if (applier == 0L) {
|
||||
applier = req?.req_uin?.get() ?: 0L
|
||||
}
|
||||
"$seq;$groupCode;$applier"
|
||||
} catch (err: Throwable) {
|
||||
"$time;$groupCode;$applier"
|
||||
}
|
||||
LogCenter.log("邀请入群申请($groupCode): $applier")
|
||||
if (!GlobalEventTransmitter.RequestTransmitter
|
||||
.transGroupApply(time, applier, applierUid, "", groupCode, flag, GroupApplyType.GROUP_APPLY_ADD)
|
||||
) {
|
||||
LogCenter.log("邀请入群申请推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onInviteGroup(time: Long, msgHead: ResponseHead, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupInviteEvent>()
|
||||
val groupCode = event.groupCode
|
||||
val invitorUid = event.inviterUid
|
||||
val invitor = ContactHelper.getUinByUidAsync(invitorUid).toLong()
|
||||
val uin = msgHead.receiver
|
||||
LogCenter.log("邀请入群: $groupCode, 邀请者: \"$invitor\"")
|
||||
val flag = try {
|
||||
var reqs = requestGroupSystemMsgNew(10, 1)
|
||||
val riskReqs = requestGroupSystemMsgNew(10, 2)
|
||||
reqs = reqs + riskReqs
|
||||
val req = reqs.firstOrNull {
|
||||
it.msg_time.get() == time
|
||||
}
|
||||
val seq = req?.msg_seq?.get() ?: time
|
||||
"$seq;$groupCode;$uin"
|
||||
} catch (err: Throwable) {
|
||||
"$time;$groupCode;$uin"
|
||||
}
|
||||
if (!GlobalEventTransmitter.RequestTransmitter
|
||||
.transGroupApply(time, invitor, invitorUid, "", groupCode, flag, GroupApplyType.GROUP_APPLY_INVITE)
|
||||
) {
|
||||
LogCenter.log("邀请入群推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -195,7 +195,7 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgRecall(i2: Int, str: String?, j2: Long) {
|
||||
override fun onMsgRecall(chatType: Int, tips: String?, msgId: Long) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package qq.service.msg
|
||||
import com.tencent.qqnt.kernel.api.IKernelService
|
||||
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||
import com.tencent.qqnt.kernel.nativeinterface.TempChatInfo
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
@ -32,12 +33,28 @@ internal object MessageHelper: QQInterfaces() {
|
||||
return Result.success(info)
|
||||
}
|
||||
|
||||
suspend fun generateContact(record: MsgRecord): Contact {
|
||||
val peerId = when (record.chatType) {
|
||||
MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> record.senderUid
|
||||
MsgConstant.KCHATTYPEGUILD -> record.channelId
|
||||
else -> record.peerUin.toString()
|
||||
}
|
||||
return Contact(record.chatType, peerId, if (record.chatType == MsgConstant.KCHATTYPEGUILD) {
|
||||
record.guildId
|
||||
} else if(record.chatType == MsgConstant.KCHATTYPETEMPC2CFROMGROUP) {
|
||||
val tempInfo = getTempChatInfo(record.chatType, peerId).getOrThrow()
|
||||
tempInfo.groupCode
|
||||
} else {
|
||||
null
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun generateContact(chatType: Int, id: String, subId: String = ""): Contact {
|
||||
val peerId = when (chatType) {
|
||||
MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> {
|
||||
ContactHelper.getUidByUinAsync(id.toLong())
|
||||
if (id.startsWith("u_")) id
|
||||
else ContactHelper.getUidByUinAsync(id.toLong())
|
||||
}
|
||||
|
||||
else -> id
|
||||
}
|
||||
return if (chatType == MsgConstant.KCHATTYPEGUILD) {
|
||||
|
@ -1,8 +1,10 @@
|
||||
package qq.service.msg
|
||||
|
||||
import com.tencent.mobileqq.qroute.QRoute
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||
import com.tencent.qqnt.msg.api.IMsgService
|
||||
import io.kritor.event.AtElement
|
||||
import io.kritor.event.Element
|
||||
import io.kritor.event.ElementKt
|
||||
@ -21,10 +23,13 @@ import io.kritor.event.imageElement
|
||||
import io.kritor.event.jsonElement
|
||||
import io.kritor.event.locationElement
|
||||
import io.kritor.event.pokeElement
|
||||
import io.kritor.event.replyElement
|
||||
import io.kritor.event.rpsElement
|
||||
import io.kritor.event.textElement
|
||||
import io.kritor.event.videoElement
|
||||
import io.kritor.event.voiceElement
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
@ -40,6 +45,7 @@ import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils.QQ_9_0_8_VER
|
||||
import qq.service.bdh.RichProtoSvc
|
||||
import qq.service.contact.ContactHelper
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
typealias NtMessages = ArrayList<MsgElement>
|
||||
typealias Convertor = suspend (MsgRecord, MsgElement) -> Result<Element>
|
||||
@ -308,8 +314,22 @@ private object MsgConvertor {
|
||||
suspend fun convertReply(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||
val reply = element.replyElement
|
||||
val elem = Element.newBuilder()
|
||||
elem.setReply(io.kritor.event.replyElement {
|
||||
this.messageId = reply.replayMsgId
|
||||
elem.setReply(replyElement {
|
||||
val msgSeq = reply.replayMsgSeq
|
||||
val contact = MessageHelper.generateContact(record)
|
||||
val sourceRecords = withTimeoutOrNull(3000) {
|
||||
suspendCancellableCoroutine {
|
||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||
it.resume(records)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sourceRecords.isNullOrEmpty()) {
|
||||
LogCenter.log("无法查询到回复的消息ID: seq = $msgSeq", Level.WARN)
|
||||
this.messageId = reply.replayMsgId
|
||||
} else {
|
||||
this.messageId = sourceRecords.first().msgId
|
||||
}
|
||||
})
|
||||
return Result.success(elem.build())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user