From 13a9d087e732294d73a9da0a0a50efc73e6b8ed0 Mon Sep 17 00:00:00 2001 From: fumiama Date: Fri, 26 Nov 2021 15:02:44 +0800 Subject: [PATCH] =?UTF-8?q?perf(jce):=20drop=20reflect=20in=20reader=20nam?= =?UTF-8?q?e=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20old?= =?UTF-8?q?=20time/op=20=20=20=20new=20time/op=20=20=20=20delta=20JceReade?= =?UTF-8?q?r=5FReadSlice-8=20=20=20=201.53ms=20=C2=B190%=20=20=20=200.82ms?= =?UTF-8?q?=20=C2=B186%=20=20-46.30%=20=20(p=3D0.017=20n=3D16+16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit name old speed new speed delta JceReader_ReadSlice-8 117MB/s ± 3% 228MB/s ± 4% +94.43% (p=0.000 n=16+16) name old alloc/op new alloc/op delta JceReader_ReadSlice-8 516kB ±88% 536kB ±85% ~ (p=0.780 n=16+16) name old allocs/op new allocs/op delta JceReader_ReadSlice-8 25.6k ±88% 26.6k ±85% ~ (p=0.780 n=16+16) --- binary/jce/reader.go | 433 ++++++++++++++++++++++++++++++++------ binary/jce/reader_test.go | 12 +- binary/jce/structs.go | 53 ++--- client/decoders.go | 18 +- client/global.go | 3 +- client/group_info.go | 3 +- client/online_push.go | 3 +- client/sync.go | 7 +- 8 files changed, 406 insertions(+), 126 deletions(-) diff --git a/binary/jce/reader.go b/binary/jce/reader.go index e1f88fb3..eff8e1dc 100644 --- a/binary/jce/reader.go +++ b/binary/jce/reader.go @@ -3,7 +3,6 @@ package jce import ( goBinary "encoding/binary" "math" - "reflect" "github.com/Mrs4s/MiraiGo/utils" ) @@ -22,28 +21,36 @@ func NewJceReader(data []byte) *JceReader { return &JceReader{buf: data} } -func (r *JceReader) readHead() (hd HeadData, l int32) { - b := r.buf[r.off] - hd.Type = b & 0xF - hd.Tag = (int(b) & 0xF0) >> 4 - l = 1 - if hd.Tag == 15 { - b = r.buf[r.off+1] - hd.Tag = int(b) & 0xFF - l = 2 - } - r.off += int(l) +func (r *JceReader) readHead() (hd HeadData, l int) { + hd, l = r.peakHead() + r.off += l return } -func (r *JceReader) peakHead() (h HeadData, l int32) { - h, l = r.readHead() - r.off -= int(l) +func (r *JceReader) peakHead() (hd HeadData, l int) { + b := r.buf[r.off] + hd.Type = b & 0xF + hd.Tag = int(uint(b) >> 4) + l = 1 + if hd.Tag == 0xF { + b = r.buf[r.off+1] + hd.Tag = int(uint(b)) + l = 2 + } + return +} + +func (r *JceReader) skipHead() { + l := 1 + if int(uint(r.buf[r.off])>>4) == 0xF { + l = 2 + } + r.off += l return } func (r *JceReader) skip(l int) { - r.readBytes(l) + r.skipBytes(l) } func (r *JceReader) skipField(t byte) { @@ -57,10 +64,9 @@ func (r *JceReader) skipField(t byte) { case 3, 5: r.skip(8) case 6: - b := r.readByte() - r.skip(int(b)) + r.skip(int(r.readByte())) case 7: - r.skip(int(r.readInt32())) + r.skip(int(r.readUInt32())) case 8: s := r.ReadInt32(0) for i := 0; i < int(s)*2; i++ { @@ -72,7 +78,7 @@ func (r *JceReader) skipField(t byte) { r.skipNextField() } case 13: - r.readHead() + r.skipHead() s := r.ReadInt32(0) r.skip(int(s)) case 10: @@ -96,11 +102,21 @@ func (r *JceReader) readBytes(n int) []byte { panic("readBytes: EOF") } b := make([]byte, n) - n = copy(b, r.buf[r.off:]) - r.off += n + r.off += copy(b, r.buf[r.off:]) return b } +func (r *JceReader) skipBytes(n int) { + if r.off+n > len(r.buf) { + panic("skipBytes: EOF") + } + lremain := len(r.buf[r.off:]) + if lremain < n { + n = lremain + } + r.off += n +} + func (r *JceReader) readByte() byte { if r.off >= len(r.buf) { panic("readByte: EOF") @@ -111,48 +127,40 @@ func (r *JceReader) readByte() byte { } func (r *JceReader) readUInt16() uint16 { - b := r.readBytes(2) - return uint16((int32(b[0]) << 8) + int32(b[1])) + return goBinary.BigEndian.Uint16(r.readBytes(2)) } -func (r *JceReader) readInt32() int32 { - b := r.readBytes(4) - return int32(goBinary.BigEndian.Uint32(b)) +func (r *JceReader) readUInt32() uint32 { + return goBinary.BigEndian.Uint32(r.readBytes(4)) } -func (r *JceReader) readInt64() int64 { - b := r.readBytes(8) - return int64(goBinary.BigEndian.Uint64(b)) +func (r *JceReader) readUInt64() uint64 { + return goBinary.BigEndian.Uint64(r.readBytes(8)) } func (r *JceReader) readFloat32() float32 { - b := r.readInt32() - return math.Float32frombits(uint32(b)) + return math.Float32frombits(r.readUInt32()) } func (r *JceReader) readFloat64() float64 { - b := r.readInt64() - return math.Float64frombits(uint64(b)) + return math.Float64frombits(r.readUInt64()) } func (r *JceReader) skipToTag(tag int) bool { - for { - hd, l := r.peakHead() - if tag <= hd.Tag || hd.Type == 11 { - return tag == hd.Tag - } - r.skip(int(l)) + hd, l := r.peakHead() + for tag > hd.Tag && hd.Type != 11 { + r.skip(l) r.skipField(hd.Type) + hd, l = r.peakHead() } + return tag == hd.Tag } func (r *JceReader) skipToStructEnd() { - for { - hd, _ := r.readHead() + hd, _ := r.readHead() + for hd.Type != 11 { r.skipField(hd.Type) - if hd.Type == 11 { - return - } + hd, _ = r.readHead() } } @@ -205,7 +213,7 @@ func (r *JceReader) ReadInt32(tag int) int32 { case 1: return int32(r.readUInt16()) case 2: - return r.readInt32() + return int32(r.readUInt32()) default: return 0 } @@ -224,9 +232,9 @@ func (r *JceReader) ReadInt64(tag int) int64 { case 1: return int64(int16(r.readUInt16())) case 2: - return int64(r.readInt32()) + return int64(r.readUInt32()) case 3: - return r.readInt64() + return int64(r.readUInt64()) default: return 0 } @@ -273,7 +281,7 @@ func (r *JceReader) ReadString(tag int) string { case 6: return utils.B2S(r.readBytes(int(r.readByte()))) case 7: - return utils.B2S(r.readBytes(int(r.readInt32()))) + return utils.B2S(r.readBytes(int(r.readUInt32()))) default: return "" } @@ -293,13 +301,32 @@ func (r *JceReader) ReadBytes(tag int) []byte { } return b case 13: - r.readHead() + r.skipHead() return r.readBytes(int(r.ReadInt32(0))) default: return nil } } +func (r *JceReader) ReadByteArrArr(tag int) (baa [][]byte) { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + baa = make([][]byte, s) + for i := 0; i < int(s); i++ { + baa[i] = r.ReadBytes(0) + } + return baa + default: + return nil + } +} + +/* // ReadAny Read any type via tag, unsupported JceStruct func (r *JceReader) ReadAny(tag int) interface{} { if !r.skipToTag(tag) { @@ -312,17 +339,17 @@ func (r *JceReader) ReadAny(tag int) interface{} { case 1: return r.readUInt16() case 2: - return r.readInt32() + return r.readUInt32() case 3: - return r.readInt64() + return r.readUInt64() case 4: return r.readFloat32() case 5: return r.readFloat64() case 6: - return string(r.readBytes(int(r.readByte()))) + return utils.B2S(r.readBytes(int(r.readByte()))) case 7: - return string(r.readBytes(int(r.readInt32()))) + return utils.B2S(r.readBytes(int(r.readUInt32()))) case 8: s := r.ReadInt32(0) m := make(map[interface{}]interface{}) @@ -340,12 +367,13 @@ func (r *JceReader) ReadAny(tag int) interface{} { case 12: return 0 case 13: - r.readHead() + r.skipHead() return r.readBytes(int(r.ReadInt32(0))) default: return nil } } +*/ func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) { if !r.skipToTag(tag) { @@ -359,9 +387,63 @@ func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) { r.skipToStructEnd() } +func (r *JceReader) ReadMapStrStr(tag int) map[string]string { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 8: + s := r.ReadInt32(0) + m := make(map[string]string, s) + for i := 0; i < int(s); i++ { + m[r.ReadString(0)] = r.ReadString(1) + } + return m + default: + return nil + } +} + +func (r *JceReader) ReadMapStrByte(tag int) map[string][]byte { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 8: + s := r.ReadInt32(0) + m := make(map[string][]byte, s) + for i := 0; i < int(s); i++ { + m[r.ReadString(0)] = r.ReadBytes(1) + } + return m + default: + return nil + } +} + +func (r *JceReader) ReadMapStrMapStrByte(tag int) map[string]map[string][]byte { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 8: + s := r.ReadInt32(0) + m := make(map[string]map[string][]byte, s) + for i := 0; i < int(s); i++ { + m[r.ReadString(0)] = r.ReadMapStrByte(1) + } + return m + default: + return nil + } +} + +/* func (r *JceReader) ReadMap(i interface{}, tag int) { - v := reflect.ValueOf(i) - r.readMap(v, tag) + r.readMap(reflect.ValueOf(i), tag) } func (r *JceReader) readMap(v reflect.Value, tag int) { @@ -372,7 +454,7 @@ func (r *JceReader) readMap(v reflect.Value, tag int) { kt := t.Key() vt := t.Elem() - r.readHead() + r.skipHead() s := r.ReadInt32(0) // map with string key or string value is very common. @@ -404,21 +486,240 @@ func (r *JceReader) readMap(v reflect.Value, tag int) { v.SetMapIndex(kv.Elem(), vv.Elem()) } } +*/ +func (r *JceReader) ReadFileStorageServerInfos(tag int) []FileStorageServerInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]FileStorageServerInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadBigDataIPLists(tag int) []BigDataIPList { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]BigDataIPList, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadBigDataIPInfos(tag int) []BigDataIPInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]BigDataIPInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadOnlineInfos(tag int) []OnlineInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]OnlineInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadInstanceInfos(tag int) []InstanceInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]InstanceInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadSsoServerInfos(tag int) []SsoServerInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]SsoServerInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadFriendInfos(tag int) []FriendInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]FriendInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadTroopNumbers(tag int) []TroopNumber { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]TroopNumber, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadTroopMemberInfos(tag int) []TroopMemberInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]TroopMemberInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadPushMessageInfos(tag int) []PushMessageInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]PushMessageInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +func (r *JceReader) ReadSvcDevLoginInfos(tag int) []SvcDevLoginInfo { + if !r.skipToTag(tag) { + return nil + } + hd, _ := r.readHead() + switch hd.Type { + case 9: + s := r.ReadInt32(0) + sl := make([]SvcDevLoginInfo, s) + for i := 0; i < int(s); i++ { + r.skipHead() + sl[i].ReadFrom(r) + r.skipToStructEnd() + } + return sl + default: + return nil + } +} + +/* func (r *JceReader) ReadSlice(i interface{}, tag int) { r.readSlice(reflect.ValueOf(i), tag) } func (r *JceReader) readSlice(v reflect.Value, tag int) { t := v.Type() - if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice { + if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice || !r.skipToTag(tag) { return } v = v.Elem() t = t.Elem() - if !r.skipToTag(tag) { - return - } hd, _ := r.readHead() if hd.Type == 9 { s := r.ReadInt32(0) @@ -432,15 +733,14 @@ func (r *JceReader) readSlice(v reflect.Value, tag int) { v.Set(sv) } if hd.Type == 13 && t.Elem().Kind() == reflect.Uint8 { - r.readHead() + r.skipHead() arr := r.readBytes(int(r.ReadInt32(0))) v.SetBytes(arr) } } func (r *JceReader) ReadObject(i interface{}, tag int) { - v := reflect.ValueOf(i) - r.readObject(v, tag) + r.readObject(reflect.ValueOf(i), tag) } func (r *JceReader) readObject(v reflect.Value, tag int) { @@ -478,7 +778,7 @@ func (r *JceReader) readObject(v reflect.Value, tag int) { // other cases switch o := v.Interface().(type) { case IJceStruct: - r.readHead() + r.skipHead() o.ReadFrom(r) r.skipToStructEnd() case *float32: @@ -488,3 +788,4 @@ func (r *JceReader) readObject(v reflect.Value, tag int) { } } } +*/ diff --git a/binary/jce/reader_test.go b/binary/jce/reader_test.go index cebad57b..7caec125 100644 --- a/binary/jce/reader_test.go +++ b/binary/jce/reader_test.go @@ -8,15 +8,16 @@ import ( ) func TestJceReader_ReadSlice(t *testing.T) { - s := make([]int64, 50) + s := make([][]byte, 50) for i := range s { - s[i] = rand.Int63() + b := make([]byte, 64) + _, _ = rand.Read(b) + s[i] = b } w := NewJceWriter() w.WriteObject(s, 1) r := NewJceReader(w.Bytes()) - var result []int64 - r.ReadSlice(&result, 1) + result := r.ReadByteArrArr(1) assert.Equal(t, s, result) } @@ -35,10 +36,9 @@ func BenchmarkJceReader_ReadSlice(b *testing.B) { src := w.Bytes() b.SetBytes(int64(len(src))) b.StartTimer() - result := make([]BigDataIPInfo, 0) for i := 0; i < b.N; i++ { r := NewJceReader(src) - r.ReadSlice(&result, 1) + _ = r.ReadBigDataIPInfos(1) } } diff --git a/binary/jce/structs.go b/binary/jce/structs.go index cab8bcd0..65ecc6e9 100644 --- a/binary/jce/structs.go +++ b/binary/jce/structs.go @@ -555,10 +555,12 @@ func (pkt *RequestPacket) ReadFrom(r *JceReader) { pkt.IRequestId = r.ReadInt32(4) pkt.SServantName = r.ReadString(5) pkt.SFuncName = r.ReadString(6) - r.ReadSlice(&pkt.SBuffer, 7) + pkt.SBuffer = r.ReadBytes(7) pkt.ITimeout = r.ReadInt32(8) - r.ReadMap(pkt.Context, 9) - r.ReadMap(pkt.Status, 10) + // r.ReadMap(pkt.Context, 9) + pkt.Context = r.ReadMapStrStr(9) + // r.ReadMap(pkt.Status, 10) + pkt.Status = r.ReadMapStrStr(10) } func (pkt *RequestDataVersion3) ToBytes() []byte { @@ -568,8 +570,7 @@ func (pkt *RequestDataVersion3) ToBytes() []byte { } func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) { - pkt.Map = make(map[string][]byte) - r.ReadMap(pkt.Map, 0) + pkt.Map = r.ReadMapStrByte(0) } func (pkt *RequestDataVersion2) ToBytes() []byte { @@ -579,8 +580,7 @@ func (pkt *RequestDataVersion2) ToBytes() []byte { } func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) { - pkt.Map = make(map[string]map[string][]byte) - r.ReadMap(pkt.Map, 0) + pkt.Map = r.ReadMapStrMapStrByte(0) } func (pkt *SsoServerInfo) ReadFrom(r *JceReader) { @@ -590,22 +590,15 @@ func (pkt *SsoServerInfo) ReadFrom(r *JceReader) { } func (pkt *FileStoragePushFSSvcList) ReadFrom(r *JceReader) { - pkt.UploadList = []FileStorageServerInfo{} - pkt.PicDownloadList = []FileStorageServerInfo{} - pkt.GPicDownloadList = []FileStorageServerInfo{} - pkt.QZoneProxyServiceList = []FileStorageServerInfo{} - pkt.UrlEncodeServiceList = []FileStorageServerInfo{} + pkt.UploadList = r.ReadFileStorageServerInfos(0) + pkt.PicDownloadList = r.ReadFileStorageServerInfos(1) + pkt.GPicDownloadList = r.ReadFileStorageServerInfos(2) + pkt.QZoneProxyServiceList = r.ReadFileStorageServerInfos(3) + pkt.UrlEncodeServiceList = r.ReadFileStorageServerInfos(4) 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) + pkt.VipEmotionList = r.ReadFileStorageServerInfos(5) + pkt.C2CPicDownList = r.ReadFileStorageServerInfos(7) r.ReadJceStruct(pkt.BigDataChannel, 5) - r.ReadSlice(&pkt.VipEmotionList, 6) - r.ReadSlice(&pkt.C2CPicDownList, 7) pkt.PttList = r.ReadBytes(10) } @@ -615,8 +608,7 @@ func (pkt *FileStorageServerInfo) ReadFrom(r *JceReader) { } func (pkt *BigDataChannel) ReadFrom(r *JceReader) { - pkt.IPLists = []BigDataIPList{} - r.ReadSlice(&pkt.IPLists, 0) + pkt.IPLists = r.ReadBigDataIPLists(0) pkt.SigSession = r.ReadBytes(1) pkt.KeySession = r.ReadBytes(2) pkt.SigUin = r.ReadInt64(3) @@ -625,9 +617,8 @@ func (pkt *BigDataChannel) ReadFrom(r *JceReader) { } func (pkt *BigDataIPList) ReadFrom(r *JceReader) { - pkt.IPList = []BigDataIPInfo{} pkt.ServiceType = r.ReadInt64(0) - r.ReadSlice(&pkt.IPList, 1) + pkt.IPList = r.ReadBigDataIPInfos(1) pkt.FragmentSize = r.ReadInt64(3) } @@ -692,8 +683,7 @@ func (pkt *FriendInfo) ReadFrom(r *JceReader) { pkt.Nick = r.ReadString(14) pkt.Network = r.ReadByte(20) pkt.NetworkType = r.ReadInt32(24) - pkt.CardID = []byte{} - r.ReadObject(&pkt.CardID, 41) + pkt.CardID = r.ReadBytes(41) } func (pkt *TroopListRequest) ToBytes() []byte { @@ -750,8 +740,7 @@ func (pkt *PushMessageInfo) ReadFrom(r *JceReader) { func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) { pkt.AppId = r.ReadInt64(0) - pkt.Guid = []byte{} - r.ReadSlice(&pkt.Guid, 1) + pkt.Guid = r.ReadBytes(1) pkt.LoginTime = r.ReadInt64(2) pkt.LoginPlatform = r.ReadInt64(3) pkt.LoginLocation = r.ReadString(4) @@ -763,7 +752,6 @@ func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) { } func (pkt *SvcRespParam) ReadFrom(r *JceReader) { - pkt.OnlineInfos = []OnlineInfo{} pkt.PCStat = r.ReadInt32(0) pkt.IsSupportC2CRoamMsg = r.ReadInt32(1) pkt.IsSupportDataLine = r.ReadInt32(2) @@ -771,7 +759,7 @@ func (pkt *SvcRespParam) ReadFrom(r *JceReader) { pkt.IsSupportViewPCFile = r.ReadInt32(4) pkt.PcVersion = r.ReadInt32(5) pkt.RoamFlag = r.ReadInt64(6) - r.ReadSlice(&pkt.OnlineInfos, 7) + pkt.OnlineInfos = r.ReadOnlineInfos(7) pkt.PCClientType = r.ReadInt32(8) } @@ -797,7 +785,6 @@ func (pkt *OnlineInfo) ReadFrom(r *JceReader) { } func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) { - pkt.InstanceList = []InstanceInfo{} pkt.AppId = r.ReadInt64(0) pkt.Status = r.ReadByte(1) pkt.Tablet = r.ReadByte(2) @@ -806,7 +793,7 @@ func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) { pkt.Info = r.ReadString(5) pkt.ProductType = r.ReadInt64(6) pkt.ClientType = r.ReadInt64(7) - r.ReadSlice(&pkt.InstanceList, 8) + pkt.InstanceList = r.ReadInstanceInfos(8) } func (pkt *InstanceInfo) ReadFrom(r *JceReader) { diff --git a/client/decoders.go b/client/decoders.go index a1f45a15..0bf9b8bb 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -312,8 +312,7 @@ func decodePushReqPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (in switch t { case 1: ssoPkt := jce.NewJceReader(jceBuf) - servers := []jce.SsoServerInfo{} - ssoPkt.ReadSlice(&servers, 1) + servers := ssoPkt.ReadSsoServerInfos(1) if len(servers) > 0 { var adds []*net.TCPAddr for _, s := range servers { @@ -433,8 +432,7 @@ func decodeSummaryCardResponse(_ *QQClient, _ *incomingPacketInfo, payload []byt Uin: rsp.ReadInt64(23), LoginDays: rsp.ReadInt64(36), } - services := [][]byte{} - rsp.ReadSlice(&services, 46) + services := rsp.ReadByteArrArr(46) readService := func(buf []byte) (*profilecard.BusiComm, []byte) { r := binary.NewReader(buf) r.ReadByte() @@ -467,8 +465,7 @@ func decodeFriendGroupListResponse(_ *QQClient, _ *incomingPacketInfo, payload [ data.ReadFrom(jce.NewJceReader(request.SBuffer)) r := jce.NewJceReader(data.Map["FLRESP"][1:]) totalFriendCount := r.ReadInt16(5) - friends := make([]jce.FriendInfo, 0) - r.ReadSlice(&friends, 7) + friends := r.ReadFriendInfos(7) l := make([]*FriendInfo, 0, len(friends)) for _, f := range friends { l = append(l, &FriendInfo{ @@ -505,10 +502,8 @@ func decodeGroupListResponse(c *QQClient, _ *incomingPacketInfo, payload []byte) data := &jce.RequestDataVersion3{} data.ReadFrom(jce.NewJceReader(request.SBuffer)) r := jce.NewJceReader(data.Map["GetTroopListRespV2"][1:]) - vecCookie := []byte{} - groups := []jce.TroopNumber{} - r.ReadSlice(&vecCookie, 4) - r.ReadSlice(&groups, 5) + vecCookie := r.ReadBytes(4) + groups := r.ReadTroopNumbers(5) l := make([]*GroupInfo, 0, len(groups)) for _, g := range groups { l = append(l, &GroupInfo{ @@ -539,8 +534,7 @@ func decodeGroupMemberListResponse(_ *QQClient, _ *incomingPacketInfo, payload [ data := &jce.RequestDataVersion3{} data.ReadFrom(jce.NewJceReader(request.SBuffer)) r := jce.NewJceReader(data.Map["GTMLRESP"][1:]) - members := make([]jce.TroopMemberInfo, 0) - r.ReadSlice(&members, 3) + members := r.ReadTroopMemberInfos(3) next := r.ReadInt64(4) l := make([]*GroupMemberInfo, 0, len(members)) for _, m := range members { diff --git a/client/global.go b/client/global.go index a239f61f..62471e62 100644 --- a/client/global.go +++ b/client/global.go @@ -476,8 +476,7 @@ func getSSOAddress() ([]*net.TCPAddr, error) { rspPkt.ReadFrom(jce.NewJceReader(tea.Decrypt(rsp)[4:])) data.ReadFrom(jce.NewJceReader(rspPkt.SBuffer)) reader := jce.NewJceReader(data.Map["HttpServerListRes"][1:]) - servers := []jce.SsoServerInfo{} - reader.ReadSlice(&servers, 2) + servers := reader.ReadSsoServerInfos(2) adds := make([]*net.TCPAddr, 0, len(servers)) for _, s := range servers { if strings.Contains(s.Server, "com") { diff --git a/client/group_info.go b/client/group_info.go index c103c904..46add952 100644 --- a/client/group_info.go +++ b/client/group_info.go @@ -200,7 +200,8 @@ func decodeGroupSearchResponse(_ *QQClient, _ *incomingPacketInfo, payload []byt } rsp := data.Map["RespSearch"]["SummaryCard.RespSearch"][1:] r := jce.NewJceReader(rsp) - rspService := r.ReadAny(2).([]interface{})[0].([]byte) + // rspService := r.ReadAny(2).([]interface{})[0].([]byte) + rspService := r.ReadByteArrArr(2)[0] sr := binary.NewReader(rspService) sr.ReadByte() ld1 := sr.ReadInt32() diff --git a/client/online_push.go b/client/online_push.go index 2718a930..c94b0cf0 100644 --- a/client/online_push.go +++ b/client/online_push.go @@ -28,9 +28,8 @@ func decodeOnlinePushReqPacket(c *QQClient, info *incomingPacketInfo, payload [] data := &jce.RequestDataVersion2{} data.ReadFrom(jce.NewJceReader(request.SBuffer)) jr := jce.NewJceReader(data.Map["req"]["OnlinePushPack.SvcReqPushMsg"][1:]) - msgInfos := []jce.PushMessageInfo{} uin := jr.ReadInt64(0) - jr.ReadSlice(&msgInfos, 2) + msgInfos := jr.ReadPushMessageInfos(2) _ = c.sendPacket(c.buildDeleteOnlinePushPacket(uin, 0, nil, info.SequenceId, msgInfos)) for _, m := range msgInfos { k := fmt.Sprintf("%v%v%v", m.MsgSeq, m.MsgTime, m.MsgUid) diff --git a/client/sync.go b/client/sync.go index 7b9e05ee..1e073376 100644 --- a/client/sync.go +++ b/client/sync.go @@ -302,16 +302,15 @@ func decodeDevListResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) ( 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) + d := rsp.ReadSvcDevLoginInfos(4) if len(d) > 0 { return d, nil } - rsp.ReadSlice(&d, 5) + d = rsp.ReadSvcDevLoginInfos(5) if len(d) > 0 { return d, nil } - rsp.ReadSlice(&d, 6) + d = rsp.ReadSvcDevLoginInfos(6) if len(d) > 0 { return d, nil }