1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

Merge pull request #118 from wdvxdr1123/patch/essence_msg

feat essence msg operation
This commit is contained in:
Mrs4s 2021-02-02 21:59:46 +08:00 committed by GitHub
commit 553229fea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 813 additions and 98 deletions

View File

@ -558,7 +558,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
TargetUin: target,
Time: t,
})
case 0x10, 0x11, 0x14: // group notify msg
case 0x10, 0x11, 0x14, 0x15: // group notify msg
r.ReadByte()
b := notify.NotifyMsgBody{}
_ = proto.Unmarshal(r.ReadAvailable(), &b)
@ -588,6 +588,20 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
})
}
}
if b.QqGroupDigestMsg != nil {
var digest = b.QqGroupDigestMsg
c.dispatchGroupDigestEvent(&GroupDigestEvent{
GroupCode: int64(digest.GroupCode),
MessageID: int32(digest.Seq),
InternalMessageID: int32(digest.Random),
OperationType: digest.OpType,
OperateTime: digest.OpTime,
SenderUin: int64(digest.Sender),
OperatorUin: int64(digest.DigestOper),
SenderNick: string(digest.SenderNick),
OperatorNick: string(digest.OperNick),
})
}
}
}
if m.MsgType == 528 {

View File

@ -162,6 +162,32 @@ type (
DownloadUrl string
}
// GroupDigest 群精华消息
GroupDigest struct {
GroupCode string `json:"group_code"`
MessageID uint32 `json:"msg_seq"`
InternalMessageID uint32 `json:"msg_random"`
SenderUin string `json:"sender_uin"`
SenderNick string `json:"sender_nick"`
SenderTime int64 `json:"sender_time"`
AddDigestUin string `json:"add_digest_uin"`
AddDigestNick string `json:"add_digest_nick"`
AddDigestTime int64 `json:"add_digest_time"`
}
// GroupDigestEvent 群精华消息 不知道tx为什么搞两种名字
GroupDigestEvent struct {
GroupCode int64
MessageID int32
InternalMessageID int32
OperationType int32 // 1 -> 设置精华消息, 2 -> 移除精华消息
OperateTime uint32
SenderUin int64
OperatorUin int64
SenderNick string
OperatorNick string
}
OcrResponse struct {
Texts []*TextDetection `json:"texts"`
Language string `json:"language"`

View File

@ -32,6 +32,7 @@ type eventHandlers struct {
friendNotifyHandlers []func(*QQClient, INotifyEvent)
offlineFileHandlers []func(*QQClient, *OfflineFileEvent)
otherClientStatusChangedHandlers []func(*QQClient, *OtherClientStatusChangedEvent)
groupDigestHandlers []func(*QQClient, *GroupDigestEvent)
groupMessageReceiptHandlers sync.Map
}
@ -135,6 +136,11 @@ func (c *QQClient) OnFriendNotify(f func(*QQClient, INotifyEvent)) {
c.eventHandlers.friendNotifyHandlers = append(c.eventHandlers.friendNotifyHandlers, f)
}
// OnGroupDigest 群精华消息事件注册
func (c *QQClient) OnGroupDigest(f func(*QQClient, *GroupDigestEvent)) {
c.eventHandlers.groupDigestHandlers = append(c.eventHandlers.groupDigestHandlers, f)
}
func NewUinFilterPrivate(uin int64) func(*message.PrivateMessage) bool {
return func(msg *message.PrivateMessage) bool {
return msg.Sender.Uin == uin
@ -387,6 +393,17 @@ func (c *QQClient) dispatchOtherClientStatusChangedEvent(e *OtherClientStatusCha
}
}
func (c *QQClient) dispatchGroupDigestEvent(e *GroupDigestEvent) {
if e == nil {
return
}
for _, f := range c.eventHandlers.groupDigestHandlers {
cover(func() {
f(c, e)
})
}
}
func (c *QQClient) dispatchLogEvent(e *LogEvent) {
if e == nil {
return

View File

@ -1,8 +1,14 @@
package client
import (
"bytes"
"encoding/base64"
"fmt"
"math"
"math/rand"
"strconv"
"time"
"github.com/Mrs4s/MiraiGo/client/pb/longmsg"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
@ -10,11 +16,9 @@ import (
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/protocol/packets"
"github.com/Mrs4s/MiraiGo/utils"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
"math"
"math/rand"
"time"
)
func init() {
@ -22,6 +26,8 @@ func init() {
decoders["MessageSvc.PbSendMsg"] = decodeMsgSendResponse
decoders["MessageSvc.PbGetGroupMsg"] = decodeGetGroupMsgResponse
decoders["OidbSvc.0x8a7_0"] = decodeAtAllRemainResponse
decoders["OidbSvc.0xeac_1"] = decodeEssenceMsgResponse
decoders["OidbSvc.0xeac_2"] = decodeEssenceMsgResponse
}
// SendGroupMessage 发送群消息
@ -520,3 +526,73 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
}
return g
}
// SetEssenceMessage 设为群精华消息
func (c *QQClient) SetEssenceMessage(groupCode int64, msgId, msgInternalId int32) error {
r, err := c.sendAndWait(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgId), uint32(msgInternalId), 1))
if err != nil {
return errors.Wrap(err, "set essence msg network")
}
rsp := r.(*oidb.EACRspBody)
if rsp.GetErrorCode() != 0 {
return errors.New(rsp.GetWording())
}
return nil
}
// DeleteEssenceMessage 移出群精华消息
func (c *QQClient) DeleteEssenceMessage(groupCode int64, msgId, msgInternalId int32) error {
r, err := c.sendAndWait(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgId), uint32(msgInternalId), 2))
if err != nil {
return errors.Wrap(err, "set essence msg networ")
}
rsp := r.(*oidb.EACRspBody)
if rsp.GetErrorCode() != 0 {
return errors.New(rsp.GetWording())
}
return nil
}
func (c *QQClient) buildEssenceMsgOperatePacket(groupCode int64, msgSeq, msgRand, opType uint32) (uint16, []byte) {
seq := c.nextSeq()
commandName := "OidbSvc.0xeac_" + strconv.FormatInt(int64(opType), 10)
payload := c.packOIDBPackageProto(3756, int32(opType), &oidb.EACReqBody{ // serviceType 2 取消
GroupCode: proto.Uint64(uint64(groupCode)),
Seq: proto.Uint32(msgSeq),
Random: proto.Uint32(msgRand),
})
packet := packets.BuildUniPacket(c.Uin, seq, commandName, 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
// OidbSvc.0xeac_1/2
func decodeEssenceMsgResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
pkg := oidb.OIDBSSOPkg{}
rsp := &oidb.EACRspBody{}
if err := proto.Unmarshal(payload, &pkg); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
if err := proto.Unmarshal(pkg.Bodybuffer, rsp); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
return rsp, nil
}
// GetGroupEssenceMsgList 获取群精华消息列表
func (c *QQClient) GetGroupEssenceMsgList(groupCode int64) ([]GroupDigest, error) {
essenceURL := "https://qun.qq.com/essence/index?gc=" + strconv.FormatInt(groupCode, 10) + "&_wv=3&_wwv=128&_wvx=2&_wvxBclr=f5f6fa"
rsp, err := utils.HttpGetBytes(essenceURL, c.getCookiesWithDomain("qun.qq.com"))
if err != nil {
return nil, errors.Wrap(err, "get essence msg network error")
}
rsp = rsp[bytes.Index(rsp, []byte("window.__INITIAL_STATE__={"))+25:]
rsp = rsp[:bytes.Index(rsp, []byte("</script>"))]
var data = &struct {
List []GroupDigest `json:"msgList"`
}{}
err = json.Unmarshal(rsp, data)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal json")
}
return data.List, nil
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.11.4
// protoc v3.13.0
// source: group0x857.proto
package notify
@ -34,6 +34,7 @@ type NotifyMsgBody struct {
OptMsgRedTips *RedGrayTipsInfo `protobuf:"bytes,9,opt,name=optMsgRedTips,proto3" json:"optMsgRedTips,omitempty"`
OptMsgRecall *MessageRecallReminder `protobuf:"bytes,11,opt,name=optMsgRecall,proto3" json:"optMsgRecall,omitempty"`
OptGeneralGrayTip *GeneralGrayTipInfo `protobuf:"bytes,26,opt,name=optGeneralGrayTip,proto3" json:"optGeneralGrayTip,omitempty"`
QqGroupDigestMsg *QQGroupDigestMsg `protobuf:"bytes,33,opt,name=qqGroupDigestMsg,proto3" json:"qqGroupDigestMsg,omitempty"`
ServiceType int32 `protobuf:"varint,13,opt,name=serviceType,proto3" json:"serviceType,omitempty"`
}
@ -97,6 +98,13 @@ func (x *NotifyMsgBody) GetOptGeneralGrayTip() *GeneralGrayTipInfo {
return nil
}
func (x *NotifyMsgBody) GetQqGroupDigestMsg() *QQGroupDigestMsg {
if x != nil {
return x.QqGroupDigestMsg
}
return nil
}
func (x *NotifyMsgBody) GetServiceType() int32 {
if x != nil {
return x.ServiceType
@ -642,11 +650,138 @@ func (x *RedGrayTipsInfo) GetHideFlag() uint32 {
return 0
}
type QQGroupDigestMsg struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
GroupCode uint64 `protobuf:"varint,1,opt,name=groupCode,proto3" json:"groupCode,omitempty"`
Seq uint32 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq,omitempty"`
Random uint32 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"`
OpType int32 `protobuf:"varint,4,opt,name=opType,proto3" json:"opType,omitempty"`
Sender uint64 `protobuf:"varint,5,opt,name=sender,proto3" json:"sender,omitempty"`
DigestOper uint64 `protobuf:"varint,6,opt,name=digestOper,proto3" json:"digestOper,omitempty"`
OpTime uint32 `protobuf:"varint,7,opt,name=opTime,proto3" json:"opTime,omitempty"`
LastestMsgSeq uint32 `protobuf:"varint,8,opt,name=lastestMsgSeq,proto3" json:"lastestMsgSeq,omitempty"`
OperNick []byte `protobuf:"bytes,9,opt,name=operNick,proto3" json:"operNick,omitempty"`
SenderNick []byte `protobuf:"bytes,10,opt,name=senderNick,proto3" json:"senderNick,omitempty"`
ExtInfo int32 `protobuf:"varint,11,opt,name=extInfo,proto3" json:"extInfo,omitempty"`
}
func (x *QQGroupDigestMsg) Reset() {
*x = QQGroupDigestMsg{}
if protoimpl.UnsafeEnabled {
mi := &file_group0x857_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *QQGroupDigestMsg) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*QQGroupDigestMsg) ProtoMessage() {}
func (x *QQGroupDigestMsg) ProtoReflect() protoreflect.Message {
mi := &file_group0x857_proto_msgTypes[7]
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 QQGroupDigestMsg.ProtoReflect.Descriptor instead.
func (*QQGroupDigestMsg) Descriptor() ([]byte, []int) {
return file_group0x857_proto_rawDescGZIP(), []int{7}
}
func (x *QQGroupDigestMsg) GetGroupCode() uint64 {
if x != nil {
return x.GroupCode
}
return 0
}
func (x *QQGroupDigestMsg) GetSeq() uint32 {
if x != nil {
return x.Seq
}
return 0
}
func (x *QQGroupDigestMsg) GetRandom() uint32 {
if x != nil {
return x.Random
}
return 0
}
func (x *QQGroupDigestMsg) GetOpType() int32 {
if x != nil {
return x.OpType
}
return 0
}
func (x *QQGroupDigestMsg) GetSender() uint64 {
if x != nil {
return x.Sender
}
return 0
}
func (x *QQGroupDigestMsg) GetDigestOper() uint64 {
if x != nil {
return x.DigestOper
}
return 0
}
func (x *QQGroupDigestMsg) GetOpTime() uint32 {
if x != nil {
return x.OpTime
}
return 0
}
func (x *QQGroupDigestMsg) GetLastestMsgSeq() uint32 {
if x != nil {
return x.LastestMsgSeq
}
return 0
}
func (x *QQGroupDigestMsg) GetOperNick() []byte {
if x != nil {
return x.OperNick
}
return nil
}
func (x *QQGroupDigestMsg) GetSenderNick() []byte {
if x != nil {
return x.SenderNick
}
return nil
}
func (x *QQGroupDigestMsg) GetExtInfo() int32 {
if x != nil {
return x.ExtInfo
}
return 0
}
var File_group0x857_proto protoreflect.FileDescriptor
var file_group0x857_proto_rawDesc = []byte{
0x0a, 0x10, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x30, 0x78, 0x38, 0x35, 0x37, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0xa2, 0x02, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x73, 0x67,
0x74, 0x6f, 0x22, 0xe1, 0x02, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x73, 0x67,
0x42, 0x6f, 0x64, 0x79, 0x12, 0x38, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x4d, 0x73, 0x67, 0x47, 0x72,
0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41,
0x49, 0x4f, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e,
@ -662,89 +797,113 @@ var file_group0x857_proto_rawDesc = []byte{
0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x11, 0x6f, 0x70, 0x74, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x47, 0x72,
0x61, 0x79, 0x54, 0x69, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x54, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x0f, 0x41, 0x49, 0x4f, 0x47,
0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x0a, 0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x12, 0x14, 0x0a,
0x05, 0x62, 0x72, 0x69, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x72,
0x69, 0x65, 0x66, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x55,
0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76,
0x65, 0x72, 0x55, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x69, 0x61, 0x6f, 0x41,
0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72,
0x65, 0x6c, 0x69, 0x61, 0x6f, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x22, 0x87, 0x02,
0x0a, 0x12, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, 0x54, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, 0x54, 0x79, 0x70, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x73, 0x69, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
0x52, 0x06, 0x62, 0x75, 0x73, 0x69, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x74, 0x72, 0x6c,
0x46, 0x6c, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x74, 0x72, 0x6c,
0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x32, 0x63, 0x54, 0x79, 0x70, 0x65, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x32, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20,
0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65,
0x12, 0x18, 0x0a, 0x07, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
0x04, 0x52, 0x07, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x0d, 0x6d, 0x73,
0x67, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x07, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0b, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x0d,
0x6d, 0x73, 0x67, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x18, 0x0a,
0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x36, 0x0a, 0x0a, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,
0xff, 0x01, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x61, 0x6c,
0x6c, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6e,
0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e,
0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x61, 0x6c,
0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x14, 0x2e, 0x52, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64,
0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x69, 0x6e,
0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0f, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
0x74, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x64, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x64, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x54,
0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x70, 0x54, 0x79, 0x70,
0x65, 0x22, 0xab, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12,
0x1c, 0x0a, 0x09, 0x6d, 0x73, 0x67, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07,
0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x46, 0x6c,
0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x46, 0x6c, 0x61,
0x67, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x55, 0x69, 0x6e, 0x18, 0x06,
0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x55, 0x69, 0x6e, 0x22,
0xbf, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x64, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74,
0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x69, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x69,
0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x55, 0x69, 0x6e,
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72,
0x55, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x69, 0x63,
0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11,
0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
0x74, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x52, 0x69, 0x63,
0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13,
0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x74,
0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52, 0x07,
0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x75, 0x63, 0x6b, 0x79,
0x46, 0x6c, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x75, 0x63, 0x6b,
0x79, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x69, 0x64, 0x65, 0x46, 0x6c, 0x61,
0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x68, 0x69, 0x64, 0x65, 0x46, 0x6c, 0x61,
0x67, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x62, 0x06, 0x70,
0x61, 0x79, 0x54, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x10, 0x71, 0x71, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x11, 0x2e, 0x51, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4d,
0x73, 0x67, 0x52, 0x10, 0x71, 0x71, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x69, 0x67, 0x65, 0x73,
0x74, 0x4d, 0x73, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54,
0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x0f, 0x41, 0x49, 0x4f, 0x47, 0x72,
0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x68,
0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a,
0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e,
0x74, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x62, 0x72, 0x69, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x72, 0x69,
0x65, 0x66, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x55, 0x69,
0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x55, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x69, 0x61, 0x6f, 0x41, 0x64,
0x6d, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65,
0x6c, 0x69, 0x61, 0x6f, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x22, 0x87, 0x02, 0x0a,
0x12, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, 0x54, 0x79, 0x70, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, 0x54, 0x79, 0x70, 0x65, 0x12,
0x16, 0x0a, 0x06, 0x62, 0x75, 0x73, 0x69, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x06, 0x62, 0x75, 0x73, 0x69, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x74, 0x72, 0x6c, 0x46,
0x6c, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x74, 0x72, 0x6c, 0x46,
0x6c, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x32, 0x63, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x32, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a,
0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12,
0x18, 0x0a, 0x07, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04,
0x52, 0x07, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x0d, 0x6d, 0x73, 0x67,
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0b, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x0d, 0x6d,
0x73, 0x67, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x18, 0x0a, 0x07,
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x36, 0x0a, 0x0a, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xff,
0x01, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x61, 0x6c, 0x6c,
0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69,
0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x69,
0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x61, 0x6c, 0x6c,
0x65, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x14, 0x2e, 0x52, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x4d,
0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64,
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0f, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x64, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x64, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72,
0x6f, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x54, 0x79,
0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x70, 0x54, 0x79, 0x70, 0x65,
0x22, 0xab, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18,
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69,
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x6d, 0x73, 0x67, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d,
0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x46, 0x6c, 0x61,
0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x46, 0x6c, 0x61, 0x67,
0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x55, 0x69, 0x6e, 0x18, 0x06, 0x20,
0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x55, 0x69, 0x6e, 0x22, 0xbf,
0x02, 0x0a, 0x0f, 0x52, 0x65, 0x64, 0x47, 0x72, 0x61, 0x79, 0x54, 0x69, 0x70, 0x73, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x4c, 0x61, 0x74, 0x65,
0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x69, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x69, 0x6e,
0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x55, 0x69, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x55,
0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68,
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
0x12, 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68,
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72,
0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x52, 0x69, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65,
0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52, 0x07, 0x6d,
0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x75, 0x63, 0x6b, 0x79, 0x46,
0x6c, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x75, 0x63, 0x6b, 0x79,
0x46, 0x6c, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x69, 0x64, 0x65, 0x46, 0x6c, 0x61, 0x67,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x68, 0x69, 0x64, 0x65, 0x46, 0x6c, 0x61, 0x67,
0x22, 0xbe, 0x02, 0x0a, 0x10, 0x51, 0x51, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x69, 0x67, 0x65,
0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f,
0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43,
0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x16, 0x0a,
0x06, 0x6f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f,
0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18,
0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a,
0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x12, 0x16, 0x0a,
0x06, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f,
0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x73, 0x74,
0x4d, 0x73, 0x67, 0x53, 0x65, 0x71, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6c, 0x61,
0x73, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x6f,
0x70, 0x65, 0x72, 0x4e, 0x69, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f,
0x70, 0x65, 0x72, 0x4e, 0x69, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x4e, 0x69, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x65, 0x6e,
0x64, 0x65, 0x72, 0x4e, 0x69, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x49, 0x6e,
0x66, 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66,
0x6f, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
@ -760,7 +919,7 @@ func file_group0x857_proto_rawDescGZIP() []byte {
return file_group0x857_proto_rawDescData
}
var file_group0x857_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_group0x857_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_group0x857_proto_goTypes = []interface{}{
(*NotifyMsgBody)(nil), // 0: NotifyMsgBody
(*AIOGrayTipsInfo)(nil), // 1: AIOGrayTipsInfo
@ -769,19 +928,21 @@ var file_group0x857_proto_goTypes = []interface{}{
(*MessageRecallReminder)(nil), // 4: MessageRecallReminder
(*RecalledMessageMeta)(nil), // 5: RecalledMessageMeta
(*RedGrayTipsInfo)(nil), // 6: RedGrayTipsInfo
(*QQGroupDigestMsg)(nil), // 7: QQGroupDigestMsg
}
var file_group0x857_proto_depIdxs = []int32{
1, // 0: NotifyMsgBody.optMsgGrayTips:type_name -> AIOGrayTipsInfo
6, // 1: NotifyMsgBody.optMsgRedTips:type_name -> RedGrayTipsInfo
4, // 2: NotifyMsgBody.optMsgRecall:type_name -> MessageRecallReminder
2, // 3: NotifyMsgBody.optGeneralGrayTip:type_name -> GeneralGrayTipInfo
3, // 4: GeneralGrayTipInfo.msgTemplParam:type_name -> TemplParam
5, // 5: MessageRecallReminder.recalledMsgList:type_name -> RecalledMessageMeta
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
7, // 4: NotifyMsgBody.qqGroupDigestMsg:type_name -> QQGroupDigestMsg
3, // 5: GeneralGrayTipInfo.msgTemplParam:type_name -> TemplParam
5, // 6: MessageRecallReminder.recalledMsgList:type_name -> RecalledMessageMeta
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_group0x857_proto_init() }
@ -874,6 +1035,18 @@ func file_group0x857_proto_init() {
return nil
}
}
file_group0x857_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*QQGroupDigestMsg); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -881,7 +1054,7 @@ func file_group0x857_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_group0x857_proto_rawDesc,
NumEnums: 0,
NumMessages: 7,
NumMessages: 8,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -7,6 +7,7 @@ message NotifyMsgBody {
RedGrayTipsInfo optMsgRedTips = 9;
MessageRecallReminder optMsgRecall = 11;
GeneralGrayTipInfo optGeneralGrayTip = 26;
QQGroupDigestMsg qqGroupDigestMsg = 33;
int32 serviceType = 13;
}
@ -65,3 +66,17 @@ message RedGrayTipsInfo {
uint32 luckyFlag = 8;
uint32 hideFlag = 9;
}
message QQGroupDigestMsg {
uint64 groupCode = 1;
uint32 seq = 2;
uint32 random = 3;
int32 opType = 4;
uint64 sender = 5;
uint64 digestOper = 6;
uint32 opTime = 7;
uint32 lastestMsgSeq = 8;
bytes operNick = 9;
bytes senderNick = 10;
int32 extInfo = 11;
}

View File

@ -0,0 +1,258 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// source: oidb0xeac.proto
package oidb
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type EACReqBody struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
GroupCode *uint64 `protobuf:"varint,1,opt,name=groupCode" json:"groupCode,omitempty"`
Seq *uint32 `protobuf:"varint,2,opt,name=seq" json:"seq,omitempty"`
Random *uint32 `protobuf:"varint,3,opt,name=random" json:"random,omitempty"`
}
func (x *EACReqBody) Reset() {
*x = EACReqBody{}
if protoimpl.UnsafeEnabled {
mi := &file_oidb0xeac_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EACReqBody) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EACReqBody) ProtoMessage() {}
func (x *EACReqBody) ProtoReflect() protoreflect.Message {
mi := &file_oidb0xeac_proto_msgTypes[0]
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 EACReqBody.ProtoReflect.Descriptor instead.
func (*EACReqBody) Descriptor() ([]byte, []int) {
return file_oidb0xeac_proto_rawDescGZIP(), []int{0}
}
func (x *EACReqBody) GetGroupCode() uint64 {
if x != nil && x.GroupCode != nil {
return *x.GroupCode
}
return 0
}
func (x *EACReqBody) GetSeq() uint32 {
if x != nil && x.Seq != nil {
return *x.Seq
}
return 0
}
func (x *EACReqBody) GetRandom() uint32 {
if x != nil && x.Random != nil {
return *x.Random
}
return 0
}
type EACRspBody struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Wording *string `protobuf:"bytes,1,opt,name=wording" json:"wording,omitempty"`
DigestUin *uint64 `protobuf:"varint,2,opt,name=digestUin" json:"digestUin,omitempty"`
DigestTime *uint32 `protobuf:"varint,3,opt,name=digestTime" json:"digestTime,omitempty"`
//optional DigestMsg msg = 4;
ErrorCode *uint32 `protobuf:"varint,10,opt,name=errorCode" json:"errorCode,omitempty"`
}
func (x *EACRspBody) Reset() {
*x = EACRspBody{}
if protoimpl.UnsafeEnabled {
mi := &file_oidb0xeac_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EACRspBody) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EACRspBody) ProtoMessage() {}
func (x *EACRspBody) ProtoReflect() protoreflect.Message {
mi := &file_oidb0xeac_proto_msgTypes[1]
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 EACRspBody.ProtoReflect.Descriptor instead.
func (*EACRspBody) Descriptor() ([]byte, []int) {
return file_oidb0xeac_proto_rawDescGZIP(), []int{1}
}
func (x *EACRspBody) GetWording() string {
if x != nil && x.Wording != nil {
return *x.Wording
}
return ""
}
func (x *EACRspBody) GetDigestUin() uint64 {
if x != nil && x.DigestUin != nil {
return *x.DigestUin
}
return 0
}
func (x *EACRspBody) GetDigestTime() uint32 {
if x != nil && x.DigestTime != nil {
return *x.DigestTime
}
return 0
}
func (x *EACRspBody) GetErrorCode() uint32 {
if x != nil && x.ErrorCode != nil {
return *x.ErrorCode
}
return 0
}
var File_oidb0xeac_proto protoreflect.FileDescriptor
var file_oidb0xeac_proto_rawDesc = []byte{
0x0a, 0x0f, 0x6f, 0x69, 0x64, 0x62, 0x30, 0x78, 0x65, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x54, 0x0a, 0x0a, 0x45, 0x41, 0x43, 0x52, 0x65, 0x71, 0x42, 0x6f, 0x64, 0x79, 0x12,
0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a,
0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12,
0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x82, 0x01, 0x0a, 0x0a, 0x45, 0x41, 0x43, 0x52,
0x73, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x6f, 0x72, 0x64, 0x69, 0x6e,
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67,
0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x55, 0x69, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x55, 0x69, 0x6e, 0x12, 0x1e,
0x0a, 0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x08, 0x5a, 0x06,
0x2e, 0x3b, 0x6f, 0x69, 0x64, 0x62,
}
var (
file_oidb0xeac_proto_rawDescOnce sync.Once
file_oidb0xeac_proto_rawDescData = file_oidb0xeac_proto_rawDesc
)
func file_oidb0xeac_proto_rawDescGZIP() []byte {
file_oidb0xeac_proto_rawDescOnce.Do(func() {
file_oidb0xeac_proto_rawDescData = protoimpl.X.CompressGZIP(file_oidb0xeac_proto_rawDescData)
})
return file_oidb0xeac_proto_rawDescData
}
var file_oidb0xeac_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_oidb0xeac_proto_goTypes = []interface{}{
(*EACReqBody)(nil), // 0: EACReqBody
(*EACRspBody)(nil), // 1: EACRspBody
}
var file_oidb0xeac_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_oidb0xeac_proto_init() }
func file_oidb0xeac_proto_init() {
if File_oidb0xeac_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_oidb0xeac_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EACReqBody); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_oidb0xeac_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EACRspBody); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_oidb0xeac_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_oidb0xeac_proto_goTypes,
DependencyIndexes: file_oidb0xeac_proto_depIdxs,
MessageInfos: file_oidb0xeac_proto_msgTypes,
}.Build()
File_oidb0xeac_proto = out.File
file_oidb0xeac_proto_rawDesc = nil
file_oidb0xeac_proto_goTypes = nil
file_oidb0xeac_proto_depIdxs = nil
}

View File

@ -0,0 +1,135 @@
syntax = "proto2";
option go_package = ".;oidb";
/*
message ArkMsg {
optional string appName = 1;
optional string json = 2;
}
message BatchReqBody {
optional uint64 groupCode = 1;
repeated MsgInfo msgs = 2;
}
message BatchRspBody {
optional string wording = 1;
optional uint32 errorCode = 2;
optional int32 succCnt = 3;
repeated MsgProcessInfo procInfos = 4;
optional uint32 digestTime = 5;
}
message DigestMsg {
optional uint64 groupCode = 1;
optional uint32 seq = 2;
optional uint32 random = 3;
repeated MsgElem content = 4;
optional uint64 textSize = 5;
optional uint64 picSize = 6;
optional uint64 videoSize = 7;
optional uint64 senderUin = 8;
optional uint32 senderTime = 9;
optional uint64 addDigestUin = 10;
optional uint32 addDigestTime = 11;
optional uint32 startTime = 12;
optional uint32 latestMsgSeq = 13;
optional uint32 opType = 14;
}
message FaceMsg {
optional uint32 index = 1;
optional string text = 2;
}
message GroupFileMsg {
optional bytes fileName = 1;
optional uint32 busId = 2;
optional string fileId = 3;
optional uint64 fileSize = 4;
optional uint64 deadTime = 5;
optional bytes fileSha1 = 6;
optional bytes ext = 7;
optional bytes fileMd5 = 8;
}
message ImageMsg {
optional string md5 = 1;
optional string uuid = 2;
optional uint32 imgType = 3;
optional uint32 fileSize = 4;
optional uint32 width = 5;
optional uint32 height = 6;
optional uint32 fileId = 101;
optional uint32 serverIp = 102;
optional uint32 serverPort = 103;
optional string filePath = 104;
optional string thumbUrl = 201;
optional string originalUrl = 202;
optional string resaveUrl = 203;
}
message MsgElem {
optional uint32 type = 1;
optional TextMsg textMsg = 11;
optional FaceMsg faceMsg = 12;
optional ImageMsg imageMsg = 13;
optional GroupFileMsg groupFileMsg = 14;
optional ShareMsg shareMsg = 15;
optional RichMsg richMsg = 16;
optional ArkMsg arkMsg = 17;
}
message MsgInfo {
optional uint32 seq = 1;
optional uint32 random = 2;
}
message MsgProcessInfo {
optional MsgInfo msg = 1;
optional uint32 errorCode = 2;
optional uint64 digestUin = 3;
optional uint32 digestTime = 4;
}
*/
message EACReqBody {
optional uint64 groupCode = 1;
optional uint32 seq = 2;
optional uint32 random = 3;
}
/*
message RichMsg {
optional uint32 serviceId = 1;
optional string xml = 2;
optional string longMsgResid = 3;
}
*/
message EACRspBody {
optional string wording = 1;
optional uint64 digestUin = 2;
optional uint32 digestTime = 3;
//optional DigestMsg msg = 4;
optional uint32 errorCode = 10;
}
/*
message ShareMsg {
optional string type = 1;
optional string title = 2;
optional string summary = 3;
optional string brief = 4;
optional string url = 5;
optional string pictureUrl = 6;
optional string action = 7;
optional string source = 8;
optional string sourceUrl = 9;
}
message TextMsg {
optional bytes str = 1;
}
*/

View File

@ -8,6 +8,7 @@ import (
"strings"
)
// HttpGetBytes 带 cookie 的 GET 请求
func HttpGetBytes(url, cookie string) ([]byte, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {