1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

refactor: 手动指定decode函数

(cherry picked from commit 13d6711f27a100a6098c478f05d3ae8a32117d94)
This commit is contained in:
wdvxdr 2021-12-25 17:23:44 +08:00
parent 723563415f
commit 435d2fd85f
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
26 changed files with 463 additions and 435 deletions

View File

@ -27,7 +27,7 @@ var (
syncConst2 = rand.Int63()
)
func (c *QQClient) buildLoginPacket() (uint16, []byte) {
func (c *QQClient) buildLoginRequest() *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(9)
@ -91,7 +91,7 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00})))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -99,10 +99,9 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
func (c *QQClient) buildDeviceLockLoginRequest() *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(20)
@ -113,7 +112,7 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T401(c.sig.G))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -121,10 +120,9 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (uint16, []byte) {
func (c *QQClient) buildQRCodeFetchRequest(size, margin, ecLevel uint32) *network.Request {
watch := auth.AndroidWatch.Version()
seq := c.nextSeq()
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
@ -147,7 +145,7 @@ func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (
}))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -155,12 +153,9 @@ func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (
CommandName: "wtlogin.trans_emp",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
version := c.transport.Version
c.transport.Version = auth.AndroidWatch.Version()
func (c *QQClient) buildQRCodeResultQueryRequest(sig []byte) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
w.WriteHex(`0000620000001000000072000000`) // trans header
@ -178,7 +173,7 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by
}))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -186,12 +181,9 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by
CommandName: "wtlogin.trans_emp",
Body: req,
}
payload := c.transport.PackPacket(&req2)
c.transport.Version = version
return seq, payload
}
func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []byte) {
func (c *QQClient) buildQRCodeLoginRequest(t106, t16a, t318 []byte) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(9)
@ -254,7 +246,7 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
w.WriteBytesShort(t318)
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -262,10 +254,9 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byte) {
func (c *QQClient) buildCaptchaRequest(result string, sign []byte) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(2) // sub command
@ -277,7 +268,7 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -285,10 +276,9 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
func (c *QQClient) buildSMSRequest() *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(8)
@ -302,7 +292,7 @@ func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
w.Write(tlv.T197())
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -310,10 +300,9 @@ func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
func (c *QQClient) buildSMSCodeSubmitRequest(code string) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(7)
@ -328,7 +317,7 @@ func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
w.Write(tlv.T198())
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -336,10 +325,9 @@ func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
func (c *QQClient) buildTicketSubmitRequest(ticket string) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(2)
@ -351,7 +339,7 @@ func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -359,10 +347,9 @@ func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
CommandName: "wtlogin.login",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
func (c *QQClient) buildRequestTgtgtNopicsigRequest() *network.Request {
seq := c.nextSeq()
req := binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(15)
@ -423,7 +410,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
Body: req,
}
nreq := network.Request{
return &network.Request{
Type: network.RequestTypeSimple,
EncryptType: network.EncryptTypeEmptyKey,
Uin: c.Uin,
@ -431,10 +418,9 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
CommandName: "wtlogin.exchange_emp",
Body: c.oicq.Marshal(&m),
}
return seq, c.transport.PackPacket(&nreq)
}
func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byte) {
func (c *QQClient) buildRequestChangeSigRequest(mainSigMap uint32) *network.Request {
seq := c.nextSeq()
req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(11)
@ -477,7 +463,7 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
// w.Write(tlv.T202(c.deviceInfo.WifiBSSID, c.deviceInfo.WifiSSID))
}))
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeEmptyKey,
SequenceID: int32(seq),
@ -485,11 +471,10 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
CommandName: "wtlogin.exchange_emp",
Body: req,
}
return seq, c.transport.PackPacket(&req2)
}
// StatSvc.register
func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
func (c *QQClient) buildClientRegisterPacket() *network.Request {
seq := c.nextSeq()
svc := &jce.SvcReqRegister{
ConnType: 0,
@ -532,7 +517,7 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
Status: make(map[string]string),
}
req2 := network.Request{
return &network.Request{
Type: network.RequestTypeLogin,
EncryptType: network.EncryptTypeD2Key,
SequenceID: int32(seq),
@ -540,10 +525,9 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
CommandName: "StatSvc.register",
Body: pkt.ToBytes(),
}
return seq, c.transport.PackPacket(&req2)
}
func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte) {
func (c *QQClient) buildStatusSetPacket(status, extStatus int32) *network.Request {
svc := &jce.SvcReqRegister{
ConnType: 0,
Uin: c.Uin,
@ -576,11 +560,11 @@ func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("StatSvc.SetStatusFromClient", pkt.ToBytes())
return c.uniRequest("StatSvc.SetStatusFromClient", pkt.ToBytes())
}
// ConfigPushSvc.PushResp
func (c *QQClient) buildConfPushRespPacket(t int32, pktSeq int64, jceBuf []byte) (uint16, []byte) {
func (c *QQClient) buildConfPushRespPacket(t int32, pktSeq int64, jceBuf []byte) *network.Request {
req := jce.NewJceWriter()
req.WriteInt32(t, 1)
req.WriteInt64(pktSeq, 2)
@ -596,11 +580,11 @@ func (c *QQClient) buildConfPushRespPacket(t int32, pktSeq int64, jceBuf []byte)
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("ConfigPushSvc.PushResp", pkt.ToBytes())
return c.uniRequest("ConfigPushSvc.PushResp", pkt.ToBytes())
}
// friendlist.getFriendGroupList
func (c *QQClient) buildFriendGroupListRequestPacket(friendStartIndex, friendListCount, groupStartIndex, groupListCount int16) (uint16, []byte) {
func (c *QQClient) buildFriendGroupListRequest(friendStartIndex, friendListCount, groupStartIndex, groupListCount int16) *network.Request {
d50, _ := proto.Marshal(&pb.D50ReqBody{
Appid: 1002,
ReqMusicSwitch: 1,
@ -652,11 +636,11 @@ func (c *QQClient) buildFriendGroupListRequestPacket(friendStartIndex, friendLis
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("friendlist.getFriendGroupList", pkt.ToBytes())
return c.uniRequest("friendlist.getFriendGroupList", pkt.ToBytes())
}
// SummaryCard.ReqSummaryCard
func (c *QQClient) buildSummaryCardRequestPacket(target int64) (uint16, []byte) {
func (c *QQClient) buildSummaryCardRequest(target int64) *network.Request {
seq := c.nextSeq()
packBusinessBuf := func(t int32, buf []byte) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
@ -736,11 +720,11 @@ func (c *QQClient) buildSummaryCardRequestPacket(target int64) (uint16, []byte)
Context: make(map[string]string),
Status: make(map[string]string),
}
return seq, c.uniPacketWithSeq(seq, "SummaryCard.ReqSummaryCard", pkt.ToBytes())
return c.uniPacketWithSeq(seq, "SummaryCard.ReqSummaryCard", pkt.ToBytes())
}
// friendlist.delFriend
func (c *QQClient) buildFriendDeletePacket(target int64) (uint16, []byte) {
func (c *QQClient) buildFriendDeletePacket(target int64) *network.Request {
req := &jce.DelFriendReq{
Uin: c.Uin,
DelUin: target,
@ -759,11 +743,11 @@ func (c *QQClient) buildFriendDeletePacket(target int64) (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("friendlist.delFriend", pkt.ToBytes())
return c.uniRequest("friendlist.delFriend", pkt.ToBytes())
}
// friendlist.GetTroopListReqV2
func (c *QQClient) buildGroupListRequestPacket(vecCookie []byte) (uint16, []byte) {
func (c *QQClient) buildGroupListRequest(vecCookie []byte) *network.Request {
req := &jce.TroopListRequest{
Uin: c.Uin,
GetMSFMsgFlag: 1,
@ -788,11 +772,11 @@ func (c *QQClient) buildGroupListRequestPacket(vecCookie []byte) (uint16, []byte
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("friendlist.GetTroopListReqV2", pkt.ToBytes())
return c.uniRequest("friendlist.GetTroopListReqV2", pkt.ToBytes())
}
// friendlist.GetTroopMemberListReq
func (c *QQClient) buildGroupMemberListRequestPacket(groupUin, groupCode, nextUin int64) (uint16, []byte) {
func (c *QQClient) buildGroupMemberListRequest(groupUin, groupCode, nextUin int64) *network.Request {
req := &jce.TroopMemberListRequest{
Uin: c.Uin,
GroupCode: groupCode,
@ -814,11 +798,11 @@ func (c *QQClient) buildGroupMemberListRequestPacket(groupUin, groupCode, nextUi
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("friendlist.GetTroopMemberListReq", pkt.ToBytes())
return c.uniRequest("friendlist.GetTroopMemberListReq", pkt.ToBytes())
}
// group_member_card.get_group_member_card_info
func (c *QQClient) buildGroupMemberInfoRequestPacket(groupCode, uin int64) (uint16, []byte) {
func (c *QQClient) buildGroupMemberInfoRequest(groupCode, uin int64) *network.Request {
req := &pb.GroupMemberReqBody{
GroupCode: groupCode,
Uin: uin,
@ -827,7 +811,7 @@ func (c *QQClient) buildGroupMemberInfoRequestPacket(groupCode, uin int64) (uint
RichCardNameVer: 1,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("group_member_card.get_group_member_card_info", payload)
return c.uniRequest("group_member_card.get_group_member_card_info", payload)
}
// MessageSvc.PbGetMsg
@ -856,14 +840,15 @@ func (c *QQClient) buildGetMessageRequestPacket(flag msg.SyncFlag, msgTime int64
ServerBuf: EmptyBytes,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbGetMsg", payload)
req2 := c.uniRequest("MessageSvc.PbGetMsg", payload)
return uint16(req2.SequenceID), c.transport.PackPacket(req2)
}
// MessageSvc.PbDeleteMsg
func (c *QQClient) buildDeleteMessageRequestPacket(msg []*pb.MessageItem) (uint16, []byte) {
func (c *QQClient) buildDeleteMessageRequestPacket(msg []*pb.MessageItem) *network.Request {
req := &pb.DeleteMessageRequest{Items: msg}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbDeleteMsg", payload)
return c.uniRequest("MessageSvc.PbDeleteMsg", payload)
}
// OnlinePush.RespPush
@ -890,11 +875,11 @@ func (c *QQClient) buildDeleteOnlinePushPacket(uin int64, svrip int32, pushToken
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacketWithSeq(seq, "OnlinePush.RespPush", pkt.ToBytes())
return c.transport.PackPacket(c.uniPacketWithSeq(seq, "OnlinePush.RespPush", pkt.ToBytes()))
}
// LongConn.OffPicUp
func (c *QQClient) buildOffPicUpPacket(target int64, md5 []byte, size int32) (uint16, []byte) {
func (c *QQClient) buildOffPicUpRequest(target int64, md5 []byte, size int32) *network.Request {
req := &cmd0x352.ReqBody{
Subcmd: proto.Uint32(1),
TryupImgReq: []*cmd0x352.D352TryUpImgReq{
@ -917,11 +902,11 @@ func (c *QQClient) buildOffPicUpPacket(target int64, md5 []byte, size int32) (ui
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("LongConn.OffPicUp", payload)
return c.uniRequest("LongConn.OffPicUp", payload)
}
// ProfileService.Pb.ReqSystemMsgNew.Friend
func (c *QQClient) buildSystemMsgNewFriendPacket() (uint16, []byte) {
func (c *QQClient) buildSystemMsgNewFriendRequest() *network.Request {
req := &structmsg.ReqSystemMsgNew{
MsgNum: 20,
Version: 1000,
@ -936,11 +921,11 @@ func (c *QQClient) buildSystemMsgNewFriendPacket() (uint16, []byte) {
FriendMsgTypeFlag: 1,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ProfileService.Pb.ReqSystemMsgNew.Friend", payload)
return c.uniRequest("ProfileService.Pb.ReqSystemMsgNew.Friend", payload)
}
// friendlist.ModifyGroupCardReq
func (c *QQClient) buildEditGroupTagPacket(groupCode, memberUin int64, newTag string) (uint16, []byte) {
func (c *QQClient) buildEditGroupTagPacket(groupCode, memberUin int64, newTag string) *network.Request {
req := &jce.ModifyGroupCardRequest{
GroupCode: groupCode,
UinInfo: []jce.IJceStruct{
@ -961,11 +946,11 @@ func (c *QQClient) buildEditGroupTagPacket(groupCode, memberUin int64, newTag st
Context: map[string]string{},
Status: map[string]string{},
}
return c.uniPacket("friendlist.ModifyGroupCardReq", pkt.ToBytes())
return c.uniRequest("friendlist.ModifyGroupCardReq", pkt.ToBytes())
}
// OidbSvc.0x8fc_2
func (c *QQClient) buildEditSpecialTitlePacket(groupCode, memberUin int64, newTitle string) (uint16, []byte) {
func (c *QQClient) buildEditSpecialTitlePacket(groupCode, memberUin int64, newTitle string) *network.Request {
body := &oidb.D8FCReqBody{
GroupCode: &groupCode,
MemLevelInfo: []*oidb.D8FCMemberInfo{
@ -979,18 +964,18 @@ func (c *QQClient) buildEditSpecialTitlePacket(groupCode, memberUin int64, newTi
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(2300, 2, b)
return c.uniPacket("OidbSvc.0x8fc_2", payload)
return c.uniRequest("OidbSvc.0x8fc_2", payload)
}
// OidbSvc.0x89a_0
func (c *QQClient) buildGroupOperationPacket(body *oidb.D89AReqBody) (uint16, []byte) {
func (c *QQClient) buildGroupOperationPacket(body *oidb.D89AReqBody) *network.Request {
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(2202, 0, b)
return c.uniPacket("OidbSvc.0x89a_0", payload)
return c.uniRequest("OidbSvc.0x89a_0", payload)
}
// OidbSvc.0x89a_0
func (c *QQClient) buildGroupNameUpdatePacket(groupCode int64, newName string) (uint16, []byte) {
func (c *QQClient) buildGroupNameUpdateRequest(groupCode int64, newName string) *network.Request {
body := &oidb.D89AReqBody{
GroupCode: groupCode,
StGroupInfo: &oidb.D89AGroupinfo{
@ -1000,7 +985,7 @@ func (c *QQClient) buildGroupNameUpdatePacket(groupCode int64, newName string) (
return c.buildGroupOperationPacket(body)
}
func (c *QQClient) buildGroupMemoUpdatePacket(groupCode int64, newMemo string) (uint16, []byte) {
func (c *QQClient) buildGroupMemoUpdatePacket(groupCode int64, newMemo string) *network.Request {
body := &oidb.D89AReqBody{
GroupCode: groupCode,
StGroupInfo: &oidb.D89AGroupinfo{
@ -1011,7 +996,7 @@ func (c *QQClient) buildGroupMemoUpdatePacket(groupCode int64, newMemo string) (
}
// OidbSvc.0x89a_0
func (c *QQClient) buildGroupMuteAllPacket(groupCode int64, mute bool) (uint16, []byte) {
func (c *QQClient) buildGroupMuteAllPacket(groupCode int64, mute bool) *network.Request {
shutUpTime := int32(0)
if mute {
shutUpTime = 268435455
@ -1026,7 +1011,7 @@ func (c *QQClient) buildGroupMuteAllPacket(groupCode int64, mute bool) (uint16,
}
// OidbSvc.0x8a0_0
func (c *QQClient) buildGroupKickPacket(groupCode, memberUin int64, kickMsg string, block bool) (uint16, []byte) {
func (c *QQClient) buildGroupKickPacket(groupCode, memberUin int64, kickMsg string, block bool) *network.Request {
flagBlock := 0
if block {
flagBlock = 1
@ -1044,11 +1029,11 @@ func (c *QQClient) buildGroupKickPacket(groupCode, memberUin int64, kickMsg stri
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(2208, 0, b)
return c.uniPacket("OidbSvc.0x8a0_0", payload)
return c.uniRequest("OidbSvc.0x8a0_0", payload)
}
// OidbSvc.0x570_8
func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32) (uint16, []byte) {
func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32) *network.Request {
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
w.WriteUInt32(uint32(groupCode))
w.WriteByte(32)
@ -1058,33 +1043,33 @@ func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32)
})
payload := c.packOIDBPackage(1392, 8, b)
cl()
return c.uniPacket("OidbSvc.0x570_8", payload)
return c.uniRequest("OidbSvc.0x570_8", payload)
}
// OidbSvc.0xed3
func (c *QQClient) buildGroupPokePacket(groupCode, target int64) (uint16, []byte) {
func (c *QQClient) buildGroupPokeRequest(groupCode, target int64) *network.Request {
body := &oidb.DED3ReqBody{
ToUin: target,
GroupCode: groupCode,
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(3795, 1, b)
return c.uniPacket("OidbSvc.0xed3", payload)
return c.uniRequest("OidbSvc.0xed3", payload)
}
// OidbSvc.0xed3
func (c *QQClient) buildFriendPokePacket(target int64) (uint16, []byte) {
func (c *QQClient) buildFriendPokeRequest(target int64) *network.Request {
body := &oidb.DED3ReqBody{
ToUin: target,
AioUin: target,
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(3795, 1, b)
return c.uniPacket("OidbSvc.0xed3", payload)
return c.uniRequest("OidbSvc.0xed3", payload)
}
// OidbSvc.0x55c_1
func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) (uint16, []byte) {
func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) *network.Request {
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
w.WriteUInt32(uint32(groupCode))
w.WriteUInt32(uint32(member))
@ -1092,11 +1077,11 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool)
})
payload := c.packOIDBPackage(1372, 1, b)
cl()
return c.uniPacket("OidbSvc.0x55c_1", payload)
return c.uniRequest("OidbSvc.0x55c_1", payload)
}
// ProfileService.GroupMngReq
func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
func (c *QQClient) buildQuitGroupPacket(groupCode int64) *network.Request {
jw := jce.NewJceWriter()
jw.WriteInt32(2, 0)
jw.WriteInt64(c.Uin, 1)
@ -1116,12 +1101,12 @@ func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
Context: map[string]string{},
Status: map[string]string{},
}
return c.uniPacket("ProfileService.GroupMngReq", pkt.ToBytes())
return c.uniRequest("ProfileService.GroupMngReq", pkt.ToBytes())
}
/* this function is unused
// LightAppSvc.mini_app_info.GetAppInfoById
func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
func (c *QQClient) buildAppInfoRequestPacket(id string) *network.Request {
seq := c.nextSeq()
req := &qweb.GetAppInfoByIdReq{
AppId: id,
@ -1141,11 +1126,11 @@ func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
}
*/
func (c *QQClient) buildWordSegmentationPacket(data []byte) (uint16, []byte) {
func (c *QQClient) buildWordSegmentationPacket(data []byte) *network.Request {
payload := c.packOIDBPackageProto(3449, 1, &oidb.D79ReqBody{
Uin: uint64(c.Uin),
Content: data,
Qua: []byte("and_537065262_8.4.5"),
})
return c.uniPacket("OidbSvc.0xd79", payload)
return c.uniRequest("OidbSvc.0xd79", payload)
}

View File

@ -68,7 +68,7 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, resp *ne
}
}
if delItems != nil {
_, _ = c.sendAndWait(c.buildDeleteMessageRequestPacket(delItems))
_, _ = c.call(c.buildDeleteMessageRequestPacket(delItems))
}
if rsp.GetSyncFlag() != msg.SyncFlag_STOP {
c.Debug("continue sync with flag: %v", rsp.SyncFlag)
@ -227,8 +227,7 @@ func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, resp *networ
}
func systemMessageDecoder(c *QQClient, _ *msg.Message, _ *network.Response) {
_, pkt := c.buildSystemMsgNewFriendPacket()
_ = c.sendPacket(pkt)
_, _ = c.call(c.buildSystemMsgNewFriendRequest())
}
func troopSystemMessageDecoder(c *QQClient, pMsg *msg.Message, info *network.Response) {
@ -257,7 +256,8 @@ func msgType0x211Decoder(c *QQClient, pMsg *msg.Message, info *network.Response)
return
}
if sub4.NotOnlineFile != nil && sub4.NotOnlineFile.GetSubcmd() == 1 { // subcmd: 1 -> sendPacket, 2-> recv
rsp, err := c.sendAndWait(c.buildOfflineFileDownloadRequestPacket(sub4.NotOnlineFile.FileUuid)) // offline_file.go
rsp, err := c.callAndDecode(c.buildOfflineFileDownloadRequestPacket(sub4.NotOnlineFile.FileUuid),
decodeOfflineFileDownloadResponse) // offline_file.go
if err != nil {
return
}

View File

@ -50,9 +50,12 @@ type QQClient struct {
SequenceId atomic.Int32
SessionId []byte
RandomKey []byte
TCP *network.TCPListener // todo: combine other protocol state into one struct
TCP *network.TCPListener
ConnectTime time.Time
// todo: combine net conn, transport, pending into one struct
pendingMu sync.Mutex
pending map[uint16]*network.Call
transport *network.Transport
oicq *oicq.Codec
@ -117,10 +120,6 @@ func (h *handlerInfo) getParams() network.RequestParams {
}
var decoders = map[string]func(*QQClient, *network.Response) (interface{}, error){
"wtlogin.login": decodeLoginResponse,
"wtlogin.exchange_emp": decodeExchangeEmpResponse,
"wtlogin.trans_emp": decodeTransEmpResponse,
"StatSvc.register": decodeClientRegisterResponse,
"StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
"MessageSvc.PushNotify": decodeSvcNotify,
"OnlinePush.ReqPush": decodeOnlinePushReqPacket,
@ -129,18 +128,6 @@ var decoders = map[string]func(*QQClient, *network.Response) (interface{}, error
"ConfigPushSvc.PushReq": decodePushReqPacket,
"MessageSvc.PbGetMsg": decodeMessageSvcPacket,
"MessageSvc.PushForceOffline": decodeForceOfflinePacket,
"PbMessageSvc.PbMsgWithDraw": decodeMsgWithDrawResponse,
"friendlist.getFriendGroupList": decodeFriendGroupListResponse,
"friendlist.delFriend": decodeFriendDeleteResponse,
"friendlist.GetTroopListReqV2": decodeGroupListResponse,
"friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
"group_member_card.get_group_member_card_info": decodeGroupMemberInfoResponse,
"LongConn.OffPicUp": decodeOffPicUpResponse,
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
"ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
"OidbSvc.0xd79": decodeWordSegmentation,
"OidbSvc.0x990": decodeTranslateResponse,
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
}
func init() {
@ -173,6 +160,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
alive: true,
highwaySession: new(highway.Session),
pending: make(map[uint16]*network.Call),
version: new(auth.AppVersion),
deviceInfo: new(auth.Device),
}
@ -268,7 +256,7 @@ func (c *QQClient) Login() (*LoginResponse, error) {
if err != nil {
return nil, err
}
rsp, err := c.sendAndWait(c.buildLoginPacket())
rsp, err := c.callAndDecode(c.buildLoginRequest(), decodeLoginResponse)
if err != nil {
c.Disconnect()
return nil, err
@ -302,7 +290,7 @@ func (c *QQClient) TokenLogin(token []byte) error {
// SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
c.deviceInfo.TgtgtKey = r.ReadBytesShort()
}
_, err = c.sendAndWait(c.buildRequestChangeSigPacket(c.version.MainSigMap))
_, err = c.callAndDecode(c.buildRequestChangeSigRequest(c.version.MainSigMap), decodeExchangeEmpResponse)
if err != nil {
return err
}
@ -321,7 +309,9 @@ func (c *QQClient) FetchQRCodeCustomSize(size, margin, ecLevel uint32) (*QRCodeL
if err != nil {
return nil, err
}
i, err := c.sendAndWait(c.buildQRCodeFetchRequestPacket(size, margin, ecLevel))
c.transport.Version = auth.AndroidWatch.Version()
i, err := c.callAndDecode(c.buildQRCodeFetchRequest(size, margin, ecLevel), decodeTransEmpResponse)
c.transport.Version = c.version
if err != nil {
return nil, errors.Wrap(err, "fetch qrcode error")
}
@ -329,7 +319,9 @@ func (c *QQClient) FetchQRCodeCustomSize(size, margin, ecLevel uint32) (*QRCodeL
}
func (c *QQClient) QueryQRCodeStatus(sig []byte) (*QRCodeLoginResponse, error) {
i, err := c.sendAndWait(c.buildQRCodeResultQueryRequestPacket(sig))
c.transport.Version = auth.AndroidWatch.Version()
i, err := c.callAndDecode(c.buildQRCodeResultQueryRequest(sig), decodeTransEmpResponse)
c.transport.Version = c.version
if err != nil {
return nil, errors.Wrap(err, "query result error")
}
@ -337,7 +329,7 @@ func (c *QQClient) QueryQRCodeStatus(sig []byte) (*QRCodeLoginResponse, error) {
}
func (c *QQClient) QRCodeLogin(info *QRCodeLoginInfo) (*LoginResponse, error) {
i, err := c.sendAndWait(c.buildQRCodeLoginPacket(info.tmpPwd, info.tmpNoPicSig, info.tgtQR))
i, err := c.callAndDecode(c.buildQRCodeLoginRequest(info.tmpPwd, info.tmpNoPicSig, info.tgtQR), decodeLoginResponse)
if err != nil {
return nil, errors.Wrap(err, "qrcode login error")
}
@ -350,8 +342,8 @@ func (c *QQClient) QRCodeLogin(info *QRCodeLoginInfo) (*LoginResponse, error) {
// SubmitCaptcha send captcha to server
func (c *QQClient) SubmitCaptcha(result string, sign []byte) (*LoginResponse, error) {
seq, packet := c.buildCaptchaPacket(result, sign)
rsp, err := c.sendAndWait(seq, packet)
req := c.buildCaptchaRequest(result, sign)
rsp, err := c.callAndDecode(req, decodeLoginResponse)
if err != nil {
c.Disconnect()
return nil, err
@ -364,8 +356,8 @@ func (c *QQClient) SubmitCaptcha(result string, sign []byte) (*LoginResponse, er
}
func (c *QQClient) SubmitTicket(ticket string) (*LoginResponse, error) {
seq, packet := c.buildTicketSubmitPacket(ticket)
rsp, err := c.sendAndWait(seq, packet)
req := c.buildTicketSubmitRequest(ticket)
rsp, err := c.callAndDecode(req, decodeLoginResponse)
if err != nil {
c.Disconnect()
return nil, err
@ -378,7 +370,7 @@ func (c *QQClient) SubmitTicket(ticket string) (*LoginResponse, error) {
}
func (c *QQClient) SubmitSMS(code string) (*LoginResponse, error) {
rsp, err := c.sendAndWait(c.buildSMSCodeSubmitPacket(code))
rsp, err := c.callAndDecode(c.buildSMSCodeSubmitRequest(code), decodeLoginResponse)
if err != nil {
c.Disconnect()
return nil, err
@ -391,7 +383,7 @@ func (c *QQClient) SubmitSMS(code string) (*LoginResponse, error) {
}
func (c *QQClient) RequestSMS() bool {
rsp, err := c.sendAndWait(c.buildSMSRequestPacket())
rsp, err := c.callAndDecode(c.buildSMSRequest(), decodeLoginResponse)
if err != nil {
c.Error("request sms error: %v", err)
return false
@ -431,8 +423,8 @@ func (c *QQClient) init(tokenLogin bool) error {
}
_ = c.RefreshStatus()
if c.version.Protocol == auth.QiDian {
_, _ = c.sendAndWait(c.buildLoginExtraPacket()) // 小登录
_, _ = c.sendAndWait(c.buildConnKeyRequestPacket()) // big data key 如果等待 config push 的话时间来不及
_, _ = c.callAndDecode(c.buildLoginExtraPacket(), decodeLoginExtraResponse) // 小登录
_, _ = c.callAndDecode(c.buildConnKeyRequestPacket(), decodeConnKeyResponse) // big data key 如果等待 config push 的话时间来不及
}
seq, pkt := c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix())
_, _ = c.sendAndWaitParams(seq, pkt, network.RequestParams{"used_reg_proxy": true, "init": true})
@ -457,14 +449,14 @@ func (c *QQClient) GenToken() []byte {
func (c *QQClient) SetOnlineStatus(s UserOnlineStatus) {
if s < 1000 {
_, _ = c.sendAndWait(c.buildStatusSetPacket(int32(s), 0))
_, _ = c.call(c.buildStatusSetPacket(int32(s), 0))
return
}
_, _ = c.sendAndWait(c.buildStatusSetPacket(11, int32(s)))
_, _ = c.call(c.buildStatusSetPacket(11, int32(s)))
}
func (c *QQClient) GetWordSegmentation(text string) ([]string, error) {
rsp, err := c.sendAndWait(c.buildWordSegmentationPacket([]byte(text)))
rsp, err := c.callAndDecode(c.buildWordSegmentationPacket([]byte(text)), decodeWordSegmentation)
if err != nil {
return nil, err
}
@ -479,7 +471,7 @@ func (c *QQClient) GetWordSegmentation(text string) ([]string, error) {
}
func (c *QQClient) GetSummaryInfo(target int64) (*SummaryCardInfo, error) {
rsp, err := c.sendAndWait(c.buildSummaryCardRequestPacket(target))
rsp, err := c.callAndDecode(c.buildSummaryCardRequest(target), decodeSummaryCardResponse)
if err != nil {
return nil, err
}
@ -510,7 +502,8 @@ func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
curFriendCount := 0
r := &FriendListResponse{}
for {
rsp, err := c.sendAndWait(c.buildFriendGroupListRequestPacket(int16(curFriendCount), 150, 0, 0))
call := c.buildFriendGroupListRequest(int16(curFriendCount), 150, 0, 0)
rsp, err := c.callAndDecode(call, decodeFriendGroupListResponse)
if err != nil {
return nil, err
}
@ -526,11 +519,11 @@ func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
}
func (c *QQClient) SendGroupPoke(groupCode, target int64) {
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
_, _ = c.call(c.buildGroupPokeRequest(groupCode, target))
}
func (c *QQClient) SendFriendPoke(target int64) {
_, _ = c.sendAndWait(c.buildFriendPokePacket(target))
_, _ = c.call(c.buildFriendPokeRequest(target))
}
func (c *QQClient) ReloadGroupList() error {
@ -545,7 +538,7 @@ func (c *QQClient) ReloadGroupList() error {
}
func (c *QQClient) GetGroupList() ([]*GroupInfo, error) {
rsp, err := c.sendAndWait(c.buildGroupListRequestPacket(EmptyBytes))
rsp, err := c.callAndDecode(c.buildGroupListRequest(EmptyBytes), decodeGroupListResponse)
if err != nil {
return nil, err
}
@ -577,7 +570,7 @@ func (c *QQClient) GetGroupMembers(group *GroupInfo) ([]*GroupMemberInfo, error)
var nextUin int64
var list []*GroupMemberInfo
for {
data, err := c.sendAndWait(c.buildGroupMemberListRequestPacket(group.Uin, group.Code, nextUin))
data, err := c.callAndDecode(c.buildGroupMemberListRequest(group.Uin, group.Code, nextUin), decodeGroupMemberListResponse)
if err != nil {
return nil, err
}
@ -603,7 +596,7 @@ func (c *QQClient) GetGroupMembers(group *GroupInfo) ([]*GroupMemberInfo, error)
}
func (c *QQClient) GetMemberInfo(groupCode, memberUin int64) (*GroupMemberInfo, error) {
info, err := c.sendAndWait(c.buildGroupMemberInfoRequestPacket(groupCode, memberUin))
info, err := c.callAndDecode(c.buildGroupMemberInfoRequest(groupCode, memberUin), decodeGroupMemberInfoResponse)
if err != nil {
return nil, err
}
@ -624,7 +617,7 @@ func (c *QQClient) DeleteFriend(uin int64) error {
if c.FindFriend(uin) == nil {
return errors.New("friend not found")
}
_, err := c.sendAndWait(c.buildFriendDeletePacket(uin))
_, err := c.callAndDecode(c.buildFriendDeletePacket(uin), decodeFriendDeleteResponse)
return errors.Wrap(err, "delete friend error")
}
@ -655,29 +648,28 @@ func (c *QQClient) SolveGroupJoinRequest(i interface{}, accept, block bool, reas
switch req := i.(type) {
case *UserJoinGroupRequest:
_, pkt := c.buildSystemMsgGroupActionPacket(req.RequestId, req.RequesterUin, req.GroupCode, func() int32 {
call := c.buildSystemMsgGroupActionPacket(req.RequestId, req.RequesterUin, req.GroupCode, func() int32 {
if req.Suspicious {
return 2
} else {
return 1
}
}(), false, accept, block, reason)
_ = c.sendPacket(pkt)
_, _ = c.call(call)
case *GroupInvitedRequest:
_, pkt := c.buildSystemMsgGroupActionPacket(req.RequestId, req.InvitorUin, req.GroupCode, 1, true, accept, block, reason)
_ = c.sendPacket(pkt)
call := c.buildSystemMsgGroupActionPacket(req.RequestId, req.InvitorUin, req.GroupCode, 1, true, accept, block, reason)
_, _ = c.call(call)
}
}
func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
_, pkt := c.buildSystemMsgFriendActionPacket(req.RequestId, req.RequesterUin, accept)
_ = c.sendPacket(pkt)
_, _ = c.call(c.buildSystemMsgFriendActionPacket(req.RequestId, req.RequesterUin, accept))
}
func (c *QQClient) getSKey() string {
if c.sig.SKeyExpiredTime < time.Now().Unix() && len(c.sig.G) > 0 {
c.Debug("skey expired. refresh...")
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
_, _ = c.callAndDecode(c.buildRequestTgtgtNopicsigRequest(), decodeExchangeEmpResponse)
}
return string(c.sig.SKey)
}
@ -705,39 +697,39 @@ func (c *QQClient) getCSRFToken() int {
}
func (c *QQClient) editMemberCard(groupCode, memberUin int64, card string) {
_, _ = c.sendAndWait(c.buildEditGroupTagPacket(groupCode, memberUin, card))
_, _ = c.call(c.buildEditGroupTagPacket(groupCode, memberUin, card))
}
func (c *QQClient) editMemberSpecialTitle(groupCode, memberUin int64, title string) {
_, _ = c.sendAndWait(c.buildEditSpecialTitlePacket(groupCode, memberUin, title))
_, _ = c.call(c.buildEditSpecialTitlePacket(groupCode, memberUin, title))
}
func (c *QQClient) setGroupAdmin(groupCode, memberUin int64, flag bool) {
_, _ = c.sendAndWait(c.buildGroupAdminSetPacket(groupCode, memberUin, flag))
_, _ = c.call(c.buildGroupAdminSetPacket(groupCode, memberUin, flag))
}
func (c *QQClient) updateGroupName(groupCode int64, newName string) {
_, _ = c.sendAndWait(c.buildGroupNameUpdatePacket(groupCode, newName))
_, _ = c.call(c.buildGroupNameUpdateRequest(groupCode, newName))
}
func (c *QQClient) updateGroupMemo(groupCode int64, newMemo string) {
_, _ = c.sendAndWait(c.buildGroupMemoUpdatePacket(groupCode, newMemo))
_, _ = c.call(c.buildGroupMemoUpdatePacket(groupCode, newMemo))
}
func (c *QQClient) groupMuteAll(groupCode int64, mute bool) {
_, _ = c.sendAndWait(c.buildGroupMuteAllPacket(groupCode, mute))
_, _ = c.call(c.buildGroupMuteAllPacket(groupCode, mute))
}
func (c *QQClient) groupMute(groupCode, memberUin int64, time uint32) {
_, _ = c.sendAndWait(c.buildGroupMutePacket(groupCode, memberUin, time))
_, _ = c.call(c.buildGroupMutePacket(groupCode, memberUin, time))
}
func (c *QQClient) quitGroup(groupCode int64) {
_, _ = c.sendAndWait(c.buildQuitGroupPacket(groupCode))
_, _ = c.call(c.buildQuitGroupPacket(groupCode))
}
func (c *QQClient) kickGroupMember(groupCode, memberUin int64, msg string, block bool) {
_, _ = c.sendAndWait(c.buildGroupKickPacket(groupCode, memberUin, msg, block))
_, _ = c.call(c.buildGroupKickPacket(groupCode, memberUin, msg, block))
}
func (g *GroupInfo) removeMember(uin int64) {
@ -757,7 +749,7 @@ func (c *QQClient) SetCustomServer(servers []*net.TCPAddr) {
}
func (c *QQClient) registerClient() error {
_, err := c.sendAndWait(c.buildClientRegisterPacket())
_, err := c.callAndDecode(c.buildClientRegisterPacket(), decodeClientRegisterResponse)
if err == nil {
c.Online.Store(true)
}

View File

@ -148,7 +148,7 @@ func decodeLoginResponse(c *QQClient, resp *network.Response) (interface{}, erro
if t == 204 {
c.sig.T104 = m[0x104]
c.sig.RandSeed = m[0x403]
return c.sendAndWait(c.buildDeviceLockLoginPacket())
return c.callAndDecode(c.buildDeviceLockLoginRequest(), decodeLoginResponse)
} // drive lock
if t149, ok := m[0x149]; ok {
@ -365,8 +365,8 @@ func decodePushReqPacket(c *QQClient, resp *network.Response) (interface{}, erro
}
seq := r.ReadInt64(3)
_, pkt := c.buildConfPushRespPacket(t, seq, jceBuf)
return nil, c.sendPacket(pkt)
err := c.sendPacket(c.transport.PackPacket(c.buildConfPushRespPacket(t, seq, jceBuf)))
return nil, err
}
// MessageSvc.PbGetMsg
@ -399,8 +399,8 @@ func decodeSvcNotify(c *QQClient, resp *network.Response) (interface{}, error) {
return nil, nil
}
if typ == sysMsgDecoders {
_, pkt := c.buildSystemMsgNewFriendPacket()
return nil, c.sendPacket(pkt)
_, err := c.callAndDecode(c.buildSystemMsgNewFriendRequest(), decodeSystemMsgFriendPacket)
return nil, err
}
}
_, err := c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix()))
@ -516,7 +516,7 @@ func decodeGroupListResponse(c *QQClient, resp *network.Response) (interface{},
})
}
if len(vecCookie) > 0 {
rsp, err := c.sendAndWait(c.buildGroupListRequestPacket(vecCookie))
rsp, err := c.callAndDecode(c.buildGroupListRequest(vecCookie), decodeGroupListResponse)
if err != nil {
return nil, err
}
@ -796,14 +796,14 @@ func decodeWordSegmentation(_ *QQClient, resp *network.Response) (interface{}, e
}
func decodeSidExpiredPacket(c *QQClient, resp *network.Response) (interface{}, error) {
_, err := c.sendAndWait(c.buildRequestChangeSigPacket(3554528))
_, err := c.callAndDecode(c.buildRequestChangeSigRequest(3554528), decodeExchangeEmpResponse)
if err != nil {
return nil, errors.Wrap(err, "resign client error")
}
if err = c.registerClient(); err != nil {
return nil, errors.Wrap(err, "register error")
}
_ = c.sendPacket(c.uniPacketWithSeq(uint16(resp.SequenceID), "OnlinePush.SidTicketExpired", EmptyBytes))
_, _ = c.call(c.uniPacketWithSeq(uint16(resp.SequenceID), "OnlinePush.SidTicketExpired", EmptyBytes))
return nil, nil
}

View File

@ -15,19 +15,15 @@ type CustomFace struct {
Url string
}
func init() {
decoders["Faceroam.OpReq"] = decodeFaceroamResponse
}
func (c *QQClient) GetCustomFaces() ([]*CustomFace, error) {
i, err := c.sendAndWait(c.buildFaceroamRequestPacket())
i, err := c.callAndDecode(c.buildFaceroamRequestPacket(), decodeFaceroamResponse)
if err != nil {
return nil, errors.Wrap(err, "get faces error")
}
return i.([]*CustomFace), nil
}
func (c *QQClient) buildFaceroamRequestPacket() (uint16, []byte) {
func (c *QQClient) buildFaceroamRequestPacket() *network.Request {
payload, _ := proto.Marshal(&faceroam.FaceroamReqBody{
Comm: &faceroam.PlatInfo{
Implat: proto.Int64(109),
@ -38,7 +34,7 @@ func (c *QQClient) buildFaceroamRequestPacket() (uint16, []byte) {
SubCmd: proto.Uint32(1),
ReqUserInfo: &faceroam.ReqUserInfo{},
})
return c.uniPacket("Faceroam.OpReq", payload)
return c.uniRequest("Faceroam.OpReq", payload)
}
func decodeFaceroamResponse(c *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -57,17 +57,6 @@ type (
var fsWaiter = utils.NewUploadWaiter()
func init() {
decoders["OidbSvc.0x6d8_1"] = decodeOIDB6d81Response
decoders["OidbSvc.0x6d6_0"] = decodeOIDB6d60Response
decoders["OidbSvc.0x6d6_2"] = decodeOIDB6d62Response
decoders["OidbSvc.0x6d6_3"] = decodeOIDB6d63Response
decoders["OidbSvc.0x6d7_0"] = decodeOIDB6d7Response
decoders["OidbSvc.0x6d7_1"] = decodeOIDB6d7Response
decoders["OidbSvc.0x6d7_2"] = decodeOIDB6d7Response
decoders["OidbSvc.0x6d9_4"] = ignoreDecoder
}
func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) {
defer func() {
if pan := recover(); pan != nil {
@ -79,7 +68,7 @@ func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err
if g == nil {
return nil, errors.New("group not found")
}
rsp, e := c.sendAndWait(c.buildGroupFileCountRequestPacket(groupCode))
rsp, e := c.callAndDecode(c.buildGroupFileCountRequest(groupCode), decodeOIDB6d81Response)
if e != nil {
return nil, e
}
@ -89,7 +78,7 @@ func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err
GroupCode: groupCode,
client: c,
}
rsp, err = c.sendAndWait(c.buildGroupFileSpaceRequestPacket(groupCode))
rsp, err = c.callAndDecode(c.buildGroupFileSpaceRequest(groupCode), decodeOIDB6d81Response)
if err != nil {
return nil, err
}
@ -99,7 +88,7 @@ func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err
}
func (c *QQClient) GetGroupFileUrl(groupCode int64, fileId string, busId int32) string {
i, err := c.sendAndWait(c.buildGroupFileDownloadReqPacket(groupCode, fileId, busId))
i, err := c.callAndDecode(c.buildGroupFileDownloadReq(groupCode, fileId, busId), decodeOIDB6d62Response)
if err != nil {
return ""
}
@ -117,7 +106,8 @@ func (fs *GroupFileSystem) GetFilesByFolder(folderID string) ([]*GroupFile, []*G
var files []*GroupFile
var folders []*GroupFolder
for {
i, err := fs.client.sendAndWait(fs.client.buildGroupFileListRequestPacket(fs.GroupCode, folderID, startIndex))
req := fs.client.buildGroupFileListRequest(fs.GroupCode, folderID, startIndex)
i, err := fs.client.callAndDecode(req, decodeOIDB6d81Response)
if err != nil {
return nil, nil, err
}
@ -177,14 +167,16 @@ func (fs *GroupFileSystem) UploadFile(p, name, folderId string) error {
_, _ = io.Copy(sha1H, file)
sha1Hash := sha1H.Sum(nil)
_, _ = file.Seek(0, io.SeekStart)
i, err := fs.client.sendAndWait(fs.client.buildGroupFileUploadReqPacket(folderId, name, fs.GroupCode, size, md5Hash, sha1Hash))
req := fs.client.buildGroupFileUploadReq(folderId, name, fs.GroupCode, size, md5Hash, sha1Hash)
i, err := fs.client.callAndDecode(req, decodeOIDB6d60Response)
if err != nil {
return errors.Wrap(err, "query upload failed")
}
rsp := i.(*oidb.UploadFileRspBody)
if rsp.GetBoolFileExist() {
_, pkt := fs.client.buildGroupFileFeedsRequest(fs.GroupCode, rsp.GetFileId(), rsp.GetBusId(), rand.Int31())
return fs.client.sendPacket(pkt)
req := fs.client.buildGroupFileFeedsRequest(fs.GroupCode, rsp.GetFileId(), rsp.GetBusId(), rand.Int31())
_, err := fs.client.call(req)
return err
}
if len(rsp.UploadIpLanV4) == 0 {
return errors.New("server requires unsupported ftn upload")
@ -236,8 +228,9 @@ func (fs *GroupFileSystem) UploadFile(p, name, folderId string) error {
if _, err = fs.client.highwaySession.UploadExciting(input); err != nil {
return errors.Wrap(err, "upload failed")
}
_, pkt := client.buildGroupFileFeedsRequest(fs.GroupCode, rsp.GetFileId(), rsp.GetBusId(), rand.Int31())
return client.sendPacket(pkt)
req = client.buildGroupFileFeedsRequest(fs.GroupCode, rsp.GetFileId(), rsp.GetBusId(), rand.Int31())
_, err = client.call(req)
return err
}
func (fs *GroupFileSystem) GetDownloadUrl(file *GroupFile) string {
@ -245,21 +238,21 @@ func (fs *GroupFileSystem) GetDownloadUrl(file *GroupFile) string {
}
func (fs *GroupFileSystem) CreateFolder(parentFolder, name string) error {
if _, err := fs.client.sendAndWait(fs.client.buildGroupFileCreateFolderPacket(fs.GroupCode, parentFolder, name)); err != nil {
if _, err := fs.client.callAndDecode(fs.client.buildGroupFileCreateFolderRequest(fs.GroupCode, parentFolder, name), decodeOIDB6d7Response); err != nil {
return errors.Wrap(err, "create folder error")
}
return nil
}
func (fs *GroupFileSystem) RenameFolder(folderId, newName string) error {
if _, err := fs.client.sendAndWait(fs.client.buildGroupFileRenameFolderPacket(fs.GroupCode, folderId, newName)); err != nil {
if _, err := fs.client.callAndDecode(fs.client.buildGroupFileRenameFolderRequest(fs.GroupCode, folderId, newName), decodeOIDB6d7Response); err != nil {
return errors.Wrap(err, "rename folder error")
}
return nil
}
func (fs *GroupFileSystem) DeleteFolder(folderId string) error {
if _, err := fs.client.sendAndWait(fs.client.buildGroupFileDeleteFolderPacket(fs.GroupCode, folderId)); err != nil {
if _, err := fs.client.callAndDecode(fs.client.buildGroupFileDeleteFolderRequest(fs.GroupCode, folderId), decodeOIDB6d7Response); err != nil {
return errors.Wrap(err, "rename folder error")
}
return nil
@ -268,14 +261,14 @@ func (fs *GroupFileSystem) DeleteFolder(folderId string) error {
// DeleteFile 删除群文件,需要管理权限.
// 返回错误, 空为删除成功
func (fs *GroupFileSystem) DeleteFile(parentFolderID, fileId string, busId int32) string {
i, err := fs.client.sendAndWait(fs.client.buildGroupFileDeleteReqPacket(fs.GroupCode, parentFolderID, fileId, busId))
i, err := fs.client.callAndDecode(fs.client.buildGroupFileDeleteReq(fs.GroupCode, parentFolderID, fileId, busId), decodeOIDB6d63Response)
if err != nil {
return err.Error()
}
return i.(string)
}
func (c *QQClient) buildGroupFileUploadReqPacket(parentFolderID, fileName string, groupCode, fileSize int64, md5, sha1 []byte) (uint16, []byte) {
func (c *QQClient) buildGroupFileUploadReq(parentFolderID, fileName string, groupCode, fileSize int64, md5, sha1 []byte) *network.Request {
b, _ := proto.Marshal(&oidb.D6D6ReqBody{UploadFileReq: &oidb.UploadFileReqBody{
GroupCode: &groupCode,
AppId: proto.Int32(3),
@ -296,10 +289,10 @@ func (c *QQClient) buildGroupFileUploadReqPacket(parentFolderID, fileName string
ClientVersion: "android 8.4.8",
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d6_0", payload)
return c.uniRequest("OidbSvc.0x6d6_0", payload)
}
func (c *QQClient) buildGroupFileFeedsRequest(groupCode int64, fileID string, busId, msgRand int32) (uint16, []byte) {
func (c *QQClient) buildGroupFileFeedsRequest(groupCode int64, fileID string, busId, msgRand int32) *network.Request {
req := c.packOIDBPackageProto(1753, 4, &oidb.D6D9ReqBody{FeedsInfoReq: &oidb.FeedsReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
@ -310,11 +303,11 @@ func (c *QQClient) buildGroupFileFeedsRequest(groupCode int64, fileID string, bu
MsgRandom: proto.Uint32(uint32(msgRand)),
}},
}})
return c.uniPacket("OidbSvc.0x6d9_4", req)
return c.uniRequest("OidbSvc.0x6d9_4", req)
}
// OidbSvc.0x6d8_1
func (c *QQClient) buildGroupFileListRequestPacket(groupCode int64, folderID string, startIndex uint32) (uint16, []byte) {
func (c *QQClient) buildGroupFileListRequest(groupCode int64, folderID string, startIndex uint32) *network.Request {
body := &oidb.D6D8ReqBody{FileListInfoReq: &oidb.GetFileListReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
@ -336,10 +329,10 @@ func (c *QQClient) buildGroupFileListRequestPacket(groupCode int64, folderID str
ClientVersion: "android 8.4.8",
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d8_1", payload)
return c.uniRequest("OidbSvc.0x6d8_1", payload)
}
func (c *QQClient) buildGroupFileCountRequestPacket(groupCode int64) (uint16, []byte) {
func (c *QQClient) buildGroupFileCountRequest(groupCode int64) *network.Request {
body := &oidb.D6D8ReqBody{GroupFileCountReq: &oidb.GetFileCountReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
@ -353,10 +346,10 @@ func (c *QQClient) buildGroupFileCountRequestPacket(groupCode int64) (uint16, []
ClientVersion: "android 8.4.8",
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d8_1", payload)
return c.uniRequest("OidbSvc.0x6d8_1", payload)
}
func (c *QQClient) buildGroupFileSpaceRequestPacket(groupCode int64) (uint16, []byte) {
func (c *QQClient) buildGroupFileSpaceRequest(groupCode int64) *network.Request {
body := &oidb.D6D8ReqBody{GroupSpaceReq: &oidb.GetSpaceReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
@ -369,40 +362,40 @@ func (c *QQClient) buildGroupFileSpaceRequestPacket(groupCode int64) (uint16, []
ClientVersion: "android 8.4.8",
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d8_1", payload)
return c.uniRequest("OidbSvc.0x6d8_1", payload)
}
func (c *QQClient) buildGroupFileCreateFolderPacket(groupCode int64, parentFolder, name string) (uint16, []byte) {
func (c *QQClient) buildGroupFileCreateFolderRequest(groupCode int64, parentFolder, name string) *network.Request {
payload := c.packOIDBPackageProto(1751, 0, &oidb.D6D7ReqBody{CreateFolderReq: &oidb.CreateFolderReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
ParentFolderId: &parentFolder,
FolderName: &name,
}})
return c.uniPacket("OidbSvc.0x6d7_0", payload)
return c.uniRequest("OidbSvc.0x6d7_0", payload)
}
func (c *QQClient) buildGroupFileRenameFolderPacket(groupCode int64, folderId, newName string) (uint16, []byte) {
func (c *QQClient) buildGroupFileRenameFolderRequest(groupCode int64, folderId, newName string) *network.Request {
payload := c.packOIDBPackageProto(1751, 2, &oidb.D6D7ReqBody{RenameFolderReq: &oidb.RenameFolderReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
FolderId: proto.String(folderId),
NewFolderName: proto.String(newName),
}})
return c.uniPacket("OidbSvc.0x6d7_2", payload)
return c.uniRequest("OidbSvc.0x6d7_2", payload)
}
func (c *QQClient) buildGroupFileDeleteFolderPacket(groupCode int64, folderId string) (uint16, []byte) {
func (c *QQClient) buildGroupFileDeleteFolderRequest(groupCode int64, folderId string) *network.Request {
payload := c.packOIDBPackageProto(1751, 1, &oidb.D6D7ReqBody{DeleteFolderReq: &oidb.DeleteFolderReqBody{
GroupCode: proto.Uint64(uint64(groupCode)),
AppId: proto.Uint32(3),
FolderId: proto.String(folderId),
}})
return c.uniPacket("OidbSvc.0x6d7_1", payload)
return c.uniRequest("OidbSvc.0x6d7_1", payload)
}
// OidbSvc.0x6d6_2
func (c *QQClient) buildGroupFileDownloadReqPacket(groupCode int64, fileId string, busId int32) (uint16, []byte) {
func (c *QQClient) buildGroupFileDownloadReq(groupCode int64, fileId string, busId int32) *network.Request {
body := &oidb.D6D6ReqBody{
DownloadFileReq: &oidb.DownloadFileReqBody{
GroupCode: &groupCode,
@ -418,10 +411,10 @@ func (c *QQClient) buildGroupFileDownloadReqPacket(groupCode int64, fileId strin
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d6_2", payload)
return c.uniRequest("OidbSvc.0x6d6_2", payload)
}
func (c *QQClient) buildGroupFileDeleteReqPacket(groupCode int64, parentFolderId, fileId string, busId int32) (uint16, []byte) {
func (c *QQClient) buildGroupFileDeleteReq(groupCode int64, parentFolderId, fileId string, busId int32) *network.Request {
body := &oidb.D6D6ReqBody{DeleteFileReq: &oidb.DeleteFileReqBody{
GroupCode: &groupCode,
AppId: proto.Int32(3),
@ -437,7 +430,7 @@ func (c *QQClient) buildGroupFileDeleteReqPacket(groupCode int64, parentFolderId
ClientVersion: "android 8.4.8",
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x6d6_3", payload)
return c.uniRequest("OidbSvc.0x6d6_3", payload)
}
func decodeOIDB6d81Response(_ *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -65,13 +65,8 @@ type (
}
)
func init() {
decoders["SummaryCard.ReqSearch"] = decodeGroupSearchResponse
decoders["OidbSvc.0x88d_0"] = decodeGroupInfoResponse
}
func (c *QQClient) GetGroupInfo(groupCode int64) (*GroupInfo, error) {
i, err := c.sendAndWait(c.buildGroupInfoRequestPacket(groupCode))
i, err := c.callAndDecode(c.buildGroupInfoRequestPacket(groupCode), decodeGroupInfoResponse)
if err != nil {
return nil, err
}
@ -79,7 +74,7 @@ func (c *QQClient) GetGroupInfo(groupCode int64) (*GroupInfo, error) {
}
// OidbSvc.0x88d_0
func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte) {
func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) *network.Request {
body := &oidb.D88DReqBody{
AppId: proto.Uint32(c.version.AppId),
ReqGroupInfo: []*oidb.ReqGroupInfo{
@ -122,12 +117,12 @@ func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte)
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x88d_0", payload)
return c.uniRequest("OidbSvc.0x88d_0", payload)
}
// SearchGroupByKeyword 通过关键词搜索陌生群组
func (c *QQClient) SearchGroupByKeyword(keyword string) ([]GroupSearchInfo, error) {
rsp, err := c.sendAndWait(c.buildGroupSearchPacket(keyword))
rsp, err := c.callAndDecode(c.buildGroupSearchPacket(keyword), decodeGroupSearchResponse)
if err != nil {
return nil, errors.Wrap(err, "group search failed")
}
@ -135,7 +130,7 @@ func (c *QQClient) SearchGroupByKeyword(keyword string) ([]GroupSearchInfo, erro
}
// SummaryCard.ReqSearch
func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
func (c *QQClient) buildGroupSearchPacket(keyword string) *network.Request {
comm, _ := proto.Marshal(&profilecard.BusiComm{
Ver: proto.Int32(1),
Seq: proto.Int32(rand.Int31()),
@ -184,7 +179,7 @@ func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("SummaryCard.ReqSearch", pkt.ToBytes())
return c.uniRequest("SummaryCard.ReqSearch", pkt.ToBytes())
}
// SummaryCard.ReqSearch

View File

@ -28,9 +28,6 @@ func init() {
decoders["OnlinePush.PbPushGroupMsg"] = decodeGroupMessagePacket
decoders["MessageSvc.PbSendMsg"] = decodeMsgSendResponse
decoders["MessageSvc.PbGetGroupMsg"] = decodeGetGroupMsgResponse
decoders["OidbSvc.0x8a7_0"] = decodeAtAllRemainResponse
decoders["OidbSvc.0xeac_1"] = decodeEssenceMsgResponse
decoders["OidbSvc.0xeac_2"] = decodeEssenceMsgResponse
}
// SendGroupMessage 发送群消息
@ -80,8 +77,8 @@ func (c *QQClient) SendGroupForwardMessage(groupCode int64, m *message.ForwardEl
// GetGroupMessages 从服务器获取历史信息
func (c *QQClient) GetGroupMessages(groupCode, beginSeq, endSeq int64) ([]*message.GroupMessage, error) {
seq, pkt := c.buildGetGroupMsgRequest(groupCode, beginSeq, endSeq)
i, err := c.sendAndWaitParams(seq, pkt, network.RequestParams{"raw": false})
req := c.buildGetGroupMsgRequest(groupCode, beginSeq, endSeq)
i, err := c.sendAndWaitParams(uint16(req.SequenceID), c.transport.PackPacket(req), network.RequestParams{"raw": false})
if err != nil {
return nil, err
}
@ -89,7 +86,7 @@ func (c *QQClient) GetGroupMessages(groupCode, beginSeq, endSeq int64) ([]*messa
}
func (c *QQClient) GetAtAllRemain(groupCode int64) (*AtAllRemainInfo, error) {
i, err := c.sendAndWait(c.buildAtAllRemainRequestPacket(groupCode))
i, err := c.callAndDecode(c.buildAtAllRemainRequestPacket(groupCode), decodeAtAllRemainResponse)
if err != nil {
return nil, err
}
@ -123,12 +120,12 @@ func (c *QQClient) sendGroupMessage(groupCode int64, forward bool, m *message.Se
div := int32(rand.Uint32())
fragmented := m.ToFragmented()
for i, elems := range fragmented {
_, pkt := c.buildGroupSendingPacket(groupCode, mr, int32(len(fragmented)), int32(i), div, forward, elems)
_ = c.sendPacket(pkt)
req := c.buildGroupSendingReq(groupCode, mr, int32(len(fragmented)), int32(i), div, forward, elems)
c.sendReq(req)
}
} else {
_, pkt := c.buildGroupSendingPacket(groupCode, mr, 1, 0, 0, forward, m.Elements)
_ = c.sendPacket(pkt)
req := c.buildGroupSendingReq(groupCode, mr, 1, 0, 0, forward, m.Elements)
c.sendReq(req)
}
var mid int32
ret := &message.GroupMessage{
@ -214,7 +211,7 @@ func (c *QQClient) UploadGroupForwardMessage(groupCode int64, m *message.Forward
}
func (c *QQClient) multiMsgApplyUp(groupCode int64, data []byte, hash []byte, buType int32) (*multimsg.MultiMsgApplyUpRsp, []byte, error) {
i, err := c.sendAndWait(c.buildMultiApplyUpPacket(data, hash, buType, utils.ToGroupUin(groupCode)))
i, err := c.callAndDecode(c.buildMultiApplyUpPacket(data, hash, buType, utils.ToGroupUin(groupCode)), decodeMultiApplyUpResponse)
if err != nil {
return nil, nil, err
}
@ -237,7 +234,7 @@ func (c *QQClient) multiMsgApplyUp(groupCode int64, data []byte, hash []byte, bu
}
// MessageSvc.PbSendMsg
func (c *QQClient) buildGroupSendingPacket(groupCode int64, r, pkgNum, pkgIndex, pkgDiv int32, forward bool, m []message.IMessageElement) (uint16, []byte) {
func (c *QQClient) buildGroupSendingReq(groupCode int64, r, pkgNum, pkgIndex, pkgDiv int32, forward bool, m []message.IMessageElement) *network.Request {
var ptt *message.GroupVoiceElement
if len(m) > 0 {
if p, ok := m[0].(*message.GroupVoiceElement); ok {
@ -271,10 +268,10 @@ func (c *QQClient) buildGroupSendingPacket(groupCode int64, r, pkgNum, pkgIndex,
}(),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbSendMsg", payload)
return c.uniRequest("MessageSvc.PbSendMsg", payload)
}
func (c *QQClient) buildGetGroupMsgRequest(groupCode, beginSeq, endSeq int64) (uint16, []byte) {
func (c *QQClient) buildGetGroupMsgRequest(groupCode, beginSeq, endSeq int64) *network.Request {
req := &msg.GetGroupMsgReq{
GroupCode: proto.Uint64(uint64(groupCode)),
BeginSeq: proto.Uint64(uint64(beginSeq)),
@ -282,10 +279,10 @@ func (c *QQClient) buildGetGroupMsgRequest(groupCode, beginSeq, endSeq int64) (u
PublicGroup: proto.Bool(false),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbGetGroupMsg", payload)
return c.uniRequest("MessageSvc.PbGetGroupMsg", payload)
}
func (c *QQClient) buildAtAllRemainRequestPacket(groupCode int64) (uint16, []byte) {
func (c *QQClient) buildAtAllRemainRequestPacket(groupCode int64) *network.Request {
payload := c.packOIDBPackageProto(2215, 0, &oidb.D8A7ReqBody{
SubCmd: proto.Uint32(1),
LimitIntervalTypeForUin: proto.Uint32(2),
@ -293,7 +290,7 @@ func (c *QQClient) buildAtAllRemainRequestPacket(groupCode int64) (uint16, []byt
Uin: proto.Uint64(uint64(c.Uin)),
GroupCode: proto.Uint64(uint64(groupCode)),
})
return c.uniPacket("OidbSvc.0x8a7_0", payload)
return c.uniRequest("OidbSvc.0x8a7_0", payload)
}
// OnlinePush.PbPushGroupMsg
@ -374,8 +371,8 @@ func decodeGetGroupMsgResponse(c *QQClient, resp *network.Response) (interface{}
builder := &groupMessageBuilder{}
for {
end := int32(math.Min(float64(i+19), float64(m.Head.GetMsgSeq()+m.Content.GetPkgNum())))
seq, pkt := c.buildGetGroupMsgRequest(m.Head.GroupInfo.GetGroupCode(), int64(i), int64(end))
data, err := c.sendAndWaitParams(seq, pkt, network.RequestParams{"raw": true})
req := c.buildGetGroupMsgRequest(m.Head.GroupInfo.GetGroupCode(), int64(i), int64(end))
data, err := c.sendAndWaitParams(uint16(req.SequenceID), c.transport.PackPacket(req), network.RequestParams{"raw": true})
if err != nil {
return nil, errors.Wrap(err, "build fragmented message error")
}
@ -563,7 +560,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
// SetEssenceMessage 设为群精华消息
func (c *QQClient) SetEssenceMessage(groupCode int64, msgID, msgInternalId int32) error {
r, err := c.sendAndWait(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgID), uint32(msgInternalId), 1))
r, err := c.callAndDecode(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgID), uint32(msgInternalId), 1), decodeEssenceMsgResponse)
if err != nil {
return errors.Wrap(err, "set essence msg network")
}
@ -576,7 +573,7 @@ func (c *QQClient) SetEssenceMessage(groupCode int64, msgID, msgInternalId int32
// DeleteEssenceMessage 移出群精华消息
func (c *QQClient) DeleteEssenceMessage(groupCode int64, msgID, msgInternalId int32) error {
r, err := c.sendAndWait(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgID), uint32(msgInternalId), 2))
r, err := c.callAndDecode(c.buildEssenceMsgOperatePacket(groupCode, uint32(msgID), uint32(msgInternalId), 2), decodeEssenceMsgResponse)
if err != nil {
return errors.Wrap(err, "set essence msg networ")
}
@ -587,14 +584,14 @@ func (c *QQClient) DeleteEssenceMessage(groupCode int64, msgID, msgInternalId in
return nil
}
func (c *QQClient) buildEssenceMsgOperatePacket(groupCode int64, msgSeq, msgRand, opType uint32) (uint16, []byte) {
func (c *QQClient) buildEssenceMsgOperatePacket(groupCode int64, msgSeq, msgRand, opType uint32) *network.Request {
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),
})
return c.uniPacket(commandName, payload)
return c.uniRequest(commandName, payload)
}
// OidbSvc.0xeac_1/2

View File

@ -187,12 +187,12 @@ func (s *GuildService) GetUserProfile(tinyId uint64) (*GuildUserProfile, error)
3: tinyId,
4: uint32(0),
})
rsp, err := s.c.sendAndWaitDynamic(s.c.uniPacket("OidbSvcTrpcTcp.0xfc9_1", payload))
rsp, err := s.c.commandCall("OidbSvcTrpcTcp.0xfc9_1", payload)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xfc9Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
// todo: 解析个性档案
@ -208,7 +208,6 @@ func (s *GuildService) GetUserProfile(tinyId uint64) (*GuildUserProfile, error)
// 第一次请求: startIndex = 0 , roleIdIndex = 2 param = ""
// 后续请求请根据上次请求的返回值进行设置
func (s *GuildService) FetchGuildMemberListWithRole(guildId, channelId uint64, startIndex uint32, roleIdIndex uint64, param string) (*FetchGuildMemberListWithRoleResult, error) {
seq := s.c.nextSeq()
u1 := uint32(1)
m := binary.DynamicProtoMessage{
1: guildId, // guild id
@ -225,13 +224,12 @@ func (s *GuildService) FetchGuildMemberListWithRole(guildId, channelId uint64, s
m[13] = param
}
m[14] = roleIdIndex
packet := s.c.uniPacketWithSeq(seq, "OidbSvcTrpcTcp.0xf5b_1", s.c.packOIDBPackageDynamically(3931, 1, m))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.commandCall("OidbSvcTrpcTcp.0xf5b_1", s.c.packOIDBPackageDynamically(3931, 1, m))
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xf5BRsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
var ret []*GuildMemberInfo
@ -268,7 +266,6 @@ func (s *GuildService) FetchGuildMemberListWithRole(guildId, channelId uint64, s
// FetchGuildMemberProfileInfo 获取单个频道成员资料
func (s *GuildService) FetchGuildMemberProfileInfo(guildId, tinyId uint64) (*GuildUserProfile, error) {
seq := s.c.nextSeq()
flags := binary.DynamicProtoMessage{}
for i := 3; i <= 29; i++ {
flags[uint64(i)] = uint32(1)
@ -280,13 +277,12 @@ func (s *GuildService) FetchGuildMemberProfileInfo(guildId, tinyId uint64) (*Gui
3: tinyId,
4: guildId,
})
packet := s.c.uniPacketWithSeq(seq, "OidbSvcTrpcTcp.0xf88_1", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.commandCall("OidbSvcTrpcTcp.0xf88_1", payload)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xf88Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
roles, err := s.fetchMemberRoles(guildId, tinyId)
@ -304,14 +300,14 @@ func (s *GuildService) FetchGuildMemberProfileInfo(guildId, tinyId uint64) (*Gui
}
func (s *GuildService) GetGuildRoles(guildId uint64) ([]*GuildRole, error) {
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x1019_1",
req := s.c.uniRequest("OidbSvcTrpcTcp.0x1019_1",
s.c.packOIDBPackageDynamically(4121, 1, binary.DynamicProtoMessage{1: guildId}))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.call(req)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0X1019Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
roles := make([]*GuildRole, 0, len(body.GetRoles()))
@ -332,7 +328,7 @@ func (s *GuildService) GetGuildRoles(guildId uint64) ([]*GuildRole, error) {
func (s *GuildService) CreateGuildRole(guildId uint64, name string, color uint32, independent bool, initialUsers []uint64) (uint64, error) {
u1 := uint32(1)
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x1016_1", s.c.packOIDBPackageDynamically(4118, 1, binary.DynamicProtoMessage{
req := s.c.uniRequest("OidbSvcTrpcTcp.0x1016_1", s.c.packOIDBPackageDynamically(4118, 1, binary.DynamicProtoMessage{
1: guildId,
2: binary.DynamicProtoMessage{ // todo: 未知参数
1: u1,
@ -346,23 +342,23 @@ func (s *GuildService) CreateGuildRole(guildId uint64, name string, color uint32
},
4: initialUsers,
}))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.call(req)
if err != nil {
return 0, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0X1016Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return 0, errors.Wrap(err, "decode packet error")
}
return body.GetRoleId(), nil
}
func (s *GuildService) DeleteGuildRole(guildId uint64, roleId uint64) error {
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x100e_1", s.c.packOIDBPackageDynamically(4110, 1, binary.DynamicProtoMessage{
req := s.c.uniRequest("OidbSvcTrpcTcp.0x100e_1", s.c.packOIDBPackageDynamically(4110, 1, binary.DynamicProtoMessage{
1: guildId,
2: roleId,
}))
_, err := s.c.sendAndWaitDynamic(seq, packet)
_, err := s.c.call(req)
if err != nil {
return errors.Wrap(err, "send packet error")
}
@ -378,11 +374,11 @@ func (s *GuildService) SetUserRoleInGuild(guildId uint64, set bool, roleId uint6
} else {
setOrRemove[3] = user
}
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x101a_1", s.c.packOIDBPackageDynamically(4122, 1, binary.DynamicProtoMessage{
req := s.c.uniRequest("OidbSvcTrpcTcp.0x101a_1", s.c.packOIDBPackageDynamically(4122, 1, binary.DynamicProtoMessage{
1: guildId,
2: setOrRemove,
}))
_, err := s.c.sendAndWaitDynamic(seq, packet)
_, err := s.c.call(req)
if err != nil {
return errors.Wrap(err, "send packet error")
}
@ -391,7 +387,7 @@ func (s *GuildService) SetUserRoleInGuild(guildId uint64, set bool, roleId uint6
func (s *GuildService) ModifyRoleInGuild(guildId uint64, roleId uint64, name string, color uint32, indepedent bool) error {
u1 := uint32(1)
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x100d_1", s.c.packOIDBPackageDynamically(4109, 1, binary.DynamicProtoMessage{
req := s.c.uniRequest("OidbSvcTrpcTcp.0x100d_1", s.c.packOIDBPackageDynamically(4109, 1, binary.DynamicProtoMessage{
1: guildId,
2: roleId,
3: binary.DynamicProtoMessage{
@ -405,7 +401,7 @@ func (s *GuildService) ModifyRoleInGuild(guildId uint64, roleId uint64, name str
3: indepedent,
},
}))
_, err := s.c.sendAndWaitDynamic(seq, packet)
_, err := s.c.call(req)
if err != nil {
return errors.Wrap(err, "send packet error")
}
@ -428,13 +424,13 @@ func (s *GuildService) FetchGuestGuild(guildId uint64) (*GuildMeta, error) {
1: guildId,
},
})
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0xf57_9", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
req := s.c.uniRequest("OidbSvcTrpcTcp.0xf57_9", payload)
rsp, err := s.c.call(req)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xf57Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
return &GuildMeta{
@ -450,7 +446,7 @@ func (s *GuildService) FetchGuestGuild(guildId uint64) (*GuildMeta, error) {
}
func (s *GuildService) FetchChannelList(guildId uint64) (r []*ChannelInfo, e error) {
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0xf5d_1",
req := s.c.uniRequest("OidbSvcTrpcTcp.0xf5d_1",
s.c.packOIDBPackageDynamically(3933, 1,
binary.DynamicProtoMessage{
1: guildId,
@ -458,12 +454,12 @@ func (s *GuildService) FetchChannelList(guildId uint64) (r []*ChannelInfo, e err
1: uint32(1),
},
}))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.call(req)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xf5DRsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
for _, info := range body.Rsp.Channels {
@ -473,13 +469,13 @@ func (s *GuildService) FetchChannelList(guildId uint64) (r []*ChannelInfo, e err
}
func (s *GuildService) FetchChannelInfo(guildId, channelId uint64) (*ChannelInfo, error) {
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0xf55_1", s.c.packOIDBPackageDynamically(3925, 1, binary.DynamicProtoMessage{1: guildId, 2: channelId}))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
req := s.c.uniRequest("OidbSvcTrpcTcp.0xf55_1", s.c.packOIDBPackageDynamically(3925, 1, binary.DynamicProtoMessage{1: guildId, 2: channelId}))
rsp, err := s.c.call(req)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0Xf55Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
return convertChannelInfo(body.Info), nil
@ -527,14 +523,14 @@ func (s *GuildService) GetTopicChannelFeeds(guildId, channelId uint64) ([]*topic
},
},
})
seq, packet := s.c.uniPacket("QChannelSvr.trpc.qchannel.commreader.ComReader.GetChannelTimelineFeeds", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
call := s.c.uniRequest("QChannelSvr.trpc.qchannel.commreader.ComReader.GetChannelTimelineFeeds", payload)
rsp, err := s.c.call(call)
if err != nil {
return nil, errors.New("send packet error")
}
pkg := new(qweb.QWebRsp)
body := new(channel.StGetChannelFeedsRsp)
if err = proto.Unmarshal(rsp, pkg); err != nil {
if err = proto.Unmarshal(rsp.Body, pkg); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
if err = proto.Unmarshal(pkg.BusiBuff, body); err != nil {
@ -597,14 +593,13 @@ func (s *GuildService) PostTopicChannelFeed(guildId, channelId uint64, feed *top
},
},
})
seq, packet := s.c.uniPacket("QChannelSvr.trpc.qchannel.commwriter.ComWriter.PublishFeed", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.call(s.c.uniRequest("QChannelSvr.trpc.qchannel.commwriter.ComWriter.PublishFeed", payload))
if err != nil {
return errors.New("send packet error")
}
pkg := new(qweb.QWebRsp)
body := new(channel.StPublishFeedRsp)
if err = proto.Unmarshal(rsp, pkg); err != nil {
if err = proto.Unmarshal(rsp.Body, pkg); err != nil {
return errors.Wrap(err, "failed to unmarshal protobuf message")
}
if err = proto.Unmarshal(pkg.BusiBuff, body); err != nil {
@ -618,7 +613,7 @@ func (s *GuildService) PostTopicChannelFeed(guildId, channelId uint64, feed *top
func (s *GuildService) fetchMemberRoles(guildId uint64, tinyId uint64) ([]*GuildRole, error) {
u1 := uint32(1)
seq, packet := s.c.uniPacket("OidbSvcTrpcTcp.0x1017_1", s.c.packOIDBPackageDynamically(4119, 1, binary.DynamicProtoMessage{
req := s.c.uniRequest("OidbSvcTrpcTcp.0x1017_1", s.c.packOIDBPackageDynamically(4119, 1, binary.DynamicProtoMessage{
1: guildId,
2: tinyId,
4: binary.DynamicProtoMessage{
@ -627,12 +622,12 @@ func (s *GuildService) fetchMemberRoles(guildId uint64, tinyId uint64) ([]*Guild
3: u1,
},
}))
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.call(req)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.ChannelOidb0X1017Rsp)
if err = unpackOIDBPackage(rsp, body); err != nil {
if err = unpackOIDBPackage(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "decode packet error")
}
p1 := body.GetP1()
@ -709,13 +704,13 @@ func convertChannelInfo(info *channel.GuildChannelInfo) *ChannelInfo {
}
func (c *QQClient) syncChannelFirstView() {
rsp, err := c.sendAndWaitDynamic(c.buildSyncChannelFirstViewPacket())
rsp, err := c.call(c.buildSyncChannelFirstViewPacket())
if err != nil {
c.Error("sync channel error: %v", err)
return
}
firstViewRsp := new(channel.FirstViewRsp)
if err = proto.Unmarshal(rsp, firstViewRsp); err != nil {
if err = proto.Unmarshal(rsp.Body, firstViewRsp); err != nil {
return
}
c.GuildService.TinyId = firstViewRsp.GetSelfTinyid()
@ -728,14 +723,14 @@ func (c *QQClient) syncChannelFirstView() {
}
}
func (c *QQClient) buildSyncChannelFirstViewPacket() (uint16, []byte) {
func (c *QQClient) buildSyncChannelFirstViewPacket() *network.Request {
req := &channel.FirstViewReq{
LastMsgTime: proto.Uint64(0),
Seq: proto.Uint32(0),
DirectMessageFlag: proto.Uint32(1),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("trpc.group_pro.synclogic.SyncLogic.SyncFirstView", payload)
return c.uniRequest("trpc.group_pro.synclogic.SyncLogic.SyncFirstView", payload)
}
func decodeGuildPushFirstView(c *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -35,10 +35,6 @@ type guildImageUploadResponse struct {
IsExists bool
}
func init() {
decoders["ImgStore.QQMeetPicUp"] = decodeGuildImageStoreResponse
}
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) (*message.GuildChannelMessage, error) {
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
for _, elem := range m.Elements {
@ -68,13 +64,12 @@ func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *mes
},
}}
payload, _ := proto.Marshal(req)
seq, packet := s.c.uniPacket("MsgProxy.SendMsg", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.commandCall("MsgProxy.SendMsg", payload)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
body := new(channel.DF62RspBody)
if err = proto.Unmarshal(rsp, body); err != nil {
if err = proto.Unmarshal(rsp.Body, body); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
if body.GetResult() != 0 {
@ -99,7 +94,7 @@ func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *mes
}
func (s *GuildService) QueryImage(guildId, channelId uint64, hash []byte, size uint64) (*message.GuildImageElement, error) {
rsp, err := s.c.sendAndWait(s.c.buildGuildImageStorePacket(guildId, channelId, hash, size))
rsp, err := s.c.callAndDecode(s.c.buildGuildImageStorePacket(guildId, channelId, hash, size), decodeGuildImageStoreResponse)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
@ -122,7 +117,7 @@ func (s *GuildService) UploadGuildImage(guildId, channelId uint64, img io.ReadSe
_, _ = img.Seek(0, io.SeekStart) // safe
fh, length := utils.ComputeMd5AndLength(img)
_, _ = img.Seek(0, io.SeekStart)
rsp, err := s.c.sendAndWait(s.c.buildGuildImageStorePacket(guildId, channelId, fh, uint64(length)))
rsp, err := s.c.callAndDecode(s.c.buildGuildImageStorePacket(guildId, channelId, fh, uint64(length)), decodeGuildImageStoreResponse)
if err != nil {
return nil, err
}
@ -215,19 +210,18 @@ func (s *GuildService) pullChannelMessages(guildId, channelId, beginSeq, endSeq,
WithVersionFlag: &withVersionFlag,
DirectMessageFlag: &directFlag,
})
seq, packet := s.c.uniPacket("trpc.group_pro.synclogic.SyncLogic.GetChannelMsg", payload)
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
rsp, err := s.c.commandCall("trpc.group_pro.synclogic.SyncLogic.GetChannelMsg", payload)
if err != nil {
return nil, errors.Wrap(err, "send packet error")
}
msgRsp := new(channel.ChannelMsgRsp)
if err = proto.Unmarshal(rsp, msgRsp); err != nil {
if err = proto.Unmarshal(rsp.Body, msgRsp); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
return msgRsp.ChannelMsg.Msgs, nil
}
func (c *QQClient) buildGuildImageStorePacket(guildId, channelId uint64, hash []byte, size uint64) (uint16, []byte) {
func (c *QQClient) buildGuildImageStorePacket(guildId, channelId uint64, hash []byte, size uint64) *network.Request {
payload, _ := proto.Marshal(&cmd0x388.D388ReqBody{
NetType: proto.Uint32(3),
Subcmd: proto.Uint32(1),
@ -252,7 +246,7 @@ func (c *QQClient) buildGuildImageStorePacket(guildId, channelId uint64, hash []
},
CommandId: proto.Uint32(83),
})
return c.uniPacket("ImgStore.QQMeetPicUp", payload)
return c.uniRequest("ImgStore.QQMeetPicUp", payload)
}
func decodeGuildMessageEmojiReactions(content *channel.ChannelMsgContent) (r []*message.GuildMessageEmojiReaction) {
@ -349,13 +343,13 @@ func (s *GuildService) parseGuildChannelMessage(msg *channel.ChannelMsgContent)
}
// PttCenterSvr.GroupShortVideoUpReq
func (c *QQClient) buildPttGuildVideoUpReq(videoHash, thumbHash []byte, guildId, channelId int64, videoSize, thumbSize int64) (uint16, []byte) {
func (c *QQClient) buildPttGuildVideoUpReq(videoHash, thumbHash []byte, guildId, channelId int64, videoSize, thumbSize int64) *network.Request {
pb := c.buildPttGroupShortVideoProto(videoHash, thumbHash, guildId, videoSize, thumbSize, 4)
pb.PttShortVideoUploadReq.BusinessType = 4601
pb.PttShortVideoUploadReq.ToUin = channelId
pb.ExtensionReq[0].SubBusiType = 4601
payload, _ := proto.Marshal(pb)
return c.uniPacket("PttCenterSvr.GroupShortVideoUpReq", payload)
return c.uniRequest("PttCenterSvr.GroupShortVideoUpReq", payload)
}
func (c *QQClient) UploadGuildShortVideo(guildId, channelId uint64, video, thumb io.ReadSeeker) (*message.ShortVideoElement, error) {
@ -367,7 +361,7 @@ func (c *QQClient) UploadGuildShortVideo(guildId, channelId uint64, video, thumb
pttWaiter.Wait(key)
defer pttWaiter.Done(key)
i, err := c.sendAndWait(c.buildPttGuildVideoUpReq(videoHash, thumbHash, int64(guildId), int64(channelId), videoLen, thumbLen))
i, err := c.callAndDecode(c.buildPttGuildVideoUpReq(videoHash, thumbHash, int64(guildId), int64(channelId), videoLen, thumbLen), decodeGroupShortVideoUploadResponse)
if err != nil {
return nil, errors.Wrap(err, "upload req error")
}

View File

@ -23,12 +23,6 @@ import (
"github.com/Mrs4s/MiraiGo/utils"
)
func init() {
decoders["ImgStore.GroupPicUp"] = decodeGroupImageStoreResponse
decoders["ImgStore.GroupPicDown"] = decodeGroupImageDownloadResponse
decoders["OidbSvc.0xe07_0"] = decodeImageOcrResponse
}
var imgWaiter = utils.NewUploadWaiter()
type imageUploadResponse struct {
@ -53,8 +47,8 @@ func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*messag
imgWaiter.Wait(key)
defer imgWaiter.Done(key)
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh, int32(length))
r, err := c.sendAndWait(seq, pkt)
req := c.buildGroupImageStoreRequest(groupCode, fh, int32(length))
r, err := c.callAndDecode(req, decodeGroupImageStoreResponse)
if err != nil {
return nil, err
}
@ -105,8 +99,8 @@ func (c *QQClient) UploadGroupImageByFile(groupCode int64, path string) (*messag
imgWaiter.Wait(key)
defer imgWaiter.Done(key)
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh, int32(length))
r, err := c.sendAndWait(seq, pkt)
req := c.buildGroupImageStoreRequest(groupCode, fh, int32(length))
r, err := c.callAndDecode(req, decodeGroupImageStoreResponse)
if err != nil {
return nil, err
}
@ -151,7 +145,7 @@ func (c *QQClient) UploadPrivateImage(target int64, img io.ReadSeeker) (*message
}
func (c *QQClient) GetGroupImageDownloadUrl(fileId, groupCode int64, fileMd5 []byte) (string, error) {
i, err := c.sendAndWait(c.buildGroupImageDownloadPacket(fileId, groupCode, fileMd5))
i, err := c.callAndDecode(c.buildGroupImageDownloadRequest(fileId, groupCode, fileMd5), decodeGroupImageDownloadResponse)
if err != nil {
return "", err
}
@ -191,7 +185,8 @@ func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
}
_ = b.Close()
}
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
call := c.buildImageOcrRequestPacket(url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height)
rsp, err := c.callAndDecode(call, decodeImageOcrResponse)
if err != nil {
return nil, err
}
@ -201,7 +196,7 @@ func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
}
func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) {
r, err := c.sendAndWait(c.buildGroupImageStorePacket(groupCode, hash, size))
r, err := c.callAndDecode(c.buildGroupImageStoreRequest(groupCode, hash, size), decodeGroupImageStoreResponse)
if err != nil {
return nil, err
}
@ -216,7 +211,7 @@ func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*m
}
func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*message.FriendImageElement, error) {
i, err := c.sendAndWait(c.buildOffPicUpPacket(target, hash, size))
i, err := c.callAndDecode(c.buildOffPicUpRequest(target, hash, size), decodeOffPicUpResponse)
if err != nil {
return nil, err
}
@ -239,7 +234,7 @@ func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*mes
}
// ImgStore.GroupPicUp
func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size int32) (uint16, []byte) {
func (c *QQClient) buildGroupImageStoreRequest(groupCode int64, md5 []byte, size int32) *network.Request {
name := utils.RandomString(16) + ".gif"
req := &cmd0x388.D388ReqBody{
NetType: proto.Uint32(3),
@ -264,10 +259,10 @@ func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size
Extension: EmptyBytes,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ImgStore.GroupPicUp", payload)
return c.uniRequest("ImgStore.GroupPicUp", payload)
}
func (c *QQClient) buildGroupImageDownloadPacket(fileId, groupCode int64, fileMd5 []byte) (uint16, []byte) {
func (c *QQClient) buildGroupImageDownloadRequest(fileId, groupCode int64, fileMd5 []byte) *network.Request {
req := &cmd0x388.D388ReqBody{
NetType: proto.Uint32(3),
Subcmd: proto.Uint32(2),
@ -288,7 +283,7 @@ func (c *QQClient) buildGroupImageDownloadPacket(fileId, groupCode int64, fileMd
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ImgStore.GroupPicDown", payload)
return c.uniRequest("ImgStore.GroupPicDown", payload)
}
func (c *QQClient) uploadOcrImage(img io.Reader) (string, error) {
@ -318,7 +313,7 @@ func (c *QQClient) uploadOcrImage(img io.Reader) (string, error) {
}
// OidbSvc.0xe07_0
func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, height int32) (uint16, []byte) {
func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, height int32) *network.Request {
body := &oidb.DE07ReqBody{
Version: 1,
Entrance: 3,
@ -334,7 +329,7 @@ func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, hei
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(3591, 0, b)
return c.uniPacket("OidbSvc.0xe07_0", payload)
return c.uniRequest("OidbSvc.0xe07_0", payload)
}
// ImgStore.GroupPicUp

View File

@ -1,5 +1,15 @@
package network
// Call is a client-side RPC call.
// refer to `net/rpc`
type Call struct {
Request *Request
Response *Response
Err error
Params RequestParams
Done chan *Call
}
type RequestParams map[string]interface{}
func (p RequestParams) Bool(k string) bool {

View File

@ -17,13 +17,8 @@ import (
"github.com/Mrs4s/MiraiGo/utils"
)
func init() {
decoders["MultiMsg.ApplyUp"] = decodeMultiApplyUpResponse
decoders["MultiMsg.ApplyDown"] = decodeMultiApplyDownResponse
}
// MultiMsg.ApplyUp
func (c *QQClient) buildMultiApplyUpPacket(data, hash []byte, buType int32, groupUin int64) (uint16, []byte) {
func (c *QQClient) buildMultiApplyUpPacket(data, hash []byte, buType int32, groupUin int64) *network.Request {
req := &multimsg.MultiReqBody{
Subcmd: 1,
TermType: 5,
@ -41,7 +36,7 @@ func (c *QQClient) buildMultiApplyUpPacket(data, hash []byte, buType int32, grou
BuType: buType,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MultiMsg.ApplyUp", payload)
return c.uniRequest("MultiMsg.ApplyUp", payload)
}
// MultiMsg.ApplyUp
@ -64,7 +59,7 @@ func decodeMultiApplyUpResponse(_ *QQClient, resp *network.Response) (interface{
}
// MultiMsg.ApplyDown
func (c *QQClient) buildMultiApplyDownPacket(resID string) (uint16, []byte) {
func (c *QQClient) buildMultiApplyDownPacket(resID string) *network.Request {
req := &multimsg.MultiReqBody{
Subcmd: 2,
TermType: 5,
@ -81,7 +76,7 @@ func (c *QQClient) buildMultiApplyDownPacket(resID string) (uint16, []byte) {
ReqChannelType: 2,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MultiMsg.ApplyDown", payload)
return c.uniRequest("MultiMsg.ApplyDown", payload)
}
// MultiMsg.ApplyDown
@ -182,7 +177,7 @@ func (c *QQClient) GetForwardMessage(resID string) *message.ForwardMessage {
}
func (c *QQClient) DownloadForwardMessage(resId string) *message.ForwardElement {
i, err := c.sendAndWait(c.buildMultiApplyDownPacket(resId))
i, err := c.callAndDecode(c.buildMultiApplyDownPacket(resId), decodeMultiApplyDownResponse)
if err != nil {
return nil
}

View File

@ -146,6 +146,52 @@ func (c *QQClient) Disconnect() {
c.TCP.Close()
}
func (c *QQClient) send(call *network.Call) {
if call.Done == nil {
call.Done = make(chan *network.Call, 3) // use buffered channel
}
seq := uint16(call.Request.SequenceID)
c.pendingMu.Lock()
c.pending[seq] = call
c.pendingMu.Unlock()
err := c.sendPacket(c.transport.PackPacket(call.Request))
if err != nil {
c.pendingMu.Lock()
call = c.pending[seq]
delete(c.pending, seq)
call.Err = err
call.Done <- call
c.pendingMu.Unlock()
}
}
func (c *QQClient) sendReq(req *network.Request) {
c.send(&network.Call{Request: req})
}
func (c *QQClient) call(req *network.Request) (*network.Response, error) {
call := &network.Call{
Request: req,
Done: make(chan *network.Call, 3),
}
c.send(call)
select {
case <-call.Done:
return call.Response, call.Err
case <-time.After(time.Second * 15):
return nil, errors.New("Packet timed out")
}
}
func (c *QQClient) callAndDecode(req *network.Request, decoder func(*QQClient, *network.Response) (interface{}, error)) (interface{}, error) {
resp, err := c.call(req)
if err != nil {
return nil, err
}
return decoder(c, resp)
}
func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
return c.sendAndWaitParams(seq, pkt, nil)
}
@ -325,6 +371,26 @@ func (c *QQClient) netLoop() {
c.Dump("packet decode error: %v - %v", req.Body, req.CommandName, pan)
}
}()
// snapshot of read call
c.pendingMu.Lock()
call := c.pending[uint16(req.SequenceID)]
if call != nil {
call.Response = &network.Response{
SequenceID: req.SequenceID,
CommandName: req.CommandName,
Body: req.Body,
// Request: nil,
}
}
c.pendingMu.Unlock()
if call != nil {
select {
case call.Done <- call:
default:
}
}
if decoder, ok := decoders[req.CommandName]; ok {
// found predefined decoder
info, ok := c.handlers.LoadAndDelete(uint16(req.SequenceID))

View File

@ -8,11 +8,7 @@ import (
"github.com/Mrs4s/MiraiGo/internal/proto"
)
func init() {
decoders["OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200"] = decodeOfflineFileDownloadResponse
}
func (c *QQClient) buildOfflineFileDownloadRequestPacket(uuid []byte) (uint16, []byte) {
func (c *QQClient) buildOfflineFileDownloadRequestPacket(uuid []byte) *network.Request {
seq := c.nextSeq()
req := &cmd0x346.C346ReqBody{
Cmd: 1200,
@ -29,8 +25,7 @@ func (c *QQClient) buildOfflineFileDownloadRequestPacket(uuid []byte) (uint16, [
},
}
payload, _ := proto.Marshal(req)
packet := c.uniPacketWithSeq(seq, "OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200", payload)
return seq, packet
return c.uniPacketWithSeq(seq, "OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200", payload)
}
func decodeOfflineFileDownloadResponse(c *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -17,7 +17,19 @@ func (c *QQClient) buildOicqRequestPacket(uin int64, command uint16, body []byte
}
//go:noinline
func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
func (c *QQClient) uniRequest(command string, body []byte) *network.Request {
seq := c.nextSeq()
return &network.Request{
Type: network.RequestTypeSimple,
EncryptType: network.EncryptTypeD2Key,
Uin: c.Uin,
SequenceID: int32(seq),
CommandName: command,
Body: body,
}
}
func (c *QQClient) commandCall(command string, body []byte) (*network.Response, error) {
seq := c.nextSeq()
req := network.Request{
Type: network.RequestTypeSimple,
@ -27,11 +39,11 @@ func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
CommandName: command,
Body: body,
}
return seq, c.transport.PackPacket(&req)
return c.call(&req)
}
//go:noinline
func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []byte {
func (c *QQClient) commandCallAndDecode(command string, body []byte, decode func(*QQClient, *network.Response) (interface{}, error)) (interface{}, error) {
seq := c.nextSeq()
req := network.Request{
Type: network.RequestTypeSimple,
EncryptType: network.EncryptTypeD2Key,
@ -40,5 +52,22 @@ func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []b
CommandName: command,
Body: body,
}
return c.transport.PackPacket(&req)
resp, err := c.call(&req)
if err != nil {
return nil, err
}
return decode(c, resp)
}
//go:noinline
func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) *network.Request {
req := network.Request{
Type: network.RequestTypeSimple,
EncryptType: network.EncryptTypeD2Key,
Uin: c.Uin,
SequenceID: int32(seq),
CommandName: command,
Body: body,
}
return &req
}

View File

@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
"github.com/Mrs4s/MiraiGo/client/internal/network"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/internal/proto"
"github.com/Mrs4s/MiraiGo/message"
@ -37,13 +38,13 @@ func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) *
if i == 0 {
seq = fseq
}
_, pkt := c.buildFriendSendingPacket(target, fseq, mr, int32(len(fragmented)), int32(i), div, t, elems)
_ = c.sendPacket(pkt)
req := c.buildFriendSendingPacket(target, fseq, mr, int32(len(fragmented)), int32(i), div, t, elems)
c.sendReq(req)
}
} else {
seq = c.nextFriendSeq()
_, pkt := c.buildFriendSendingPacket(target, seq, mr, 1, 0, 0, t, m.Elements)
_ = c.sendPacket(pkt)
pkt := c.buildFriendSendingPacket(target, seq, mr, 1, 0, 0, t, m.Elements)
c.sendReq(pkt)
}
c.stat.MessageSent.Add(1)
ret := &message.PrivateMessage{
@ -82,8 +83,8 @@ func (c *QQClient) SendGroupTempMessage(groupCode, target int64, m *message.Send
mr := int32(rand.Uint32())
seq := c.nextFriendSeq()
t := time.Now().Unix()
_, pkt := c.buildGroupTempSendingPacket(group.Uin, target, seq, mr, t, m)
_ = c.sendPacket(pkt)
pkt := c.buildGroupTempSendingPacket(group.Uin, target, seq, mr, t, m)
c.sendReq(pkt)
c.stat.MessageSent.Add(1)
return &message.TempMessage{
Id: seq,
@ -103,8 +104,8 @@ func (c *QQClient) sendWPATempMessage(target int64, sig []byte, m *message.Sendi
mr := int32(rand.Uint32())
seq := c.nextFriendSeq()
t := time.Now().Unix()
_, pkt := c.buildWPATempSendingPacket(target, sig, seq, mr, t, m)
_ = c.sendPacket(pkt)
pkt := c.buildWPATempSendingPacket(target, sig, seq, mr, t, m)
c.sendReq(pkt)
c.stat.MessageSent.Add(1)
return &message.TempMessage{
Id: seq,
@ -130,7 +131,7 @@ func (s *TempSessionInfo) SendMessage(m *message.SendingMessage) (*message.TempM
}
/* this function is unused
func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int64, count uint32) (uint16, []byte) {
func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int64, count uint32) *network.Request {
seq := c.nextSeq()
req := &msg.PbGetOneDayRoamMsgReq{
PeerUin: proto.Uint64(uint64(target)),
@ -145,7 +146,7 @@ func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int6
*/
// MessageSvc.PbSendMsg
func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r, pkgNum, pkgIndex, pkgDiv int32, time int64, m []message.IMessageElement) (uint16, []byte) {
func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r, pkgNum, pkgIndex, pkgDiv int32, time int64, m []message.IMessageElement) *network.Request {
var ptt *msg.Ptt
if len(m) > 0 {
if p, ok := m[0].(*message.PrivateVoiceElement); ok {
@ -178,11 +179,11 @@ func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r, pkgNum, pkg
}(),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbSendMsg", payload)
return c.uniRequest("MessageSvc.PbSendMsg", payload)
}
// MessageSvc.PbSendMsg
func (c *QQClient) buildGroupTempSendingPacket(groupUin, target int64, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) {
func (c *QQClient) buildGroupTempSendingPacket(groupUin, target int64, msgSeq, r int32, time int64, m *message.SendingMessage) *network.Request {
req := &msg.SendMessageRequest{
RoutingHead: &msg.RoutingHead{GrpTmp: &msg.GrpTmp{
GroupUin: &groupUin,
@ -210,10 +211,10 @@ func (c *QQClient) buildGroupTempSendingPacket(groupUin, target int64, msgSeq, r
}(),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbSendMsg", payload)
return c.uniRequest("MessageSvc.PbSendMsg", payload)
}
func (c *QQClient) buildWPATempSendingPacket(uin int64, sig []byte, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) {
func (c *QQClient) buildWPATempSendingPacket(uin int64, sig []byte, msgSeq, r int32, time int64, m *message.SendingMessage) *network.Request {
req := &msg.SendMessageRequest{
RoutingHead: &msg.RoutingHead{WpaTmp: &msg.WPATmp{
ToUin: proto.Uint64(uint64(uin)),
@ -241,5 +242,5 @@ func (c *QQClient) buildWPATempSendingPacket(uin int64, sig []byte, msgSeq, r in
}(),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("MessageSvc.PbSendMsg", payload)
return c.uniRequest("MessageSvc.PbSendMsg", payload)
}

View File

@ -147,7 +147,8 @@ func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSe
pttWaiter.Wait(key)
defer pttWaiter.Done(key)
i, err := c.sendAndWait(c.buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash, groupCode, videoLen, thumbLen))
i, err := c.callAndDecode(c.buildPttGroupShortVideoUploadReq(videoHash, thumbHash, groupCode, videoLen, thumbLen),
decodeGroupShortVideoUploadResponse)
if err != nil {
return nil, errors.Wrap(err, "upload req error")
}
@ -210,7 +211,7 @@ func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSe
}
func (c *QQClient) GetShortVideoUrl(uuid, md5 []byte) string {
i, err := c.sendAndWait(c.buildPttShortVideoDownReqPacket(uuid, md5))
i, err := c.callAndDecode(c.buildPttShortVideoDownReq(uuid, md5), decodePttShortVideoDownResponse)
if err != nil {
return ""
}
@ -245,7 +246,7 @@ func (c *QQClient) buildGroupPttStoreBDHExt(groupCode int64, md5 []byte, size, c
}
// PttCenterSvr.ShortVideoDownReq
func (c *QQClient) buildPttShortVideoDownReqPacket(uuid, md5 []byte) (uint16, []byte) {
func (c *QQClient) buildPttShortVideoDownReq(uuid, md5 []byte) *network.Request {
seq := c.nextSeq()
body := &pttcenter.ShortVideoReqBody{
Cmd: 400,
@ -265,8 +266,7 @@ func (c *QQClient) buildPttShortVideoDownReqPacket(uuid, md5 []byte) (uint16, []
},
}
payload, _ := proto.Marshal(body)
packet := c.uniPacketWithSeq(seq, "PttCenterSvr.ShortVideoDownReq", payload)
return seq, packet
return c.uniPacketWithSeq(seq, "PttCenterSvr.ShortVideoDownReq", payload)
}
func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64, chattype int32) *pttcenter.ShortVideoReqBody {
@ -303,9 +303,9 @@ func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toU
}
// PttCenterSvr.GroupShortVideoUpReq
func (c *QQClient) buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) (uint16, []byte) {
func (c *QQClient) buildPttGroupShortVideoUploadReq(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) *network.Request {
payload, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, toUin, videoSize, thumbSize, 1))
return c.uniPacket("PttCenterSvr.GroupShortVideoUpReq", payload)
return c.uniRequest("PttCenterSvr.GroupShortVideoUpReq", payload)
}
// PttCenterSvr.pb_pttCenter_CMD_REQ_APPLY_UPLOAD-500

View File

@ -63,7 +63,7 @@ func (c *QQClient) getQiDianAddressDetailList() ([]*FriendInfo, error) {
return ret, nil
}
func (c *QQClient) buildLoginExtraPacket() (uint16, []byte) {
func (c *QQClient) buildLoginExtraPacket() *network.Request {
req := &cmd0x3f6.C3F6ReqBody{
SubCmd: proto.Uint32(69),
CrmCommonHead: &cmd0x3f6.C3F6CRMMsgHead{
@ -86,10 +86,10 @@ func (c *QQClient) buildLoginExtraPacket() (uint16, []byte) {
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("qidianservice.69", payload)
return c.uniRequest("qidianservice.69", payload)
}
func (c *QQClient) buildConnKeyRequestPacket() (uint16, []byte) {
func (c *QQClient) buildConnKeyRequestPacket() *network.Request {
req := &cmd0x6ff.C501ReqBody{
ReqBody: &cmd0x6ff.SubCmd0X501ReqBody{
Uin: proto.Uint64(uint64(c.Uin)),
@ -101,7 +101,7 @@ func (c *QQClient) buildConnKeyRequestPacket() (uint16, []byte) {
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("HttpConn.0x6ff_501", payload)
return c.uniRequest("HttpConn.0x6ff_501", payload)
}
func (c *QQClient) bigDataRequest(subCmd uint32, req proto.Message) ([]byte, error) {

View File

@ -22,7 +22,7 @@ func (c *QQClient) RecallGroupMessage(groupCode int64, msgID, msgInternalId int3
}
}
}
_, err := c.sendAndWait(c.buildGroupRecallPacket(groupCode, msgID, msgInternalId))
_, err := c.callAndDecode(c.buildGroupRecallPacket(groupCode, msgID, msgInternalId), decodeMsgWithDrawResponse)
return err
}
@ -30,7 +30,7 @@ func (c *QQClient) internalGroupRecall(groupCode int64, msgInternalID int32, m [
for _, item := range m {
if item.InternalId == msgInternalID {
flag = true
if _, err := c.sendAndWait(c.buildGroupRecallPacket(groupCode, item.Id, item.InternalId)); err != nil {
if _, err := c.callAndDecode(c.buildGroupRecallPacket(groupCode, item.Id, item.InternalId), decodeMsgWithDrawResponse); err != nil {
return false, err
}
}
@ -39,12 +39,12 @@ func (c *QQClient) internalGroupRecall(groupCode int64, msgInternalID int32, m [
}
func (c *QQClient) RecallPrivateMessage(uin, ts int64, msgID, msgInternalId int32) error {
_, err := c.sendAndWait(c.buildPrivateRecallPacket(uin, ts, msgID, msgInternalId))
_, err := c.callAndDecode(c.buildPrivateRecallPacket(uin, ts, msgID, msgInternalId), decodeMsgWithDrawResponse)
return err
}
// PbMessageSvc.PbMsgWithDraw
func (c *QQClient) buildGroupRecallPacket(groupCode int64, msgSeq, msgRan int32) (uint16, []byte) {
func (c *QQClient) buildGroupRecallPacket(groupCode int64, msgSeq, msgRan int32) *network.Request {
req := &msg.MsgWithDrawReq{
GroupWithDraw: []*msg.GroupMsgWithDrawReq{
{
@ -62,10 +62,10 @@ func (c *QQClient) buildGroupRecallPacket(groupCode int64, msgSeq, msgRan int32)
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("PbMessageSvc.PbMsgWithDraw", payload)
return c.uniRequest("PbMessageSvc.PbMsgWithDraw", payload)
}
func (c *QQClient) buildPrivateRecallPacket(uin, ts int64, msgSeq, random int32) (uint16, []byte) {
func (c *QQClient) buildPrivateRecallPacket(uin, ts int64, msgSeq, random int32) *network.Request {
req := &msg.MsgWithDrawReq{C2CWithDraw: []*msg.C2CMsgWithDrawReq{
{
MsgInfo: []*msg.C2CMsgInfo{
@ -89,7 +89,7 @@ func (c *QQClient) buildPrivateRecallPacket(uin, ts int64, msgSeq, random int32)
},
}}
payload, _ := proto.Marshal(req)
return c.uniPacket("PbMessageSvc.PbMsgWithDraw", payload)
return c.uniRequest("PbMessageSvc.PbMsgWithDraw", payload)
}
func decodeMsgWithDrawResponse(_ *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
"github.com/Mrs4s/MiraiGo/client/internal/network"
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
"github.com/Mrs4s/MiraiGo/internal/proto"
"github.com/Mrs4s/MiraiGo/message"
@ -76,7 +77,7 @@ func (c *QQClient) SendGroupMusicShare(target int64, msg *message.MusicShareElem
}
})
defer c.onGroupMessageReceipt(eid)
_, _ = c.sendAndWait(c.buildRichMsgSendingPacket(0, target, msg, 1)) // rsp is empty chunk
_, _ = c.call(c.buildRichMsgSendingPacket(0, target, msg, 1)) // rsp is empty chunk
select {
case ret := <-ch:
return ret, nil
@ -87,17 +88,17 @@ func (c *QQClient) SendGroupMusicShare(target int64, msg *message.MusicShareElem
// SendFriendMusicShare 发送好友音乐卡片
func (c *QQClient) SendFriendMusicShare(target int64, msg *message.MusicShareElement) {
_, _ = c.sendAndWait(c.buildRichMsgSendingPacket(0, target, msg, 0))
_, _ = c.call(c.buildRichMsgSendingPacket(0, target, msg, 0))
}
// SendGuildMusicShare 发送频道音乐卡片
func (c *QQClient) SendGuildMusicShare(guildID, channelID uint64, msg *message.MusicShareElement) {
// todo(wdvxdr): message receipt?
_, _ = c.sendAndWait(c.buildRichMsgSendingPacket(guildID, int64(channelID), msg, 3))
_, _ = c.call(c.buildRichMsgSendingPacket(guildID, int64(channelID), msg, 3))
}
// OidbSvc.0xb77_9
func (c *QQClient) buildRichMsgSendingPacket(guild uint64, target int64, msg *message.MusicShareElement, sendType uint32) (uint16, []byte) {
func (c *QQClient) buildRichMsgSendingPacket(guild uint64, target int64, msg *message.MusicShareElement, sendType uint32) *network.Request {
tp := musicType[msg.MusicType] // MusicType
msgStyle := uint32(0)
if msg.MusicUrl != "" {
@ -128,5 +129,5 @@ func (c *QQClient) buildRichMsgSendingPacket(guild uint64, target int64, msg *me
}
b, _ := proto.Marshal(body)
payload := c.packOIDBPackage(2935, 9, b)
return c.uniPacket("OidbSvc.0xb77_9", payload)
return c.uniRequest("OidbSvc.0xb77_9", payload)
}

View File

@ -8,10 +8,6 @@ import (
"github.com/Mrs4s/MiraiGo/internal/proto"
)
func init() {
decoders["OidbSvc.0xbcb_0"] = decodeUrlCheckResponse
}
type UrlSecurityLevel int
const (
@ -22,14 +18,14 @@ const (
// CheckUrlSafely 通过TX服务器检查URL安全性
func (c *QQClient) CheckUrlSafely(url string) UrlSecurityLevel {
i, err := c.sendAndWait(c.buildUrlCheckRequest(url))
i, err := c.callAndDecode(c.buildUrlCheckRequest(url), decodeUrlCheckResponse)
if err != nil {
return Unknown
}
return i.(UrlSecurityLevel)
}
func (c *QQClient) buildUrlCheckRequest(url string) (uint16, []byte) {
func (c *QQClient) buildUrlCheckRequest(url string) *network.Request {
payload := c.packOIDBPackageProto(3019, 0, &oidb.DBCBReqBody{
CheckUrlReq: &oidb.CheckUrlReq{
Url: []string{url},
@ -45,7 +41,7 @@ func (c *QQClient) buildUrlCheckRequest(url string) (uint16, []byte) {
Qua: proto.String("AQQ_2013 4.6/2013 8.4.184945&NA_0/000000&ADR&null18&linux&2017&C2293D02BEE31158&7.1.2&V3"),
},
})
return c.uniPacket("OidbSvc.0xbcb_0", payload)
return c.uniRequest("OidbSvc.0xbcb_0", payload)
}
func decodeUrlCheckResponse(_ *QQClient, resp *network.Response) (interface{}, error) {

View File

@ -17,16 +17,9 @@ import (
)
func init() {
decoders["StatSvc.GetDevLoginInfo"] = decodeDevListResponse
decoders["StatSvc.SvcReqMSFLoginNotify"] = decodeLoginNotifyPacket
decoders["RegPrxySvc.getOffMsg"] = ignoreDecoder
decoders["RegPrxySvc.GetMsgV2"] = ignoreDecoder
decoders["RegPrxySvc.PbGetMsg"] = ignoreDecoder
decoders["RegPrxySvc.NoticeEnd"] = ignoreDecoder
decoders["RegPrxySvc.PushParam"] = decodePushParamPacket
decoders["RegPrxySvc.PbSyncMsg"] = decodeMsgSyncResponse
decoders["PbMessageSvc.PbMsgReadedReport"] = decodeMsgReadedResponse
decoders["MessageSvc.PushReaded"] = ignoreDecoder
decoders["OnlinePush.PbC2CMsgSync"] = decodeC2CSyncPacket
}
@ -52,7 +45,7 @@ type (
// GetAllowedClients 获取已允许的其他客户端
func (c *QQClient) GetAllowedClients() ([]*OtherClientInfo, error) {
i, err := c.sendAndWait(c.buildDeviceListRequestPacket())
i, err := c.callAndDecode(c.buildDeviceListRequestPacket(), decodeDevListResponse)
if err != nil {
return nil, err
}
@ -70,7 +63,7 @@ func (c *QQClient) GetAllowedClients() ([]*OtherClientInfo, error) {
// RefreshStatus 刷新客户端状态
func (c *QQClient) RefreshStatus() error {
_, err := c.sendAndWait(c.buildGetOfflineMsgRequestPacket())
_, err := c.call(c.buildGetOfflineMsgRequestPacket())
return err
}
@ -95,8 +88,8 @@ func (c *QQClient) SyncSessions() (*SessionSyncResponse, error) {
notifyChan <- true
}
})
_, pkt := c.buildSyncMsgRequestPacket()
if err := c.sendPacket(pkt); err != nil {
pkt := c.buildSyncMsgRequestPacket()
if _, err := c.call(pkt); err != nil {
stop()
return nil, err
}
@ -111,15 +104,15 @@ func (c *QQClient) SyncSessions() (*SessionSyncResponse, error) {
// MarkGroupMessageReaded 标记群消息已读, 适当调用应该能减少风控
func (c *QQClient) MarkGroupMessageReaded(groupCode, seq int64) {
_, _ = c.sendAndWait(c.buildGroupMsgReadedPacket(groupCode, seq))
_, _ = c.callAndDecode(c.buildGroupMsgReadedPacket(groupCode, seq), decodeMsgReadedResponse)
}
func (c *QQClient) MarkPrivateMessageReaded(uin, time int64) {
_, _ = c.sendAndWait(c.buildPrivateMsgReadedPacket(uin, time))
_, _ = c.callAndDecode(c.buildPrivateMsgReadedPacket(uin, time), decodeMsgReadedResponse)
}
// StatSvc.GetDevLoginInfo
func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
func (c *QQClient) buildDeviceListRequestPacket() *network.Request {
req := &jce.SvcReqGetDevLoginInfo{
Guid: c.deviceInfo.Guid,
LoginType: 1,
@ -136,11 +129,11 @@ func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("StatSvc.GetDevLoginInfo", pkt.ToBytes())
return c.uniRequest("StatSvc.GetDevLoginInfo", pkt.ToBytes())
}
// RegPrxySvc.getOffMsg
func (c *QQClient) buildGetOfflineMsgRequestPacket() (uint16, []byte) {
func (c *QQClient) buildGetOfflineMsgRequestPacket() *network.Request {
regReq := &jce.SvcReqRegisterNew{
RequestOptional: 0x101C2 | 32,
C2CMsg: &jce.SvcReqGetMsgV2{
@ -190,11 +183,11 @@ func (c *QQClient) buildGetOfflineMsgRequestPacket() (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("RegPrxySvc.getOffMsg", pkt.ToBytes())
return c.uniRequest("RegPrxySvc.getOffMsg", pkt.ToBytes())
}
// RegPrxySvc.PbSyncMsg
func (c *QQClient) buildSyncMsgRequestPacket() (uint16, []byte) {
func (c *QQClient) buildSyncMsgRequestPacket() *network.Request {
oidbReq, _ := proto.Marshal(&oidb.D769RspBody{
ConfigList: []*oidb.D769ConfigSeq{
{
@ -262,26 +255,26 @@ func (c *QQClient) buildSyncMsgRequestPacket() (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
return c.uniPacket("RegPrxySvc.infoSync", pkt.ToBytes())
return c.uniRequest("RegPrxySvc.infoSync", pkt.ToBytes())
}
// PbMessageSvc.PbMsgReadedReport
func (c *QQClient) buildGroupMsgReadedPacket(groupCode, msgSeq int64) (uint16, []byte) {
func (c *QQClient) buildGroupMsgReadedPacket(groupCode, msgSeq int64) *network.Request {
req, _ := proto.Marshal(&msg.PbMsgReadedReportReq{GrpReadReport: []*msg.PbGroupReadedReportReq{{
GroupCode: proto.Uint64(uint64(groupCode)),
LastReadSeq: proto.Uint64(uint64(msgSeq)),
}}})
return c.uniPacket("PbMessageSvc.PbMsgReadedReport", req)
return c.uniRequest("PbMessageSvc.PbMsgReadedReport", req)
}
func (c *QQClient) buildPrivateMsgReadedPacket(uin, time int64) (uint16, []byte) {
func (c *QQClient) buildPrivateMsgReadedPacket(uin, time int64) *network.Request {
req, _ := proto.Marshal(&msg.PbMsgReadedReportReq{C2CReadReport: &msg.PbC2CReadedReportReq{PairInfo: []*msg.UinPairReadInfo{
{
PeerUin: proto.Uint64(uint64(uin)),
LastReadTime: proto.Uint32(uint32(time)),
},
}, SyncCookie: c.sig.SyncCookie}})
return c.uniPacket("PbMessageSvc.PbMsgReadedReport", req)
return c.uniRequest("PbMessageSvc.PbMsgReadedReport", req)
}
// StatSvc.GetDevLoginInfo

View File

@ -44,12 +44,12 @@ type (
)
func (c *QQClient) GetGroupSystemMessages() (*GroupSystemMessages, error) {
i, err := c.sendAndWait(c.buildSystemMsgNewGroupPacket(false))
i, err := c.callAndDecode(c.buildSystemMsgNewGroupPacket(false), decodeSystemMsgGroupPacket)
if err != nil {
return nil, err
}
msg := i.(*GroupSystemMessages)
i, err = c.sendAndWait(c.buildSystemMsgNewGroupPacket(true))
i, err = c.callAndDecode(c.buildSystemMsgNewGroupPacket(true), decodeSystemMsgGroupPacket)
if err != nil {
return nil, err
}
@ -98,7 +98,7 @@ func (c *QQClient) exceptAndDispatchGroupSysMsg() {
}
// ProfileService.Pb.ReqSystemMsgNew.Group
func (c *QQClient) buildSystemMsgNewGroupPacket(suspicious bool) (uint16, []byte) {
func (c *QQClient) buildSystemMsgNewGroupPacket(suspicious bool) *network.Request {
req := &structmsg.ReqSystemMsgNew{
MsgNum: 100,
Version: 1000,
@ -130,11 +130,11 @@ func (c *QQClient) buildSystemMsgNewGroupPacket(suspicious bool) (uint16, []byte
}(),
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ProfileService.Pb.ReqSystemMsgNew.Group", payload)
return c.uniRequest("ProfileService.Pb.ReqSystemMsgNew.Group", payload)
}
// ProfileService.Pb.ReqSystemMsgAction.Group
func (c *QQClient) buildSystemMsgGroupActionPacket(reqID, requester, group int64, msgType int32, isInvite, accept, block bool, reason string) (uint16, []byte) {
func (c *QQClient) buildSystemMsgGroupActionPacket(reqID, requester, group int64, msgType int32, isInvite, accept, block bool, reason string) *network.Request {
subSrcId := int32(31)
groupMsgType := int32(1)
if isInvite {
@ -163,11 +163,11 @@ func (c *QQClient) buildSystemMsgGroupActionPacket(reqID, requester, group int64
Language: 1000,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ProfileService.Pb.ReqSystemMsgAction.Group", payload)
return c.uniRequest("ProfileService.Pb.ReqSystemMsgAction.Group", payload)
}
// ProfileService.Pb.ReqSystemMsgAction.Friend
func (c *QQClient) buildSystemMsgFriendActionPacket(reqID, requester int64, accept bool) (uint16, []byte) {
func (c *QQClient) buildSystemMsgFriendActionPacket(reqID, requester int64, accept bool) *network.Request {
infoType := int32(3)
if accept {
infoType = 2
@ -186,7 +186,7 @@ func (c *QQClient) buildSystemMsgFriendActionPacket(reqID, requester int64, acce
},
}
payload, _ := proto.Marshal(req)
return c.uniPacket("ProfileService.Pb.ReqSystemMsgAction.Friend", payload)
return c.uniRequest("ProfileService.Pb.ReqSystemMsgAction.Friend", payload)
}
// ProfileService.Pb.ReqSystemMsgNew.Group

View File

@ -8,7 +8,7 @@ import (
"github.com/Mrs4s/MiraiGo/internal/proto"
)
func (c *QQClient) buildTranslatePacket(src, dst, text string) (uint16, []byte) {
func (c *QQClient) buildTranslatePacket(src, dst, text string) *network.Request {
body := &oidb.TranslateReqBody{
BatchTranslateReq: &oidb.BatchTranslateReq{
SrcLanguage: src,
@ -23,11 +23,11 @@ func (c *QQClient) buildTranslatePacket(src, dst, text string) (uint16, []byte)
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
return c.uniPacket("OidbSvc.0x990", payload)
return c.uniRequest("OidbSvc.0x990", payload)
}
func (c *QQClient) Translate(src, dst, text string) (string, error) {
rsp, err := c.sendAndWait(c.buildTranslatePacket(src, dst, text))
rsp, err := c.callAndDecode(c.buildTranslatePacket(src, dst, text), decodeTranslateResponse)
if err != nil {
return "", err
}

View File

@ -90,12 +90,12 @@ func (c *QQClient) webSsoRequest(host, webCmd, data string) (string, error) {
Type: proto.Uint32(0),
Data: &data,
})
rspData, err := c.sendAndWaitDynamic(c.uniPacket(cmd, req))
rspData, err := c.call(c.uniRequest(cmd, req))
if err != nil {
return "", errors.Wrap(err, "send web sso request error")
}
rsp := &web.WebSsoResponseBody{}
if err = proto.Unmarshal(rspData, rsp); err != nil {
if err = proto.Unmarshal(rspData.Body, rsp); err != nil {
return "", errors.Wrap(err, "unmarshal response error")
}
return rsp.GetData(), nil