diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/FriendSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/FriendSvc.kt index 2dde121..bf99fd2 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/FriendSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/FriendSvc.kt @@ -58,7 +58,7 @@ internal object FriendSvc: BaseSvc() { ) } - suspend fun requestFriendSystemMsgNew(msgNum: Int, latestFriendSeq: Long, latestGroupSeq: Long): List? { + suspend fun requestFriendSystemMsgNew(msgNum: Int, latestFriendSeq: Long = 0, latestGroupSeq: Long = 0, retryCnt: Int = 3): List? { val req = `structmsg$ReqSystemMsgNew`() req.msg_num.set(msgNum) req.latest_friend_seq.set(latestFriendSeq) @@ -90,10 +90,15 @@ internal object FriendSvc: BaseSvc() { req.uint32_req_msg_type.set(1) req.uint32_need_uid.set(1) val respBuffer = sendBufferAW("ProfileService.Pb.ReqSystemMsgNew.Friend", true, req.toByteArray()) - ?: return ArrayList() - val msg = `structmsg$RspSystemMsgNew`() - msg.mergeFrom(respBuffer.slice(4)) - return msg.friendmsgs.get() + return if (respBuffer == null && retryCnt >= 0) { + requestFriendSystemMsgNew(msgNum, latestFriendSeq, latestGroupSeq, retryCnt - 1) + } else if (respBuffer == null) { + ArrayList() + } else { + val msg = `structmsg$RspSystemMsgNew`() + msg.mergeFrom(respBuffer.slice(4)) + return msg.friendmsgs.get() + } } diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt index bbfd639..fc52b8f 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt @@ -677,7 +677,7 @@ internal object GroupSvc: BaseSvc() { } } - suspend fun requestGroupSystemMsgNew(msgNum: Int, latestFriendSeq: Long, latestGroupSeq: Long): List? { + suspend fun requestGroupSystemMsgNew(msgNum: Int, latestFriendSeq: Long = 0, latestGroupSeq: Long = 0, retryCnt: Int = 3): List? { val req = ReqSystemMsgNew() req.msg_num.set(msgNum) req.latest_friend_seq.set(latestFriendSeq) @@ -709,9 +709,14 @@ internal object GroupSvc: BaseSvc() { req.uint32_req_msg_type.set(1) req.uint32_need_uid.set(1) val respBuffer = sendBufferAW("ProfileService.Pb.ReqSystemMsgNew.Group", true, req.toByteArray()) - ?: return ArrayList() - val msg = RspSystemMsgNew() - msg.mergeFrom(respBuffer.slice(4)) - return msg.groupmsgs.get() + return if (respBuffer == null && retryCnt >= 0) { + requestGroupSystemMsgNew(msgNum, latestFriendSeq, latestGroupSeq, retryCnt - 1) + } else if (respBuffer == null) { + ArrayList() + } else { + val msg = RspSystemMsgNew() + msg.mergeFrom(respBuffer.slice(4)) + return msg.groupmsgs.get() + } } } \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupSystemMsg.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupSystemMsg.kt index 865a65c..35ef84a 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupSystemMsg.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupSystemMsg.kt @@ -2,6 +2,7 @@ package moe.fuqiuluo.shamrock.remote.action.handlers import kotlinx.serialization.json.JsonElement import moe.fuqiuluo.qqinterface.servlet.GroupSvc +import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.service.data.GroupRequest @@ -10,11 +11,11 @@ import moe.fuqiuluo.shamrock.tools.EmptyJsonString internal object GetGroupSystemMsg: IActionHandler() { override suspend fun internalHandle(session: ActionSession): String { - return invoke(session.echo) + return invoke(echo = session.echo) } suspend operator fun invoke(echo: JsonElement = EmptyJsonString): String { - val list = GroupSvc.requestGroupSystemMsgNew(20, 0, 0) + val list = GroupSvc.requestGroupSystemMsgNew(20) val msgs = GroupSystemMessage( invited = mutableListOf(), join = mutableListOf() diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetFriendAddRequest.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetFriendAddRequest.kt index b47c7cb..7f720d7 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetFriendAddRequest.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetFriendAddRequest.kt @@ -16,12 +16,21 @@ internal object SetFriendAddRequest: IActionHandler() { return invoke(flag, approve, remark, notSeen, session.echo) } - operator fun invoke(flag: String, approve: Boolean? = true, remark: String? = "", notSeen: Boolean? = false, echo: JsonElement = EmptyJsonString): String { + suspend operator fun invoke(flag: String, approve: Boolean? = true, remark: String? = "", notSeen: Boolean? = false, echo: JsonElement = EmptyJsonString): String { val flags = flag.split(";") - val ts = flags[0].toLong() + var ts = flags[0].toLong() // val src = flags[1].toInt() // val subSrc = flags[2].toInt() val applier = flags[3].toLong() + if (ts.toString().length < 13) { + // time but not seq, query seq again + val reqs = FriendSvc.requestFriendSystemMsgNew(20, 0, 0, 1) + val req = reqs?.first { + it.msg_time.get() == ts + } + // 好友请求seq貌似就是time*1000,查不到直接*1000 + ts = req?.msg_seq?.get() ?: (ts * 1000) + } return try { FriendSvc.requestFriendRequest(ts, applier, remark ?: "", approve, notSeen) ok("成功", echo) diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetGroupAddRequest.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetGroupAddRequest.kt index 4d8450a..21b0bad 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetGroupAddRequest.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetGroupAddRequest.kt @@ -1,6 +1,7 @@ package moe.fuqiuluo.shamrock.remote.action.handlers import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.FriendSvc import moe.fuqiuluo.qqinterface.servlet.GroupSvc import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.IActionHandler @@ -18,7 +19,15 @@ internal object SetGroupAddRequest: IActionHandler() { suspend operator fun invoke(flag: String, approve: Boolean? = true, subType: String, remark: String? = "", notSeen: Boolean? = false, echo: JsonElement = EmptyJsonString): String { val flags = flag.split(";") - val ts = flags[0].toLong() + var ts = flags[0].toLong() + if (ts.toString().length < 13) { + // time but not seq, query seq again + val reqs = GroupSvc.requestGroupSystemMsgNew(20) + val req = reqs?.first { + it.msg_time.get() == ts + } + ts = req?.msg_seq?.get() ?: return error("失败:未找到该请求", echo) + } val groupCode = flags[1].toLong() val uin = flags[2].toLong() return try { @@ -32,7 +41,6 @@ internal object SetGroupAddRequest: IActionHandler() { err.printStackTrace() error("失败:${err.message}", echo) } - } override fun path(): String = "set_group_add_request" diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/HttpService.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/HttpService.kt index 180e164..4372005 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/HttpService.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/HttpService.kt @@ -54,6 +54,12 @@ internal object HttpService: HttpTransmitServlet() { GlobalEventTransmitter.onNoticeEvent { event -> pushTo(event) } + + }) + submitFlowJob(GlobalScope.launch { + GlobalEventTransmitter.onRequestEvent { + pushTo(it) + } }) LogCenter.log("HttpService: 初始化服务", Level.WARN) } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketClientService.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketClientService.kt index 8e3c428..714b8df 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketClientService.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketClientService.kt @@ -33,6 +33,11 @@ internal class WebSocketClientService( pushTo(event) } }) + submitFlowJob(GlobalScope.launch { + GlobalEventTransmitter.onRequestEvent() { event -> + pushTo(event) + } + }) LogCenter.log("WebSocketClientService: 初始化服务", Level.WARN) } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketService.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketService.kt index fe591a5..4558149 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketService.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/WebSocketService.kt @@ -39,6 +39,11 @@ internal class WebSocketService(host: String, port: Int): WebSocketTransmitServl pushTo(event) } }) + submitFlowJob(GlobalScope.launch { + GlobalEventTransmitter.onRequestEvent { event -> + pushTo(event) + } + }) LogCenter.log("WebSocketService: 初始化服务", Level.WARN) } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/GlobalEventTransmitter.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/GlobalEventTransmitter.kt index d42f5f0..b004d55 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/GlobalEventTransmitter.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/GlobalEventTransmitter.kt @@ -20,6 +20,9 @@ import moe.fuqiuluo.shamrock.remote.service.data.push.NoticeEvent import moe.fuqiuluo.shamrock.remote.service.data.push.NoticeSubType import moe.fuqiuluo.shamrock.remote.service.data.push.NoticeType import moe.fuqiuluo.shamrock.remote.service.data.push.PrivateFileMsg +import moe.fuqiuluo.shamrock.remote.service.data.push.RequestEvent +import moe.fuqiuluo.shamrock.remote.service.data.push.RequestSubType +import moe.fuqiuluo.shamrock.remote.service.data.push.RequestType import moe.fuqiuluo.shamrock.remote.service.data.push.Sender import moe.fuqiuluo.shamrock.tools.ShamrockDsl import moe.fuqiuluo.shamrock.tools.json @@ -32,9 +35,14 @@ internal object GlobalEventTransmitter: BaseSvc() { private val noticeEventFlow by lazy { MutableSharedFlow() } + private val requestEventFlow by lazy { + MutableSharedFlow() + } 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) /** @@ -314,30 +322,6 @@ internal object GlobalEventTransmitter: BaseSvc() { )) return true } - - suspend fun transGroupApply( - time: Long, - operator: Long, - reason: String, - groupCode: Long, - flag: String, - subType: NoticeSubType - ): Boolean { - pushNotice(NoticeEvent( - time = time, - selfId = app.longAccountUin, - postType = PostType.Notice, - type = NoticeType.GroupApply, - operatorId = operator, - userId = operator, - tip = reason, - groupId = groupCode, - subType = subType, - flag = flag - )) - return true - } - } /** @@ -373,15 +357,42 @@ internal object GlobalEventTransmitter: BaseSvc() { return true } - suspend fun transFriendApply(time: Long, operation: Long, tipText: String, flag: String): Boolean { - pushNotice(NoticeEvent( + } + + /** + * 请求 通知器 + */ + object RequestTransmitter { + suspend fun transFriendApp(time: Long, operation: Long, tipText: String, flag: String): Boolean { + pushRequest(RequestEvent( time = time, selfId = app.longAccountUin, - postType = PostType.Notice, - type = NoticeType.FriendApply, - operatorId = operation, + postType = PostType.Request, + type = RequestType.Friend, userId = operation, - tip = tipText, + comment = tipText, + flag = flag + )) + return true + } + + suspend fun transGroupApply( + time: Long, + operator: Long, + reason: String, + groupCode: Long, + flag: String, + subType: RequestSubType + ): Boolean { + pushRequest(RequestEvent( + time = time, + selfId = app.longAccountUin, + postType = PostType.Request, + type = RequestType.Group, + userId = operator, + comment = reason, + groupId = groupCode, + subType = subType, flag = flag )) return true @@ -398,6 +409,12 @@ internal object GlobalEventTransmitter: BaseSvc() { noticeEventFlow .collect(collector) } + + @ShamrockDsl + suspend inline fun onRequestEvent(collector: FlowCollector) { + requestEventFlow + .collect(collector) + } } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/MessageEvent.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/MessageEvent.kt index e157ee5..9ccf17c 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/MessageEvent.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/MessageEvent.kt @@ -33,6 +33,7 @@ internal enum class MsgType { internal enum class PostType { @SerialName("meta_event") Meta, @SerialName("notice") Notice, + @SerialName("request") Request, @SerialName("message") Msg, @SerialName("message_sent") MsgSent, } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/NoticeEvent.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/NoticeEvent.kt index c1dcdbe..8c138d0 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/NoticeEvent.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/data/push/NoticeEvent.kt @@ -10,14 +10,18 @@ internal enum class NoticeType { @SerialName("group_decrease") GroupMemDecrease, @SerialName("group_increase") GroupMemIncrease, @SerialName("group_recall") GroupRecall, - @SerialName("group_apply") GroupApply, @SerialName("friend_recall") FriendRecall, - @SerialName("friend_add") FriendApply, @SerialName("notify") Notify, @SerialName("group_upload") GroupUpload, @SerialName("private_upload") PrivateUpload } +@Serializable +internal enum class RequestType { + @SerialName("friend ") Friend, + @SerialName("group") Group, +} + @Serializable internal enum class NoticeSubType { @SerialName("none") None, @@ -38,6 +42,13 @@ internal enum class NoticeSubType { @SerialName("poke") Poke, } +@Serializable +internal enum class RequestSubType { + @SerialName("none") None, + @SerialName("add") Add, + @SerialName("invite") Invite, +} + /** * 不要使用继承的方式实现通用字段,那样会很难维护! */ @@ -61,6 +72,23 @@ internal data class NoticeEvent( @SerialName("flag") val flag: String? = null, ) +/** + * 不要使用继承的方式实现通用字段,那样会很难维护! + */ +@Serializable +internal data class RequestEvent( + @SerialName("time") val time: Long, + @SerialName("self_id") val selfId: Long, + @SerialName("post_type") val postType: PostType, + @SerialName("request_type ") val type: RequestType, + @SerialName("sub_type") val subType: RequestSubType = RequestSubType.None, + @SerialName("group_id") val groupId: Long = 0, + @SerialName("user_id") val userId: Long = 0, + @SerialName("comment") val comment: String = "", + @SerialName("flag") val flag: String? = null, +) + + @Serializable internal data class GroupFileMsg( val id: String, diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt index b7d645a..852d4dc 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt @@ -29,6 +29,7 @@ import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter +import moe.fuqiuluo.shamrock.remote.service.data.push.RequestSubType import moe.fuqiuluo.shamrock.tools.readBuf32Long import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.xposed.helper.PacketHandler @@ -118,19 +119,21 @@ internal object PrimitiveListener { if (applier == 0L) { applier = pb[4, 3, 8].asLong } - val msg_time = pb[1, 3, 2, 1, 9].asLong val src = pb[1, 3, 2, 1, 7].asInt val subSrc = pb[1, 3, 2, 1, 8].asInt - val reqs = requestFriendSystemMsgNew(20, 0, 0) - val req = reqs?.first { - it.msg_time.get() == msg_time + 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" } - val seq = req?.msg_seq?.get() - val flag = "$seq;$src;$subSrc;$applier" - LogCenter.log("来自$applier 的好友申请:$msg ($source)") - if(!GlobalEventTransmitter.PrivateNoticeTransmitter - .transFriendApply(msgTime, applier, msg, flag)) { + if(!GlobalEventTransmitter.RequestTransmitter + .transFriendApp(msgTime, applier, msg, flag)) { LogCenter.log("好友申请推送失败!", Level.WARN) } } @@ -340,24 +343,20 @@ internal object PrimitiveListener { val applier = ContactHelper.getUinByUidAsync(applierUid).toLong() LogCenter.log("入群申请($groupCode) $applier: \"$reason\"") - try { - val reqs = requestGroupSystemMsgNew(20, 0, 0) + val flag = try { + val reqs = requestGroupSystemMsgNew(10, 0, 0) val req = reqs?.first { it.msg_time.get() == time } val seq = req?.msg_seq?.get() - val flag = "$seq;$groupCode;$applierUid" - if(!seq?.let { - GlobalEventTransmitter.GroupNoticeTransmitter - .transGroupApply(it, applier, reason, groupCode, flag, NoticeSubType.Add) - }!!) { - LogCenter.log("入群申请推送失败!", Level.WARN) - } + "$seq;$groupCode;$applierUid" } catch (err: Throwable) { - LogCenter.log("入群申请推送失败!", Level.WARN) - LogCenter.log(err.stackTraceToString(), Level.ERROR) + "$time;$groupCode;$applierUid" + } + if(!GlobalEventTransmitter.RequestTransmitter + .transGroupApply(time, applier, reason, groupCode, flag, RequestSubType.Add)) { + LogCenter.log("入群申请推送失败!", Level.WARN) } - } 528 -> { val groupCode = pb[1, 3, 2, 2, 3].asULong @@ -368,23 +367,19 @@ internal object PrimitiveListener { return } LogCenter.log("邀请入群申请($groupCode): $applier") - try { - val reqs = requestGroupSystemMsgNew(20, 0, 0) + val flag = try { + val reqs = requestGroupSystemMsgNew(10, 0, 0) val req = reqs?.first { it.msg_time.get() == time } val seq = req?.msg_seq?.get() - val flag = "$seq;$groupCode;$applier" - if(!seq?.let { - GlobalEventTransmitter.GroupNoticeTransmitter - .transGroupApply(it, applier, "", groupCode, flag, NoticeSubType.Add) - }!!) { - LogCenter.log("邀请入群申请推送失败!", Level.WARN) - } - + "$seq;$groupCode;$applier" } catch (err: Throwable) { + "$time;$groupCode;$applierUid" + } + if(GlobalEventTransmitter.RequestTransmitter + .transGroupApply(time, applier, "", groupCode, flag, RequestSubType.Add)) { LogCenter.log("邀请入群申请推送失败!", Level.WARN) - LogCenter.log(err.stackTraceToString(), Level.ERROR) } } } @@ -395,22 +390,19 @@ internal object PrimitiveListener { val invitor = ContactHelper.getUinByUidAsync(invitorUid).toLong() val uin = pb[1, 1, 5].asLong LogCenter.log("邀请入群$groupCode 邀请者: \"$invitor\"") - try { - val reqs = requestGroupSystemMsgNew(20, 0, 0) + val flag = try { + val reqs = requestGroupSystemMsgNew(10, 0, 0) val req = reqs?.first { it.msg_time.get() == time } val seq = req?.msg_seq?.get() - val flag = "$seq;$groupCode;$uin" - if(!seq?.let { - GlobalEventTransmitter.GroupNoticeTransmitter - .transGroupApply(it, invitor, "", groupCode, flag, NoticeSubType.Invite) - }!!) { - LogCenter.log("邀请入群推送失败!", Level.WARN) - } + "$seq;$groupCode;$uin" } catch (err: Throwable) { + "$time;$groupCode;$uin" + } + if(GlobalEventTransmitter.RequestTransmitter + .transGroupApply(time, invitor, "", groupCode, flag, RequestSubType.Invite)) { LogCenter.log("邀请入群推送失败!", Level.WARN) - LogCenter.log(err.stackTraceToString(), Level.ERROR) } }