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

perf(jce): drop reflect in reader

name                   old time/op    new time/op    delta
JceReader_ReadSlice-8    1.53ms ±90%    0.82ms ±86%  -46.30%  (p=0.017 n=16+16)

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)
This commit is contained in:
fumiama 2021-11-26 15:02:44 +08:00
parent a70e0f20de
commit 13a9d087e7
8 changed files with 406 additions and 126 deletions

View File

@ -3,7 +3,6 @@ package jce
import ( import (
goBinary "encoding/binary" goBinary "encoding/binary"
"math" "math"
"reflect"
"github.com/Mrs4s/MiraiGo/utils" "github.com/Mrs4s/MiraiGo/utils"
) )
@ -22,28 +21,36 @@ func NewJceReader(data []byte) *JceReader {
return &JceReader{buf: data} return &JceReader{buf: data}
} }
func (r *JceReader) readHead() (hd HeadData, l int32) { func (r *JceReader) readHead() (hd HeadData, l int) {
b := r.buf[r.off] hd, l = r.peakHead()
hd.Type = b & 0xF r.off += l
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)
return return
} }
func (r *JceReader) peakHead() (h HeadData, l int32) { func (r *JceReader) peakHead() (hd HeadData, l int) {
h, l = r.readHead() b := r.buf[r.off]
r.off -= int(l) 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 return
} }
func (r *JceReader) skip(l int) { func (r *JceReader) skip(l int) {
r.readBytes(l) r.skipBytes(l)
} }
func (r *JceReader) skipField(t byte) { func (r *JceReader) skipField(t byte) {
@ -57,10 +64,9 @@ func (r *JceReader) skipField(t byte) {
case 3, 5: case 3, 5:
r.skip(8) r.skip(8)
case 6: case 6:
b := r.readByte() r.skip(int(r.readByte()))
r.skip(int(b))
case 7: case 7:
r.skip(int(r.readInt32())) r.skip(int(r.readUInt32()))
case 8: case 8:
s := r.ReadInt32(0) s := r.ReadInt32(0)
for i := 0; i < int(s)*2; i++ { for i := 0; i < int(s)*2; i++ {
@ -72,7 +78,7 @@ func (r *JceReader) skipField(t byte) {
r.skipNextField() r.skipNextField()
} }
case 13: case 13:
r.readHead() r.skipHead()
s := r.ReadInt32(0) s := r.ReadInt32(0)
r.skip(int(s)) r.skip(int(s))
case 10: case 10:
@ -96,11 +102,21 @@ func (r *JceReader) readBytes(n int) []byte {
panic("readBytes: EOF") panic("readBytes: EOF")
} }
b := make([]byte, n) b := make([]byte, n)
n = copy(b, r.buf[r.off:]) r.off += copy(b, r.buf[r.off:])
r.off += n
return b 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 { func (r *JceReader) readByte() byte {
if r.off >= len(r.buf) { if r.off >= len(r.buf) {
panic("readByte: EOF") panic("readByte: EOF")
@ -111,48 +127,40 @@ func (r *JceReader) readByte() byte {
} }
func (r *JceReader) readUInt16() uint16 { func (r *JceReader) readUInt16() uint16 {
b := r.readBytes(2) return goBinary.BigEndian.Uint16(r.readBytes(2))
return uint16((int32(b[0]) << 8) + int32(b[1]))
} }
func (r *JceReader) readInt32() int32 { func (r *JceReader) readUInt32() uint32 {
b := r.readBytes(4) return goBinary.BigEndian.Uint32(r.readBytes(4))
return int32(goBinary.BigEndian.Uint32(b))
} }
func (r *JceReader) readInt64() int64 { func (r *JceReader) readUInt64() uint64 {
b := r.readBytes(8) return goBinary.BigEndian.Uint64(r.readBytes(8))
return int64(goBinary.BigEndian.Uint64(b))
} }
func (r *JceReader) readFloat32() float32 { func (r *JceReader) readFloat32() float32 {
b := r.readInt32() return math.Float32frombits(r.readUInt32())
return math.Float32frombits(uint32(b))
} }
func (r *JceReader) readFloat64() float64 { func (r *JceReader) readFloat64() float64 {
b := r.readInt64() return math.Float64frombits(r.readUInt64())
return math.Float64frombits(uint64(b))
} }
func (r *JceReader) skipToTag(tag int) bool { func (r *JceReader) skipToTag(tag int) bool {
for {
hd, l := r.peakHead() hd, l := r.peakHead()
if tag <= hd.Tag || hd.Type == 11 { for tag > hd.Tag && hd.Type != 11 {
return tag == hd.Tag r.skip(l)
}
r.skip(int(l))
r.skipField(hd.Type) r.skipField(hd.Type)
hd, l = r.peakHead()
} }
return tag == hd.Tag
} }
func (r *JceReader) skipToStructEnd() { func (r *JceReader) skipToStructEnd() {
for {
hd, _ := r.readHead() hd, _ := r.readHead()
for hd.Type != 11 {
r.skipField(hd.Type) r.skipField(hd.Type)
if hd.Type == 11 { hd, _ = r.readHead()
return
}
} }
} }
@ -205,7 +213,7 @@ func (r *JceReader) ReadInt32(tag int) int32 {
case 1: case 1:
return int32(r.readUInt16()) return int32(r.readUInt16())
case 2: case 2:
return r.readInt32() return int32(r.readUInt32())
default: default:
return 0 return 0
} }
@ -224,9 +232,9 @@ func (r *JceReader) ReadInt64(tag int) int64 {
case 1: case 1:
return int64(int16(r.readUInt16())) return int64(int16(r.readUInt16()))
case 2: case 2:
return int64(r.readInt32()) return int64(r.readUInt32())
case 3: case 3:
return r.readInt64() return int64(r.readUInt64())
default: default:
return 0 return 0
} }
@ -273,7 +281,7 @@ func (r *JceReader) ReadString(tag int) string {
case 6: case 6:
return utils.B2S(r.readBytes(int(r.readByte()))) return utils.B2S(r.readBytes(int(r.readByte())))
case 7: case 7:
return utils.B2S(r.readBytes(int(r.readInt32()))) return utils.B2S(r.readBytes(int(r.readUInt32())))
default: default:
return "" return ""
} }
@ -293,13 +301,32 @@ func (r *JceReader) ReadBytes(tag int) []byte {
} }
return b return b
case 13: case 13:
r.readHead() r.skipHead()
return r.readBytes(int(r.ReadInt32(0))) return r.readBytes(int(r.ReadInt32(0)))
default: default:
return nil 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 // ReadAny Read any type via tag, unsupported JceStruct
func (r *JceReader) ReadAny(tag int) interface{} { func (r *JceReader) ReadAny(tag int) interface{} {
if !r.skipToTag(tag) { if !r.skipToTag(tag) {
@ -312,17 +339,17 @@ func (r *JceReader) ReadAny(tag int) interface{} {
case 1: case 1:
return r.readUInt16() return r.readUInt16()
case 2: case 2:
return r.readInt32() return r.readUInt32()
case 3: case 3:
return r.readInt64() return r.readUInt64()
case 4: case 4:
return r.readFloat32() return r.readFloat32()
case 5: case 5:
return r.readFloat64() return r.readFloat64()
case 6: case 6:
return string(r.readBytes(int(r.readByte()))) return utils.B2S(r.readBytes(int(r.readByte())))
case 7: case 7:
return string(r.readBytes(int(r.readInt32()))) return utils.B2S(r.readBytes(int(r.readUInt32())))
case 8: case 8:
s := r.ReadInt32(0) s := r.ReadInt32(0)
m := make(map[interface{}]interface{}) m := make(map[interface{}]interface{})
@ -340,12 +367,13 @@ func (r *JceReader) ReadAny(tag int) interface{} {
case 12: case 12:
return 0 return 0
case 13: case 13:
r.readHead() r.skipHead()
return r.readBytes(int(r.ReadInt32(0))) return r.readBytes(int(r.ReadInt32(0)))
default: default:
return nil return nil
} }
} }
*/
func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) { func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) {
if !r.skipToTag(tag) { if !r.skipToTag(tag) {
@ -359,9 +387,63 @@ func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) {
r.skipToStructEnd() 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) { func (r *JceReader) ReadMap(i interface{}, tag int) {
v := reflect.ValueOf(i) r.readMap(reflect.ValueOf(i), tag)
r.readMap(v, tag)
} }
func (r *JceReader) readMap(v reflect.Value, tag int) { 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() kt := t.Key()
vt := t.Elem() vt := t.Elem()
r.readHead() r.skipHead()
s := r.ReadInt32(0) s := r.ReadInt32(0)
// map with string key or string value is very common. // 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()) 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) { func (r *JceReader) ReadSlice(i interface{}, tag int) {
r.readSlice(reflect.ValueOf(i), tag) r.readSlice(reflect.ValueOf(i), tag)
} }
func (r *JceReader) readSlice(v reflect.Value, tag int) { func (r *JceReader) readSlice(v reflect.Value, tag int) {
t := v.Type() 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 return
} }
v = v.Elem() v = v.Elem()
t = t.Elem() t = t.Elem()
if !r.skipToTag(tag) {
return
}
hd, _ := r.readHead() hd, _ := r.readHead()
if hd.Type == 9 { if hd.Type == 9 {
s := r.ReadInt32(0) s := r.ReadInt32(0)
@ -432,15 +733,14 @@ func (r *JceReader) readSlice(v reflect.Value, tag int) {
v.Set(sv) v.Set(sv)
} }
if hd.Type == 13 && t.Elem().Kind() == reflect.Uint8 { if hd.Type == 13 && t.Elem().Kind() == reflect.Uint8 {
r.readHead() r.skipHead()
arr := r.readBytes(int(r.ReadInt32(0))) arr := r.readBytes(int(r.ReadInt32(0)))
v.SetBytes(arr) v.SetBytes(arr)
} }
} }
func (r *JceReader) ReadObject(i interface{}, tag int) { func (r *JceReader) ReadObject(i interface{}, tag int) {
v := reflect.ValueOf(i) r.readObject(reflect.ValueOf(i), tag)
r.readObject(v, tag)
} }
func (r *JceReader) readObject(v reflect.Value, tag int) { func (r *JceReader) readObject(v reflect.Value, tag int) {
@ -478,7 +778,7 @@ func (r *JceReader) readObject(v reflect.Value, tag int) {
// other cases // other cases
switch o := v.Interface().(type) { switch o := v.Interface().(type) {
case IJceStruct: case IJceStruct:
r.readHead() r.skipHead()
o.ReadFrom(r) o.ReadFrom(r)
r.skipToStructEnd() r.skipToStructEnd()
case *float32: case *float32:
@ -488,3 +788,4 @@ func (r *JceReader) readObject(v reflect.Value, tag int) {
} }
} }
} }
*/

View File

@ -8,15 +8,16 @@ import (
) )
func TestJceReader_ReadSlice(t *testing.T) { func TestJceReader_ReadSlice(t *testing.T) {
s := make([]int64, 50) s := make([][]byte, 50)
for i := range s { for i := range s {
s[i] = rand.Int63() b := make([]byte, 64)
_, _ = rand.Read(b)
s[i] = b
} }
w := NewJceWriter() w := NewJceWriter()
w.WriteObject(s, 1) w.WriteObject(s, 1)
r := NewJceReader(w.Bytes()) r := NewJceReader(w.Bytes())
var result []int64 result := r.ReadByteArrArr(1)
r.ReadSlice(&result, 1)
assert.Equal(t, s, result) assert.Equal(t, s, result)
} }
@ -35,10 +36,9 @@ func BenchmarkJceReader_ReadSlice(b *testing.B) {
src := w.Bytes() src := w.Bytes()
b.SetBytes(int64(len(src))) b.SetBytes(int64(len(src)))
b.StartTimer() b.StartTimer()
result := make([]BigDataIPInfo, 0)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r := NewJceReader(src) r := NewJceReader(src)
r.ReadSlice(&result, 1) _ = r.ReadBigDataIPInfos(1)
} }
} }

