mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
feature GetAllowedClients() & OnlineClients.
This commit is contained in:
parent
b007a4d0d6
commit
a618d101db
@ -136,6 +136,65 @@ type (
|
|||||||
ClientAutoStatusInterval int64 `jceId:"19"`
|
ClientAutoStatusInterval int64 `jceId:"19"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SvcReqRegisterNew struct {
|
||||||
|
IJceStruct
|
||||||
|
RequestOptional int64 `jceId:"0"`
|
||||||
|
C2CMsg IJceStruct `jceId:"1"` // SvcReqGetMsgV2
|
||||||
|
GroupMsg IJceStruct `jceId:"2"` // SvcReqPullGroupMsgSeq
|
||||||
|
GroupMask byte `jceId:"15"`
|
||||||
|
EndSeq int64 `jceId:"16"`
|
||||||
|
}
|
||||||
|
|
||||||
|
SvcReqGetMsgV2 struct {
|
||||||
|
IJceStruct
|
||||||
|
Uin int64 `jceId:"0"`
|
||||||
|
DateTime int32 `jceId:"1"`
|
||||||
|
RecivePic byte `jceId:"4"`
|
||||||
|
Ability int16 `jceId:"6"`
|
||||||
|
Channel byte `jceId:"9"`
|
||||||
|
Inst byte `jceId:"16"`
|
||||||
|
ChannelEx byte `jceId:"17"`
|
||||||
|
SyncCookie []byte `jceId:"18"`
|
||||||
|
SyncFlag int `jceId:"19"`
|
||||||
|
RambleFlag byte `jceId:"20"`
|
||||||
|
GeneralAbi int64 `jceId:"26"`
|
||||||
|
PubAccountCookie []byte `jceId:"27"`
|
||||||
|
}
|
||||||
|
|
||||||
|
SvcReqPullGroupMsgSeq struct {
|
||||||
|
IJceStruct
|
||||||
|
GroupInfo []IJceStruct `jceId:"0"` // PullGroupSeqParam
|
||||||
|
VerifyType byte `jceId:"1"`
|
||||||
|
Filter int32 `jceId:"2"`
|
||||||
|
}
|
||||||
|
|
||||||
|
PullGroupSeqParam struct {
|
||||||
|
IJceStruct
|
||||||
|
GroupCode int64 `jceId:"0"`
|
||||||
|
LastSeqId int64 `jceId:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
SvcRespParam struct {
|
||||||
|
PCStat int32 `jceId:"0"`
|
||||||
|
IsSupportC2CRoamMsg int32 `jceId:"1"`
|
||||||
|
IsSupportDataLine int32 `jceId:"2"`
|
||||||
|
IsSupportPrintable int32 `jceId:"3"`
|
||||||
|
IsSupportViewPCFile int32 `jceId:"4"`
|
||||||
|
PcVersion int32 `jceId:"5"`
|
||||||
|
RoamFlag int64 `jceId:"6"`
|
||||||
|
OnlineInfos []OnlineInfo `jceId:"7"`
|
||||||
|
PCClientType int32 `jceId:"8"`
|
||||||
|
}
|
||||||
|
|
||||||
|
OnlineInfo struct {
|
||||||
|
InstanceId int32 `jceId:"0"`
|
||||||
|
ClientType int32 `jceId:"1"`
|
||||||
|
OnlineStatus int32 `jceId:"2"`
|
||||||
|
PlatformId int32 `jceId:"3"`
|
||||||
|
SubPlatform string `jceId:"4"`
|
||||||
|
UClientType int64 `jceId:"5"`
|
||||||
|
}
|
||||||
|
|
||||||
PushMessageInfo struct {
|
PushMessageInfo struct {
|
||||||
FromUin int64 `jceId:"0"`
|
FromUin int64 `jceId:"0"`
|
||||||
MsgTime int64 `jceId:"1"`
|
MsgTime int64 `jceId:"1"`
|
||||||
@ -665,6 +724,28 @@ func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) {
|
|||||||
pkt.CanBeKicked = r.ReadInt64(10)
|
pkt.CanBeKicked = r.ReadInt64(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pkt *SvcRespParam) ReadFrom(r *JceReader) {
|
||||||
|
pkt.OnlineInfos = []OnlineInfo{}
|
||||||
|
pkt.PCStat = r.ReadInt32(0)
|
||||||
|
pkt.IsSupportC2CRoamMsg = r.ReadInt32(1)
|
||||||
|
pkt.IsSupportDataLine = r.ReadInt32(2)
|
||||||
|
pkt.IsSupportPrintable = r.ReadInt32(3)
|
||||||
|
pkt.IsSupportViewPCFile = r.ReadInt32(4)
|
||||||
|
pkt.PcVersion = r.ReadInt32(5)
|
||||||
|
pkt.RoamFlag = r.ReadInt64(6)
|
||||||
|
r.ReadSlice(&pkt.OnlineInfos, 7)
|
||||||
|
pkt.PCClientType = r.ReadInt32(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pkt *OnlineInfo) ReadFrom(r *JceReader) {
|
||||||
|
pkt.InstanceId = r.ReadInt32(0)
|
||||||
|
pkt.ClientType = r.ReadInt32(1)
|
||||||
|
pkt.OnlineStatus = r.ReadInt32(2)
|
||||||
|
pkt.PlatformId = r.ReadInt32(3)
|
||||||
|
pkt.SubPlatform = string(r.ReadAny(4).([]byte))
|
||||||
|
pkt.UClientType = r.ReadInt64(5)
|
||||||
|
}
|
||||||
|
|
||||||
func (pkt *SvcRespPushMsg) ToBytes() []byte {
|
func (pkt *SvcRespPushMsg) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
w.WriteJceStructRaw(pkt)
|
w.WriteJceStructRaw(pkt)
|
||||||
@ -682,3 +763,9 @@ func (pkt *SvcReqGetDevLoginInfo) ToBytes() []byte {
|
|||||||
w.WriteJceStructRaw(pkt)
|
w.WriteJceStructRaw(pkt)
|
||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pkt *SvcReqRegisterNew) ToBytes() []byte {
|
||||||
|
w := NewJceWriter()
|
||||||
|
w.WriteJceStructRaw(pkt)
|
||||||
|
return w.Bytes()
|
||||||
|
}
|
||||||
|
@ -96,11 +96,12 @@ func (w *JceWriter) WriteString(s string, tag int) *JceWriter {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *JceWriter) WriteBytes(l []byte, tag int) {
|
func (w *JceWriter) WriteBytes(l []byte, tag int) *JceWriter {
|
||||||
w.writeHead(13, tag)
|
w.writeHead(13, tag)
|
||||||
w.writeHead(0, 0)
|
w.writeHead(0, 0)
|
||||||
w.WriteInt32(int32(len(l)), 0)
|
w.WriteInt32(int32(len(l)), 0)
|
||||||
w.buf.Write(l)
|
w.buf.Write(l)
|
||||||
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *JceWriter) WriteInt64Slice(l []int64, tag int) {
|
func (w *JceWriter) WriteInt64Slice(l []int64, tag int) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package binary
|
package binary
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -302,29 +302,6 @@ func (c *QQClient) buildConfPushRespPacket(t int32, pktSeq int64, jceBuf []byte)
|
|||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatSvc.GetDevLoginInfo
|
|
||||||
func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
|
|
||||||
seq := c.nextSeq()
|
|
||||||
req := &jce.SvcReqGetDevLoginInfo{
|
|
||||||
Guid: SystemDeviceInfo.Guid,
|
|
||||||
LoginType: 1,
|
|
||||||
AppName: "com.tencent.mobileqq",
|
|
||||||
RequireMax: 20,
|
|
||||||
GetDevListType: 2,
|
|
||||||
}
|
|
||||||
buf := &jce.RequestDataVersion3{Map: map[string][]byte{"SvcReqGetDevLoginInfo": packUniRequestData(req.ToBytes())}}
|
|
||||||
pkt := &jce.RequestPacket{
|
|
||||||
IVersion: 3,
|
|
||||||
SServantName: "StatSvc",
|
|
||||||
SFuncName: "SvcReqGetDevLoginInfo",
|
|
||||||
SBuffer: buf.ToBytes(),
|
|
||||||
Context: make(map[string]string),
|
|
||||||
Status: make(map[string]string),
|
|
||||||
}
|
|
||||||
packet := packets.BuildUniPacket(c.Uin, seq, "StatSvc.GetDevLoginInfo", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, pkt.ToBytes())
|
|
||||||
return seq, packet
|
|
||||||
}
|
|
||||||
|
|
||||||
// friendlist.getFriendGroupList
|
// friendlist.getFriendGroupList
|
||||||
func (c *QQClient) buildFriendGroupListRequestPacket(friendStartIndex, friendListCount, groupStartIndex, groupListCount int16) (uint16, []byte) {
|
func (c *QQClient) buildFriendGroupListRequestPacket(friendStartIndex, friendListCount, groupStartIndex, groupListCount int16) (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
|
@ -36,13 +36,14 @@ type QQClient struct {
|
|||||||
PasswordMd5 [16]byte
|
PasswordMd5 [16]byte
|
||||||
AllowSlider bool
|
AllowSlider bool
|
||||||
|
|
||||||
Nickname string
|
Nickname string
|
||||||
Age uint16
|
Age uint16
|
||||||
Gender uint16
|
Gender uint16
|
||||||
FriendList []*FriendInfo
|
FriendList []*FriendInfo
|
||||||
GroupList []*GroupInfo
|
GroupList []*GroupInfo
|
||||||
Online bool
|
OnlineClients []*OtherClientInfo
|
||||||
NetLooping bool
|
Online bool
|
||||||
|
NetLooping bool
|
||||||
|
|
||||||
SequenceId int32
|
SequenceId int32
|
||||||
OutGoingPacketSessionId []byte
|
OutGoingPacketSessionId []byte
|
||||||
@ -121,7 +122,6 @@ var decoders = map[string]func(*QQClient, uint16, []byte) (interface{}, error){
|
|||||||
"wtlogin.exchange_emp": decodeExchangeEmpResponse,
|
"wtlogin.exchange_emp": decodeExchangeEmpResponse,
|
||||||
"StatSvc.register": decodeClientRegisterResponse,
|
"StatSvc.register": decodeClientRegisterResponse,
|
||||||
"StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
|
"StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
|
||||||
"StatSvc.GetDevLoginInfo": decodeDevListResponse,
|
|
||||||
"MessageSvc.PushNotify": decodeSvcNotify,
|
"MessageSvc.PushNotify": decodeSvcNotify,
|
||||||
"OnlinePush.ReqPush": decodeOnlinePushReqPacket,
|
"OnlinePush.ReqPush": decodeOnlinePushReqPacket,
|
||||||
"OnlinePush.PbPushTransMsg": decodeOnlinePushTransPacket,
|
"OnlinePush.PbPushTransMsg": decodeOnlinePushTransPacket,
|
||||||
@ -289,29 +289,6 @@ func (c *QQClient) SubmitSMS(code string) (*LoginResponse, error) {
|
|||||||
return &l, nil
|
return &l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) init() {
|
|
||||||
c.Online = true
|
|
||||||
_ = c.registerClient()
|
|
||||||
c.groupSysMsgCache, _ = c.GetGroupSystemMessages()
|
|
||||||
if !c.heartbeatEnabled {
|
|
||||||
go c.doHeartbeat()
|
|
||||||
}
|
|
||||||
c.stat.once.Do(func() {
|
|
||||||
c.OnGroupMessage(func(_ *QQClient, _ *message.GroupMessage) {
|
|
||||||
c.stat.MessageReceived++
|
|
||||||
})
|
|
||||||
c.OnPrivateMessage(func(_ *QQClient, _ *message.PrivateMessage) {
|
|
||||||
c.stat.MessageReceived++
|
|
||||||
})
|
|
||||||
c.OnTempMessage(func(_ *QQClient, _ *message.TempMessage) {
|
|
||||||
c.stat.MessageReceived++
|
|
||||||
})
|
|
||||||
c.onGroupMessageReceipt("internal", func(_ *QQClient, _ *groupMessageReceiptEvent) {
|
|
||||||
c.stat.MessageSent++
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) RequestSMS() bool {
|
func (c *QQClient) RequestSMS() bool {
|
||||||
rsp, err := c.sendAndWait(c.buildSMSRequestPacket())
|
rsp, err := c.sendAndWait(c.buildSMSRequestPacket())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -321,6 +298,33 @@ func (c *QQClient) RequestSMS() bool {
|
|||||||
return rsp.(LoginResponse).Error == SMSNeededError
|
return rsp.(LoginResponse).Error == SMSNeededError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) init() {
|
||||||
|
c.Online = true
|
||||||
|
_ = c.registerClient()
|
||||||
|
c.groupSysMsgCache, _ = c.GetGroupSystemMessages()
|
||||||
|
if !c.heartbeatEnabled {
|
||||||
|
go c.doHeartbeat()
|
||||||
|
}
|
||||||
|
_ = c.RefreshStatus()
|
||||||
|
c.stat.once.Do(func() {
|
||||||
|
c.OnGroupMessage(func(_ *QQClient, _ *message.GroupMessage) {
|
||||||
|
c.stat.MessageReceived++
|
||||||
|
c.stat.LastMessageTime = time.Now().Unix()
|
||||||
|
})
|
||||||
|
c.OnPrivateMessage(func(_ *QQClient, _ *message.PrivateMessage) {
|
||||||
|
c.stat.MessageReceived++
|
||||||
|
c.stat.LastMessageTime = time.Now().Unix()
|
||||||
|
})
|
||||||
|
c.OnTempMessage(func(_ *QQClient, _ *message.TempMessage) {
|
||||||
|
c.stat.MessageReceived++
|
||||||
|
c.stat.LastMessageTime = time.Now().Unix()
|
||||||
|
})
|
||||||
|
c.onGroupMessageReceipt("internal", func(_ *QQClient, _ *groupMessageReceiptEvent) {
|
||||||
|
c.stat.MessageSent++
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
|
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
|
||||||
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
|
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -413,19 +413,6 @@ func decodeSvcNotify(c *QQClient, _ uint16, _ []byte) (interface{}, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatSvc.GetDevLoginInfo
|
|
||||||
func decodeDevListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
|
||||||
request := &jce.RequestPacket{}
|
|
||||||
request.ReadFrom(jce.NewJceReader(payload))
|
|
||||||
data := &jce.RequestDataVersion2{}
|
|
||||||
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
|
||||||
rsp := jce.NewJceReader(data.Map["SvcRspGetDevLoginInfo"]["QQService.SvcRspGetDevLoginInfo"][1:])
|
|
||||||
d := []jce.SvcDevLoginInfo{}
|
|
||||||
ret := rsp.ReadInt64(3)
|
|
||||||
rsp.ReadSlice(&d, 5)
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SummaryCard.ReqSummaryCard
|
// SummaryCard.ReqSummaryCard
|
||||||
func decodeSummaryCardResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeSummaryCardResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
request := &jce.RequestPacket{}
|
request := &jce.RequestPacket{}
|
||||||
|
@ -58,6 +58,12 @@ type (
|
|||||||
Qid string
|
Qid string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OtherClientInfo struct {
|
||||||
|
AppId int64
|
||||||
|
DeviceName string
|
||||||
|
DeviceKind string
|
||||||
|
}
|
||||||
|
|
||||||
FriendListResponse struct {
|
FriendListResponse struct {
|
||||||
TotalCount int32
|
TotalCount int32
|
||||||
List []*FriendInfo
|
List []*FriendInfo
|
||||||
|
@ -151,7 +151,7 @@ func (fs *GroupFileSystem) GetFilesByFolder(folderId string) ([]*GroupFile, []*G
|
|||||||
return files, folders, nil
|
return files, folders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *GroupFileSystem) UploadFile(p, name, folderId string) error {
|
func (fs *GroupFileSystem) uploadFile(p, name, folderId string) error {
|
||||||
file, err := os.OpenFile(p, os.O_RDONLY, 0666)
|
file, err := os.OpenFile(p, os.O_RDONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -311,7 +311,7 @@ func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if pkt.Message.Content != nil && pkt.Message.Content.GetPkgNum() > 1 {
|
if pkt.Message.Content != nil && pkt.Message.Content.GetPkgNum() > 1 {
|
||||||
var builder *groupMessageBuilder // TODO: 支持多SEQ
|
var builder *groupMessageBuilder
|
||||||
i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.GetDivSeq())
|
i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.GetDivSeq())
|
||||||
if !ok {
|
if !ok {
|
||||||
builder = &groupMessageBuilder{}
|
builder = &groupMessageBuilder{}
|
||||||
|
@ -10,6 +10,7 @@ type Statistics struct {
|
|||||||
MessageSent uint64 `json:"message_sent"`
|
MessageSent uint64 `json:"message_sent"`
|
||||||
DisconnectTimes uint32 `json:"disconnect_times"`
|
DisconnectTimes uint32 `json:"disconnect_times"`
|
||||||
LostTimes uint32 `json:"lost_times"`
|
LostTimes uint32 `json:"lost_times"`
|
||||||
|
LastMessageTime int64 `json:"last_message_time"`
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
196
client/sync.go
Normal file
196
client/sync.go
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
decoders["StatSvc.GetDevLoginInfo"] = decodeDevListResponse
|
||||||
|
decoders["RegPrxySvc.getOffMsg"] = decodeOfflineMsgResponse
|
||||||
|
decoders["RegPrxySvc.PushParam"] = decodePushParamPacket
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllowedClients 获取已允许的其他客户端
|
||||||
|
func (c *QQClient) GetAllowedClients() ([]*OtherClientInfo, error) {
|
||||||
|
i, err := c.sendAndWait(c.buildDeviceListRequestPacket())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list := i.([]jce.SvcDevLoginInfo)
|
||||||
|
var ret []*OtherClientInfo
|
||||||
|
for _, l := range list {
|
||||||
|
ret = append(ret, &OtherClientInfo{
|
||||||
|
AppId: l.AppId,
|
||||||
|
DeviceName: l.DeviceName,
|
||||||
|
DeviceKind: l.DeviceTypeInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshClientStatus 刷新客户端状态
|
||||||
|
func (c *QQClient) RefreshStatus() error {
|
||||||
|
_, pkt := c.buildGetOfflineMsgRequest()
|
||||||
|
c.send(pkt)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatSvc.GetDevLoginInfo
|
||||||
|
func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
|
req := &jce.SvcReqGetDevLoginInfo{
|
||||||
|
Guid: SystemDeviceInfo.Guid,
|
||||||
|
LoginType: 1,
|
||||||
|
AppName: "com.tencent.mobileqq",
|
||||||
|
RequireMax: 20,
|
||||||
|
GetDevListType: 2,
|
||||||
|
}
|
||||||
|
buf := &jce.RequestDataVersion3{Map: map[string][]byte{"SvcReqGetDevLoginInfo": packUniRequestData(req.ToBytes())}}
|
||||||
|
pkt := &jce.RequestPacket{
|
||||||
|
IVersion: 3,
|
||||||
|
SServantName: "StatSvc",
|
||||||
|
SFuncName: "SvcReqGetDevLoginInfo",
|
||||||
|
SBuffer: buf.ToBytes(),
|
||||||
|
Context: make(map[string]string),
|
||||||
|
Status: make(map[string]string),
|
||||||
|
}
|
||||||
|
packet := packets.BuildUniPacket(c.Uin, seq, "StatSvc.GetDevLoginInfo", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, pkt.ToBytes())
|
||||||
|
return seq, packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegPrxySvc.getOffMsg
|
||||||
|
func (c *QQClient) buildGetOfflineMsgRequest() (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
|
regReq := &jce.SvcReqRegisterNew{
|
||||||
|
RequestOptional: 0x101C2 | 32,
|
||||||
|
C2CMsg: &jce.SvcReqGetMsgV2{
|
||||||
|
Uin: c.Uin,
|
||||||
|
DateTime: func() int32 {
|
||||||
|
if c.stat.LastMessageTime == 0 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return int32(c.stat.LastMessageTime)
|
||||||
|
}(),
|
||||||
|
RecivePic: 1,
|
||||||
|
Ability: 15,
|
||||||
|
Channel: 4,
|
||||||
|
Inst: 1,
|
||||||
|
ChannelEx: 1,
|
||||||
|
SyncCookie: c.syncCookie,
|
||||||
|
SyncFlag: 0, // START
|
||||||
|
RambleFlag: 0,
|
||||||
|
GeneralAbi: 1,
|
||||||
|
PubAccountCookie: c.pubAccountCookie,
|
||||||
|
},
|
||||||
|
GroupMsg: &jce.SvcReqPullGroupMsgSeq{
|
||||||
|
VerifyType: 0,
|
||||||
|
Filter: 1, // LIMIT_10_AND_IN_3_DAYS
|
||||||
|
},
|
||||||
|
EndSeq: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
flag := msg.SyncFlag_START
|
||||||
|
msgReq, _ := proto.Marshal(&msg.GetMessageRequest{
|
||||||
|
SyncFlag: &flag,
|
||||||
|
SyncCookie: c.syncCookie,
|
||||||
|
RambleFlag: proto.Int32(0),
|
||||||
|
ContextFlag: proto.Int32(1),
|
||||||
|
OnlineSyncFlag: proto.Int32(0),
|
||||||
|
LatestRambleNumber: proto.Int32(20),
|
||||||
|
OtherRambleNumber: proto.Int32(3),
|
||||||
|
})
|
||||||
|
buf := &jce.RequestDataVersion3{Map: map[string][]byte{
|
||||||
|
"req_PbOffMsg": jce.NewJceWriter().WriteBytes(append([]byte{0, 0, 0, 0}, msgReq...), 0).Bytes(),
|
||||||
|
"req_OffMsg": packUniRequestData(regReq.ToBytes()),
|
||||||
|
}}
|
||||||
|
pkt := &jce.RequestPacket{
|
||||||
|
IVersion: 3,
|
||||||
|
SServantName: "RegPrxySvc",
|
||||||
|
SBuffer: buf.ToBytes(),
|
||||||
|
Context: make(map[string]string),
|
||||||
|
Status: make(map[string]string),
|
||||||
|
}
|
||||||
|
packet := packets.BuildUniPacket(c.Uin, seq, "RegPrxySvc.getOffMsg", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, pkt.ToBytes())
|
||||||
|
return seq, packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatSvc.GetDevLoginInfo
|
||||||
|
func decodeDevListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
|
request := &jce.RequestPacket{}
|
||||||
|
request.ReadFrom(jce.NewJceReader(payload))
|
||||||
|
data := &jce.RequestDataVersion2{}
|
||||||
|
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
||||||
|
rsp := jce.NewJceReader(data.Map["SvcRspGetDevLoginInfo"]["QQService.SvcRspGetDevLoginInfo"][1:])
|
||||||
|
d := []jce.SvcDevLoginInfo{}
|
||||||
|
rsp.ReadSlice(&d, 4)
|
||||||
|
if len(d) > 0 {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
rsp.ReadSlice(&d, 5)
|
||||||
|
if len(d) > 0 {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
rsp.ReadSlice(&d, 6)
|
||||||
|
if len(d) > 0 {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("not any device")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegPrxySvc.getOffMsg
|
||||||
|
func decodeOfflineMsgResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
|
/*
|
||||||
|
request := &jce.RequestPacket{}
|
||||||
|
request.ReadFrom(jce.NewJceReader(payload))
|
||||||
|
*/
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegPrxySvc.PushParam
|
||||||
|
func decodePushParamPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
|
request := &jce.RequestPacket{}
|
||||||
|
request.ReadFrom(jce.NewJceReader(payload))
|
||||||
|
data := &jce.RequestDataVersion2{}
|
||||||
|
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
||||||
|
reader := jce.NewJceReader(data.Map["SvcRespParam"]["RegisterProxySvcPack.SvcRespParam"][1:])
|
||||||
|
rsp := &jce.SvcRespParam{}
|
||||||
|
rsp.ReadFrom(reader)
|
||||||
|
allowedClients, _ := c.GetAllowedClients()
|
||||||
|
c.OnlineClients = []*OtherClientInfo{}
|
||||||
|
for _, i := range rsp.OnlineInfos {
|
||||||
|
c.OnlineClients = append(c.OnlineClients, &OtherClientInfo{
|
||||||
|
AppId: int64(i.InstanceId),
|
||||||
|
DeviceName: func() string {
|
||||||
|
for _, ac := range allowedClients {
|
||||||
|
if ac.AppId == int64(i.InstanceId) {
|
||||||
|
return ac.DeviceName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i.SubPlatform
|
||||||
|
}(),
|
||||||
|
DeviceKind: func() string {
|
||||||
|
switch i.UClientType {
|
||||||
|
case 65793:
|
||||||
|
return "Windows"
|
||||||
|
case 65805, 68104:
|
||||||
|
return "aPad"
|
||||||
|
case 66818, 66831, 81154:
|
||||||
|
return "Mac"
|
||||||
|
case 68361, 72194:
|
||||||
|
return "iPad"
|
||||||
|
case 75023, 78082, 78096:
|
||||||
|
return "Watch"
|
||||||
|
case 77313:
|
||||||
|
return "Windows TIM"
|
||||||
|
default:
|
||||||
|
return i.SubPlatform
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user