diff --git a/binary/jce/reader.go b/binary/jce/reader.go index eb11f5f1..5a098e3b 100644 --- a/binary/jce/reader.go +++ b/binary/jce/reader.go @@ -322,6 +322,18 @@ func (r *JceReader) ReadAny(tag int) interface{} { } } +func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) { + if !r.skipToTag(tag) { + return + } + hd, _ := r.readHead() + if hd.Type != 10 { + return + } + obj.ReadFrom(r) + r.skipToStructEnd() +} + func (r *JceReader) ReadMapF(tag int, f func(interface{}, interface{})) { if !r.skipToTag(tag) { return diff --git a/binary/jce/structs.go b/binary/jce/structs.go index d0483654..70f0d4bd 100644 --- a/binary/jce/structs.go +++ b/binary/jce/structs.go @@ -33,6 +33,46 @@ type ( Location string `jceId:"8"` } + FileStoragePushFSSvcList struct { + UploadList []FileStorageServerInfo `jceId:"0"` + PicDownloadList []FileStorageServerInfo `jceId:"1"` + GPicDownloadList []FileStorageServerInfo `jceId:"2"` + QZoneProxyServiceList []FileStorageServerInfo `jceId:"3"` + UrlEncodeServiceList []FileStorageServerInfo `jceId:"4"` + BigDataChannel *BigDataChannel `jceId:"5"` + VipEmotionList []FileStorageServerInfo `jceId:"6"` + C2CPicDownList []FileStorageServerInfo `jceId:"7"` + //FmtIPInfo *FmtIPInfo `jceId:"8"` + //DomainIPChannel *DomainIPChannel `jceId:"9"` + PttList []byte `jceId:"10"` + } + + FileStorageServerInfo struct { + Server string `jceId:"1"` + Port int32 `jceId:"2"` + } + + BigDataChannel struct { + IPLists []BigDataIPList `jceId:"0"` + SigSession []byte `jceId:"1"` + KeySession []byte `jceId:"2"` + SigUin int64 `jceId:"3"` + ConnectFlag int32 `jceId:"4"` + PbBuf []byte `jceId:"5"` + } + + BigDataIPList struct { + ServiceType int64 `jceId:"0"` + IPList []BigDataIPInfo `jceId:"1"` + FragmentSize int64 `jceId:"3"` + } + + BigDataIPInfo struct { + Type int64 `jceId:"0"` + Server string `jceId:"1"` + Port int64 `jceId:"2"` + } + SvcReqRegister struct { IJceStruct Uin int64 `jceId:"0"` @@ -452,6 +492,54 @@ func (pkt *SsoServerInfo) ReadFrom(r *JceReader) { pkt.Location = r.ReadString(8) } +func (pkt *FileStoragePushFSSvcList) ReadFrom(r *JceReader) { + pkt.UploadList = []FileStorageServerInfo{} + pkt.PicDownloadList = []FileStorageServerInfo{} + pkt.GPicDownloadList = []FileStorageServerInfo{} + pkt.QZoneProxyServiceList = []FileStorageServerInfo{} + pkt.UrlEncodeServiceList = []FileStorageServerInfo{} + pkt.BigDataChannel = &BigDataChannel{} + pkt.VipEmotionList = []FileStorageServerInfo{} + pkt.C2CPicDownList = []FileStorageServerInfo{} + r.ReadSlice(&pkt.UploadList, 0) + r.ReadSlice(&pkt.PicDownloadList, 1) + r.ReadSlice(&pkt.GPicDownloadList, 2) + r.ReadSlice(&pkt.QZoneProxyServiceList, 3) + r.ReadSlice(&pkt.UrlEncodeServiceList, 4) + r.ReadJceStruct(pkt.BigDataChannel, 5) + r.ReadSlice(&pkt.VipEmotionList, 6) + r.ReadSlice(&pkt.C2CPicDownList, 7) + pkt.PttList = r.ReadAny(10).([]byte) +} + +func (pkt *FileStorageServerInfo) ReadFrom(r *JceReader) { + pkt.Server = r.ReadString(1) + pkt.Port = r.ReadInt32(2) +} + +func (pkt *BigDataChannel) ReadFrom(r *JceReader) { + pkt.IPLists = []BigDataIPList{} + r.ReadSlice(&pkt.IPLists, 0) + pkt.SigSession = r.ReadAny(1).([]byte) + pkt.KeySession = r.ReadAny(2).([]byte) + pkt.SigUin = r.ReadInt64(3) + pkt.ConnectFlag = r.ReadInt32(4) + pkt.PbBuf = r.ReadAny(5).([]byte) +} + +func (pkt *BigDataIPList) ReadFrom(r *JceReader) { + pkt.IPList = []BigDataIPInfo{} + pkt.ServiceType = r.ReadInt64(0) + r.ReadSlice(&pkt.IPList, 1) + pkt.FragmentSize = r.ReadInt64(3) +} + +func (pkt *BigDataIPInfo) ReadFrom(r *JceReader) { + pkt.Type = r.ReadInt64(0) + pkt.Server = r.ReadString(1) + pkt.Port = r.ReadInt64(2) +} + func (pkt *SvcReqRegister) ToBytes() []byte { w := NewJceWriter() w.WriteJceStructRaw(pkt) diff --git a/client/client.go b/client/client.go index 1976c208..ad806b28 100644 --- a/client/client.go +++ b/client/client.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/Mrs4s/MiraiGo/binary/jce" "image" "io" "math/rand" @@ -68,6 +69,7 @@ type QQClient struct { rollbackSig []byte timeDiff int64 sigInfo *loginSigInfo + fileStorageInfo *jce.FileStoragePushFSSvcList pwdFlag bool lastMessageSeq int32 diff --git a/client/decoders.go b/client/decoders.go index 1031d738..c39df5d8 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -210,39 +210,48 @@ func decodePushReqPacket(c *QQClient, _ uint16, payload []byte) (interface{}, er data := &jce.RequestDataVersion2{} data.ReadFrom(jce.NewJceReader(request.SBuffer)) r := jce.NewJceReader(data.Map["PushReq"]["ConfigPush.PushReq"][1:]) - jceBuf := []byte{} t := r.ReadInt32(1) - r.ReadSlice(&jceBuf, 2) - if t == 1 && len(jceBuf) > 0 { - ssoPkt := jce.NewJceReader(jceBuf) - servers := []jce.SsoServerInfo{} - ssoPkt.ReadSlice(&servers, 1) - if len(servers) > 0 { - var adds []*net.TCPAddr - for _, s := range servers { - if strings.Contains(s.Server, "com") { - continue - } - c.Debug("got new server addr: %v location: %v", s.Server, s.Location) - adds = append(adds, &net.TCPAddr{ - IP: net.ParseIP(s.Server), - Port: int(s.Port), - }) - } - f := true - for _, e := range c.eventHandlers.serverUpdatedHandlers { - cover(func() { - if !e(c, &ServerUpdatedEvent{Servers: servers}) { - f = false + jceBuf := r.ReadAny(2).([]byte) + if len(jceBuf) > 0 { + switch t { + case 1: + ssoPkt := jce.NewJceReader(jceBuf) + servers := []jce.SsoServerInfo{} + ssoPkt.ReadSlice(&servers, 1) + if len(servers) > 0 { + var adds []*net.TCPAddr + for _, s := range servers { + if strings.Contains(s.Server, "com") { + continue } - }) + c.Debug("got new server addr: %v location: %v", s.Server, s.Location) + adds = append(adds, &net.TCPAddr{ + IP: net.ParseIP(s.Server), + Port: int(s.Port), + }) + } + f := true + for _, e := range c.eventHandlers.serverUpdatedHandlers { + cover(func() { + if !e(c, &ServerUpdatedEvent{Servers: servers}) { + f = false + } + }) + } + if f { + c.SetCustomServer(adds) + } + return nil, nil } - if f { - c.SetCustomServer(adds) - } - return nil, nil + case 2: + fmtPkt := jce.NewJceReader(jceBuf) + list := &jce.FileStoragePushFSSvcList{} + list.ReadFrom(fmtPkt) + c.Debug("got file storage svc push.") + c.fileStorageInfo = list } } + seq := r.ReadInt64(3) _, pkt := c.buildConfPushRespPacket(t, seq, jceBuf) return nil, c.send(pkt)