View File

@ -555,10 +555,12 @@ func (pkt *RequestPacket) ReadFrom(r *JceReader) {
pkt.IRequestId = r.ReadInt32(4) pkt.IRequestId = r.ReadInt32(4)
pkt.SServantName = r.ReadString(5) pkt.SServantName = r.ReadString(5)
pkt.SFuncName = r.ReadString(6) pkt.SFuncName = r.ReadString(6)
r.ReadSlice(&pkt.SBuffer, 7) pkt.SBuffer = r.ReadBytes(7)
pkt.ITimeout = r.ReadInt32(8) pkt.ITimeout = r.ReadInt32(8)
r.ReadMap(pkt.Context, 9) // r.ReadMap(pkt.Context, 9)
r.ReadMap(pkt.Status, 10) pkt.Context = r.ReadMapStrStr(9)
// r.ReadMap(pkt.Status, 10)
pkt.Status = r.ReadMapStrStr(10)
} }
func (pkt *RequestDataVersion3) ToBytes() []byte { func (pkt *RequestDataVersion3) ToBytes() []byte {
@ -568,8 +570,7 @@ func (pkt *RequestDataVersion3) ToBytes() []byte {
} }
func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) { func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) {
pkt.Map = make(map[string][]byte) pkt.Map = r.ReadMapStrByte(0)
r.ReadMap(pkt.Map, 0)
} }
func (pkt *RequestDataVersion2) ToBytes() []byte { func (pkt *RequestDataVersion2) ToBytes() []byte {
@ -579,8 +580,7 @@ func (pkt *RequestDataVersion2) ToBytes() []byte {
} }
func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) { func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) {
pkt.Map = make(map[string]map[string][]byte) pkt.Map = r.ReadMapStrMapStrByte(0)
r.ReadMap(pkt.Map, 0)
} }
func (pkt *SsoServerInfo) ReadFrom(r *JceReader) { func (pkt *SsoServerInfo) ReadFrom(r *JceReader) {
@ -590,22 +590,15 @@ func (pkt *SsoServerInfo) ReadFrom(r *JceReader) {
} }
func (pkt *FileStoragePushFSSvcList) ReadFrom(r *JceReader) { func (pkt *FileStoragePushFSSvcList) ReadFrom(r *JceReader) {
pkt.UploadList = []FileStorageServerInfo{} pkt.UploadList = r.ReadFileStorageServerInfos(0)
pkt.PicDownloadList = []FileStorageServerInfo{} pkt.PicDownloadList = r.ReadFileStorageServerInfos(1)
pkt.GPicDownloadList = []FileStorageServerInfo{} pkt.GPicDownloadList = r.ReadFileStorageServerInfos(2)
pkt.QZoneProxyServiceList = []FileStorageServerInfo{} pkt.QZoneProxyServiceList = r.ReadFileStorageServerInfos(3)
pkt.UrlEncodeServiceList = []FileStorageServerInfo{} pkt.UrlEncodeServiceList = r.ReadFileStorageServerInfos(4)
pkt.BigDataChannel = &BigDataChannel{} pkt.BigDataChannel = &BigDataChannel{}
pkt.VipEmotionList = []FileStorageServerInfo{} pkt.VipEmotionList = r.ReadFileStorageServerInfos(5)
pkt.C2CPicDownList = []FileStorageServerInfo{} pkt.C2CPicDownList = r.ReadFileStorageServerInfos(7)
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.ReadJceStruct(pkt.BigDataChannel, 5)
r.ReadSlice(&pkt.VipEmotionList, 6)
r.ReadSlice(&pkt.C2CPicDownList, 7)
pkt.PttList = r.ReadBytes(10) pkt.PttList = r.ReadBytes(10)
} }
@ -615,8 +608,7 @@ func (pkt *FileStorageServerInfo) ReadFrom(r *JceReader) {
} }
func (pkt *BigDataChannel) ReadFrom(r *JceReader) { func (pkt *BigDataChannel) ReadFrom(r *JceReader) {
pkt.IPLists = []BigDataIPList{} pkt.IPLists = r.ReadBigDataIPLists(0)
r.ReadSlice(&pkt.IPLists, 0)
pkt.SigSession = r.ReadBytes(1) pkt.SigSession = r.ReadBytes(1)
pkt.KeySession = r.ReadBytes(2) pkt.KeySession = r.ReadBytes(2)
pkt.SigUin = r.ReadInt64(3) pkt.SigUin = r.ReadInt64(3)
@ -625,9 +617,8 @@ func (pkt *BigDataChannel) ReadFrom(r *JceReader) {
} }
func (pkt *BigDataIPList) ReadFrom(r *JceReader) { func (pkt *BigDataIPList) ReadFrom(r *JceReader) {
pkt.IPList = []BigDataIPInfo{}
pkt.ServiceType = r.ReadInt64(0) pkt.ServiceType = r.ReadInt64(0)
r.ReadSlice(&pkt.IPList, 1) pkt.IPList = r.ReadBigDataIPInfos(1)
pkt.FragmentSize = r.ReadInt64(3) pkt.FragmentSize = r.ReadInt64(3)
} }
@ -692,8 +683,7 @@ func (pkt *FriendInfo) ReadFrom(r *JceReader) {
pkt.Nick = r.ReadString(14) pkt.Nick = r.ReadString(14)
pkt.Network = r.ReadByte(20) pkt.Network = r.ReadByte(20)
pkt.NetworkType = r.ReadInt32(24) pkt.NetworkType = r.ReadInt32(24)
pkt.CardID = []byte{} pkt.CardID = r.ReadBytes(41)
r.ReadObject(&pkt.CardID, 41)
} }
func (pkt *TroopListRequest) ToBytes() []byte { func (pkt *TroopListRequest) ToBytes() []byte {
@ -750,8 +740,7 @@ func (pkt *PushMessageInfo) ReadFrom(r *JceReader) {
func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) { func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) {
pkt.AppId = r.ReadInt64(0) pkt.AppId = r.ReadInt64(0)
pkt.Guid = []byte{} pkt.Guid = r.ReadBytes(1)
r.ReadSlice(&pkt.Guid, 1)
pkt.LoginTime = r.ReadInt64(2) pkt.LoginTime = r.ReadInt64(2)
pkt.LoginPlatform = r.ReadInt64(3) pkt.LoginPlatform = r.ReadInt64(3)
pkt.LoginLocation = r.ReadString(4) pkt.LoginLocation = r.ReadString(4)
@ -763,7 +752,6 @@ func (pkt *SvcDevLoginInfo) ReadFrom(r *JceReader) {
} }
func (pkt *SvcRespParam) ReadFrom(r *JceReader) { func (pkt *SvcRespParam) ReadFrom(r *JceReader) {
pkt.OnlineInfos = []OnlineInfo{}
pkt.PCStat = r.ReadInt32(0) pkt.PCStat = r.ReadInt32(0)
pkt.IsSupportC2CRoamMsg = r.ReadInt32(1) pkt.IsSupportC2CRoamMsg = r.ReadInt32(1)
pkt.IsSupportDataLine = r.ReadInt32(2) pkt.IsSupportDataLine = r.ReadInt32(2)
@ -771,7 +759,7 @@ func (pkt *SvcRespParam) ReadFrom(r *JceReader) {
pkt.IsSupportViewPCFile = r.ReadInt32(4) pkt.IsSupportViewPCFile = r.ReadInt32(4)
pkt.PcVersion = r.ReadInt32(5) pkt.PcVersion = r.ReadInt32(5)
pkt.RoamFlag = r.ReadInt64(6) pkt.RoamFlag = r.ReadInt64(6)
r.ReadSlice(&pkt.OnlineInfos, 7) pkt.OnlineInfos = r.ReadOnlineInfos(7)
pkt.PCClientType = r.ReadInt32(8) pkt.PCClientType = r.ReadInt32(8)
} }
@ -797,7 +785,6 @@ func (pkt *OnlineInfo) ReadFrom(r *JceReader) {
} }
func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) { func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) {
pkt.InstanceList = []InstanceInfo{}
pkt.AppId = r.ReadInt64(0) pkt.AppId = r.ReadInt64(0)
pkt.Status = r.ReadByte(1) pkt.Status = r.ReadByte(1)
pkt.Tablet = r.ReadByte(2) pkt.Tablet = r.ReadByte(2)
@ -806,7 +793,7 @@ func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) {
pkt.Info = r.ReadString(5) pkt.Info = r.ReadString(5)
pkt.ProductType = r.ReadInt64(6) pkt.ProductType = r.ReadInt64(6)
pkt.ClientType = r.ReadInt64(7) pkt.ClientType = r.ReadInt64(7)
r.ReadSlice(&pkt.InstanceList, 8) pkt.InstanceList = r.ReadInstanceInfos(8)
} }
func (pkt *InstanceInfo) ReadFrom(r *JceReader) { func (pkt *InstanceInfo) ReadFrom(r *JceReader) {

View File

@ -312,8 +312,7 @@ func decodePushReqPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
switch t { switch t {
case 1: case 1:
ssoPkt := jce.NewJceReader(jceBuf) ssoPkt := jce.NewJceReader(jceBuf)
servers := []jce.SsoServerInfo{} servers := ssoPkt.ReadSsoServerInfos(1)
ssoPkt.ReadSlice(&servers, 1)
if len(servers) > 0 { if len(servers) > 0 {
var adds []*net.TCPAddr var adds []*net.TCPAddr
for _, s := range servers { for _, s := range servers {
@ -433,8 +432,7 @@ func decodeSummaryCardResponse(_ *QQClient, _ *incomingPacketInfo, payload []byt
Uin: rsp.ReadInt64(23), Uin: rsp.ReadInt64(23),
LoginDays: rsp.ReadInt64(36), LoginDays: rsp.ReadInt64(36),
} }
services := [][]byte{} services := rsp.ReadByteArrArr(46)
rsp.ReadSlice(&services, 46)
readService := func(buf []byte) (*profilecard.BusiComm, []byte) { readService := func(buf []byte) (*profilecard.BusiComm, []byte) {
r := binary.NewReader(buf) r := binary.NewReader(buf)
r.ReadByte() r.ReadByte()
@ -467,8 +465,7 @@ func decodeFriendGroupListResponse(_ *QQClient, _ *incomingPacketInfo, payload [
data.ReadFrom(jce.NewJceReader(request.SBuffer)) data.ReadFrom(jce.NewJceReader(request.SBuffer))
r := jce.NewJceReader(data.Map["FLRESP"][1:]) r := jce.NewJceReader(data.Map["FLRESP"][1:])
totalFriendCount := r.ReadInt16(5) totalFriendCount := r.ReadInt16(5)
friends := make([]jce.FriendInfo, 0) friends := r.ReadFriendInfos(7)
r.ReadSlice(&friends, 7)
l := make([]*FriendInfo, 0, len(friends)) l := make([]*FriendInfo, 0, len(friends))
for _, f := range friends { for _, f := range friends {
l = append(l, &FriendInfo{ l = append(l, &FriendInfo{
@ -505,10 +502,8 @@ func decodeGroupListResponse(c *QQClient, _ *incomingPacketInfo, payload []byte)
data := &jce.RequestDataVersion3{} data := &jce.RequestDataVersion3{}
data.ReadFrom(jce.NewJceReader(request.SBuffer)) data.ReadFrom(jce.NewJceReader(request.SBuffer))
r := jce.NewJceReader(data.Map["GetTroopListRespV2"][1:]) r := jce.NewJceReader(data.Map["GetTroopListRespV2"][1:])
vecCookie := []byte{} vecCookie := r.ReadBytes(4)
groups := []jce.TroopNumber{} groups := r.ReadTroopNumbers(5)
r.ReadSlice(&vecCookie, 4)
r.ReadSlice(&groups, 5)
l := make([]*GroupInfo, 0, len(groups)) l := make([]*GroupInfo, 0, len(groups))
for _, g := range groups { for _, g := range groups {
l = append(l, &GroupInfo{ l = append(l, &GroupInfo{
@ -539,8 +534,7 @@ func decodeGroupMemberListResponse(_ *QQClient, _ *incomingPacketInfo, payload [
data := &jce.RequestDataVersion3{} data := &jce.RequestDataVersion3{}
data.ReadFrom(jce.NewJceReader(request.SBuffer)) data.ReadFrom(jce.NewJceReader(request.SBuffer))
r := jce.NewJceReader(data.Map["GTMLRESP"][1:]) r := jce.NewJceReader(data.Map["GTMLRESP"][1:])
members := make([]jce.TroopMemberInfo, 0) members := r.ReadTroopMemberInfos(3)
r.ReadSlice(&members, 3)
next := r.ReadInt64(4) next := r.ReadInt64(4)
l := make([]*GroupMemberInfo, 0, len(members)) l := make([]*GroupMemberInfo, 0, len(members))
for _, m := range members { for _, m := range members {

View File

@ -476,8 +476,7 @@ func getSSOAddress() ([]*net.TCPAddr, error) {
rspPkt.ReadFrom(jce.NewJceReader(tea.Decrypt(rsp)[4:])) rspPkt.ReadFrom(jce.NewJceReader(tea.Decrypt(rsp)[4:]))
data.ReadFrom(jce.NewJceReader(rspPkt.SBuffer)) data.ReadFrom(jce.NewJceReader(rspPkt.SBuffer))
reader := jce.NewJceReader(data.Map["HttpServerListRes"][1:]) reader := jce.NewJceReader(data.Map["HttpServerListRes"][1:])
servers := []jce.SsoServerInfo{} servers := reader.ReadSsoServerInfos(2)
reader.ReadSlice(&servers, 2)
adds := make([]*net.TCPAddr, 0, len(servers)) adds := make([]*net.TCPAddr, 0, len(servers))
for _, s := range servers { for _, s := range servers {
if strings.Contains(s.Server, "com") { if strings.Contains(s.Server, "com") {

View File

@ -200,7 +200,8 @@ func decodeGroupSearchResponse(_ *QQClient, _ *incomingPacketInfo, payload []byt
} }
rsp := data.Map["RespSearch"]["SummaryCard.RespSearch"][1:] rsp := data.Map["RespSearch"]["SummaryCard.RespSearch"][1:]
r := jce.NewJceReader(rsp) 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 := binary.NewReader(rspService)
sr.ReadByte() sr.ReadByte()
ld1 := sr.ReadInt32() ld1 := sr.ReadInt32()

View File

@ -28,9 +28,8 @@ func decodeOnlinePushReqPacket(c *QQClient, info *incomingPacketInfo, payload []
data := &jce.RequestDataVersion2{} data := &jce.RequestDataVersion2{}
data.ReadFrom(jce.NewJceReader(request.SBuffer)) data.ReadFrom(jce.NewJceReader(request.SBuffer))
jr := jce.NewJceReader(data.Map["req"]["OnlinePushPack.SvcReqPushMsg"][1:]) jr := jce.NewJceReader(data.Map["req"]["OnlinePushPack.SvcReqPushMsg"][1:])
msgInfos := []jce.PushMessageInfo{}
uin := jr.ReadInt64(0) uin := jr.ReadInt64(0)
jr.ReadSlice(&msgInfos, 2) msgInfos := jr.ReadPushMessageInfos(2)
_ = c.sendPacket(c.buildDeleteOnlinePushPacket(uin, 0, nil, info.SequenceId, msgInfos)) _ = c.sendPacket(c.buildDeleteOnlinePushPacket(uin, 0, nil, info.SequenceId, msgInfos))
for _, m := range msgInfos { for _, m := range msgInfos {
k := fmt.Sprintf("%v%v%v", m.MsgSeq, m.MsgTime, m.MsgUid) k := fmt.Sprintf("%v%v%v", m.MsgSeq, m.MsgTime, m.MsgUid)

View File

@ -302,16 +302,15 @@ func decodeDevListResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (
data := &jce.RequestDataVersion2{} data := &jce.RequestDataVersion2{}
data.ReadFrom(jce.NewJceReader(request.SBuffer)) data.ReadFrom(jce.NewJceReader(request.SBuffer))
rsp := jce.NewJceReader(data.Map["SvcRspGetDevLoginInfo"]["QQService.SvcRspGetDevLoginInfo"][1:]) rsp := jce.NewJceReader(data.Map["SvcRspGetDevLoginInfo"]["QQService.SvcRspGetDevLoginInfo"][1:])
d := []jce.SvcDevLoginInfo{} d := rsp.ReadSvcDevLoginInfos(4)
rsp.ReadSlice(&d, 4)
if len(d) > 0 { if len(d) > 0 {
return d, nil return d, nil
} }
rsp.ReadSlice(&d, 5) d = rsp.ReadSvcDevLoginInfos(5)
if len(d) > 0 { if len(d) > 0 {
return d, nil return d, nil
} }
rsp.ReadSlice(&d, 6) d = rsp.ReadSvcDevLoginInfos(6)
if len(d) > 0 { if len(d) > 0 {
return d, nil return d, nil
} }