diff --git a/client/c2c_switch.go b/client/c2c_switch.go index fb9199ec..5e792c97 100644 --- a/client/c2c_switch.go +++ b/client/c2c_switch.go @@ -8,11 +8,11 @@ import ( const ( UnknownDecoder = iota - privateMsgDecoders nonSvcNotifyTroopSystemMsgDecoders troopSystemMsgDecoders sysMsgDecoders otherDecoders + privateMsgDecoders ) func peekC2CDecoder(msgType int32) (decoder func(*QQClient, *msg.Message, *incomingPacketInfo), decoderType uint8) { diff --git a/client/pb/msg/msg.pb.go b/client/pb/msg/msg.pb.go index e78a8a5d..9cc1dd30 100644 --- a/client/pb/msg/msg.pb.go +++ b/client/pb/msg/msg.pb.go @@ -1,17 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.14.0 +// protoc-gen-go v1.26.0 +// protoc v3.17.1 // source: pb/msg/msg.proto package msg import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( @@ -7507,6 +7506,117 @@ func (x *PbPushMsg) GetBindUin() uint64 { return 0 } +type MsgElemInfoServtype37 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Packid []byte `protobuf:"bytes,1,opt,name=packid" json:"packid,omitempty"` + Stickerid []byte `protobuf:"bytes,2,opt,name=stickerid" json:"stickerid,omitempty"` + Qsid *uint32 `protobuf:"varint,3,opt,name=qsid" json:"qsid,omitempty"` + Sourcetype *uint32 `protobuf:"varint,4,opt,name=sourcetype" json:"sourcetype,omitempty"` + Stickertype *uint32 `protobuf:"varint,5,opt,name=stickertype" json:"stickertype,omitempty"` + Resultid []byte `protobuf:"bytes,6,opt,name=resultid" json:"resultid,omitempty"` + Text []byte `protobuf:"bytes,7,opt,name=text" json:"text,omitempty"` + Surpriseid []byte `protobuf:"bytes,8,opt,name=surpriseid" json:"surpriseid,omitempty"` + Randomtype *uint32 `protobuf:"varint,9,opt,name=randomtype" json:"randomtype,omitempty"` +} + +func (x *MsgElemInfoServtype37) Reset() { + *x = MsgElemInfoServtype37{} + if protoimpl.UnsafeEnabled { + mi := &file_pb_msg_msg_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgElemInfoServtype37) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgElemInfoServtype37) ProtoMessage() {} + +func (x *MsgElemInfoServtype37) ProtoReflect() protoreflect.Message { + mi := &file_pb_msg_msg_proto_msgTypes[75] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MsgElemInfoServtype37.ProtoReflect.Descriptor instead. +func (*MsgElemInfoServtype37) Descriptor() ([]byte, []int) { + return file_pb_msg_msg_proto_rawDescGZIP(), []int{75} +} + +func (x *MsgElemInfoServtype37) GetPackid() []byte { + if x != nil { + return x.Packid + } + return nil +} + +func (x *MsgElemInfoServtype37) GetStickerid() []byte { + if x != nil { + return x.Stickerid + } + return nil +} + +func (x *MsgElemInfoServtype37) GetQsid() uint32 { + if x != nil && x.Qsid != nil { + return *x.Qsid + } + return 0 +} + +func (x *MsgElemInfoServtype37) GetSourcetype() uint32 { + if x != nil && x.Sourcetype != nil { + return *x.Sourcetype + } + return 0 +} + +func (x *MsgElemInfoServtype37) GetStickertype() uint32 { + if x != nil && x.Stickertype != nil { + return *x.Stickertype + } + return 0 +} + +func (x *MsgElemInfoServtype37) GetResultid() []byte { + if x != nil { + return x.Resultid + } + return nil +} + +func (x *MsgElemInfoServtype37) GetText() []byte { + if x != nil { + return x.Text + } + return nil +} + +func (x *MsgElemInfoServtype37) GetSurpriseid() []byte { + if x != nil { + return x.Surpriseid + } + return nil +} + +func (x *MsgElemInfoServtype37) GetRandomtype() uint32 { + if x != nil && x.Randomtype != nil { + return *x.Randomtype + } + return 0 +} + type ElemFlags2_Inst struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7519,7 +7629,7 @@ type ElemFlags2_Inst struct { func (x *ElemFlags2_Inst) Reset() { *x = ElemFlags2_Inst{} if protoimpl.UnsafeEnabled { - mi := &file_pb_msg_msg_proto_msgTypes[75] + mi := &file_pb_msg_msg_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7532,7 +7642,7 @@ func (x *ElemFlags2_Inst) String() string { func (*ElemFlags2_Inst) ProtoMessage() {} func (x *ElemFlags2_Inst) ProtoReflect() protoreflect.Message { - mi := &file_pb_msg_msg_proto_msgTypes[75] + mi := &file_pb_msg_msg_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8746,11 +8856,29 @@ var file_pb_msg_msg_proto_rawDesc = []byte{ 0x12, 0x20, 0x0a, 0x0b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x55, 0x69, 0x6e, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x55, 0x69, 0x6e, 0x2a, 0x2e, 0x0a, 0x08, - 0x53, 0x79, 0x6e, 0x63, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, - 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x4d, 0x45, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x42, 0x0c, 0x5a, 0x0a, - 0x70, 0x62, 0x2f, 0x6d, 0x73, 0x67, 0x3b, 0x6d, 0x73, 0x67, + 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x55, 0x69, 0x6e, 0x22, 0x94, 0x02, 0x0a, + 0x16, 0x4d, 0x73, 0x67, 0x45, 0x6c, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x74, 0x79, 0x70, 0x65, 0x33, 0x37, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x69, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x71, 0x73, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x71, 0x73, 0x69, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, + 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x69, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x72, 0x70, 0x72, 0x69, 0x73, + 0x65, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x74, + 0x79, 0x70, 0x65, 0x2a, 0x2e, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x46, 0x6c, 0x61, 0x67, 0x12, + 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, + 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, + 0x50, 0x10, 0x02, 0x42, 0x0c, 0x5a, 0x0a, 0x70, 0x62, 0x2f, 0x6d, 0x73, 0x67, 0x3b, 0x6d, 0x73, + 0x67, } var ( @@ -8766,7 +8894,7 @@ func file_pb_msg_msg_proto_rawDescGZIP() []byte { } var file_pb_msg_msg_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pb_msg_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 76) +var file_pb_msg_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 77) var file_pb_msg_msg_proto_goTypes = []interface{}{ (SyncFlag)(0), // 0: msg.SyncFlag (*GetMessageRequest)(nil), // 1: msg.GetMessageRequest @@ -8844,7 +8972,8 @@ var file_pb_msg_msg_proto_goTypes = []interface{}{ (*PbGetOneDayRoamMsgReq)(nil), // 73: msg.PbGetOneDayRoamMsgReq (*PbGetOneDayRoamMsgResp)(nil), // 74: msg.PbGetOneDayRoamMsgResp (*PbPushMsg)(nil), // 75: msg.PbPushMsg - (*ElemFlags2_Inst)(nil), // 76: msg.ElemFlags2.Inst + (*MsgElemInfoServtype37)(nil), // 76: msg.MsgElemInfo_servtype37 + (*ElemFlags2_Inst)(nil), // 77: msg.ElemFlags2.Inst } var file_pb_msg_msg_proto_depIdxs = []int32{ 0, // 0: msg.GetMessageRequest.syncFlag:type_name -> msg.SyncFlag @@ -8894,8 +9023,8 @@ var file_pb_msg_msg_proto_depIdxs = []int32{ 45, // 44: msg.Elem.srcMsg:type_name -> msg.SourceMsg 47, // 45: msg.Elem.lightApp:type_name -> msg.LightAppElem 28, // 46: msg.Elem.commonElem:type_name -> msg.CommonElem - 76, // 47: msg.ElemFlags2.insts:type_name -> msg.ElemFlags2.Inst - 76, // 48: msg.ElemFlags2.srcInst:type_name -> msg.ElemFlags2.Inst + 77, // 47: msg.ElemFlags2.insts:type_name -> msg.ElemFlags2.Inst + 77, // 48: msg.ElemFlags2.srcInst:type_name -> msg.ElemFlags2.Inst 27, // 49: msg.ElemFlags2.pcSupportDef:type_name -> msg.PcSupportDef 30, // 50: msg.QQWalletMsg.aioBody:type_name -> msg.QQWalletAioBody 31, // 51: msg.QQWalletAioBody.sender:type_name -> msg.QQWalletAioElem @@ -9836,6 +9965,18 @@ func file_pb_msg_msg_proto_init() { } } file_pb_msg_msg_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgElemInfoServtype37); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pb_msg_msg_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ElemFlags2_Inst); i { case 0: return &v.state @@ -9854,7 +9995,7 @@ func file_pb_msg_msg_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pb_msg_msg_proto_rawDesc, NumEnums: 1, - NumMessages: 76, + NumMessages: 77, NumExtensions: 0, NumServices: 0, }, diff --git a/client/pb/msg/msg.proto b/client/pb/msg/msg.proto index 92bb34c5..57098a31 100644 --- a/client/pb/msg/msg.proto +++ b/client/pb/msg/msg.proto @@ -855,3 +855,15 @@ message PbPushMsg { optional uint32 generalFlag = 9; optional uint64 bindUin = 10; } + +message MsgElemInfo_servtype37 { + optional bytes packid = 1; + optional bytes stickerid = 2; + optional uint32 qsid = 3; + optional uint32 sourcetype = 4; + optional uint32 stickertype = 5; + optional bytes resultid = 6; + optional bytes text = 7; + optional bytes surpriseid = 8; + optional uint32 randomtype = 9; +} diff --git a/message/elements.go b/message/elements.go index b8577eaa..4c7a0fb8 100644 --- a/message/elements.go +++ b/message/elements.go @@ -101,6 +101,10 @@ type MusicShareElement struct { MusicUrl string // 音乐播放链接 } +type AnimatedSticker struct { + ID int32 +} + type RedBagMessageType int // /com/tencent/mobileqq/data/MessageForQQWalletMsg.java @@ -270,3 +274,7 @@ func (e *MusicShareElement) Type() ElementType { func (e *RedBagElement) Type() ElementType { return RedBag } + +func (e *AnimatedSticker) Type() ElementType { + return Face +} diff --git a/message/face.go b/message/face.go index b874b9cd..9740bcda 100644 --- a/message/face.go +++ b/message/face.go @@ -258,3 +258,20 @@ var faceMap = map[int]string{ 131: "街舞", 276: "辣椒酱", } + +var stickerMap = map[int]string{ + 311: "1", + 312: "2", + 313: "3", + 314: "4", + 315: "5", + 316: "6", + 317: "7", + 318: "8", + 319: "9", + 320: "10", + 321: "11", + 324: "12", + 325: "14", + 326: "15", +} diff --git a/message/generate.go b/message/generate.go index 776117a3..7eeb6490 100644 --- a/message/generate.go +++ b/message/generate.go @@ -17,13 +17,20 @@ import ( const faceDownloadUrl = `https://down.qq.com/qqface/config/face_config2021071501.zip?mType=Other` //? 好像是会自动更新的 +type ani struct { + QSid string + StickerID string +} + type config struct { SystemFace []face `json:"sysface"` + Stickers []ani `json:"-"` } type face struct { - QSid string `json:"QSid"` - QDes string `json:"QDes"` + QSid string `json:"QSid"` + QDes string `json:"QDes"` + AniStickerId string `json:"AniStickerId"` } const codeTemplate = `// Code generated by message/generate.go DO NOT EDIT. @@ -34,6 +41,11 @@ var faceMap = map[int]string{ {{range .SystemFace}} {{.QSid}}: "{{.QDes}}", {{end}} } + +var stickerMap = map[int]string{ +{{range .Stickers}} {{.QSid}}: "{{.StickerID}}", +{{end}} +} ` func main() { @@ -50,8 +62,14 @@ func main() { data, _ := io.ReadAll(file) faceConfig := config{} _ = json.Unmarshal(data, &faceConfig) - for i := range faceConfig.SystemFace { + for i, sysface := range faceConfig.SystemFace { faceConfig.SystemFace[i].QDes = strings.TrimPrefix(faceConfig.SystemFace[i].QDes, "/") + if sysface.AniStickerId != "" { + faceConfig.Stickers = append(faceConfig.Stickers, ani{ + Qsid: sysface.QSid, + StickerID: sysface.AniStickerId, + }) + } } tmpl, _ := template.New("template").Parse(codeTemplate) buffer := &bytes.Buffer{} diff --git a/message/pack.go b/message/pack.go index b3b0a9f0..0a696206 100644 --- a/message/pack.go +++ b/message/pack.go @@ -2,6 +2,7 @@ package message import ( "encoding/hex" + "fmt" "google.golang.org/protobuf/proto" @@ -152,3 +153,35 @@ func (e *ShortVideoElement) Pack() (r []*msg.Elem) { r = append(r, &msg.Elem{VideoFile: video}) return } + +func (e *AnimatedSticker) Pack() []*msg.Elem { + name := "/" + faceMap[int(e.ID)] + pbElem, _ := proto.Marshal(&msg.MsgElemInfoServtype37{ + Packid: []byte("1"), + Stickerid: []byte(stickerMap[int(e.ID)]), + Qsid: proto.Uint32(uint32(e.ID)), + Sourcetype: proto.Uint32(1), + Stickertype: proto.Uint32(1), + Resultid: []byte{}, + Text: []byte(name), + Surpriseid: []byte{}, + Randomtype: proto.Uint32(1), + }) + common := &msg.Elem{ + CommonElem: &msg.CommonElem{ + ServiceType: proto.Int32(37), + PbElem: pbElem, + BusinessType: proto.Int32(1), + }, + } + + pbReverse, _ := proto.Marshal(&msg.Text{Str: proto.String(fmt.Sprintf("[%s]请使用最新版手机QQ体验新功能", faceMap[int(e.ID)]))}) + text := &msg.Elem{ + Text: &msg.Text{ + Str: &name, + PbReserve: pbReverse, + }, + } + + return []*msg.Elem{common, text} +}