diff --git a/message/elements.go b/message/elements.go index a3390c8d..6f8764f0 100644 --- a/message/elements.go +++ b/message/elements.go @@ -19,6 +19,11 @@ type ( SubType AtType } + FaceElement struct { + FaceID uint16 + isLargeFace bool + } + ReplyElement struct { ReplySeq int32 Sender uint64 @@ -79,6 +84,10 @@ func (e *AtElement) Type() ElementType { return At } +func (e *FaceElement) Type() ElementType { + return Face +} + func (e *GroupImageElement) Type() ElementType { return Image } @@ -121,6 +130,34 @@ func (e *AtElement) BuildElement() *message.Elem { }} } +func (e *FaceElement) BuildElement() *message.Elem { + faceId := int32(e.FaceID) + if e.isLargeFace { + qFace := message.QFaceExtra{ + Field1: proto.Some("1"), + Field2: proto.Some("8"), + FaceId: proto.Some(faceId), + Field4: proto.Some(int32(1)), + Field5: proto.Some(int32(1)), + Field6: proto.Some(""), + Preview: proto.Some(""), + Field9: proto.Some(int32(1)), + } + qFaceData, _ := proto.Marshal(&qFace) + return &message.Elem{ + CommonElem: &message.CommonElem{ + ServiceType: 37, + PbElem: qFaceData, + BusinessType: 1, + }, + } + } else { + return &message.Elem{ + Face: &message.Face{Index: proto.Some(faceId)}, + } + } +} + func (e *GroupImageElement) BuildElement() *message.Elem { return nil } diff --git a/message/message.go b/message/message.go index 4d15ed5d..5e3d02eb 100644 --- a/message/message.go +++ b/message/message.go @@ -7,6 +7,7 @@ import ( "github.com/LagrangeDev/LagrangeGo/packets/pb/message" "github.com/LagrangeDev/LagrangeGo/utils/binary" + "github.com/LagrangeDev/LagrangeGo/utils/proto" ) type IMessage interface { @@ -159,6 +160,30 @@ func parseMessageElements(msg []*message.Elem) []IMessageElement { } } + if elem.Face != nil { + if len(elem.Face.Old) > 0 { + faceId := elem.Face.Index + if faceId.IsSome() { + res = append(res, &FaceElement{FaceID: uint16(faceId.Unwrap())}) + } + } else if elem.CommonElem.ServiceType == 37 && elem.CommonElem.PbElem != nil { + qFace := message.QFaceExtra{} + err := proto.Unmarshal(elem.CommonElem.PbElem, &qFace) + if err == nil { + faceId := qFace.FaceId + if faceId.IsSome() { + res = append(res, &FaceElement{FaceID: uint16(faceId.Unwrap()), isLargeFace: true}) + } + } + } else if elem.CommonElem.ServiceType == 33 && elem.CommonElem.PbElem != nil { + qFace := message.QSmallFaceExtra{} + err := proto.Unmarshal(elem.CommonElem.PbElem, &qFace) + if err == nil { + res = append(res, &FaceElement{FaceID: uint16(qFace.FaceId), isLargeFace: false}) + } + } + } + if elem.VideoFile != nil { return []IMessageElement{ &ShortVideoElement{ @@ -235,6 +260,13 @@ func (msg *GroupMessage) ToString() (res string) { strBuilder.WriteString("[Reply: ") strBuilder.WriteString(strconv.FormatInt(int64(e.ReplySeq), 10)) strBuilder.WriteString("]") + case *FaceElement: + strBuilder.WriteString("[Face: ") + strBuilder.WriteString(strconv.FormatInt(int64(e.FaceID), 10)) + if e.isLargeFace { + strBuilder.WriteString(", isLargeFace: true]") + } + strBuilder.WriteString("]") } } res = strBuilder.String() @@ -250,6 +282,12 @@ func ToReadableString(m []IMessageElement) string { sb.WriteString("[图片]") case *AtElement: sb.WriteString(e.Display) + case *ReplyElement: + sb.WriteString("[回复]") + case *FaceElement: + sb.WriteString("[表情:") + sb.WriteString(strconv.FormatInt(int64(e.FaceID), 10)) + sb.WriteString("]") } } return sb.String() diff --git a/packets/pb/message/element.pb.go b/packets/pb/message/element.pb.go index 65bb1dcb..ac7ef722 100644 --- a/packets/pb/message/element.pb.go +++ b/packets/pb/message/element.pb.go @@ -398,3 +398,10 @@ type QFaceExtra struct { Field9 proto.Option[int32] `protobuf:"varint,9,opt"` _ [0]func() } + +type QSmallFaceExtra struct { + FaceId uint32 `protobuf:"varint,1,opt"` + Preview string `protobuf:"bytes,2,opt"` + Preview2 string `protobuf:"bytes,3,opt"` + _ [0]func() +} diff --git a/packets/pb/message/element.proto b/packets/pb/message/element.proto index 0d36eb3e..afdfe475 100644 --- a/packets/pb/message/element.proto +++ b/packets/pb/message/element.proto @@ -350,7 +350,7 @@ message VideoFile { repeated bytes BytesThumbFileUrls = 20; repeated bytes BytesVideoFileUrls = 21; int32 ThumbDownloadFlag = 22; - int32 VideoDownloadFlag =23; + int32 VideoDownloadFlag = 23; bytes PbReserve = 24; } @@ -386,3 +386,8 @@ message QFaceExtra { optional int32 Field9 = 9; } +message QSmallFaceExtra { + uint32 FaceId = 1; + string Preview = 2; + string Preview2 = 3; +} \ No newline at end of file