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
ca47f9dbdf
commit
7bacea3288
2
kritor
2
kritor
@ -1 +1 @@
|
|||||||
Subproject commit f007631c7e17fe6220055a404fdaaa6e7a24a7ef
|
Subproject commit e4aac653e14249cbb6f27567ffd463165f6deebe
|
@ -24,6 +24,8 @@ class KritorServer(
|
|||||||
.addService(FriendService)
|
.addService(FriendService)
|
||||||
.addService(GroupService)
|
.addService(GroupService)
|
||||||
.addService(GroupFileService)
|
.addService(GroupFileService)
|
||||||
|
.addService(MessageService)
|
||||||
|
.addService(EventService)
|
||||||
.build()!!
|
.build()!!
|
||||||
|
|
||||||
fun start(block: Boolean = false) {
|
fun start(block: Boolean = false) {
|
||||||
|
29
xposed/src/main/java/kritor/service/EventService.kt
Normal file
29
xposed/src/main/java/kritor/service/EventService.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package kritor.service
|
||||||
|
|
||||||
|
import io.kritor.event.EventRequest
|
||||||
|
import io.kritor.event.EventServiceGrpcKt
|
||||||
|
import io.kritor.event.EventStructure
|
||||||
|
import io.kritor.event.EventType
|
||||||
|
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> {
|
||||||
|
return channelFlow {
|
||||||
|
when(request.type!!) {
|
||||||
|
EventType.CORE_EVENT -> TODO()
|
||||||
|
EventType.MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
||||||
|
send(eventStructure {
|
||||||
|
this.type = EventType.MESSAGE
|
||||||
|
this.message = it.second
|
||||||
|
})
|
||||||
|
}
|
||||||
|
EventType.NOTICE -> TODO()
|
||||||
|
EventType.REQUEST -> TODO()
|
||||||
|
EventType.UNRECOGNIZED -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
xposed/src/main/java/kritor/service/MessageService.kt
Normal file
7
xposed/src/main/java/kritor/service/MessageService.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package kritor.service
|
||||||
|
|
||||||
|
import io.kritor.message.MessageServiceGrpcKt
|
||||||
|
|
||||||
|
internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImplBase() {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,473 @@
|
|||||||
|
package moe.fuqiuluo.shamrock.internals
|
||||||
|
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||||
|
import io.kritor.Scene
|
||||||
|
import io.kritor.contact
|
||||||
|
import io.kritor.event.MessageEvent
|
||||||
|
import io.kritor.event.messageEvent
|
||||||
|
import io.kritor.sender
|
||||||
|
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
|
||||||
|
|
||||||
|
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 suspend fun pushNotice(noticeEvent: NoticeEvent) = noticeEventFlow.emit(noticeEvent)
|
||||||
|
|
||||||
|
//private suspend fun pushRequest(requestEvent: RequestEvent) = requestEventFlow.emit(requestEvent)
|
||||||
|
|
||||||
|
private suspend fun transMessageEvent(record: MsgRecord, message: MessageEvent) = messageEventFlow.emit(record to message)
|
||||||
|
|
||||||
|
object MessageTransmitter {
|
||||||
|
suspend fun transGroupMessage(
|
||||||
|
record: MsgRecord,
|
||||||
|
elements: ArrayList<MsgElement>,
|
||||||
|
): Boolean {
|
||||||
|
transMessageEvent(record, messageEvent {
|
||||||
|
this.time = record.msgTime.toInt()
|
||||||
|
this.scene = Scene.GROUP
|
||||||
|
this.messageId = record.msgId
|
||||||
|
this.messageSeq = record.msgSeq
|
||||||
|
this.contact = contact {
|
||||||
|
this.scene = scene
|
||||||
|
this.peer = record.peerUin.toString()
|
||||||
|
this.subPeer = record.peerUid
|
||||||
|
}
|
||||||
|
this.sender = sender {
|
||||||
|
this.uin = record.senderUin
|
||||||
|
this.uid = record.senderUid
|
||||||
|
this.nick = record.sendNickName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transPrivateMessage(
|
||||||
|
record: MsgRecord,
|
||||||
|
elements: ArrayList<MsgElement>,
|
||||||
|
): Boolean {
|
||||||
|
val botUin = app.longAccountUin
|
||||||
|
var nickName = record.sendNickName
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transTempMessage(
|
||||||
|
record: MsgRecord,
|
||||||
|
elements: ArrayList<MsgElement>,
|
||||||
|
groupCode: Long,
|
||||||
|
fromNick: String,
|
||||||
|
): Boolean {
|
||||||
|
val botUin = app.longAccountUin
|
||||||
|
var nickName = record.sendNickName
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGuildMessage(
|
||||||
|
record: MsgRecord,
|
||||||
|
elements: ArrayList<MsgElement>,
|
||||||
|
): Boolean {
|
||||||
|
val botUin = app.longAccountUin
|
||||||
|
var nickName = record.sendNickName
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/**
|
||||||
|
* 文件通知 通知器
|
||||||
|
*/
|
||||||
|
object FileNoticeTransmitter {
|
||||||
|
/**
|
||||||
|
* 推送私聊文件事件
|
||||||
|
*/
|
||||||
|
suspend fun transPrivateFileEvent(
|
||||||
|
msgTime: Long,
|
||||||
|
userId: Long,
|
||||||
|
fileId: String,
|
||||||
|
fileSubId: String,
|
||||||
|
fileName: String,
|
||||||
|
fileSize: Long,
|
||||||
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送私聊文件事件
|
||||||
|
*/
|
||||||
|
suspend fun transGroupFileEvent(
|
||||||
|
msgTime: Long,
|
||||||
|
userId: Long,
|
||||||
|
groupId: Long,
|
||||||
|
uuid: String,
|
||||||
|
fileName: String,
|
||||||
|
fileSize: Long,
|
||||||
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群聊通知 通知器
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGroupMemberNumChanged(
|
||||||
|
time: Long,
|
||||||
|
target: Long,
|
||||||
|
targetUid: String,
|
||||||
|
groupCode: Long,
|
||||||
|
operator: Long,
|
||||||
|
operatorUid: String,
|
||||||
|
noticeType: NoticeType,
|
||||||
|
noticeSubType: NoticeSubType
|
||||||
|
): 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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGroupAdminChanged(
|
||||||
|
msgTime: Long,
|
||||||
|
target: Long,
|
||||||
|
targetUid: String,
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGroupBan(
|
||||||
|
msgTime: Long,
|
||||||
|
subType: NoticeSubType,
|
||||||
|
operator: Long,
|
||||||
|
operatorUid: String,
|
||||||
|
target: Long,
|
||||||
|
targetUid: String,
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGroupMsgRecall(
|
||||||
|
time: Long,
|
||||||
|
operator: Long,
|
||||||
|
target: Long,
|
||||||
|
groupCode: Long,
|
||||||
|
msgHash: Int,
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transCardChange(
|
||||||
|
time: Long,
|
||||||
|
targetId: Long,
|
||||||
|
oldCard: String,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transTitleChange(
|
||||||
|
time: Long,
|
||||||
|
targetId: Long,
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transEssenceChange(
|
||||||
|
time: Long,
|
||||||
|
senderUin: Long,
|
||||||
|
operatorUin: Long,
|
||||||
|
msgId: Int,
|
||||||
|
groupId: Long,
|
||||||
|
subType: NoticeSubType
|
||||||
|
): Boolean {
|
||||||
|
pushNotice(NoticeEvent(
|
||||||
|
time = time,
|
||||||
|
selfId = app.longAccountUin,
|
||||||
|
postType = PostType.Notice,
|
||||||
|
type = NoticeType.Essence,
|
||||||
|
senderId = senderUin,
|
||||||
|
groupId = groupId,
|
||||||
|
operatorId = operatorUin,
|
||||||
|
msgId = msgId,
|
||||||
|
subType = subType
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私聊通知 通知器
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求 通知器
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun transGroupApply(
|
||||||
|
time: Long,
|
||||||
|
applier: Long,
|
||||||
|
applierUid: String,
|
||||||
|
reason: String,
|
||||||
|
groupCode: Long,
|
||||||
|
flag: String,
|
||||||
|
subType: RequestSubType
|
||||||
|
): 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
|
||||||
|
))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
suspend inline fun onMessageEvent(collector: FlowCollector<Pair<MsgRecord, MessageEvent>>) {
|
||||||
|
messageEventFlow.collect {
|
||||||
|
GlobalScope.launch {
|
||||||
|
collector.emit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
suspend inline fun onNoticeEvent(collector: FlowCollector<NoticeEvent>) {
|
||||||
|
noticeEventFlow.collect {
|
||||||
|
GlobalScope.launch {
|
||||||
|
collector.emit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend inline fun onRequestEvent(collector: FlowCollector<RequestEvent>) {
|
||||||
|
requestEventFlow.collect {
|
||||||
|
GlobalScope.launch {
|
||||||
|
collector.emit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
@ -11,7 +11,7 @@ import moe.fuqiuluo.shamrock.tools.hookMethod
|
|||||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.internals.NTServiceFetcher
|
import qq.service.internals.NTServiceFetcher
|
||||||
import moe.fuqiuluo.shamrock.xposed.loader.NativeLoader
|
import moe.fuqiuluo.shamrock.xposed.loader.NativeLoader
|
||||||
import moe.fuqiuluo.symbols.XposedHook
|
import moe.fuqiuluo.symbols.XposedHook
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import com.tencent.mobileqq.profilecard.observer.ProfileCardObserver
|
|||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import moe.fuqiuluo.shamrock.internals.NTServiceFetcher
|
import qq.service.internals.NTServiceFetcher
|
||||||
import qq.service.QQInterfaces
|
import qq.service.QQInterfaces
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.sync.withLock
|
|||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.internals.NTServiceFetcher
|
import qq.service.internals.NTServiceFetcher
|
||||||
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
|
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
|
||||||
import moe.fuqiuluo.shamrock.tools.putBuf32Long
|
import moe.fuqiuluo.shamrock.tools.putBuf32Long
|
||||||
import moe.fuqiuluo.shamrock.tools.slice
|
import moe.fuqiuluo.shamrock.tools.slice
|
||||||
|
@ -24,6 +24,7 @@ import com.tencent.qqnt.kernel.nativeinterface.ImportOldDbMsgNotifyInfo
|
|||||||
import com.tencent.qqnt.kernel.nativeinterface.InputStatusInfo
|
import com.tencent.qqnt.kernel.nativeinterface.InputStatusInfo
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.KickedInfo
|
import com.tencent.qqnt.kernel.nativeinterface.KickedInfo
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgAbstract
|
import com.tencent.qqnt.kernel.nativeinterface.MsgAbstract
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgSetting
|
import com.tencent.qqnt.kernel.nativeinterface.MsgSetting
|
||||||
@ -33,12 +34,74 @@ import com.tencent.qqnt.kernel.nativeinterface.SearchGroupFileResult
|
|||||||
import com.tencent.qqnt.kernel.nativeinterface.TabStatusInfo
|
import com.tencent.qqnt.kernel.nativeinterface.TabStatusInfo
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.TempChatInfo
|
import com.tencent.qqnt.kernel.nativeinterface.TempChatInfo
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.UnreadCntInfo
|
import com.tencent.qqnt.kernel.nativeinterface.UnreadCntInfo
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
||||||
|
import qq.service.msg.MessageHelper
|
||||||
|
|
||||||
object AioListener: IKernelMsgListener {
|
object AioListener: IKernelMsgListener {
|
||||||
override fun onRecvMsg(arrayList: ArrayList<MsgRecord>?) {
|
override fun onRecvMsg(msgs: ArrayList<MsgRecord>) {
|
||||||
|
msgs.forEach {
|
||||||
|
GlobalScope.launch {
|
||||||
|
try {
|
||||||
|
onMsg(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
LogCenter.log("OnMessage: " + e.stackTraceToString(), Level.WARN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun onMsg(record: MsgRecord) {
|
||||||
|
when (record.chatType) {
|
||||||
|
MsgConstant.KCHATTYPEGROUP -> {
|
||||||
|
LogCenter.log("群消息(group = ${record.peerName}(${record.peerUin}), uin = ${record.senderUin}, id = ${record.msgId})")
|
||||||
|
|
||||||
|
if (!GlobalEventTransmitter.MessageTransmitter.transGroupMessage(record, record.elements)) {
|
||||||
|
LogCenter.log("群消息推送失败 -> 推送目标可能不存在", Level.WARN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgConstant.KCHATTYPEC2C -> {
|
||||||
|
LogCenter.log("私聊消息(private = ${record.senderUin}, id = [${record.msgId} | ${record.msgSeq}])")
|
||||||
|
|
||||||
|
if (!GlobalEventTransmitter.MessageTransmitter.transPrivateMessage(
|
||||||
|
record, record.elements
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
LogCenter.log("私聊消息推送失败 -> MessageTransmitter", Level.WARN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> {
|
||||||
|
var groupCode = 0L
|
||||||
|
var fromNick = ""
|
||||||
|
MessageHelper.getTempChatInfo(record.chatType, record.senderUid).onSuccess {
|
||||||
|
groupCode = it.groupCode.toLong()
|
||||||
|
fromNick = it.fromNick
|
||||||
|
}
|
||||||
|
|
||||||
|
LogCenter.log("私聊临时消息(private = ${record.senderUin}, groupId=$groupCode)")
|
||||||
|
|
||||||
|
if (!GlobalEventTransmitter.MessageTransmitter.transTempMessage(record, record.elements, groupCode, fromNick)
|
||||||
|
) {
|
||||||
|
LogCenter.log("私聊临时消息推送失败 -> MessageTransmitter", Level.WARN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgConstant.KCHATTYPEGUILD -> {
|
||||||
|
LogCenter.log("频道消息(guildId = ${record.guildId}, sender = ${record.senderUid}, id = [${record.msgId}])")
|
||||||
|
if (!GlobalEventTransmitter.MessageTransmitter
|
||||||
|
.transGuildMessage(record, record.elements)
|
||||||
|
) {
|
||||||
|
LogCenter.log("频道消息推送失败 -> MessageTransmitter", Level.WARN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> LogCenter.log("不支持PUSH事件: ${record.chatType}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMsgRecall(chatType: Int, peerId: String, msgId: Long) {
|
override fun onMsgRecall(chatType: Int, peerId: String, msgId: Long) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package moe.fuqiuluo.shamrock.internals
|
package qq.service.internals
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.api.IKernelService
|
import com.tencent.qqnt.kernel.api.IKernelService
|
||||||
import com.tencent.qqnt.kernel.api.impl.MsgService
|
import com.tencent.qqnt.kernel.api.impl.MsgService
|
||||||
@ -10,8 +10,6 @@ import moe.fuqiuluo.shamrock.helper.Level
|
|||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||||
import qq.service.internals.AioListener
|
|
||||||
import qq.service.internals.msgService
|
|
||||||
|
|
||||||
internal object NTServiceFetcher {
|
internal object NTServiceFetcher {
|
||||||
private lateinit var iKernelService: IKernelService
|
private lateinit var iKernelService: IKernelService
|
31
xposed/src/main/java/qq/service/msg/MessageHelper.kt
Normal file
31
xposed/src/main/java/qq/service/msg/MessageHelper.kt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package qq.service.msg
|
||||||
|
|
||||||
|
import com.tencent.qqnt.kernel.api.IKernelService
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.TempChatInfo
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import qq.service.QQInterfaces
|
||||||
|
import qq.service.internals.msgService
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
|
internal object MessageHelper: QQInterfaces() {
|
||||||
|
suspend fun getTempChatInfo(chatType: Int, uid: String): Result<TempChatInfo> {
|
||||||
|
val msgService = app.getRuntimeService(IKernelService::class.java, "all").msgService
|
||||||
|
?: return Result.failure(Exception("获取消息服务失败"))
|
||||||
|
val info: TempChatInfo = withTimeoutOrNull(5000) {
|
||||||
|
suspendCancellableCoroutine {
|
||||||
|
msgService.getTempChatInfo(chatType, uid) { code, msg, tempChatInfo ->
|
||||||
|
if (code == 0) {
|
||||||
|
it.resume(tempChatInfo)
|
||||||
|
} else {
|
||||||
|
LogCenter.log("获取临时会话信息失败: $code:$msg", Level.ERROR)
|
||||||
|
it.resume(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: return Result.failure(Exception("获取临时会话信息失败"))
|
||||||
|
return Result.success(info)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user