mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
Merge pull request #203 from fumiama/master
perf: on jce & tea & pool & writer
This commit is contained in:
commit
e043181fc1
@ -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.off += 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -16,11 +16,10 @@ var bufferPool = sync.Pool{
|
||||
|
||||
// SelectWriter 从池中取出一个 Writer
|
||||
func SelectWriter() *Writer {
|
||||
w := bufferPool.Get().(*Writer)
|
||||
if w == nil {
|
||||
return new(Writer)
|
||||
}
|
||||
return w
|
||||
// 因为 bufferPool 定义有 New 函数
|
||||
// 所以 bufferPool.Get() 永不为 nil
|
||||
// 不用判空
|
||||
return bufferPool.Get().(*Writer)
|
||||
}
|
||||
|
||||
// PutWriter 将 Writer 放回池中
|
||||
@ -103,9 +102,9 @@ var b256kPool = sync.Pool{
|
||||
// Get256KBytes 获取一个128k大小 []byte
|
||||
func Get256KBytes() *[]byte {
|
||||
buf := b256kPool.Get().(*[]byte)
|
||||
if buf == nil {
|
||||
return make128kSlicePointer()
|
||||
}
|
||||
// 因为 b256kPool 定义有 New 函数
|
||||
// 所以 b256kPool.Get() 永不为 nil
|
||||
// 不用判空
|
||||
if cap(*buf) < size256k {
|
||||
return make128kSlicePointer()
|
||||
}
|
||||
|
@ -2,11 +2,15 @@ package binary
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
_ "unsafe" // required by go:linkname
|
||||
)
|
||||
|
||||
type TEA [4]uint32
|
||||
|
||||
// Uint32 returns a lock free uint32 value.
|
||||
//go:linkname Uint32 runtime.fastrand
|
||||
func Uint32() uint32
|
||||
|
||||
// Encrypt tea 加密
|
||||
// http://bbs.chinaunix.net/thread-583468-1-1.html
|
||||
// 感谢xichen大佬对TEA的解释
|
||||
@ -14,7 +18,9 @@ func (t TEA) Encrypt(src []byte) (dst []byte) {
|
||||
lens := len(src)
|
||||
fill := 10 - (lens+1)%8
|
||||
dst = make([]byte, fill+lens+7)
|
||||
_, _ = rand.Read(dst[0:fill])
|
||||
binary.LittleEndian.PutUint32(dst, Uint32())
|
||||
binary.LittleEndian.PutUint32(dst[4:], Uint32())
|
||||
binary.LittleEndian.PutUint32(dst[8:], Uint32())
|
||||
dst[0] = byte(fill-3) | 0xF8 // 存储pad长度
|
||||
copy(dst[fill:], src)
|
||||
|
||||
@ -36,14 +42,13 @@ func (t TEA) Decrypt(data []byte) []byte {
|
||||
return nil
|
||||
}
|
||||
dst := make([]byte, len(data))
|
||||
var iv1, iv2, holder, tmp uint64
|
||||
var iv1, iv2, holder uint64
|
||||
for i := 0; i < len(dst); i += 8 {
|
||||
block := binary.BigEndian.Uint64(data[i:])
|
||||
tmp = t.decode(block ^ iv2)
|
||||
iv2 = tmp
|
||||
holder = tmp ^ iv1
|
||||
iv1 = block
|
||||
binary.BigEndian.PutUint64(dst[i:], holder)
|
||||
iv1 = binary.BigEndian.Uint64(data[i:])
|
||||
iv2 ^= iv1
|
||||
iv2 = t.decode(iv2)
|
||||
binary.BigEndian.PutUint64(dst[i:], iv2^holder)
|
||||
holder = iv1
|
||||
}
|
||||
return dst[dst[0]&7+3 : len(data)-7]
|
||||
}
|
||||
|
@ -19,6 +19,14 @@ func NewWriterF(f func(writer *Writer)) []byte {
|
||||
return b
|
||||
}
|
||||
|
||||
// OpenWriterF must call func close
|
||||
func OpenWriterF(f func(writer *Writer)) (b []byte, close func()) {
|
||||
w := SelectWriter()
|
||||
w.WriteByte(0)
|
||||
f(w)
|
||||
return w.Bytes(), func() { PutWriter(w) }
|
||||
}
|
||||
|
||||
func (w *Writer) Write(b []byte) {
|
||||
(*bytes.Buffer)(w).Write(b)
|
||||
}
|
||||
@ -69,15 +77,14 @@ func (w *Writer) WriteBool(b bool) {
|
||||
}
|
||||
|
||||
func (w *Writer) EncryptAndWrite(key []byte, data []byte) {
|
||||
tea := NewTeaCipher(key)
|
||||
ed := tea.Encrypt(data)
|
||||
w.Write(ed)
|
||||
w.Write(NewTeaCipher(key).Encrypt(data))
|
||||
}
|
||||
|
||||
func (w *Writer) WriteIntLvPacket(offset int, f func(writer *Writer)) {
|
||||
data := NewWriterF(f)
|
||||
data, close := OpenWriterF(f)
|
||||
w.WriteUInt32(uint32(len(data) + offset))
|
||||
w.Write(data)
|
||||
close()
|
||||
}
|
||||
|
||||
func (w *Writer) WriteUniPacket(commandName string, sessionId, extraData, body []byte) {
|
||||
|
@ -49,3 +49,51 @@ func BenchmarkNewWriterF128_5(b *testing.B) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkOpenWriterF128(b *testing.B) {
|
||||
test := make([]byte, 128)
|
||||
rand.Read(test)
|
||||
b.StartTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, close := OpenWriterF(func(w *Writer) {
|
||||
w.Write(test)
|
||||
})
|
||||
close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkOpenWriterF128_3(b *testing.B) {
|
||||
test := make([]byte, 128)
|
||||
rand.Read(test)
|
||||
b.StartTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, close := OpenWriterF(func(w *Writer) {
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
})
|
||||
close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkOpenWriterF128_5(b *testing.B) {
|
||||
test := make([]byte, 128)
|
||||
rand.Read(test)
|
||||
b.StartTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, close := OpenWriterF(func(w *Writer) {
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
w.Write(test)
|
||||
})
|
||||
close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -169,10 +169,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
|
||||
|
||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||
w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress))
|
||||
w.Write(binary.NewWriterF(func(w *binary.Writer) {
|
||||
wb, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x106)
|
||||
w.WriteBytesShort(t106)
|
||||
}))
|
||||
})
|
||||
w.Write(wb)
|
||||
cl()
|
||||
// w.Write(tlv.T106(uint32(c.Uin), 0, c.version.AppId, c.version.SSOVersion, c.PasswordMd5, true, c.deviceInfo.Guid, c.deviceInfo.TgtgtKey, 0))
|
||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||
w.Write(tlv.T100(c.version.SSOVersion, c.version.SubAppId, c.version.MainSigMap))
|
||||
@ -194,10 +196,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
|
||||
|
||||
w.Write(tlv.T145(c.deviceInfo.Guid))
|
||||
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
|
||||
w.Write(binary.NewWriterF(func(w *binary.Writer) {
|
||||
wb, cl = binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x16A)
|
||||
w.WriteBytesShort(t16a)
|
||||
}))
|
||||
})
|
||||
w.Write(wb)
|
||||
cl()
|
||||
w.Write(tlv.T154(seq))
|
||||
w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN))
|
||||
w.Write(tlv.T8(2052))
|
||||
@ -219,10 +223,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
|
||||
w.Write(tlv.T516())
|
||||
w.Write(tlv.T521(8))
|
||||
// w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00})))
|
||||
w.Write(binary.NewWriterF(func(w *binary.Writer) {
|
||||
wb, cl = binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x318)
|
||||
w.WriteBytesShort(t318)
|
||||
}))
|
||||
})
|
||||
w.Write(wb)
|
||||
cl()
|
||||
})
|
||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
|
||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
|
||||
@ -306,10 +312,12 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||
|
||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||
w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress))
|
||||
w.Write(binary.NewWriterF(func(w *binary.Writer) {
|
||||
wb, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x106)
|
||||
w.WriteBytesShort(c.sigInfo.encryptedA1)
|
||||
}))
|
||||
})
|
||||
w.Write(wb)
|
||||
cl()
|
||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||
w.Write(tlv.T100(c.version.SSOVersion, 2, c.version.MainSigMap))
|
||||
w.Write(tlv.T107(0))
|
||||
@ -989,13 +997,15 @@ func (c *QQClient) buildGroupKickPacket(groupCode, memberUin int64, kickMsg stri
|
||||
// OidbSvc.0x570_8
|
||||
func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
payload := c.packOIDBPackage(1392, 8, binary.NewWriterF(func(w *binary.Writer) {
|
||||
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt32(uint32(groupCode))
|
||||
w.WriteByte(32)
|
||||
w.WriteUInt16(1)
|
||||
w.WriteUInt32(uint32(memberUin))
|
||||
w.WriteUInt32(time)
|
||||
}))
|
||||
})
|
||||
payload := c.packOIDBPackage(1392, 8, b)
|
||||
cl()
|
||||
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x570_8", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||
return seq, packet
|
||||
}
|
||||
@ -1029,7 +1039,7 @@ func (c *QQClient) buildFriendPokePacket(target int64) (uint16, []byte) {
|
||||
// OidbSvc.0x55c_1
|
||||
func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
payload := c.packOIDBPackage(1372, 1, binary.NewWriterF(func(w *binary.Writer) {
|
||||
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt32(uint32(groupCode))
|
||||
w.WriteUInt32(uint32(member))
|
||||
w.WriteByte(func() byte {
|
||||
@ -1038,7 +1048,9 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool)
|
||||
}
|
||||
return 0
|
||||
}())
|
||||
}))
|
||||
})
|
||||
payload := c.packOIDBPackage(1372, 1, b)
|
||||
cl()
|
||||
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x55c_1", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||
return seq, packet
|
||||
}
|
||||
@ -1049,10 +1061,12 @@ func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
|
||||
jw := jce.NewJceWriter()
|
||||
jw.WriteInt32(2, 0)
|
||||
jw.WriteInt64(c.Uin, 1)
|
||||
jw.WriteBytes(binary.NewWriterF(func(w *binary.Writer) {
|
||||
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt32(uint32(c.Uin))
|
||||
w.WriteUInt32(uint32(groupCode))
|
||||
}), 2)
|
||||
})
|
||||
jw.WriteBytes(b, 2)
|
||||
cl()
|
||||
buf := &jce.RequestDataVersion3{Map: map[string][]byte{"GroupMngReq": packUniRequestData(jw.Bytes())}}
|
||||
pkt := &jce.RequestPacket{
|
||||
IVersion: 3,
|
||||
|
@ -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 {
|
||||
|
@ -459,12 +459,15 @@ func getSSOAddress() ([]*net.TCPAddr, error) {
|
||||
SFuncName: "HttpServerListReq",
|
||||
SBuffer: buf.ToBytes(),
|
||||
}
|
||||
tea := binary.NewTeaCipher(key)
|
||||
rsp, err := utils.HttpPostBytes("https://configsvr.msf.3g.qq.com/configsvr/serverlist.jsp", tea.Encrypt(binary.NewWriterF(func(w *binary.Writer) {
|
||||
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteIntLvPacket(0, func(w *binary.Writer) {
|
||||
w.Write(pkt.ToBytes())
|
||||
})
|
||||
})))
|
||||
})
|
||||
tea := binary.NewTeaCipher(key)
|
||||
encpkt := tea.Encrypt(b)
|
||||
cl()
|
||||
rsp, err := utils.HttpPostBytes("https://configsvr.msf.3g.qq.com/configsvr/serverlist.jsp", encpkt)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to fetch server list")
|
||||
}
|
||||
@ -473,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") {
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user