11package org.ntqqrev.acidify.message
22
3- import org.ntqqrev.acidify.Bot
43import org.ntqqrev.acidify.internal.packet.message.CommonMessage
5- import org.ntqqrev.acidify.internal.packet.message.Elem
6- import org.ntqqrev.acidify.internal.packet.message.PushMsgType
7- import org.ntqqrev.acidify.internal.packet.message.extra.PrivateFileExtra
84import org.ntqqrev.acidify.internal.protobuf.PbObject
9- import org.ntqqrev.acidify.internal.protobuf.invoke
10- import org.ntqqrev.acidify.message.internal.IncomingSegmentFactory
11- import org.ntqqrev.acidify.message.internal.MessageParsingContext
125import kotlin.js.JsExport
136
147/* *
@@ -60,128 +53,4 @@ class BotIncomingMessage internal constructor(
6053 val groupCard : String ,
6154 val specialTitle : String
6255 )
63-
64- companion object {
65- internal val factories = listOf<IncomingSegmentFactory <* >>(
66- IncomingSegmentFactory .Text ,
67- IncomingSegmentFactory .Mention ,
68- IncomingSegmentFactory .Face ,
69- IncomingSegmentFactory .Reply ,
70- IncomingSegmentFactory .Image ,
71- IncomingSegmentFactory .Record ,
72- IncomingSegmentFactory .Video ,
73- IncomingSegmentFactory .File ,
74- IncomingSegmentFactory .Forward ,
75- IncomingSegmentFactory .MarketFace ,
76- IncomingSegmentFactory .LightApp ,
77- )
78-
79- internal fun Bot.parseMessage (raw : PbObject <CommonMessage >): BotIncomingMessage ? {
80- val contentHead = raw.get { contentHead }
81- val pushMsgType = PushMsgType .from(contentHead.get { type }) ? : return null
82- val draftMsg = buildDraftMessage(raw, pushMsgType) ? : return null
83- val segments = if (pushMsgType != PushMsgType .FriendFileMessage ) {
84- buildSegments(raw.get { messageBody }.get { richText }.get { elems }, draftMsg.scene) {
85- draftMsg.extraInfo = it
86- }
87- } else {
88- val notOnlineFile = PrivateFileExtra (raw.get { messageBody }.get { msgContent })
89- .get { notOnlineFile }
90- listOf (
91- BotIncomingSegment .File (
92- fileId = notOnlineFile.get { fileUuid },
93- fileName = notOnlineFile.get { fileName },
94- fileSize = notOnlineFile.get { fileSize },
95- fileHash = notOnlineFile.get { fileIdCrcMedia }
96- )
97- )
98- }
99-
100- if (segments.isEmpty()) {
101- return null
102- }
103-
104- draftMsg.segments = segments
105- return draftMsg
106- }
107-
108- private fun Bot.buildDraftMessage (raw : PbObject <CommonMessage >, pushMsgType : PushMsgType ): BotIncomingMessage ? {
109- val routingHead = raw.get { routingHead }
110- val contentHead = raw.get { contentHead }
111-
112- return when (pushMsgType) {
113- PushMsgType .FriendMessage ,
114- PushMsgType .FriendRecordMessage ,
115- PushMsgType .FriendFileMessage -> {
116- val isSelfSend = routingHead.get { fromUin } == this .uin
117- BotIncomingMessage (
118- scene = MessageScene .FRIEND ,
119- peerUin = if (isSelfSend) routingHead.get { toUin } else routingHead.get { fromUin },
120- peerUid = if (isSelfSend) routingHead.get { toUid } else routingHead.get { fromUid },
121- sequence = contentHead.get { clientSequence },
122- timestamp = contentHead.get { time },
123- senderUin = routingHead.get { fromUin },
124- senderUid = routingHead.get { fromUid },
125- clientSequence = contentHead.get { sequence }, // weird
126- random = contentHead.get { random },
127- messageUid = contentHead.get { msgUid },
128- raw = raw,
129- )
130- }
131-
132- PushMsgType .GroupMessage -> {
133- BotIncomingMessage (
134- scene = MessageScene .GROUP ,
135- peerUin = routingHead.get { group }.get { groupCode },
136- peerUid = routingHead.get { toUid },
137- sequence = contentHead.get { sequence },
138- timestamp = contentHead.get { time },
139- senderUin = routingHead.get { fromUin },
140- senderUid = routingHead.get { fromUid },
141- clientSequence = contentHead.get { clientSequence },
142- random = contentHead.get { random },
143- messageUid = contentHead.get { msgUid },
144- raw = raw,
145- )
146- }
147-
148- else -> return null
149- }
150- }
151-
152- internal fun Bot.buildSegments (
153- elems : List <PbObject <Elem >>,
154- scene : MessageScene ,
155- onExtraInfo : ((ExtraInfo ) -> Unit )? = null
156- ): List <BotIncomingSegment > {
157- val segments = mutableListOf<BotIncomingSegment >()
158- val ctx = MessageParsingContext (scene, elems, this )
159- while (ctx.hasNext()) {
160- ctx.tryPeekType { this .extraInfo }?.let {
161- onExtraInfo?.invoke(
162- ExtraInfo (
163- nick = it.get { nick },
164- groupCard = it.get { groupCard },
165- specialTitle = it.get { senderTitle },
166- )
167- )
168- ctx.consume()
169- continue
170- }
171-
172- var matched = false
173- for (factory in factories) {
174- val segment = factory.tryParse(ctx) ? : continue
175- segments + = segment
176- matched = true
177- break
178- }
179- if (! matched) {
180- ctx.skip()
181- }
182- }
183-
184- return segments
185- }
186- }
18756}
0 commit comments