mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
send_forward_msg(support at face...)
This commit is contained in:
parent
46ed966c18
commit
d22f3ad1cb
@ -7,10 +7,6 @@ import kotlin.reflect.KClass
|
||||
|
||||
interface Protobuf<T: Protobuf<T>>
|
||||
|
||||
inline fun <reified T: Protobuf<T>> KClass<T>.decode(data: ByteArray): T {
|
||||
return ProtoBuf.decodeFromByteArray(data)
|
||||
}
|
||||
|
||||
inline fun <reified T: Protobuf<T>> ByteArray.decodeProtobuf(to: KClass<T>? = null): T {
|
||||
return ProtoBuf.decodeFromByteArray(this)
|
||||
}
|
||||
|
26
protobuf/src/main/java/protobuf/message/AppShareInfo.kt
Normal file
26
protobuf/src/main/java/protobuf/message/AppShareInfo.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class AppShareInfo(
|
||||
@ProtoNumber(1) var appshareId: UInt? = null,
|
||||
@ProtoNumber(2) var appshareCookie: ByteArray? = null,
|
||||
@ProtoNumber(3) var appshareResource: PluginInfo? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PluginInfo(
|
||||
@ProtoNumber(1) var resId: UInt = 0u,
|
||||
@ProtoNumber(2) var pkgName: String = "",
|
||||
@ProtoNumber(3) var newVer: UInt = 0u,
|
||||
@ProtoNumber(4) var resType: UInt = 0u,
|
||||
@ProtoNumber(5) var lanType: UInt = 0u,
|
||||
@ProtoNumber(6) var priority: UInt = 0u,
|
||||
@ProtoNumber(7) var resName: String = "",
|
||||
@ProtoNumber(8) var resDesc: String = "",
|
||||
@ProtoNumber(9) var resUrlBig: String = "",
|
||||
@ProtoNumber(10) var resUrlSmall: String = "",
|
||||
@ProtoNumber(11) var resConf: String = "",
|
||||
)
|
@ -4,12 +4,12 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MessageContent(
|
||||
data class ContentHead(
|
||||
@ProtoNumber(1) val msgType: Int = Int.MIN_VALUE,
|
||||
@ProtoNumber(2) val msgSubType: Int? = null,
|
||||
@ProtoNumber(3) val u1: Int? = null,
|
||||
@ProtoNumber(3) val divSeq: Int? = null,
|
||||
@ProtoNumber(4) val msgViaRandom: Long = Long.MIN_VALUE,
|
||||
@ProtoNumber(5) val msgSeq_: Long? = null,
|
||||
@ProtoNumber(5) val sequence: Long? = null,
|
||||
@ProtoNumber(6) val msgTime: Long? = null,
|
||||
@ProtoNumber(7) val u2: Int? = null,
|
||||
@ProtoNumber(8) val u6: Int? = null,
|
||||
@ -27,5 +27,5 @@ data class ForwardHead(
|
||||
@ProtoNumber(2) val u2: Int? = null,
|
||||
@ProtoNumber(3) val u3: Int? = null,
|
||||
@ProtoNumber(4) val ub641: String? = null,
|
||||
@ProtoNumber(5) val Avatar: String? = null
|
||||
@ProtoNumber(5) val avatar: String? = null
|
||||
)
|
64
protobuf/src/main/java/protobuf/message/Elem.kt
Normal file
64
protobuf/src/main/java/protobuf/message/Elem.kt
Normal file
@ -0,0 +1,64 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import protobuf.message.element.*
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializable
|
||||
data class Elem(
|
||||
@ProtoNumber(1) val text: TextMsg? = null,
|
||||
@ProtoNumber(2) val face: FaceMsg? = null,
|
||||
// @ProtoNumber(3) val onlineImage: OnlineImage? = null,
|
||||
@ProtoNumber(4) val notOnlineImage: NotOnlineImage? = null,
|
||||
// @ProtoNumber(5) var transElemInfo: TransElem? = null,
|
||||
@ProtoNumber(6) val marketFace: MarketFace? = null,
|
||||
// @ProtoNumber(7) var elemFlags: ElemFlags? = null,
|
||||
@ProtoNumber(8) val customFace: CustomFace? = null,
|
||||
@ProtoNumber(9) var elemFlags2: ElemFlags2? = null,
|
||||
// @ProtoNumber(10) var funFace: FunFace? = null,
|
||||
// @ProtoNumber(11) var secretFile: SecretFileMsg? = null,
|
||||
// @ProtoNumber(12) var richMsg: RichMsg? = null,
|
||||
// @ProtoNumber(13) var groupFile: GroupFile? = null,
|
||||
// @ProtoNumber(14) var pubGroup: PubGroup? = null,
|
||||
// @ProtoNumber(15) var marketTrans: MarketTrans? = null,
|
||||
// @ProtoNumber(16) var extraInfo: ExtraInfo? = null,
|
||||
// @ProtoNumber(17) var shakeWindow: ShakeWindow? = null,
|
||||
// @ProtoNumber(18) var pubAccount: PubAccount? = null,
|
||||
// @ProtoNumber(19) var videoFile: VideoFile? = null,
|
||||
// @ProtoNumber(20) var tipsInfo: TipsInfo? = null,
|
||||
// @ProtoNumber(21) var anonGroupMsg: AnonymousGroupMsg? = null,
|
||||
// @ProtoNumber(22) var qqLiveOld: QQLiveOld? = null,
|
||||
// @ProtoNumber(23) var lifeOnline: LifeOnlineAccount? = null,
|
||||
// @ProtoNumber(24) var qqwalletMsg: QQWalletMsg? = null,
|
||||
// @ProtoNumber(25) var crmElem: CrmElem? = null,
|
||||
// @ProtoNumber(26) var conferenceTipsInfo: ConferenceTipsInfo? = null,
|
||||
// @ProtoNumber(27) var redbagInfo: RedBagInfo? = null,
|
||||
// @ProtoNumber(28) var lowVersionTips: LowVersionTips? = null,
|
||||
// @ProtoNumber(29) var bankcodeCtrlInfo: ByteArray? = null,
|
||||
// @ProtoNumber(30) var nearByMsg: NearByMessageType? = null,
|
||||
// @ProtoNumber(31) var customElem: CustomElem? = null,
|
||||
// @ProtoNumber(32) var locationInfo: LocationInfo? = null,
|
||||
// @ProtoNumber(33) var pubAccInfo: PubAccInfo? = null,
|
||||
// @ProtoNumber(34) var smallEmoji: SmallEmoji? = null,
|
||||
// @ProtoNumber(35) var fsjMsgElem: FSJMessageElem? = null,
|
||||
// @ProtoNumber(36) var arkApp: ArkAppElem? = null,
|
||||
@ProtoNumber(37) val generalFlags: GeneralFlags? = null,
|
||||
// @ProtoNumber(38) var hcFlashPic: CustomFace? = null,
|
||||
// @ProtoNumber(39) var deliverGiftMsg: DeliverGiftMsg? = null,
|
||||
// @ProtoNumber(40) var bitapp_msg: BitAppMsg? = null,
|
||||
// @ProtoNumber(41) var openQqData: OpenQQData? = null,
|
||||
// @ProtoNumber(42) var apolloMsg: ApolloActMsg? = null,
|
||||
// @ProtoNumber(43) var groupPubAccInfo: GroupPubAccountInfo? = null,
|
||||
// @ProtoNumber(44) var blessMsg: BlessingMessage? = null,
|
||||
@ProtoNumber(45) var srcMsg: SourceMsg? = null,
|
||||
// @ProtoNumber(46) var lolaMsg: LolaMsg? = null,
|
||||
// @ProtoNumber(47) var groupBusinessMsg: GroupBusinessMsg? = null,
|
||||
// @ProtoNumber(48) var msgWorkflowNotify: WorkflowNotifyMsg? = null,
|
||||
// @ProtoNumber(49) var patElem: PatsElem? = null,
|
||||
// @ProtoNumber(50) var groupPostElem: GroupPostElem? = null,
|
||||
@ProtoNumber(51) val lightApp: LightAppElem? = null,
|
||||
// @ProtoNumber(52) var eimInfo: EIMInfo? = null,
|
||||
@ProtoNumber(53) val commonElem: CommonElem? = null,
|
||||
)
|
@ -1,17 +0,0 @@
|
||||
@file:OptIn(ExperimentalSerializationApi::class)
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class RichMessage(
|
||||
@ProtoNumber(1) val font: Font? = null,
|
||||
@ProtoNumber(2) val elements: List<MessageElement>? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Font(
|
||||
@ProtoNumber(9) val fontName: String? = null
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MessageBody(
|
||||
@ProtoNumber(1) val rich: RichMessage? = null,
|
||||
@ProtoNumber(2) val rawBuffer: ByteArray? = null,
|
||||
@ProtoNumber(3) val MsgEncryptContent: ByteArray? = null
|
||||
)
|
@ -1,13 +0,0 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import protobuf.message.element.*
|
||||
|
||||
@Serializable
|
||||
data class MessageElement(
|
||||
@ProtoNumber(1) val text: TextElement? = null,
|
||||
@ProtoNumber(2) val face: FaceElement? = null,
|
||||
@ProtoNumber(51) val json: JsonElement? = null,
|
||||
@ProtoNumber(53) val comm: CommonElement? = null,
|
||||
)
|
11
protobuf/src/main/java/protobuf/message/MsgBody.kt
Normal file
11
protobuf/src/main/java/protobuf/message/MsgBody.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MsgBody(
|
||||
@ProtoNumber(1) val richText: RichText? = null,
|
||||
@ProtoNumber(2) val msgContent: ByteArray? = null,
|
||||
@ProtoNumber(3) val msgEncryptContent: ByteArray? = null
|
||||
)
|
9
protobuf/src/main/java/protobuf/message/MsgControl.kt
Normal file
9
protobuf/src/main/java/protobuf/message/MsgControl.kt
Normal file
@ -0,0 +1,9 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MsgControl(
|
||||
@ProtoNumber(1) val msgFlag: Int? = null,
|
||||
)
|
28
protobuf/src/main/java/protobuf/message/NotOnlineFile.kt
Normal file
28
protobuf/src/main/java/protobuf/message/NotOnlineFile.kt
Normal file
@ -0,0 +1,28 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class NotOnlineFile(
|
||||
@ProtoNumber(1) var fileType: UInt? = null,
|
||||
@ProtoNumber(2) var sig: ByteArray? = null,
|
||||
@ProtoNumber(3) var fileUuid: ByteArray? = null,
|
||||
@ProtoNumber(4) var fileMd5: ByteArray? = null,
|
||||
@ProtoNumber(5) var fileName: ByteArray? = null,
|
||||
@ProtoNumber(6) var fileSize: ULong? = null,
|
||||
@ProtoNumber(7) var note: ByteArray? = null,
|
||||
@ProtoNumber(8) var reserved: UInt? = null,
|
||||
@ProtoNumber(9) var subcmd: UInt? = null,
|
||||
@ProtoNumber(10) var microCloud: UInt? = null,
|
||||
@ProtoNumber(11) var rptFileUrls: List<String>? = null,
|
||||
@ProtoNumber(12) var downloadFlag: UInt? = null,
|
||||
@ProtoNumber(50) var dangerEvel: UInt? = null,
|
||||
@ProtoNumber(51) var lifeTime: UInt? = null,
|
||||
@ProtoNumber(52) var uploadTime: UInt? = null,
|
||||
@ProtoNumber(53) var absFileType: UInt? = null,
|
||||
@ProtoNumber(54) var clientType: UInt? = null,
|
||||
@ProtoNumber(55) var expireTime: UInt? = null,
|
||||
@ProtoNumber(56) var pbReserve: ByteArray? = null,
|
||||
@ProtoNumber(57) var fileidcrcMedia: String? = null,
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class NtMessage(
|
||||
@ProtoNumber(1) val msgHead: MessageHead? = null,
|
||||
@ProtoNumber(2) val contentHead: MessageContent? = null,
|
||||
@ProtoNumber(3) val body: MessageBody? = null,
|
||||
)
|
23
protobuf/src/main/java/protobuf/message/PbSendMsgReq.kt
Normal file
23
protobuf/src/main/java/protobuf/message/PbSendMsgReq.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
@Serializable
|
||||
data class PbSendMsgReq(
|
||||
@ProtoNumber(1) val routingHead: RoutingHead? = null,
|
||||
@ProtoNumber(2) val contentHead: ContentHead? = null,
|
||||
@ProtoNumber(3) val msgBody: MsgBody? = null,
|
||||
@ProtoNumber(4) val msgSeq: UInt? = null,
|
||||
@ProtoNumber(5) val msgRand: UInt? = null,
|
||||
@ProtoNumber(6) val syncCookie: ByteArray? = null,
|
||||
@ProtoNumber(7) val appShare: AppShareInfo? = null,
|
||||
@ProtoNumber(8) val msgVia: UInt? = null,
|
||||
@ProtoNumber(9) val dataStatist: UInt? = null,
|
||||
// @ProtoNumber(10) val multiMsgAssist: MultiMsgAssist? = null,
|
||||
// @ProtoNumber(11) val inputNotifyInfo: InputNotifyInfo? = null,
|
||||
@ProtoNumber(12) val ctrl: MsgControl? = null,
|
||||
// @ProtoNumber(13) val receiptReq: ReceiptReq? = null,
|
||||
@ProtoNumber(14) val multiSendSeq: UInt? = null
|
||||
) : Protobuf<PbSendMsgReq>
|
32
protobuf/src/main/java/protobuf/message/Ptt.kt
Normal file
32
protobuf/src/main/java/protobuf/message/Ptt.kt
Normal file
@ -0,0 +1,32 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class Ptt(
|
||||
@ProtoNumber(1) var fileType: UInt?=null,
|
||||
@ProtoNumber(2) var srcUin: ULong?=null,
|
||||
@ProtoNumber(3) var fileUuid: ByteArray?=null,
|
||||
@ProtoNumber(4) var fileMd5: ByteArray?=null,
|
||||
@ProtoNumber(5) var fileName: ByteArray?=null,
|
||||
@ProtoNumber(6) var fileSize: UInt?=null,
|
||||
@ProtoNumber(7) var reserve: ByteArray?=null,
|
||||
@ProtoNumber(8) var fileId: UInt?=null,
|
||||
@ProtoNumber(9) var serverIp: UInt?=null,
|
||||
@ProtoNumber(10) var serverPort: UInt?=null,
|
||||
@ProtoNumber(11) var boolValid: Boolean = false,
|
||||
@ProtoNumber(12) var signature: ByteArray?=null,
|
||||
@ProtoNumber(13) var shortcut: ByteArray?=null,
|
||||
@ProtoNumber(14) var fileKey: ByteArray?=null,
|
||||
@ProtoNumber(15) var magicPttIndex: UInt?=null,
|
||||
@ProtoNumber(16) var voiceSwitch: UInt?=null,
|
||||
@ProtoNumber(17) var pttUrl: ByteArray?=null,
|
||||
@ProtoNumber(18) var groupFileKey: ByteArray?=null,
|
||||
@ProtoNumber(19) var time: UInt?=null,
|
||||
@ProtoNumber(20) var downPara: ByteArray?=null,
|
||||
@ProtoNumber(29) var format: UInt?=null,
|
||||
@ProtoNumber(30) var pbReserve: ByteArray?=null,
|
||||
@ProtoNumber(31) var rptPttUrls: List<String>? = null,
|
||||
@ProtoNumber(32) var downloadFlag: UInt?=null,
|
||||
)
|
11
protobuf/src/main/java/protobuf/message/PushMsgBody.kt
Normal file
11
protobuf/src/main/java/protobuf/message/PushMsgBody.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class PushMsgBody(
|
||||
@ProtoNumber(1) val msgHead: ResponseHead? = null,
|
||||
@ProtoNumber(2) val contentHead: ContentHead? = null,
|
||||
@ProtoNumber(3) val body: MsgBody? = null,
|
||||
)
|
@ -6,25 +6,25 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MessageHead(
|
||||
data class ResponseHead(
|
||||
@ProtoNumber(1) val peer: Long = Long.MIN_VALUE,
|
||||
@ProtoNumber(2) val peerUid: String? = null,
|
||||
@ProtoNumber(3) val flag: Int = Int.MIN_VALUE,
|
||||
@ProtoNumber(4) val appId: Int = Int.MIN_VALUE,
|
||||
@ProtoNumber(5) val receiver: Long? = null,
|
||||
@ProtoNumber(6) val receiverUid: String? = null,
|
||||
@ProtoNumber(7) val forward: MessageForward? = null,
|
||||
@ProtoNumber(8) val groupInfo: GroupInfo? = null,
|
||||
@ProtoNumber(7) val forward: ResponseForward? = null,
|
||||
@ProtoNumber(8) val responseGrp: ResponseGrp? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class MessageForward(
|
||||
data class ResponseForward(
|
||||
@ProtoNumber(6) val friendName: String? = null,
|
||||
@ProtoNumber(11) val u1: Int? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GroupInfo(
|
||||
data class ResponseGrp(
|
||||
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
|
||||
@ProtoNumber(4) val memberCard: String? = null,
|
||||
@ProtoNumber(5) val u1: Int? = null,
|
31
protobuf/src/main/java/protobuf/message/RichText.kt
Normal file
31
protobuf/src/main/java/protobuf/message/RichText.kt
Normal file
@ -0,0 +1,31 @@
|
||||
@file:OptIn(ExperimentalSerializationApi::class)
|
||||
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class RichText(
|
||||
@ProtoNumber(1) val attr: Attr? = null,
|
||||
@ProtoNumber(2) val elements: List<Elem>? = null,
|
||||
@ProtoNumber(3) val not_online_file: NotOnlineFile? = null,
|
||||
@ProtoNumber(4) val ptt: Ptt? = null,
|
||||
@ProtoNumber(5) val tmp_ptt: TmpPtt? = null,
|
||||
@ProtoNumber(6) val trans_211_tmp_msg: Trans211TmpMsg? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Attr(
|
||||
@ProtoNumber(1) val codePage: Int? = null,
|
||||
@ProtoNumber(2) val time: UInt? = null,
|
||||
@ProtoNumber(3) val random: UInt? = null,
|
||||
@ProtoNumber(4) val color: UInt? = null,
|
||||
@ProtoNumber(5) val size: UInt? = null,
|
||||
@ProtoNumber(6) val effect: UInt? = null,
|
||||
@ProtoNumber(7) val charSet: UInt? = null,
|
||||
@ProtoNumber(8) val pitchAndFamily: UInt? = null,
|
||||
@ProtoNumber(9) val fontName: String? = null,
|
||||
@ProtoNumber(10) val reserve_data: ByteArray? = null,
|
||||
)
|
14
protobuf/src/main/java/protobuf/message/RoutingHead.kt
Normal file
14
protobuf/src/main/java/protobuf/message/RoutingHead.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import protobuf.message.routing.*
|
||||
|
||||
@Serializable
|
||||
data class RoutingHead(
|
||||
@ProtoNumber(1) val c2c: C2C? = null,
|
||||
@ProtoNumber(2) val grp: Grp? = null,
|
||||
@ProtoNumber(3) val grpTmp: GrpTmp? = null,
|
||||
@ProtoNumber(6) val wpaTmp: WPATmp? = null,
|
||||
@ProtoNumber(15) val trans0X211: Trans0X211? = null
|
||||
)
|
20
protobuf/src/main/java/protobuf/message/TmpPtt.kt
Normal file
20
protobuf/src/main/java/protobuf/message/TmpPtt.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class TmpPtt(
|
||||
@ProtoNumber(1) var fileType: UInt? = null,
|
||||
@ProtoNumber(2) var fileUuid: ByteArray? = null,
|
||||
@ProtoNumber(3) var fileMd5: ByteArray? = null,
|
||||
@ProtoNumber(4) var fileName: ByteArray? = null,
|
||||
@ProtoNumber(5) var fileSize: UInt? = null,
|
||||
@ProtoNumber(6) var pttTimes: UInt? = null,
|
||||
@ProtoNumber(7) var userType: UInt? = null,
|
||||
@ProtoNumber(8) var ptttransFlag: UInt? = null,
|
||||
@ProtoNumber(9) var busiType: UInt? = null,
|
||||
@ProtoNumber(10) var msgId: ULong? = null,
|
||||
@ProtoNumber(30) var pbReserve: ByteArray? = null,
|
||||
@ProtoNumber(31) var pttEncodeData: ByteArray? = null,
|
||||
)
|
10
protobuf/src/main/java/protobuf/message/Trans211TmpMsg.kt
Normal file
10
protobuf/src/main/java/protobuf/message/Trans211TmpMsg.kt
Normal file
@ -0,0 +1,10 @@
|
||||
package protobuf.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class Trans211TmpMsg(
|
||||
@ProtoNumber(1) var msgBody: ByteArray? = null,
|
||||
@ProtoNumber(2) var c2cCmd: UInt? = null,
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class CommonElem(
|
||||
@ProtoNumber(1) val serviceType: Int? = null,
|
||||
@ProtoNumber(2) val elem: ByteArray? = null,
|
||||
@ProtoNumber(3) val businessType: Int? = null,
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class CommonElement(
|
||||
@ProtoNumber(1) val type: Int? = null,
|
||||
@ProtoNumber(2) val data: ByteArray? = null,
|
||||
@ProtoNumber(3) val u1: Int? = null,
|
||||
)
|
@ -0,0 +1,49 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class CustomFace(
|
||||
@ProtoNumber(1) var guid: ByteArray? = null,
|
||||
@ProtoNumber(2) var filePath: String? = null,
|
||||
@ProtoNumber(3) var shortcut: String? = null,
|
||||
@ProtoNumber(4) var buffer: ByteArray? = null,
|
||||
@ProtoNumber(5) var flag: ByteArray? = null,
|
||||
@ProtoNumber(6) var oldData: ByteArray? = null,
|
||||
@ProtoNumber(7) var fileId: UInt? = null,
|
||||
@ProtoNumber(8) var serverIp: UInt? = null,
|
||||
@ProtoNumber(9) var serverPort: UInt? = null,
|
||||
@ProtoNumber(10) var fileType: UInt? = null, // 66
|
||||
@ProtoNumber(11) var signature: ByteArray? = null,
|
||||
@ProtoNumber(12) var useful: UInt? = null,
|
||||
@ProtoNumber(13) var md5: ByteArray? = null,
|
||||
@ProtoNumber(14) var thumbUrl: String? = null,
|
||||
@ProtoNumber(15) var bigUrl: String? = null,
|
||||
@ProtoNumber(16) var origUrl: String? = null,
|
||||
@ProtoNumber(17) var bizType: UInt? = null,
|
||||
@ProtoNumber(18) var repeatIndex: UInt? = null,
|
||||
@ProtoNumber(19) var repeatImage: UInt? = null,
|
||||
@ProtoNumber(20) var imageType: UInt? = null,
|
||||
@ProtoNumber(21) var index: UInt? = null,
|
||||
@ProtoNumber(22) var width: UInt? = null,
|
||||
@ProtoNumber(23) var height: UInt? = null,
|
||||
@ProtoNumber(24) var source: UInt? = null,
|
||||
@ProtoNumber(25) var size: UInt? = null,
|
||||
@ProtoNumber(26) var origin: UInt? = null,
|
||||
@ProtoNumber(27) var thumbWidth: UInt? = null,
|
||||
@ProtoNumber(28) var thumbHeight: UInt? = null,
|
||||
@ProtoNumber(29) var showLen: UInt? = null,
|
||||
@ProtoNumber(30) var downloadLen: UInt? = null,
|
||||
@ProtoNumber(31) var url400: String? = null,
|
||||
@ProtoNumber(32) var width400: UInt? = null,
|
||||
@ProtoNumber(33) var height400: UInt? = null,
|
||||
@ProtoNumber(34) var pbReserve: PbReserve? = null,
|
||||
){
|
||||
companion object{
|
||||
@Serializable
|
||||
data class PbReserve(
|
||||
@ProtoNumber(1) var field1: Int? = null
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class ElemFlags2(
|
||||
@ProtoNumber(1) var color_text_id: UInt? = null,
|
||||
@ProtoNumber(2) var msg_id: ULong? = null,
|
||||
@ProtoNumber(3) var whisper_session_id: UInt? = null,
|
||||
@ProtoNumber(4) var ptt_change_bit: UInt? = null,
|
||||
@ProtoNumber(5) var vip_status: UInt? = null,
|
||||
@ProtoNumber(6) var compatible_id: UInt? = null,
|
||||
@ProtoNumber(7) var rpt_insts: List<Inst>? = null,
|
||||
@ProtoNumber(8) var msg_rpt_cnt: UInt? = null,
|
||||
@ProtoNumber(9) var src_inst: Inst? = null,
|
||||
@ProtoNumber(10) var longtitude: UInt? = null,
|
||||
@ProtoNumber(11) var latitude: UInt? = null,
|
||||
@ProtoNumber(12) var custom_font: UInt? = null,
|
||||
@ProtoNumber(13) var pc_support_def: PcSupportDef? = null,
|
||||
@ProtoNumber(14) var crm_flags: UInt? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Inst(
|
||||
@ProtoNumber(1) var app_id: UInt? = null,
|
||||
@ProtoNumber(2) var inst_id: UInt? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PcSupportDef(
|
||||
@ProtoNumber(1) var pc_ptl_begin: UInt? = null,
|
||||
@ProtoNumber(2) var pc_ptl_end: UInt? = null,
|
||||
@ProtoNumber(3) var mac_ptl_begin: UInt? = null,
|
||||
@ProtoNumber(4) var mac_ptl_end: UInt? = null,
|
||||
@ProtoNumber(5) var rpt_ptls_support: List<Int>? = null,
|
||||
@ProtoNumber(6) var rpt_ptls_not_support: List<Int>? = null,
|
||||
)
|
@ -4,6 +4,9 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class FaceElement(
|
||||
data class FaceMsg(
|
||||
@ProtoNumber(1) val id: Int? = null,
|
||||
@ProtoNumber(2) var old: ByteArray? = null,
|
||||
@ProtoNumber(11) var buf: ByteArray? = null,
|
||||
|
||||
)
|
@ -0,0 +1,28 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
|
||||
@Serializable
|
||||
data class GeneralFlags(
|
||||
@ProtoNumber(1) val bubbleDiyTextId: UInt? = null,
|
||||
@ProtoNumber(2) val groupFlagNew: UInt? = null,
|
||||
@ProtoNumber(3) val uin: ULong? = null,
|
||||
@ProtoNumber(4) val rpId: ByteArray? = null,
|
||||
@ProtoNumber(5) val prpFold: UInt? = null,
|
||||
@ProtoNumber(6) val longTextFlag: UInt? = null,
|
||||
@ProtoNumber(7) val longTextResid: ByteArray? = null,
|
||||
@ProtoNumber(8) val groupType: UInt? = null,
|
||||
@ProtoNumber(9) val toUinFlag: UInt? = null,
|
||||
@ProtoNumber(10) val glamourLevel: UInt? = null,
|
||||
@ProtoNumber(11) val memberLevel: UInt? = null,
|
||||
@ProtoNumber(12) val groupRankSeq: ULong? = null,
|
||||
@ProtoNumber(13) val olympicTorch: UInt? = null,
|
||||
@ProtoNumber(14) val babyqGuideMsgCookie: ByteArray? = null,
|
||||
@ProtoNumber(15) val expertFlag: UInt? = null,
|
||||
@ProtoNumber(16) val bubbleSubId: UInt? = null,
|
||||
@ProtoNumber(17) val pendantId: ULong? = null,
|
||||
@ProtoNumber(18) val rpIndex: ByteArray? = null,
|
||||
@ProtoNumber(19) val reserve: ByteArray? = null,
|
||||
)
|
@ -4,6 +4,6 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class JsonElement(
|
||||
data class LightAppElem(
|
||||
@ProtoNumber(1) val data: ByteArray? = null,
|
||||
)
|
@ -0,0 +1,21 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MarketFace(
|
||||
@ProtoNumber(1) var faceName: String? = null,
|
||||
@ProtoNumber(2) var itemType: Int? = null,
|
||||
@ProtoNumber(3) var faceInfo: Int? = null,
|
||||
@ProtoNumber(4) var faceId: String? = null,
|
||||
@ProtoNumber(5) var tabId: Int? = null,
|
||||
@ProtoNumber(6) var subType: Int? = null,
|
||||
@ProtoNumber(7) var key: ByteArray? = null,
|
||||
@ProtoNumber(8) var param: ByteArray? = null,
|
||||
@ProtoNumber(9) var mediaType: Int? = null,
|
||||
@ProtoNumber(10) var imageWidth: Int? = null,
|
||||
@ProtoNumber(11) var imageHeight: Int? = null,
|
||||
@ProtoNumber(12) var mobileparam: ByteArray? = null,
|
||||
@ProtoNumber(13) var pbReserve: ByteArray? = null,
|
||||
)
|
@ -0,0 +1,46 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class NotOnlineImage(
|
||||
@ProtoNumber(1) val filePath: ByteArray? = null,
|
||||
@ProtoNumber(2) val fileLen: UInt? = null,
|
||||
@ProtoNumber(3) val downloadPath: ByteArray? = null,
|
||||
@ProtoNumber(4) val oldVerSendFile: ByteArray? = null,
|
||||
@ProtoNumber(5) val imgType: UInt? = null,
|
||||
@ProtoNumber(6) val previewsImage: ByteArray? = null,
|
||||
@ProtoNumber(7) val picMd5: ByteArray? = null,
|
||||
@ProtoNumber(8) val picHeight: UInt? = null,
|
||||
@ProtoNumber(9) val picWidth: UInt? = null,
|
||||
@ProtoNumber(10) val resId: ByteArray? = null,
|
||||
@ProtoNumber(11) val flag: ByteArray? = null,
|
||||
@ProtoNumber(12) val thumbUrl: String? = null,
|
||||
@ProtoNumber(13) val original: UInt? = null,
|
||||
@ProtoNumber(14) val bigUrl: String? = null,
|
||||
@ProtoNumber(15) val origUrl: String? = null,
|
||||
@ProtoNumber(16) val bizType: UInt? = null,
|
||||
@ProtoNumber(17) val result: UInt? = null,
|
||||
@ProtoNumber(18) val index: UInt? = null,
|
||||
@ProtoNumber(19) val opFaceBuf: ByteArray? = null,
|
||||
@ProtoNumber(20) val oldPicMd5: Boolean = false,
|
||||
@ProtoNumber(21) val thumbWidth: UInt? = null,
|
||||
@ProtoNumber(22) val thumbHeight: UInt? = null,
|
||||
@ProtoNumber(23) val fileId: UInt? = null,
|
||||
@ProtoNumber(24) val showLen: UInt? = null,
|
||||
@ProtoNumber(25) val downloadLen: UInt? = null,
|
||||
@ProtoNumber(26) val url400: String? = null,
|
||||
@ProtoNumber(27) val width400: UInt? = null,
|
||||
@ProtoNumber(28) val height400: UInt? = null,
|
||||
@ProtoNumber(29) val pbReserve: PbReserve? = null,
|
||||
) {
|
||||
companion object {
|
||||
@Serializable
|
||||
data class PbReserve(
|
||||
@ProtoNumber(1) var field1: Int? = null,
|
||||
@ProtoNumber(8) var field8: String? = null,
|
||||
@ProtoNumber(30) var url: String? = null
|
||||
)
|
||||
}
|
||||
}
|
30
protobuf/src/main/java/protobuf/message/element/SourceMsg.kt
Normal file
30
protobuf/src/main/java/protobuf/message/element/SourceMsg.kt
Normal file
@ -0,0 +1,30 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import protobuf.message.Elem
|
||||
|
||||
@Serializable
|
||||
data class SourceMsg(
|
||||
@ProtoNumber(1) var origSeqs: List<Int>? = null,
|
||||
@ProtoNumber(2) var senderUin: ULong? = null,
|
||||
@ProtoNumber(3) var time: ULong? = null,
|
||||
@ProtoNumber(4) var flag: UInt? = null,
|
||||
@ProtoNumber(5) var elems: List<Elem>? = null,
|
||||
@ProtoNumber(6) var type: UInt? = null,
|
||||
@ProtoNumber(7) var richMsg: ByteArray? = null,
|
||||
@ProtoNumber(8) var pbReserve: PbReserve? = null,
|
||||
@ProtoNumber(9) var srcMsg: ByteArray? = null,
|
||||
@ProtoNumber(10) var toUin: ULong? = null,
|
||||
@ProtoNumber(11) var troopName: String? = null,
|
||||
) {
|
||||
companion object {
|
||||
@Serializable
|
||||
data class PbReserve(
|
||||
@ProtoNumber(3) var field3: ULong? = null,
|
||||
@ProtoNumber(6) var senderUid: String? = null,
|
||||
@ProtoNumber(7) var receiverUid: String? = null,
|
||||
@ProtoNumber(8) var field8: Int? = null,
|
||||
)
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class TextElement(
|
||||
@ProtoNumber(1) val text: String? = null,
|
||||
@ProtoNumber(2) val link: String? = null,
|
||||
@ProtoNumber(3) val attr6Buf: ByteArray? = null,
|
||||
@ProtoNumber(4) val attr7Buf: ByteArray? = null,
|
||||
@ProtoNumber(11) val buf: ByteArray? = null,
|
||||
@ProtoNumber(12) val pbReserve: TextResvAttr? = null,
|
||||
) {
|
||||
companion object {
|
||||
@Serializable
|
||||
data class TextResvAttr(
|
||||
@ProtoNumber(1) val wording: ByteArray? = null,
|
||||
@ProtoNumber(2) val textAnalysisResult: Int? = null,
|
||||
@ProtoNumber(3) val atType: Int? = null,
|
||||
@ProtoNumber(4) val atMemberUin: Long? = null,
|
||||
@ProtoNumber(5) val atMemberTinyid: Long? = null,
|
||||
@ProtoNumber(6) val atChannelInfo: ExtChannelInfo? = null,
|
||||
@ProtoNumber(7) val atRoleInfo: ExtRoleInfo? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ExtChannelInfo(
|
||||
@ProtoNumber(1) val guildId: Long? = null,
|
||||
@ProtoNumber(2) val channelId: Long? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ExtRoleInfo(
|
||||
@ProtoNumber(1) val id: Long? = null,
|
||||
@ProtoNumber(2) val info: ByteArray? = null,
|
||||
@ProtoNumber(3) val flag: Int? = null,
|
||||
)
|
||||
}
|
||||
}
|
14
protobuf/src/main/java/protobuf/message/element/TextMsg.kt
Normal file
14
protobuf/src/main/java/protobuf/message/element/TextMsg.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package protobuf.message.element
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class TextMsg(
|
||||
@ProtoNumber(1) val str: String? = null,
|
||||
@ProtoNumber(2) val link: String? = null,
|
||||
@ProtoNumber(3) val attr6Buf: ByteArray? = null,
|
||||
@ProtoNumber(4) val attr7Buf: ByteArray? = null,
|
||||
@ProtoNumber(11) val buf: ByteArray? = null,
|
||||
@ProtoNumber(12) val pbReserve: ByteArray? = null,
|
||||
)
|
@ -0,0 +1,53 @@
|
||||
package protobuf.message.element.commelem
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
|
||||
@Serializable
|
||||
data class ButtonExtra(
|
||||
@ProtoNumber(1) val field1: Object1? = null,
|
||||
) : Protobuf<ButtonExtra>
|
||||
|
||||
@Serializable
|
||||
data class Object1(
|
||||
@ProtoNumber(1) val rows: List<Row>? = null,
|
||||
@ProtoNumber(2) val appid: Int? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Row(
|
||||
@ProtoNumber(1) val buttons: List<Button>? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Button(
|
||||
@ProtoNumber(1) val id: Int? = null,
|
||||
@ProtoNumber(2) val renderData: RenderData? = null,
|
||||
@ProtoNumber(3) val action: Action? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RenderData(
|
||||
@ProtoNumber(1) val label: String? = null,
|
||||
@ProtoNumber(2) val visitedLabel: String? = null,
|
||||
@ProtoNumber(3) val style: Int? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Action(
|
||||
@ProtoNumber(1) val type: Int? = null,
|
||||
@ProtoNumber(2) val permission: Permission? = null,
|
||||
@ProtoNumber(4) val unsupportTips: String? = null,
|
||||
@ProtoNumber(5) val data: String? = null,
|
||||
@ProtoNumber(6) val reply: Boolean? = null,
|
||||
@ProtoNumber(7) val enter: Boolean? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Permission(
|
||||
@ProtoNumber(1) val type: Int? = null,
|
||||
@ProtoNumber(2) val specifyRoleIds: List<String>? = null,
|
||||
@ProtoNumber(3) val specifyUserIds: List<String>? = null,
|
||||
)
|
@ -0,0 +1,10 @@
|
||||
package protobuf.message.element.commelem
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
@Serializable
|
||||
data class MarkdownExtra(
|
||||
@ProtoNumber(1) val content: String? = null,
|
||||
) : Protobuf<MarkdownExtra>
|
@ -0,0 +1,12 @@
|
||||
package protobuf.message.element.commelem
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
@Serializable
|
||||
data class PokeExtra(
|
||||
@ProtoNumber(1) val type: Int? = null,
|
||||
@ProtoNumber(7) val field7: Int? = null,
|
||||
@ProtoNumber(8) val field8: Int? = null
|
||||
) : Protobuf<PokeExtra>
|
@ -0,0 +1,17 @@
|
||||
package protobuf.message.element.commelem
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
@Serializable
|
||||
data class QFaceExtra(
|
||||
@ProtoNumber(1) val packId: String? = null,
|
||||
@ProtoNumber(2) val stickerId: String? = null,
|
||||
@ProtoNumber(3) val faceId: Int? = null,
|
||||
@ProtoNumber(4) val field4: Int? = null,
|
||||
@ProtoNumber(5) val field5: Int? = null,
|
||||
@ProtoNumber(6) val field6: String? = null,
|
||||
@ProtoNumber(7) val faceText: String? = null,
|
||||
@ProtoNumber(9) val field9: Int? = null
|
||||
) : Protobuf<QFaceExtra>
|
@ -6,16 +6,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
import protobuf.message.MessageBody
|
||||
import protobuf.message.MessageContent
|
||||
import protobuf.message.MessageHead
|
||||
|
||||
@Serializable
|
||||
data class PushMsgBody(
|
||||
@ProtoNumber(1) val head: MessageHead? = null,
|
||||
@ProtoNumber(2) val content: MessageContent? = null,
|
||||
@ProtoNumber(3) val body: MessageBody? = null
|
||||
)
|
||||
import protobuf.message.PushMsgBody
|
||||
|
||||
@Serializable
|
||||
data class LongMsgContent(
|
||||
|
14
protobuf/src/main/java/protobuf/message/routing/C2C.kt
Normal file
14
protobuf/src/main/java/protobuf/message/routing/C2C.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package protobuf.message.routing
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class C2C(
|
||||
@ProtoNumber(1) val uin: UInt? = null,
|
||||
@ProtoNumber(2) val uid: String? = null,
|
||||
@ProtoNumber(3) val field3: UInt? = null,
|
||||
@ProtoNumber(4) val sig: UInt? = null,
|
||||
@ProtoNumber(5) val receiverUin: UInt? = null,
|
||||
@ProtoNumber(6) val receiverUid: String? = null
|
||||
)
|
9
protobuf/src/main/java/protobuf/message/routing/Grp.kt
Normal file
9
protobuf/src/main/java/protobuf/message/routing/Grp.kt
Normal file
@ -0,0 +1,9 @@
|
||||
package protobuf.message.routing
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class Grp (
|
||||
@ProtoNumber(1) var groupCode: UInt? = null,
|
||||
)
|
10
protobuf/src/main/java/protobuf/message/routing/GrpTmp.kt
Normal file
10
protobuf/src/main/java/protobuf/message/routing/GrpTmp.kt
Normal file
@ -0,0 +1,10 @@
|
||||
package protobuf.message.routing
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class GrpTmp (
|
||||
@ProtoNumber(1) var groupCode: UInt? = null,
|
||||
@ProtoNumber(2) var ToUin: UInt? = null,
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
package protobuf.message.routing
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class Trans0X211(
|
||||
@ProtoNumber(1) val toUin: ULong? = null,
|
||||
@ProtoNumber(2) val ccCmd: UInt? = null,
|
||||
@ProtoNumber(8) val uid: String? = null
|
||||
)
|
10
protobuf/src/main/java/protobuf/message/routing/WPATmp.kt
Normal file
10
protobuf/src/main/java/protobuf/message/routing/WPATmp.kt
Normal file
@ -0,0 +1,10 @@
|
||||
package protobuf.message.routing
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class WPATmp (
|
||||
@ProtoNumber(1) val toUin: Int? = null,
|
||||
@ProtoNumber(2) val sig: ByteArray? = null,
|
||||
)
|
@ -1,104 +0,0 @@
|
||||
package protobuf.msg
|
||||
|
||||
import com.google.protobuf.Internal.EMPTY_BYTE_ARRAY
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class MsgBody(
|
||||
@ProtoNumber(1) var richText: RichText,
|
||||
//@ProtoNumber(2) var msgContent: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
//@/ProtoNumber(3) var msgEncryptContent: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RichText(
|
||||
//@ProtoNumber(1) var attr: Attr? = null,
|
||||
@ProtoNumber(2) var elems: ArrayList<Elem>? = null,
|
||||
//@ProtoNumber(3) var not_online_file: NotOnlineFile? = null,
|
||||
//@ProtoNumber(4) var ptt: Ptt? = null,
|
||||
//@ProtoNumber(5) var tmp_ptt: TmpPtt? = null,
|
||||
//@ProtoNumber(6) var trans_211_tmp_msg: Trans211TmpMsg? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Elem(
|
||||
/*@ProtoNumber(1) var text: TextMsg? = null,
|
||||
@ProtoNumber(2) var face: FaceMsg? = null,
|
||||
@ProtoNumber(3) var online_image: OnlineImage? = null,
|
||||
@ProtoNumber(4) var not_online_image: NotOnlineImage? = null,
|
||||
@ProtoNumber(5) var trans_elem_info: TransElem? = null,
|
||||
@ProtoNumber(6) var market_face: MarketFace? = null,
|
||||
@ProtoNumber(7) var elem_flags: ElemFlags? = null,
|
||||
@ProtoNumber(8) var customFace: CustomFace? = null,
|
||||
@ProtoNumber(9) var elem_flags2: ElemFlags2? = null,
|
||||
@ProtoNumber(10) var fun_face: FunFace? = null,
|
||||
@ProtoNumber(11) var secret_file: SecretFileMsg? = null,
|
||||
@ProtoNumber(12) var rich_msg: RichMsg? = null,
|
||||
@ProtoNumber(13) var group_file: GroupFile? = null,
|
||||
@ProtoNumber(14) var pub_group: PubGroup? = null,
|
||||
@ProtoNumber(15) var market_trans: MarketTrans? = null,
|
||||
@ProtoNumber(16) var extra_info: ExtraInfo? = null,
|
||||
@ProtoNumber(17) var shake_window: ShakeWindow? = null,
|
||||
@ProtoNumber(18) var pub_account: PubAccount? = null,
|
||||
@ProtoNumber(19) var video_file: VideoFile? = null,
|
||||
@ProtoNumber(20) var tips_info: TipsInfo? = null,
|
||||
@ProtoNumber(21) var anon_group_msg: AnonymousGroupMsg? = null,
|
||||
@ProtoNumber(22) var qq_live_old: QQLiveOld? = null,
|
||||
@ProtoNumber(23) var life_online: LifeOnlineAccount? = null,
|
||||
@ProtoNumber(24) var qqwallet_msg: QQWalletMsg? = null,
|
||||
@ProtoNumber(25) var crm_elem: CrmElem? = null,
|
||||
@ProtoNumber(26) var conference_tips_info: ConferenceTipsInfo? = null,
|
||||
@ProtoNumber(27) var redbag_info: RedBagInfo? = null,
|
||||
@ProtoNumber(28) var low_version_tips: LowVersionTips? = null,
|
||||
@ProtoNumber(29) var bankcode_ctrl_info: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(30) var near_by_msg: NearByMessageType? = null,
|
||||
@ProtoNumber(31) var custom_elem: CustomElem? = null,
|
||||
@ProtoNumber(32) var location_info: LocationInfo? = null,
|
||||
@ProtoNumber(33) var pub_acc_info: PubAccInfo? = null,
|
||||
@ProtoNumber(34) var small_emoji: SmallEmoji? = null,
|
||||
@ProtoNumber(35) var fsj_msg_elem: FSJMessageElem? = null,
|
||||
@ProtoNumber(36) var ark_app: ArkAppElem? = null,
|
||||
*/
|
||||
@ProtoNumber(37) var generalFlags: GeneralFlags? = null,
|
||||
/*
|
||||
@ProtoNumber(38) var hc_flash_pic: CustomFace? = null,
|
||||
@ProtoNumber(39) var deliver_gift_msg: DeliverGiftMsg? = null,
|
||||
@ProtoNumber(40) var bitapp_msg: BitAppMsg? = null,
|
||||
@ProtoNumber(41) var open_qq_data: OpenQQData? = null,
|
||||
@ProtoNumber(42) var apollo_msg: ApolloActMsg? = null,
|
||||
@ProtoNumber(43) var group_pub_acc_info: GroupPubAccountInfo? = null,
|
||||
@ProtoNumber(44) var bless_msg: BlessingMessage? = null,
|
||||
@ProtoNumber(45) var src_msg: SourceMsg? = null,
|
||||
@ProtoNumber(46) var lola_msg: LolaMsg? = null,
|
||||
@ProtoNumber(47) var group_business_msg: GroupBusinessMsg? = null,
|
||||
@ProtoNumber(48) var msg_workflow_notify: WorkflowNotifyMsg? = null,
|
||||
@ProtoNumber(49) var pat_elem: PatsElem? = null,
|
||||
@ProtoNumber(50) var group_post_elem: GroupPostElem? = null,
|
||||
@ProtoNumber(51) var light_app: LightAppElem? = null,
|
||||
@ProtoNumber(52) var eim_info: EIMInfo? = null,
|
||||
@ProtoNumber(53) var commonElem: CommonElem? = null,*/
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GeneralFlags(
|
||||
@ProtoNumber(1) var uint32_bubble_diy_text_id: UInt = 0u,
|
||||
@ProtoNumber(2) var uint32_group_flag_new: UInt = 0u,
|
||||
@ProtoNumber(3) var uint64_uin: ULong = 0u,
|
||||
@ProtoNumber(4) var bytes_rp_id: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(5) var uint32_prp_fold: UInt = 0u,
|
||||
@ProtoNumber(6) var long_text_flag: UInt = 0u,
|
||||
@ProtoNumber(7) var long_text_resid: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(8) var uint32_group_type: UInt = 0u,
|
||||
@ProtoNumber(9) var uint32_to_uin_flag: UInt = 0u,
|
||||
@ProtoNumber(10) var uint32_glamour_level: UInt = 0u,
|
||||
@ProtoNumber(11) var uint32_member_level: UInt = 0u,
|
||||
@ProtoNumber(12) var uint64_group_rank_seq: ULong = 0u,
|
||||
@ProtoNumber(13) var uint32_olympic_torch: UInt = 0u,
|
||||
@ProtoNumber(14) var babyq_guide_msg_cookie: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(15) var uin32_expert_flag: UInt = 0u,
|
||||
@ProtoNumber(16) var uint32_bubble_sub_id: UInt = 0u,
|
||||
@ProtoNumber(17) var pendantId: ULong = 0u,
|
||||
@ProtoNumber(18) var bytes_rp_index: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(19) var reserve: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
)
|
@ -1,67 +0,0 @@
|
||||
package protobuf.msg
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
||||
@Serializable
|
||||
class PbSendMsgReq(
|
||||
@ProtoNumber(1) var routingHead: RoutingHead,
|
||||
@ProtoNumber(2) var contentHead: ContentHead,
|
||||
@ProtoNumber(3) var msgBody: MsgBody,
|
||||
@ProtoNumber(4) var msgSeq: ULong = 0u,
|
||||
@ProtoNumber(5) var msgRand: UInt = 0u,
|
||||
//@ProtoNumber(6) var sync_cookie: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
//@ProtoNumber(7) var app_share: AppShareInfo? = null,
|
||||
@ProtoNumber(8) var msgVia: UInt = 0u,
|
||||
//@ProtoNumber(9) var data_statist: UInt = 0u,
|
||||
//@ProtoNumber(10) var multi_msg_assist: MultiMsgAssist? = null,
|
||||
//@ProtoNumber(11) var input_notify_info: PbInputNotifyInfo? = null,
|
||||
//@ProtoNumber(12) var msgCtrl: MsgCtrl? = null,
|
||||
//@ProtoNumber(13) var receipt_req: ReceiptReq? = null,
|
||||
//@ProtoNumber(14) var multi_send_seq: UInt = 0u,
|
||||
): Protobuf<PbSendMsgReq>
|
||||
|
||||
@Serializable
|
||||
data class ContentHead(
|
||||
@ProtoNumber(1) var pkg_num: UInt = 0u,
|
||||
@ProtoNumber(2) var pkg_index: UInt = 0u,
|
||||
@ProtoNumber(3) var div_seq: UInt = 0u,
|
||||
@ProtoNumber(4) var auto_reply: UInt = 0u,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class RoutingHead(
|
||||
@ProtoNumber(1) var c2c: C2C? = null,
|
||||
@ProtoNumber(2) var grp: Grp? = null,
|
||||
// @ProtoNumber(3) var grp_tmp: GrpTmp? = null,
|
||||
//@ProtoNumber(4) var dis: Dis? = null,
|
||||
// @ProtoNumber(5) var dis_tmp: DisTmp? = null,
|
||||
// @ProtoNumber(6) var wpa_tmp: WPATmp? = null,
|
||||
// @ProtoNumber(7) var secret_file: SecretFileHead? = null,
|
||||
// @ProtoNumber(8) var public_plat: PublicPlat? = null,
|
||||
/*@ProtoNumber(9) var trans_msg: TransMsg? = null,
|
||||
@ProtoNumber(10) var address_list: AddressListTmp? = null,
|
||||
@ProtoNumber(11) var rich_status_tmp: RichStatusTmp? = null,
|
||||
@ProtoNumber(12) var trans_cmd: TransCmd? = null,
|
||||
@ProtoNumber(13) var accost_tmp: AccostTmp? = null,
|
||||
@ProtoNumber(14) var pub_group_tmp: PubGroupTmp? = null,
|
||||
@ProtoNumber(15) var trans_0x211: Trans0x211? = null,
|
||||
@ProtoNumber(16) var business_wpa_tmp: BusinessWPATmp? = null,
|
||||
@ProtoNumber(17) var auth_tmp: AuthTmp? = null,
|
||||
@ProtoNumber(18) var bsns_tmp: BsnsTmp? = null,
|
||||
@ProtoNumber(19) var qq_querybusiness_tmp: QQQueryBusinessTmp? = null,
|
||||
@ProtoNumber(20) var nearby_dating_tmp: NearByDatingTmp? = null,
|
||||
@ProtoNumber(21) var nearby_assistant_tmp: NearByAssistantTmp? = null,
|
||||
@ProtoNumber(22) var comm_tmp: CommTmp? = null,*/
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class C2C(
|
||||
@ProtoNumber(1) var to_uin: ULong = 0u,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class Grp(
|
||||
@ProtoNumber(1) var groupCode: ULong = 0u,
|
||||
)
|
@ -3,11 +3,11 @@ package protobuf.push
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
import protobuf.message.NtMessage
|
||||
import protobuf.message.PushMsgBody
|
||||
|
||||
@Serializable
|
||||
data class MessagePush(
|
||||
@ProtoNumber(1) val msgBody: NtMessage? = null,
|
||||
@ProtoNumber(1) val msgBody: PushMsgBody? = null,
|
||||
@ProtoNumber(4) val clientInfo: MessagePushClientInfo? = null,
|
||||
): Protobuf<MessagePush>
|
||||
|
||||
|
@ -9,7 +9,6 @@ import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.tools.toHexString
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import moe.fuqiuluo.symbols.decode
|
||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||
import protobuf.oidb.cmd0x6d7.CreateFolderReq
|
||||
import protobuf.oidb.cmd0x6d7.DeleteFolderReq
|
||||
|
@ -22,7 +22,6 @@ import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||
import moe.fuqiuluo.symbols.decode
|
||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||
import protobuf.auto.toByteArray
|
||||
import protobuf.guild.GetGuildFeedsReq
|
||||
|
@ -1,5 +1,3 @@
|
||||
@file:OptIn(DelicateCoroutinesApi::class)
|
||||
|
||||
package moe.fuqiuluo.qqinterface.servlet
|
||||
|
||||
import com.tencent.mobileqq.qroute.QRoute
|
||||
@ -7,14 +5,13 @@ import com.tencent.mobileqq.troop.api.ITroopMemberNameService
|
||||
import com.tencent.qqnt.kernel.api.IKernelService
|
||||
import com.tencent.qqnt.kernel.nativeinterface.*
|
||||
import com.tencent.qqnt.msg.api.IMsgService
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.messageelement.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toListMap
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
@ -26,9 +23,9 @@ import moe.fuqiuluo.shamrock.tools.*
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.msgService
|
||||
import moe.fuqiuluo.symbols.decode
|
||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||
import protobuf.auto.toByteArray
|
||||
import protobuf.message.PushMsgBody
|
||||
import protobuf.message.longmsg.*
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
@ -295,27 +292,27 @@ internal object MsgSvc : BaseSvc() {
|
||||
if (it.command == "MultiMsg") {
|
||||
return Result.success(it.data?.body?.map { msg ->
|
||||
val chatType =
|
||||
if (msg.content!!.msgType == 82) MsgConstant.KCHATTYPEGROUP else MsgConstant.KCHATTYPEC2C
|
||||
if (msg.contentHead!!.msgType == 82) MsgConstant.KCHATTYPEGROUP else MsgConstant.KCHATTYPEC2C
|
||||
MessageDetail(
|
||||
time = msg.content?.msgTime?.toInt() ?: 0,
|
||||
time = msg.contentHead?.msgTime?.toInt() ?: 0,
|
||||
msgType = MessageHelper.obtainDetailTypeByMsgType(chatType),
|
||||
msgId = 0, // MessageHelper.generateMsgIdHash(chatType, msg.content!!.msgViaRandom), msgViaRandom 为空
|
||||
realId = msg.content!!.msgSeq?.toInt() ?: 0,
|
||||
realId = msg.contentHead!!.msgSeq?.toInt() ?: 0,
|
||||
sender = MessageSender(
|
||||
msg.head?.peer ?: 0,
|
||||
msg.head?.groupInfo?.memberCard?.ifEmpty { msg.head?.forward?.friendName }
|
||||
?: msg.head?.forward?.friendName ?: "",
|
||||
msg.msgHead?.peer ?: 0,
|
||||
msg.msgHead?.responseGrp?.memberCard?.ifEmpty { msg.msgHead?.forward?.friendName }
|
||||
?: msg.msgHead?.forward?.friendName ?: "",
|
||||
"unknown",
|
||||
0,
|
||||
msg.head?.peerUid ?: "",
|
||||
msg.head?.peerUid ?: ""
|
||||
msg.msgHead?.peerUid ?: "",
|
||||
msg.msgHead?.peerUid ?: ""
|
||||
),
|
||||
message = msg.body?.rich?.elements?.toSegments(chatType, msg.head?.peer.toString(), "0")
|
||||
message = msg.body?.richText?.elements?.toSegments(chatType, msg.msgHead?.peer.toString(), "0")
|
||||
?.toListMap() ?: emptyList(),
|
||||
peerId = msg.head?.peer ?: 0,
|
||||
groupId = if (chatType == MsgConstant.KCHATTYPEGROUP) msg.head?.groupInfo?.groupCode?.toLong()
|
||||
peerId = msg.msgHead?.peer ?: 0,
|
||||
groupId = if (chatType == MsgConstant.KCHATTYPEGROUP) msg.msgHead?.responseGrp?.groupCode?.toLong()
|
||||
?: 0 else 0,
|
||||
targetId = if (chatType != MsgConstant.KCHATTYPEGROUP) msg.head?.peer ?: 0 else 0
|
||||
targetId = if (chatType != MsgConstant.KCHATTYPEGROUP) msg.msgHead?.peer ?: 0 else 0
|
||||
)
|
||||
}
|
||||
?: return Result.failure(Exception("Msg is empty")))
|
||||
|
@ -9,19 +9,18 @@ import io.ktor.utils.io.core.writeFully
|
||||
import io.ktor.utils.io.core.writeInt
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlinx.serialization.encodeToByteArray
|
||||
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
|
||||
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
|
||||
import moe.fuqiuluo.shamrock.tools.broadcast
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import protobuf.message.element.JsonElement
|
||||
import protobuf.message.NtMessage
|
||||
import protobuf.message.MessageContent
|
||||
import protobuf.message.MessageElement
|
||||
import protobuf.message.RichMessage
|
||||
import protobuf.message.MessageHead
|
||||
import protobuf.message.MessageBody
|
||||
import protobuf.message.element.LightAppElem
|
||||
import protobuf.message.PushMsgBody
|
||||
import protobuf.message.ContentHead
|
||||
import protobuf.message.Elem
|
||||
import protobuf.message.RichText
|
||||
import protobuf.message.ResponseHead
|
||||
import protobuf.message.MsgBody
|
||||
import protobuf.push.MessagePush
|
||||
import mqq.app.MobileQQ
|
||||
import protobuf.auto.toByteArray
|
||||
@ -34,14 +33,14 @@ internal object PacketSvc: BaseSvc() {
|
||||
suspend fun fakeSelfRecvJsonMsg(msgService: IKernelMsgService, content: String): Long {
|
||||
return fakeReceiveSelfMsg(msgService) {
|
||||
listOf(
|
||||
MessageElement(
|
||||
json = JsonElement((byteArrayOf(1) + DeflateTools.compress(content.toByteArray())))
|
||||
Elem(
|
||||
lightApp = LightAppElem((byteArrayOf(1) + DeflateTools.compress(content.toByteArray())))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fakeReceiveSelfMsg(msgService: IKernelMsgService, builder: () -> List<MessageElement>): Long {
|
||||
private suspend fun fakeReceiveSelfMsg(msgService: IKernelMsgService, builder: () -> List<Elem>): Long {
|
||||
val latestMsg = withTimeoutOrNull(3000) {
|
||||
suspendCancellableCoroutine {
|
||||
msgService.getMsgs(Contact(MsgConstant.KCHATTYPEC2C, app.currentUid, ""), 0L, 1, true) { code, why, msgs ->
|
||||
@ -52,27 +51,27 @@ internal object PacketSvc: BaseSvc() {
|
||||
val msgSeq = (latestMsg?.msgSeq ?: 0) + 1
|
||||
|
||||
val msgPush = MessagePush(
|
||||
msgBody = NtMessage(
|
||||
msgHead = MessageHead(
|
||||
msgBody = PushMsgBody(
|
||||
msgHead = ResponseHead(
|
||||
peer = app.longAccountUin,
|
||||
peerUid = app.currentUid,
|
||||
flag = 1001,
|
||||
receiver = app.longAccountUin,
|
||||
receiverUid = app.currentUid
|
||||
),
|
||||
contentHead = MessageContent(
|
||||
contentHead = ContentHead(
|
||||
msgType = 166,
|
||||
msgSubType = 11,
|
||||
msgSeq = msgSeq,
|
||||
msgViaRandom = msgSeq,
|
||||
msgTime = System.currentTimeMillis() / 1000,
|
||||
u2 = 1,
|
||||
msgSeq_ = msgSeq,
|
||||
sequence = msgSeq,
|
||||
msgRandom = msgService.getMsgUniqueId(System.currentTimeMillis()),
|
||||
u4 = msgSeq - 2,
|
||||
u5 = msgSeq
|
||||
),
|
||||
body = MessageBody(RichMessage(
|
||||
body = MsgBody(RichText(
|
||||
elements = builder()
|
||||
))
|
||||
)
|
||||
|
@ -0,0 +1,79 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.converter.MessageElementConverter
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.converter.MsgElementConverter
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import protobuf.message.Elem
|
||||
|
||||
@JvmName("elemListToSegments")
|
||||
internal suspend fun List<Elem>.toSegments(
|
||||
chatType: Int,
|
||||
peerId: String,
|
||||
subPeer: String
|
||||
): List<MessageSegment> {
|
||||
val messageData = arrayListOf<MessageSegment>()
|
||||
this.forEach { msg ->
|
||||
kotlin.runCatching {
|
||||
val elementType = if (msg.text != null) {
|
||||
1
|
||||
} else if (msg.face != null) {
|
||||
2
|
||||
} else if (msg.lightApp != null) {
|
||||
51
|
||||
} else if (msg.commonElem != null) {
|
||||
53
|
||||
} else
|
||||
throw UnsupportedOperationException("不支持的消息element类型:$msg")
|
||||
val converter = MessageElementConverter[elementType]
|
||||
converter?.invoke(chatType, peerId, subPeer, msg)
|
||||
?: throw UnsupportedOperationException("不支持的消息element类型:$elementType")
|
||||
}.onSuccess {
|
||||
messageData.add(it)
|
||||
}.onFailure {
|
||||
if (it is UnknownError) {
|
||||
// 不处理的消息类型,抛出unknown error
|
||||
} else {
|
||||
LogCenter.log("消息element转换错误:$it", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageData
|
||||
}
|
||||
|
||||
@JvmName("msgElementListToSegments")
|
||||
internal suspend fun List<MsgElement>.toSegments(chatType: Int, peerId: String, subPeer: String): List<MessageSegment> {
|
||||
val messageData = arrayListOf<MessageSegment>()
|
||||
this.forEach { msg ->
|
||||
kotlin.runCatching {
|
||||
val converter = MsgElementConverter[msg.elementType]
|
||||
converter?.invoke(chatType, peerId, subPeer, msg)
|
||||
?: throw UnsupportedOperationException("不支持的消息element类型:${msg.elementType}")
|
||||
}.onSuccess {
|
||||
messageData.add(it)
|
||||
}.onFailure {
|
||||
if (it is UnknownError) {
|
||||
// 不处理的消息类型,抛出unknown error
|
||||
} else {
|
||||
LogCenter.log("消息element转换错误:$it, elementType: ${msg.elementType}", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageData
|
||||
}
|
||||
|
||||
internal suspend fun List<MsgElement>.toCQCode(chatType: Int, peerId: String, subPeer: String): String {
|
||||
if (this.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
return MessageHelper.nativeEncodeCQCode(this.toSegments(chatType, peerId, subPeer).map {
|
||||
val params = hashMapOf<String, String>()
|
||||
params["_type"] = it.type
|
||||
it.data.forEach { (key, value) ->
|
||||
params[key] = value.toString()
|
||||
}
|
||||
params
|
||||
})
|
||||
}
|
@ -1,52 +1,16 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.messageelement
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.converter
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUInt
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.MessageSegment
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import moe.fuqiuluo.shamrock.tools.asJsonObject
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import protobuf.message.MessageElement
|
||||
import protobuf.message.Elem
|
||||
|
||||
|
||||
internal suspend fun List<MessageElement>.toSegments(
|
||||
chatType: Int,
|
||||
peerId: String,
|
||||
subPeer: String
|
||||
): List<MessageSegment> {
|
||||
val messageData = arrayListOf<MessageSegment>()
|
||||
this.forEach { msg ->
|
||||
kotlin.runCatching {
|
||||
val elementType = if (msg.text != null) {
|
||||
1
|
||||
} else if (msg.face != null) {
|
||||
2
|
||||
} else if (msg.json != null) {
|
||||
51
|
||||
} else if (msg.comm != null) {
|
||||
53
|
||||
} else
|
||||
throw UnsupportedOperationException("不支持的消息element类型:$msg")
|
||||
val converter = MessageElementConverter[elementType]
|
||||
converter?.invoke(chatType, peerId, subPeer, msg)
|
||||
?: throw UnsupportedOperationException("不支持的消息element类型:$elementType")
|
||||
}.onSuccess {
|
||||
messageData.add(it)
|
||||
}.onFailure {
|
||||
if (it is UnknownError) {
|
||||
// 不处理的消息类型,抛出unknown error
|
||||
} else {
|
||||
LogCenter.log("消息element转换错误:$it", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageData
|
||||
}
|
||||
|
||||
internal typealias IMessageElementConverter = suspend (Int, String, String, MessageElement) -> MessageSegment
|
||||
internal typealias IMessageElementConverter = suspend (Int, String, String, Elem) -> MessageSegment
|
||||
|
||||
internal object MessageElementConverter {
|
||||
private val convertMap = hashMapOf(
|
||||
@ -76,7 +40,7 @@ internal object MessageElementConverter {
|
||||
chatType: Int,
|
||||
peerId: String,
|
||||
subPeer: String,
|
||||
element: MessageElement
|
||||
element: Elem
|
||||
): MessageSegment {
|
||||
val text = element.text!!
|
||||
if (text.attr6Buf != null) {
|
||||
@ -89,23 +53,11 @@ internal object MessageElementConverter {
|
||||
"qq" to uin
|
||||
)
|
||||
)
|
||||
} else if (text.pbReserve != null) {
|
||||
val resv = text.pbReserve!!
|
||||
return MessageSegment(
|
||||
type = "at",
|
||||
data = hashMapOf(
|
||||
"qq" to when (resv.atType) {
|
||||
2 -> resv.atMemberTinyid!!
|
||||
4 -> resv.atChannelInfo!!.channelId!!
|
||||
else -> throw UnsupportedOperationException("Unknown at type: ${resv.atType}")
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
return MessageSegment(
|
||||
type = "text",
|
||||
data = hashMapOf(
|
||||
"text" to text.text!!
|
||||
"text" to text.str!!
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -340,9 +292,9 @@ internal object MessageElementConverter {
|
||||
chatType: Int,
|
||||
peerId: String,
|
||||
subPeer: String,
|
||||
element: MessageElement
|
||||
element: Elem
|
||||
): MessageSegment {
|
||||
val data = element.json!!.data!!
|
||||
val data = element.lightApp!!.data!!
|
||||
val jsonStr =
|
||||
(if (data[0].toInt() == 1) DeflateTools.uncompress(data.sliceArray(1 until data.size)) else data.sliceArray(1 until data.size)).toString()
|
||||
val json = jsonStr.asJsonObject
|
@ -1,8 +1,11 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.msgelement
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.converter
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.json.add
|
||||
import kotlinx.serialization.json.buildJsonObject
|
||||
import kotlinx.serialization.json.put
|
||||
import kotlinx.serialization.json.putJsonArray
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.MessageSegment
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||
@ -16,41 +19,6 @@ import moe.fuqiuluo.shamrock.tools.asJsonObject
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import moe.fuqiuluo.shamrock.tools.hex2ByteArray
|
||||
|
||||
|
||||
internal suspend fun List<MsgElement>.toSegments(chatType: Int, peerId: String, subPeer: String): List<MessageSegment> {
|
||||
val messageData = arrayListOf<MessageSegment>()
|
||||
this.forEach { msg ->
|
||||
kotlin.runCatching {
|
||||
val converter = MsgElementConverter[msg.elementType]
|
||||
converter?.invoke(chatType, peerId, subPeer, msg)
|
||||
?: throw UnsupportedOperationException("不支持的消息element类型:${msg.elementType}")
|
||||
}.onSuccess {
|
||||
messageData.add(it)
|
||||
}.onFailure {
|
||||
if (it is UnknownError) {
|
||||
// 不处理的消息类型,抛出unknown error
|
||||
} else {
|
||||
LogCenter.log("消息element转换错误:$it, elementType: ${msg.elementType}", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageData
|
||||
}
|
||||
|
||||
internal suspend fun List<MsgElement>.toCQCode(chatType: Int, peerId: String, subPeer: String): String {
|
||||
if (this.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
return MessageHelper.nativeEncodeCQCode(this.toSegments(chatType, peerId, subPeer).map {
|
||||
val params = hashMapOf<String, String>()
|
||||
params["_type"] = it.type
|
||||
it.data.forEach { (key, value) ->
|
||||
params[key] = value.toString()
|
||||
}
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
internal typealias IMsgElementConverter = suspend (Int, String, String, MsgElement) -> MessageSegment
|
||||
|
||||
internal object MsgElementConverter {
|
@ -0,0 +1,539 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.maker
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import com.tencent.qqnt.kernel.nativeinterface.*
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import moe.fuqiuluo.qqinterface.servlet.CardSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.*
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.PictureResource
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Private
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Troop
|
||||
import moe.fuqiuluo.shamrock.helper.*
|
||||
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.LogicException
|
||||
import moe.fuqiuluo.shamrock.helper.ParamsException
|
||||
import moe.fuqiuluo.shamrock.tools.*
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.msgService
|
||||
import protobuf.auto.toByteArray
|
||||
import protobuf.message.Elem
|
||||
import protobuf.message.element.*
|
||||
import protobuf.message.element.commelem.*
|
||||
import java.io.File
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextULong
|
||||
|
||||
internal typealias IMessageElementMaker = suspend (Int, Long, String, JsonObject) -> Result<Elem>
|
||||
|
||||
internal object MessageElementMaker {
|
||||
private val makerArray = hashMapOf(
|
||||
"text" to MessageElementMaker::createTextElem,
|
||||
"at" to MessageElementMaker::createAtElem,
|
||||
"face" to MessageElementMaker::createFaceElem,
|
||||
"pic" to MessageElementMaker::createImageElem,
|
||||
"image" to MessageElementMaker::createImageElem,
|
||||
// "voice" to MessageElementMaker::createRecordElem,
|
||||
// "record" to MessageElementMaker::createRecordElem,
|
||||
// "video" to MessageElementMaker::createVideoElem,
|
||||
"markdown" to MessageElementMaker::createMarkdownElem,
|
||||
"button" to MessageElementMaker::createButtonElem,
|
||||
"inline_keyboard" to MessageElementMaker::createButtonElem,
|
||||
// "dice" to MessageElementMaker::createDiceElem,
|
||||
// "rps" to MessageElementMaker::createRpsElem,
|
||||
"basketball" to MessageElementMaker::createBasketballElem,
|
||||
"new_dice" to MessageElementMaker::createNewDiceElem,
|
||||
"new_rps" to MessageElementMaker::createNewRpsElem,
|
||||
"poke" to MessageElementMaker::createPokeElem,
|
||||
// "anonymous" to MessageElementMaker::createAnonymousElem,
|
||||
// "share" to MessageElementMaker::createShareElem,
|
||||
// "contact" to MessageElementMaker::createContactElem,
|
||||
// "location" to MessageElementMaker::createLocationElem,
|
||||
// "music" to MessageElementMaker::createMusicElem,
|
||||
"reply" to MessageElementMaker::createReplyElem,
|
||||
// "touch" to MessageElementMaker::createTouchElem,
|
||||
// "weather" to MessageElementMaker::createWeatherElem,
|
||||
"json" to MessageElementMaker::createJsonElem,
|
||||
//"node" to MessageMaker::createNodeElem,
|
||||
//"multi_msg" to MessageMaker::createLongMsgStruct,
|
||||
//"bubble_face" to MessageElementMaker::createBubbleFaceElem,
|
||||
)
|
||||
|
||||
operator fun get(type: String): IMessageElementMaker? = makerArray[type]
|
||||
|
||||
private suspend fun createTextElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("text")
|
||||
val elem = Elem(
|
||||
text = TextMsg(data["text"].asString)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createAtElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
return when (chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> {
|
||||
data.checkAndThrow("qq")
|
||||
|
||||
val qq: Long
|
||||
val type: Int
|
||||
val display = when (val qqStr = data["qq"].asString) {
|
||||
"0", "all" -> {
|
||||
qq = 0
|
||||
type = 1
|
||||
"@全体成员"
|
||||
}
|
||||
|
||||
"online" -> {
|
||||
qq = 0
|
||||
type = 64
|
||||
"@在线成员"
|
||||
}
|
||||
|
||||
else -> {
|
||||
qq = qqStr.toLong()
|
||||
type = 0
|
||||
"@" + (data["name"].asStringOrNull ?: GroupSvc.getTroopMemberInfoByUinV2(peerId, qqStr, true)
|
||||
.let {
|
||||
val info = it.getOrNull()
|
||||
if (info == null)
|
||||
LogCenter.log("无法获取群成员信息: $qqStr", Level.ERROR)
|
||||
info?.troopnick
|
||||
.ifNullOrEmpty(info?.friendnick)
|
||||
.ifNullOrEmpty(qqStr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val attr6: ByteBuffer = ByteBuffer.allocate(6)
|
||||
attr6.put(byteArrayOf(0, 1, 0, 0, 0))
|
||||
attr6.putChar(display.length.toChar())
|
||||
attr6.putChar(type.toChar())
|
||||
attr6.putBuf32Long(qq)
|
||||
attr6.put(byteArrayOf(0, 0))
|
||||
val elem = Elem(
|
||||
text = TextMsg(str = display, attr6Buf = attr6.array())
|
||||
)
|
||||
Result.success(elem)
|
||||
}
|
||||
|
||||
MsgConstant.KCHATTYPEC2C -> {
|
||||
data.checkAndThrow("qq")
|
||||
|
||||
val qq = data["qq"].asString
|
||||
val display =
|
||||
"@" + (data["name"].asStringOrNull ?: CardSvc.getProfileCard(qq)
|
||||
.onSuccess {
|
||||
it.strNick.ifNullOrEmpty(qq)
|
||||
}.onFailure {
|
||||
LogCenter.log("无法获取QQ信息: $qq", Level.WARN)
|
||||
})
|
||||
|
||||
val elem = Elem(
|
||||
text = TextMsg(str = display)
|
||||
)
|
||||
Result.success(elem)
|
||||
}
|
||||
|
||||
else -> Result.failure(ActionMsgException)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createFaceElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("id")
|
||||
val elem = Elem(
|
||||
face = FaceMsg(data["id"].asInt)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createImageElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
val isOriginal = data["original"].asBooleanOrNull ?: true
|
||||
val isFlash = data["flash"].asBooleanOrNull ?: false
|
||||
val filePath = data["file"].asStringOrNull
|
||||
val url = data["url"].asStringOrNull
|
||||
var file: File? = null
|
||||
if (filePath != null) {
|
||||
val md5 = filePath
|
||||
.replace(regex = "[{}\\-]".toRegex(), replacement = "")
|
||||
.split(".")[0].lowercase()
|
||||
file = if (md5.length == 32) {
|
||||
FileUtils.getFileByMd5(md5)
|
||||
} else {
|
||||
FileUtils.parseAndSave(filePath)
|
||||
}
|
||||
}
|
||||
if ((file == null || !file.exists()) && url != null) {
|
||||
file = FileUtils.parseAndSave(url)
|
||||
}
|
||||
if (file?.exists() == false) {
|
||||
throw LogicException("Image(${file.name}) file is not exists, please check your filename.")
|
||||
}
|
||||
requireNotNull(file)
|
||||
|
||||
val md5HexStr = QQNTWrapperUtil.CppProxy.genFileMd5Hex(file.absolutePath)
|
||||
val msgService = NTServiceFetcher.kernelService.msgService!!
|
||||
val originalPath = msgService.getRichMediaFilePathForMobileQQSend(
|
||||
RichMediaFilePathInfo(
|
||||
2, 0, md5HexStr, file.name, 1, 0, null, "", true
|
||||
)
|
||||
)
|
||||
if (!QQNTWrapperUtil.CppProxy.fileIsExist(originalPath) || QQNTWrapperUtil.CppProxy.getFileSize(
|
||||
originalPath
|
||||
) != file.length()
|
||||
) {
|
||||
val thumbPath = msgService.getRichMediaFilePathForMobileQQSend(
|
||||
RichMediaFilePathInfo(
|
||||
2, 0, md5HexStr, file.name, 2, 720, null, "", true
|
||||
)
|
||||
)
|
||||
QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, originalPath)
|
||||
QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, thumbPath)
|
||||
}
|
||||
|
||||
val options = BitmapFactory.Options()
|
||||
options.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeFile(file.absolutePath, options)
|
||||
val exifInterface = ExifInterface(file.absolutePath)
|
||||
val orientation = exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_UNDEFINED
|
||||
)
|
||||
val picWidth: Int
|
||||
val picHeight: Int
|
||||
if (orientation != ExifInterface.ORIENTATION_ROTATE_90 && orientation != ExifInterface.ORIENTATION_ROTATE_270) {
|
||||
picWidth = options.outWidth
|
||||
picHeight = options.outHeight
|
||||
} else {
|
||||
picWidth = options.outHeight
|
||||
picHeight = options.outWidth
|
||||
}
|
||||
|
||||
val elem = when (chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> {
|
||||
Transfer with Troop(peerId) trans PictureResource(file)
|
||||
Elem(
|
||||
customFace = CustomFace(
|
||||
filePath = "${md5HexStr.substring(0, 8)}-${md5HexStr.substring(8, 4)}-${
|
||||
md5HexStr.substring(
|
||||
12,
|
||||
4
|
||||
)
|
||||
}-${md5HexStr.substring(16, 4)}-${md5HexStr.substring(20, 12)}.${FileUtils.getFileType(file)}",
|
||||
fileId = 0u,
|
||||
serverIp = 0u,
|
||||
serverPort = 0u,
|
||||
fileType = 1001u,
|
||||
useful = 1u,
|
||||
md5 = md5HexStr.hex2ByteArray(),
|
||||
bizType = data["subType"].asIntOrNull?.toUInt(),
|
||||
imageType = FileUtils.getPicType(file).toUInt(),
|
||||
width = picWidth.toUInt(),
|
||||
height = picHeight.toUInt(),
|
||||
size = QQNTWrapperUtil.CppProxy.getFileSize(file.absolutePath).toUInt(),
|
||||
origin = if (isOriginal) 1u else 0u,
|
||||
thumbWidth = 0u,
|
||||
thumbHeight = 0u,
|
||||
pbReserve = CustomFace.Companion.PbReserve(field1 = 0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
MsgConstant.KCHATTYPEC2C -> {
|
||||
Transfer with Private(peerId) trans PictureResource(file)
|
||||
Elem(
|
||||
notOnlineImage = NotOnlineImage(
|
||||
filePath = "${md5HexStr}.${FileUtils.getFileType(file)}".toByteArray(),
|
||||
fileLen = QQNTWrapperUtil.CppProxy.getFileSize(file.absolutePath).toUInt(),
|
||||
downloadPath = "".toByteArray(),
|
||||
imgType = FileUtils.getPicType(file).toUInt(),
|
||||
picMd5 = md5HexStr.hex2ByteArray(),
|
||||
picHeight = picWidth.toUInt(),
|
||||
picWidth = picHeight.toUInt(),
|
||||
resId = "".toByteArray(),
|
||||
original = if (isOriginal) 1u else 0u, // true
|
||||
pbReserve = NotOnlineImage.Companion.PbReserve(field1 = 0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> throw LogicException("Not supported chatType($chatType) for PictureMsg")
|
||||
}
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createReplyElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("id")
|
||||
val msgHash = data["id"].asInt
|
||||
val mapping = MessageHelper.getMsgMappingByHash(msgHash)
|
||||
?: return Result.failure(Exception("不存在该消息映射,无法回复消息"))
|
||||
|
||||
if (mapping.qqMsgId == 0L) {
|
||||
// 貌似获取失败了,555
|
||||
LogCenter.log("无法获取被回复消息", Level.ERROR)
|
||||
return Result.failure(Exception("无法获取被回复消息"))
|
||||
}
|
||||
|
||||
val elem = if (data.containsKey("text")) {
|
||||
data.checkAndThrow("qq", "time", "seq")
|
||||
Elem(
|
||||
srcMsg = SourceMsg(
|
||||
origSeqs = listOf(data["seq"].asInt),
|
||||
senderUin = data["qq"].asString.toULong(),
|
||||
time = data["time"].asString.toULong(),
|
||||
flag = 1u,
|
||||
elems = listOf(
|
||||
Elem(
|
||||
text = TextMsg(
|
||||
data["text"].asString
|
||||
)
|
||||
)
|
||||
),
|
||||
type = 0u,
|
||||
pbReserve = SourceMsg.Companion.PbReserve(
|
||||
field3 = Random.nextULong(),
|
||||
field8 = Random.nextInt(0, 10000)
|
||||
),
|
||||
)
|
||||
)
|
||||
} else {
|
||||
val msg =
|
||||
MsgSvc.getMsgByQMsgId(chatType, mapping.peerId, mapping.qqMsgId).getOrNull() ?: return Result.failure(
|
||||
Exception("无法获取被回复消息")
|
||||
)
|
||||
Elem(
|
||||
srcMsg = SourceMsg(
|
||||
origSeqs = listOf(msg.msgSeq.toInt()),
|
||||
senderUin = msg.senderUin.toULong(),
|
||||
time = msg.msgTime.toULong(),
|
||||
flag = 1u,
|
||||
// elems = msg.elements.toSegments(),
|
||||
type = 0u,
|
||||
pbReserve = SourceMsg.Companion.PbReserve(
|
||||
field3 = Random.nextULong(),
|
||||
senderUid = msg.senderUid,
|
||||
receiverUid = TicketSvc.getUid(),
|
||||
field8 = Random.nextInt(0, 10000)
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createJsonElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("data")
|
||||
|
||||
val elem = Elem(
|
||||
lightApp = LightAppElem(
|
||||
data = DeflateTools.compress(data.toString().toByteArray())
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createPokeElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("type", "id")
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 2,
|
||||
elem = PokeExtra(
|
||||
type = data["type"].asInt,
|
||||
field7 = 0,
|
||||
field8 = 0
|
||||
).toByteArray(),
|
||||
businessType = data["id"].asInt
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createBasketballElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 37,
|
||||
elem = QFaceExtra(
|
||||
packId = "1",
|
||||
stickerId = "13",
|
||||
faceId = 114,
|
||||
field4 = 1,
|
||||
field5 = 2,
|
||||
field6 = "",
|
||||
faceText = "/篮球",
|
||||
field9 = 1
|
||||
).toByteArray(),
|
||||
businessType = 2
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createNewDiceElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 37,
|
||||
elem = QFaceExtra(
|
||||
packId = "1",
|
||||
stickerId = "33",
|
||||
faceId = 358,
|
||||
field4 = 1,
|
||||
field5 = 2,
|
||||
field6 = "",
|
||||
faceText = "/骰子",
|
||||
field9 = 1
|
||||
).toByteArray(),
|
||||
businessType = 2
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createNewRpsElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 37,
|
||||
elem = QFaceExtra(
|
||||
packId = "1",
|
||||
stickerId = "34",
|
||||
faceId = 359,
|
||||
field4 = 1,
|
||||
field5 = 2,
|
||||
field6 = "",
|
||||
faceText = "/包剪锤",
|
||||
field9 = 1
|
||||
).toByteArray(),
|
||||
businessType = 1
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createMarkdownElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("content")
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 45,
|
||||
elem = MarkdownExtra(data["content"].asString).toByteArray(),
|
||||
businessType = 1
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createButtonElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<Elem> {
|
||||
data.checkAndThrow("rows")
|
||||
val elem = Elem(
|
||||
commonElem = CommonElem(
|
||||
serviceType = 46,
|
||||
elem = ButtonExtra(
|
||||
field1 = Object1(
|
||||
rows = data["rows"].asJsonArray.map { row ->
|
||||
Row(buttons = row.asJsonArray.map {
|
||||
val button = it.asJsonObject
|
||||
val renderData = button["render_data"].asJsonObject
|
||||
val action = button["action"].asJsonObject
|
||||
Button(
|
||||
id = button["id"].asIntOrNull,
|
||||
renderData = RenderData(
|
||||
label = renderData["label"].asString,
|
||||
visitedLabel = renderData["visited_label"].asString,
|
||||
style = renderData["style"].asInt
|
||||
),
|
||||
action = Action(
|
||||
type = action["type"].asInt,
|
||||
permission = Permission(
|
||||
type = action["permission"].asJsonObject["type"].asInt,
|
||||
specifyRoleIds = action["permission"].asJsonObject["specify_role_ids"].asJsonArrayOrNull?.map { id -> id.asString },
|
||||
specifyUserIds = action["permission"].asJsonObject["specify_user_ids"].asJsonArrayOrNull?.map { id -> id.asString }
|
||||
),
|
||||
unsupportTips = action["unsupport_tips"].asString,
|
||||
data = action["data"].asString,
|
||||
reply = action["reply"].asBooleanOrNull,
|
||||
enter = action["enter"].asBooleanOrNull
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
appid = data["appid"].asIntOrNull
|
||||
)
|
||||
).toByteArray(),
|
||||
businessType = 1
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private fun JsonObject.checkAndThrow(vararg key: String) {
|
||||
key.forEach {
|
||||
if (!containsKey(it)) throw ParamsException(it)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.msgelement
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.maker
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
@ -85,6 +85,7 @@ internal object MsgElementMaker {
|
||||
//"node" to MessageMaker::createNodeElem,
|
||||
//"multi_msg" to MessageMaker::createLongMsgStruct,
|
||||
"bubble_face" to MsgElementMaker::createBubbleFaceElem,
|
||||
"button" to MsgElementMaker::createInlineKeywordElem,
|
||||
"inline_keyboard" to MsgElementMaker::createInlineKeywordElem
|
||||
)
|
||||
|
@ -1,183 +0,0 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.messageelement
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import moe.fuqiuluo.qqinterface.servlet.GProSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.shamrock.helper.*
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.ParamsException
|
||||
import moe.fuqiuluo.shamrock.tools.*
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import protobuf.message.MessageElement
|
||||
import protobuf.message.element.FaceElement
|
||||
import protobuf.message.element.JsonElement
|
||||
import protobuf.message.element.TextElement
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
internal typealias IMessageElementMaker = suspend (Int, Long, String, JsonObject) -> Result<MessageElement>
|
||||
|
||||
internal object MessageElementMaker {
|
||||
private val makerArray = hashMapOf(
|
||||
"text" to MessageElementMaker::createTextElem,
|
||||
"face" to MessageElementMaker::createFaceElem,
|
||||
// "pic" to MessageElementMaker::createImageElem,
|
||||
// "image" to MessageElementMaker::createImageElem,
|
||||
// "voice" to MessageElementMaker::createRecordElem,
|
||||
// "record" to MessageElementMaker::createRecordElem,
|
||||
"at" to MessageElementMaker::createAtElem,
|
||||
// "video" to MessageElementMaker::createVideoElem,
|
||||
// "markdown" to MessageElementMaker::createMarkdownElem,
|
||||
// "dice" to MessageElementMaker::createDiceElem,
|
||||
// "rps" to MessageElementMaker::createRpsElem,
|
||||
// "poke" to MessageElementMaker::createPokeElem,
|
||||
// "anonymous" to MessageElementMaker::createAnonymousElem,
|
||||
// "share" to MessageElementMaker::createShareElem,
|
||||
// "contact" to MessageElementMaker::createContactElem,
|
||||
// "location" to MessageElementMaker::createLocationElem,
|
||||
// "music" to MessageElementMaker::createMusicElem,
|
||||
// "reply" to MessageElementMaker::createReplyElem,
|
||||
// "touch" to MessageElementMaker::createTouchElem,
|
||||
// "weather" to MessageElementMaker::createWeatherElem,
|
||||
"json" to MessageElementMaker::createJsonElem,
|
||||
//"new_dice" to MessageElementMaker::createNewDiceElem,
|
||||
//"new_rps" to MessageElementMaker::createNewRpsElem,
|
||||
//"basketball" to MessageElementMaker::createBasketballElem,
|
||||
//"node" to MessageMaker::createNodeElem,
|
||||
//"multi_msg" to MessageMaker::createLongMsgStruct,
|
||||
//"bubble_face" to MessageElementMaker::createBubbleFaceElem,
|
||||
)
|
||||
|
||||
operator fun get(type: String): IMessageElementMaker? = makerArray[type]
|
||||
|
||||
private suspend fun createTextElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<MessageElement> {
|
||||
data.checkAndThrow("text")
|
||||
val elem = MessageElement(
|
||||
text = TextElement(data["text"].asString)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createFaceElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<MessageElement> {
|
||||
data.checkAndThrow("id")
|
||||
val elem = MessageElement(
|
||||
face = FaceElement(data["id"].asInt)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private suspend fun createAtElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<MessageElement> {
|
||||
return if (chatType == MsgConstant.KCHATTYPEGROUP) {
|
||||
data.checkAndThrow("qq")
|
||||
|
||||
val qq: Long
|
||||
val type: Int
|
||||
lateinit var display: String
|
||||
when (val qqStr = data["qq"].asString) {
|
||||
"0", "all" -> {
|
||||
qq = 0
|
||||
type = 1
|
||||
display = "@全体成员"
|
||||
}
|
||||
|
||||
"online" -> {
|
||||
qq = 0
|
||||
type = 64
|
||||
display = "@在线成员"
|
||||
}
|
||||
|
||||
else -> {
|
||||
qq = qqStr.toLong()
|
||||
type = 0
|
||||
display =
|
||||
"@" + (data["name"].asStringOrNull ?: GroupSvc.getTroopMemberInfoByUinV2(peerId, qqStr, true)
|
||||
.onSuccess {
|
||||
it.troopnick
|
||||
.ifEmpty { it.friendnick }
|
||||
.ifEmpty { qqStr }
|
||||
}.onFailure {
|
||||
LogCenter.log("无法获取群成员信息: $qqStr", Level.ERROR)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val attr6: ByteBuffer = ByteBuffer.allocate(6)
|
||||
attr6.put(byteArrayOf(0, 1, 0, 0, 0))
|
||||
attr6.putChar(display.length.toChar())
|
||||
attr6.putChar(type.toChar())
|
||||
attr6.putBuf32Long(qq)
|
||||
attr6.put(byteArrayOf(0, 0))
|
||||
val elem = MessageElement(
|
||||
text = TextElement(text = display, attr6Buf = attr6.array())
|
||||
)
|
||||
Result.success(elem)
|
||||
} else if (chatType == MsgConstant.KCHATTYPEGUILD) {
|
||||
data.checkAndThrow("qq")
|
||||
|
||||
val qq: Long
|
||||
val type: Int
|
||||
lateinit var display: String
|
||||
when (val qqStr = data["qq"].asString) {
|
||||
"0", "all" -> {
|
||||
type = 2
|
||||
display = "@全体成员"
|
||||
}
|
||||
|
||||
else -> {
|
||||
qq = qqStr.toLong()
|
||||
type = 2
|
||||
display =
|
||||
"@" + (data["name"].asStringOrNull ?: GProSvc.getUserGuildInfo(0UL, 0UL)
|
||||
.onSuccess {
|
||||
it.nickName.ifNullOrEmpty(qqStr)
|
||||
}.onFailure {
|
||||
LogCenter.log("无法获取频道组成员信息: $qqStr", Level.ERROR)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val elem = MessageElement(
|
||||
text = TextElement(text = display, pbReserve = TextElement.Companion.TextResvAttr(atType = type))
|
||||
)
|
||||
Result.success(elem)
|
||||
} else Result.failure(ActionMsgException)
|
||||
}
|
||||
|
||||
private suspend fun createJsonElem(
|
||||
chatType: Int,
|
||||
msgId: Long,
|
||||
peerId: String,
|
||||
data: JsonObject
|
||||
): Result<MessageElement> {
|
||||
data.checkAndThrow("data")
|
||||
|
||||
val elem = MessageElement(
|
||||
json = JsonElement(
|
||||
data = DeflateTools.compress(data.toString().toByteArray())
|
||||
)
|
||||
)
|
||||
return Result.success(elem)
|
||||
}
|
||||
|
||||
private fun JsonObject.checkAndThrow(vararg key: String) {
|
||||
key.forEach {
|
||||
if (!containsKey(it)) throw ParamsException(it)
|
||||
}
|
||||
}
|
||||
}
|
@ -16,8 +16,8 @@ import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.messageelement.MessageElementMaker
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.MsgElementMaker
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.maker.MessageElementMaker
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.maker.MsgElementMaker
|
||||
import moe.fuqiuluo.shamrock.helper.db.MessageDB
|
||||
import moe.fuqiuluo.shamrock.helper.db.MessageMapping
|
||||
import moe.fuqiuluo.shamrock.remote.structures.SendMsgResult
|
||||
@ -26,7 +26,7 @@ import moe.fuqiuluo.shamrock.tools.asJsonObjectOrNull
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import moe.fuqiuluo.shamrock.tools.json
|
||||
import moe.fuqiuluo.shamrock.tools.jsonArray
|
||||
import protobuf.message.MessageElement
|
||||
import protobuf.message.Elem
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.math.abs
|
||||
|
||||
@ -323,8 +323,8 @@ internal object MessageHelper {
|
||||
msgId: Long,
|
||||
targetUin: String,
|
||||
messageList: JsonArray
|
||||
): Pair<Boolean, ArrayList<MessageElement>> {
|
||||
val msgList = arrayListOf<MessageElement>()
|
||||
): Pair<Boolean, ArrayList<Elem>> {
|
||||
val msgList = arrayListOf<Elem>()
|
||||
var hasActionMsg = false
|
||||
messageList.forEach {
|
||||
val msg = it.jsonObject
|
||||
|
@ -6,7 +6,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toListMap
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import moe.fuqiuluo.shamrock.helper.db.MessageDB
|
||||
|
@ -8,7 +8,7 @@ import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||
import moe.fuqiuluo.shamrock.remote.service.data.MessageDetail
|
||||
import moe.fuqiuluo.shamrock.remote.service.data.MessageSender
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toListMap
|
||||
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
||||
import moe.fuqiuluo.symbols.OneBotHandler
|
||||
|
@ -4,7 +4,7 @@ import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import kotlinx.serialization.json.*
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
@ -15,7 +15,6 @@ import moe.fuqiuluo.shamrock.remote.service.data.ForwardMessageResult
|
||||
import moe.fuqiuluo.shamrock.tools.*
|
||||
import moe.fuqiuluo.symbols.OneBotHandler
|
||||
import protobuf.message.*
|
||||
import protobuf.message.longmsg.PushMsgBody
|
||||
import java.util.*
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -96,20 +95,21 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
return@map null
|
||||
}
|
||||
if (record.chatType == MsgConstant.KCHATTYPEGROUP) groupUin = record.peerUin.toString()
|
||||
if (record.chatType == MsgConstant.KCHATTYPEC2C) uid = record.peerUid
|
||||
PushMsgBody(
|
||||
head = MessageHead(
|
||||
msgHead = ResponseHead(
|
||||
peerUid = record.senderUid,
|
||||
receiverUid = record.peerUid,
|
||||
forward = MessageForward(
|
||||
forward = ResponseForward(
|
||||
friendName = record.sendNickName
|
||||
),
|
||||
groupInfo = if (record.chatType == MsgConstant.KCHATTYPEGROUP) GroupInfo(
|
||||
responseGrp = if (record.chatType == MsgConstant.KCHATTYPEGROUP) ResponseGrp(
|
||||
groupCode = record.peerUin.toULong(),
|
||||
memberCard = record.sendMemberName,
|
||||
u1 = 2
|
||||
) else null
|
||||
),
|
||||
content = MessageContent(
|
||||
contentHead = ContentHead(
|
||||
msgType = when (record.chatType) {
|
||||
MsgConstant.KCHATTYPEC2C -> 9
|
||||
MsgConstant.KCHATTYPEGROUP -> 82
|
||||
@ -118,9 +118,9 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
)
|
||||
},
|
||||
msgSubType = if (record.chatType == MsgConstant.KCHATTYPEC2C) 175 else null,
|
||||
u1 = if (record.chatType == MsgConstant.KCHATTYPEC2C) 175 else null,
|
||||
divSeq = if (record.chatType == MsgConstant.KCHATTYPEC2C) 175 else null,
|
||||
msgViaRandom = record.msgId,
|
||||
msgSeq_ = record.msgSeq, // idk what this is(i++)
|
||||
sequence = record.msgSeq, // idk what this is(i++)
|
||||
msgTime = record.msgTime,
|
||||
u2 = 1,
|
||||
u6 = 0,
|
||||
@ -131,11 +131,11 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
u2 = 0,
|
||||
u3 = 0,
|
||||
ub641 = "",
|
||||
Avatar = ""
|
||||
avatar = ""
|
||||
)
|
||||
),
|
||||
body = MessageBody(
|
||||
rich = RichMessage(
|
||||
body = MsgBody(
|
||||
richText = RichText(
|
||||
elements = MessageHelper.messageArrayToMessageElements(
|
||||
record.chatType,
|
||||
record.msgId,
|
||||
@ -168,20 +168,20 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
)
|
||||
} else if (data.containsKey("content")) {
|
||||
PushMsgBody(
|
||||
head = MessageHead(
|
||||
msgHead = ResponseHead(
|
||||
peer = data["uin"]?.asLong ?: TicketSvc.getUin().toLong(),
|
||||
peerUid = data["uid"]?.asString ?: TicketSvc.getUid(),
|
||||
receiverUid = TicketSvc.getUid(),
|
||||
forward = MessageForward(
|
||||
forward = ResponseForward(
|
||||
friendName = data["name"]?.asStringOrNull ?: TicketSvc.getNickname()
|
||||
)
|
||||
),
|
||||
content = MessageContent(
|
||||
msgType = 9,
|
||||
contentHead = ContentHead(
|
||||
msgType = 9,
|
||||
msgSubType = 175,
|
||||
u1 = 175,
|
||||
divSeq = 175,
|
||||
msgViaRandom = Random.nextLong(),
|
||||
msgSeq_ = data["seq"]?.asLong ?: Random.nextLong(),
|
||||
sequence = data["seq"]?.asLong ?: Random.nextLong(),
|
||||
msgTime = data["time"]?.asLong ?: (System.currentTimeMillis() / 1000),
|
||||
u2 = 1,
|
||||
u6 = 0,
|
||||
@ -192,11 +192,11 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
u2 = 0,
|
||||
u3 = 2,
|
||||
ub641 = "",
|
||||
Avatar = ""
|
||||
avatar = ""
|
||||
)
|
||||
),
|
||||
body = MessageBody(
|
||||
rich = RichMessage(
|
||||
body = MsgBody(
|
||||
richText = RichText(
|
||||
elements = MessageHelper.messageArrayToMessageElements(
|
||||
1,
|
||||
Random.nextLong(),
|
||||
@ -211,15 +211,14 @@ internal object SendForwardMessage : IActionHandler() {
|
||||
?: TicketSvc.getNickname()
|
||||
}: "
|
||||
}.onEach {
|
||||
when (it.asJsonObject["type"].asString) {
|
||||
"text" -> desc[i] += it.asJsonObject["data"].asJsonObject["text"].asString
|
||||
|
||||
"at" -> desc[i] += "@${it.asJsonObject["data"].asJsonObject["name"].asStringOrNull ?: it.asJsonObject["data"].asJsonObject["qq"].asString}"
|
||||
|
||||
val type = it.asJsonObject["type"].asString
|
||||
val itData = it.asJsonObject["data"].asJsonObject
|
||||
when (type) {
|
||||
"text" -> desc[i] += itData["text"].asString
|
||||
"at" -> desc[i] += "@${itData["name"].asStringOrNull ?: itData["qq"].asString}"
|
||||
"face" -> desc[i] += "[表情]"
|
||||
|
||||
"image" -> desc[i] += "[图片]"
|
||||
"voice" -> desc[i] += "[语音]"
|
||||
|
||||
"node" -> desc[i] += "[合并转发消息]"
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,46 @@
|
||||
package moe.fuqiuluo.shamrock.remote.action.handlers
|
||||
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.serialization.encodeToByteArray
|
||||
|
||||
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||
import moe.fuqiuluo.symbols.OneBotHandler
|
||||
import protobuf.auto.toByteArray
|
||||
import protobuf.msg.C2C
|
||||
import protobuf.msg.ContentHead
|
||||
import protobuf.msg.Elem
|
||||
import protobuf.msg.GeneralFlags
|
||||
import protobuf.msg.Grp
|
||||
import protobuf.msg.MsgBody
|
||||
import protobuf.msg.PbSendMsgReq
|
||||
import protobuf.msg.RichText
|
||||
import protobuf.msg.RoutingHead
|
||||
import protobuf.message.*
|
||||
import protobuf.message.element.GeneralFlags
|
||||
import protobuf.message.routing.C2C
|
||||
import protobuf.message.routing.Grp
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextUInt
|
||||
|
||||
@OneBotHandler("send_msg_by_resid")
|
||||
internal object SendMsgByResid: IActionHandler() {
|
||||
internal object SendMsgByResid : IActionHandler() {
|
||||
private val msgSeq = atomic(1000)
|
||||
|
||||
override suspend fun internalHandle(session: ActionSession): String {
|
||||
val resid = session.getString("resid")
|
||||
val peerId = session.getString("peer")
|
||||
val req = PbSendMsgReq(
|
||||
routingHead = RoutingHead().apply {
|
||||
when(session.getStringOrNull("message_type")) {
|
||||
"group" -> grp = Grp(peerId.toULong())
|
||||
"private" -> c2c = C2C(peerId.toULong())
|
||||
else -> grp = Grp(peerId.toULong())
|
||||
}
|
||||
routingHead = when (session.getStringOrNull("message_type")) {
|
||||
"group" ->RoutingHead(grp = Grp(peerId.toUInt()))
|
||||
"private" ->RoutingHead( c2c = C2C(peerId.toUInt()))
|
||||
else ->RoutingHead( grp = Grp(peerId.toUInt()))
|
||||
},
|
||||
contentHead = ContentHead(1u, 0u, 0u, 0u),
|
||||
contentHead = ContentHead(1, 0, 0, 0),
|
||||
msgBody = MsgBody(
|
||||
richText = RichText(arrayListOf(Elem(
|
||||
generalFlags = GeneralFlags(
|
||||
long_text_flag = 1u,
|
||||
long_text_resid = resid.toByteArray()
|
||||
richText = RichText(
|
||||
elements = arrayListOf(
|
||||
Elem(
|
||||
generalFlags = GeneralFlags(
|
||||
longTextFlag = 1u,
|
||||
longTextResid = resid.toByteArray()
|
||||
)
|
||||
)
|
||||
)
|
||||
)))
|
||||
)
|
||||
),
|
||||
msgSeq = msgSeq.incrementAndGet().toULong(),
|
||||
msgSeq = msgSeq.incrementAndGet().toUInt(),
|
||||
msgRand = Random.nextUInt(),
|
||||
msgVia = 0u
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ import kotlinx.coroutines.launch
|
||||
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.CardSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toJson
|
||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.remote.service.data.push.GroupFileMsg
|
||||
|
@ -9,7 +9,7 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.msgelement.toCQCode
|
||||
import moe.fuqiuluo.qqinterface.servlet.msg.toCQCode
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
|
@ -1,54 +1,37 @@
|
||||
@file:OptIn(DelicateCoroutinesApi::class, ExperimentalSerializationApi::class)
|
||||
package moe.fuqiuluo.shamrock.remote.service.listener
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.decodeFromByteArray
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
|
||||
import moe.fuqiuluo.qqinterface.servlet.FriendSvc.requestFriendSystemMsgNew
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc.requestGroupSystemMsgNew
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getLongUin
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import moe.fuqiuluo.shamrock.remote.service.data.push.NoticeSubType
|
||||
import moe.fuqiuluo.shamrock.remote.service.data.push.NoticeType
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
||||
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.RequestSubType
|
||||
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.shamrock.xposed.helper.PacketHandler
|
||||
import moe.fuqiuluo.symbols.decode
|
||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||
import protobuf.message.MessageContent
|
||||
import protobuf.message.MessageHead
|
||||
import protobuf.message.MessageBody
|
||||
import protobuf.message.ContentHead
|
||||
import protobuf.message.MsgBody
|
||||
import protobuf.message.ResponseHead
|
||||
import protobuf.message.multimedia.RichMediaForPicData
|
||||
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 protobuf.push.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
private val RKEY_PATTERN = Pattern.compile("rkey=([A-Za-z0-9_-]+)")
|
||||
@ -106,16 +89,16 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LogCenter.log("onMsgPush(msgType: $msgType, subType: $subType): "+e.stackTraceToString(), Level.WARN)
|
||||
LogCenter.log("onMsgPush(msgType: $msgType, subType: $subType): " + e.stackTraceToString(), Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onGroupMessage(msgTime: Long, body: MessageBody) {
|
||||
private fun onGroupMessage(msgTime: Long, body: MsgBody) {
|
||||
/*runCatching {
|
||||
body.rich?.elements?.filter {
|
||||
it.comm != null && it.comm!!.type == 48
|
||||
body.richText?.elements?.filter {
|
||||
it.commonElem != null && it.commonElem!!.serviceType == 48
|
||||
}?.map {
|
||||
it.comm!!.data!!.decodeProtobuf<RichMediaForPicData>()
|
||||
it.commonElem!!.elem!!.decodeProtobuf<RichMediaForPicData>()
|
||||
}?.forEach {
|
||||
it.display?.show?.download?.url?.let {
|
||||
RKEY_PATTERN.matcher(it).takeIf {
|
||||
@ -129,8 +112,8 @@ internal object PrimitiveListener {
|
||||
}*/
|
||||
}
|
||||
|
||||
private suspend fun onC2CPoke(msgTime: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<C2CCommonTipsEvent>()
|
||||
private suspend fun onC2CPoke(msgTime: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<C2CCommonTipsEvent>()
|
||||
if (event.params == null) return
|
||||
|
||||
val params = event.params!!.associate {
|
||||
@ -155,9 +138,9 @@ internal object PrimitiveListener {
|
||||
private suspend fun onFriendApply(
|
||||
msgTime: Long,
|
||||
clientInfo: MessagePushClientInfo,
|
||||
richMsg: MessageBody
|
||||
body: MsgBody
|
||||
) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<FriendApplyEvent>()
|
||||
val event = body.msgContent!!.decodeProtobuf<FriendApplyEvent>()
|
||||
if (event.head == null) return
|
||||
val head = event.head!!
|
||||
val applierUid = head.applierUid
|
||||
@ -188,55 +171,46 @@ internal object PrimitiveListener {
|
||||
}
|
||||
|
||||
|
||||
private suspend fun onCardChange(msgTime: Long, richMsg: MessageBody) {
|
||||
LogCenter.log("群名片事件异常,请尝试提交issue!", Level.WARN)
|
||||
/*try {
|
||||
val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
|
||||
if(readPacket.readBuf32Long() ==
|
||||
readPacket.discardExact(1)
|
||||
detail = ProtoUtils.decodeFromByteArray(readPacket.readBytes(readPacket.readShort().toInt()))
|
||||
readPacket.release()
|
||||
} catch (e: Exception) {
|
||||
LogCenter.log("onCardChange error: ${e.stackTraceToString()}", Level.WARN)
|
||||
}
|
||||
|
||||
var detail = pb[1, 3, 2]
|
||||
if (detail !is ProtoMap) {
|
||||
|
||||
}
|
||||
|
||||
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暂时获取不到
|
||||
// GroupSvc.getTroopMemberInfoByUin(groupId.toString(), targetQQ.toString()).onSuccess {
|
||||
// oldCard = it.troopnick
|
||||
// }.onFailure {
|
||||
// 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)
|
||||
// }
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transCardChange(msgTime, targetQQ, oldCard, newCard, groupId)
|
||||
) {
|
||||
LogCenter.log("群名片变动推送失败!", Level.WARN)
|
||||
}*/
|
||||
}
|
||||
|
||||
private suspend fun onGroupUniqueTitleChange(msgTime: Long, richMsg: MessageBody) {
|
||||
private suspend fun onGroupUniqueTitleChange(msgTime: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.readBuf32Long()
|
||||
readPacket.discardExact(1)
|
||||
|
||||
@ -251,7 +225,7 @@ internal object PrimitiveListener {
|
||||
// (detail[5] as ProtoList).value[0]
|
||||
//} else {
|
||||
// detail[5]
|
||||
// }
|
||||
// }
|
||||
|
||||
val targetUin = detail.targetUin.toLong()
|
||||
|
||||
@ -276,13 +250,13 @@ internal object PrimitiveListener {
|
||||
private suspend fun onEssenceMessage(
|
||||
msgTime: Long,
|
||||
clientInfo: MessagePushClientInfo?,
|
||||
richMsg: MessageBody
|
||||
body: MsgBody
|
||||
) {
|
||||
if (clientInfo == null) return
|
||||
val event = runCatching {
|
||||
richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.readBuf32Long()
|
||||
readPacket.discardExact(1)
|
||||
|
||||
@ -325,11 +299,11 @@ internal object PrimitiveListener {
|
||||
}
|
||||
|
||||
|
||||
private suspend fun onGroupPokeAndGroupSign(time: Long, richMsg: MessageBody) {
|
||||
private suspend fun onGroupPokeAndGroupSign(time: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.discardExact(4)
|
||||
readPacket.discardExact(1)
|
||||
|
||||
@ -379,8 +353,8 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onC2CRecall(time: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<C2CRecallEvent>()
|
||||
private suspend fun onC2CRecall(time: Long, body: MsgBody) {
|
||||
val event = body.msgContent!!.decodeProtobuf<C2CRecallEvent>()
|
||||
val head = event.head!!
|
||||
|
||||
val operationUid = head.operator!!
|
||||
@ -404,8 +378,8 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupMemIncreased(time: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupListChangeEvent>()
|
||||
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
|
||||
@ -423,7 +397,14 @@ internal object PrimitiveListener {
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumChanged(
|
||||
time, target, targetUid, groupCode, operator, operatorUid, NoticeType.GroupMemIncrease, when (type) {
|
||||
time,
|
||||
target,
|
||||
targetUid,
|
||||
groupCode,
|
||||
operator,
|
||||
operatorUid,
|
||||
NoticeType.GroupMemIncrease,
|
||||
when (type) {
|
||||
130 -> NoticeSubType.Approve
|
||||
131 -> NoticeSubType.Invite
|
||||
else -> NoticeSubType.Approve
|
||||
@ -434,8 +415,8 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupMemberDecreased(time: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupListChangeEvent>()
|
||||
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
|
||||
@ -461,14 +442,23 @@ internal object PrimitiveListener {
|
||||
LogCenter.log("群成员减少($groupCode): $target, type = $subtype ($type)")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumChanged(time, target, targetUid, groupCode, operator, operatorUid, NoticeType.GroupMemDecrease, subtype)
|
||||
.transGroupMemberNumChanged(
|
||||
time,
|
||||
target,
|
||||
targetUid,
|
||||
groupCode,
|
||||
operator,
|
||||
operatorUid,
|
||||
NoticeType.GroupMemDecrease,
|
||||
subtype
|
||||
)
|
||||
) {
|
||||
LogCenter.log("群成员减少推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupAdminChange(msgTime: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupAdminChangeEvent>()
|
||||
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!!
|
||||
@ -494,8 +484,8 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupBan(msgTime: Long, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupBanEvent>()
|
||||
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
|
||||
@ -519,14 +509,14 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupRecall(time: Long, richMsg: MessageBody) {
|
||||
private suspend fun onGroupRecall(time: Long, body: MsgBody) {
|
||||
val event = runCatching {
|
||||
richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
body.msgContent!!.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}.getOrElse {
|
||||
val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
|
||||
val readPacket = ByteReadPacket(body.msgContent!!)
|
||||
readPacket.discardExact(4)
|
||||
readPacket.discardExact(1)
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.readBytes(readPacket.readShort().toInt()).also {
|
||||
readPacket.release()
|
||||
}.decodeProtobuf<GroupCommonTipsEvent>()
|
||||
}
|
||||
@ -553,10 +543,10 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onGroupApply(time: Long, contentHead: MessageContent, richMsg: MessageBody) {
|
||||
private suspend fun onGroupApply(time: Long, contentHead: ContentHead, body: MsgBody) {
|
||||
when (contentHead.msgType) {
|
||||
84 -> {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupApplyEvent>()
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupApplyEvent>()
|
||||
val groupCode = event.groupCode
|
||||
val applierUid = event.applierUid
|
||||
val reason = event.applyMsg ?: ""
|
||||
@ -587,8 +577,9 @@ internal object PrimitiveListener {
|
||||
LogCenter.log("入群申请推送失败!", Level.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
528 -> {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupInvitedApplyEvent>()
|
||||
val event = body.msgContent!!.decodeProtobuf<GroupInvitedApplyEvent>()
|
||||
val groupCode = event.applyInfo?.groupCode ?: return
|
||||
val applierUid = event.applyInfo?.applierUid ?: return
|
||||
var applier = ContactHelper.getUinByUidAsync(applierUid).toLong()
|
||||
@ -624,8 +615,8 @@ internal object PrimitiveListener {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onInviteGroup(time: Long, msgHead: MessageHead, richMsg: MessageBody) {
|
||||
val event = richMsg.rawBuffer!!.decodeProtobuf<GroupInviteEvent>()
|
||||
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()
|
||||
@ -644,7 +635,7 @@ internal object PrimitiveListener {
|
||||
"$time;$groupCode;$uin"
|
||||
}
|
||||
if (!GlobalEventTransmitter.RequestTransmitter
|
||||
.transGroupApply(time, invitor, invitorUid, "", groupCode, flag, RequestSubType.Invite)
|
||||
.transGroupApply(time, invitor, invitorUid, "", groupCode, flag, RequestSubType.Invite)
|
||||
) {
|
||||
LogCenter.log("邀请入群推送失败!", Level.WARN)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user