1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

Merge pull request #215 from fumiama/master

perf(jce): drop reflect in writer
This commit is contained in:
Mrs4s 2021-12-11 02:16:01 +08:00 committed by GitHub
commit be7293b1c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1213 additions and 305 deletions

View File

@ -0,0 +1,92 @@
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"strings"
_ "embed"
)
//go:embed structs_parser_tmp.go
var tmpmain string
func main() {
f := flag.String("f", "structs_tobytes.go", "output file.")
i := flag.String("i", "structs.go", "input file.")
flag.Parse()
fmt.Println("gen runs on arg", *f, *i)
fmt.Println("len of tmp main is", len(tmpmain))
tmp, err := os.Create("tmp.go")
if err != nil {
panic(err)
}
inp, err := os.Open(*i)
if err != nil {
panic(err)
}
var structs []string
var isinhead = true
var isinfill = false
var isnexttemplate = false
s := bufio.NewScanner(bytes.NewReader([]byte(tmpmain)))
for s.Scan() {
line := s.Text()
if isinhead {
if strings.Contains(line, "Main_") {
line = "func main() {"
isnexttemplate = true
isinhead = false
scanner := bufio.NewScanner(inp)
start := false
for scanner.Scan() {
t := scanner.Text()
if t == "type (" {
start = true
}
if start {
tmp.WriteString(t + "\n")
if t == ")" {
break
}
if strings.Contains(t, " struct {") {
structs = append(structs, strings.Trim(t[:len(t)-9], "\t"))
}
}
}
inp.Close()
}
tmp.WriteString(line + "\n")
} else if isinfill {
for _, s := range structs {
fmt.Fprintf(tmp, "\tWriteJceStruct(w, &%s{})\n", s)
}
isinfill = false
tmp.WriteString("// structs_parser: fill area\n")
tmp.WriteString(line + "\n")
} else {
if strings.Contains(line, "// structs_parser: fill area") {
isinfill = true
tmp.WriteString("// structs_parser: fill area\n")
} else {
if isnexttemplate {
fmt.Fprintf(tmp, line+"\n", *f)
isnexttemplate = false
} else {
tmp.WriteString(line + "\n")
}
}
}
}
tmp.Close()
c := exec.Command("go", "run", "tmp.go")
err = c.Run()
if err != nil {
panic(err)
}
os.Remove("tmp.go")
}

View File

@ -0,0 +1,149 @@
package main
import (
"fmt"
"io"
"os"
"reflect"
"strconv"
"strings"
"sync"
)
type IJceStruct interface{}
const head = "// Code generated by structs_parser; DO NOT EDIT.\npackage jce\n"
func Main_() {
w, err := os.Create("%s")
if err != nil {
panic(err)
}
w.WriteString(head)
// structs_parser: fill area
err = w.Close()
if err != nil {
panic(err)
}
}
func writeObject(w io.Writer, v reflect.Value, tag byte, name string) {
k := v.Kind()
if k == reflect.Map {
switch v.Interface().(type) {
case map[string]string:
w.Write([]byte(fmt.Sprintf("\tw.writeMapStrStr(pkt.%s, %d)\n", name, tag)))
case map[string][]byte:
w.Write([]byte(fmt.Sprintf("\tw.writeMapStrBytes(pkt.%s, %d)\n", name, tag)))
case map[string]map[string][]byte:
w.Write([]byte(fmt.Sprintf("\tw.writeMapStrMapStrBytes(pkt.%s, %d)\n", name, tag)))
default:
w.Write([]byte(fmt.Sprintf("\tw.writeMap(pkt.%s, %d)\n", name, tag)))
}
return
}
if k == reflect.Slice {
switch v.Interface().(type) {
case []byte:
w.Write([]byte(fmt.Sprintf("\tw.WriteBytes(pkt.%s, %d)\n", name, tag)))
case []int64:
w.Write([]byte(fmt.Sprintf("\tw.WriteInt64Slice(pkt.%s, %d)\n", name, tag)))
case [][]byte:
w.Write([]byte(fmt.Sprintf("\tw.WriteBytesSlice(pkt.%s, %d)\n", name, tag)))
default:
writeJceStructSlice(w, tag, name)
}
return
}
switch k {
case reflect.Uint8, reflect.Int8:
w.Write([]byte(fmt.Sprintf("\tw.WriteByte(pkt.%s, %d)\n", name, tag)))
case reflect.Uint16, reflect.Int16:
w.Write([]byte(fmt.Sprintf("\tw.WriteInt16(pkt.%s, %d)\n", name, tag)))
case reflect.Uint32, reflect.Int32:
w.Write([]byte(fmt.Sprintf("\tw.WriteInt32(pkt.%s, %d)\n", name, tag)))
case reflect.Uint64, reflect.Int64:
w.Write([]byte(fmt.Sprintf("\tw.WriteInt64(pkt.%s, %d)\n", name, tag)))
case reflect.Int, reflect.Uint:
w.Write([]byte(fmt.Sprintf("\tw.WriteInt64(int64(pkt.%s), %d)\n", name, tag)))
case reflect.String:
w.Write([]byte(fmt.Sprintf("\tw.WriteString(pkt.%s, %d)\n", name, tag)))
default:
switch v.Interface().(type) {
case float32:
w.Write([]byte(fmt.Sprintf("\tw.WriteFloat32(pkt.%s, %d)\n", name, tag)))
case float64:
w.Write([]byte(fmt.Sprintf("\tw.WriteFloat64(pkt.%s, %d)\n", name, tag)))
case IJceStruct:
w.Write([]byte(fmt.Sprintf("\tw.writeHead(10, %d)\n", tag)))
w.Write([]byte(fmt.Sprintf("\tw.buf.Write(pkt.%s.ToBytes())\n", name)))
w.Write([]byte("\tw.writeHead(11, 0)\n"))
}
}
}
type decoder struct {
index int
id int
name string
}
var decoderCache = sync.Map{}
// writeJceStructRaw 写入 Jce 结构体
func writeJceStructRaw(w io.Writer, s interface{}) {
t := reflect.TypeOf(s)
if t.Kind() != reflect.Ptr {
return
}
t = t.Elem()
v := reflect.ValueOf(s).Elem()
var jceDec []decoder
dec, ok := decoderCache.Load(t)
if ok { // 从缓存中加载
jceDec = dec.([]decoder)
} else { // 初次反射
jceDec = make([]decoder, 0, t.NumField())
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
strId := field.Tag.Get("jceId")
if strId == "" {
continue
}
id, err := strconv.Atoi(strId)
if err != nil {
continue
}
jceDec = append(jceDec, decoder{
index: i,
id: id,
name: field.Name,
})
}
decoderCache.Store(t, jceDec) // 存入缓存
}
for _, dec := range jceDec {
obj := v.Field(dec.index)
writeObject(w, obj, byte(dec.id), dec.name)
}
}
func writeJceStructSlice(w io.Writer, tag byte, name string) {
w.Write([]byte(fmt.Sprintf("\tw.writeHead(9, %d)\n", tag)))
w.Write([]byte(fmt.Sprintf("\tif len(pkt.%s) == 0 {\n", name)))
w.Write([]byte("\t\tw.writeHead(12, 0) // w.WriteInt32(0, 0)\n"))
w.Write([]byte("\t} else {\n"))
w.Write([]byte(fmt.Sprintf("\t\tw.WriteInt32(int32(len(pkt.%s)), 0)\n", name)))
w.Write([]byte(fmt.Sprintf("\t\tfor _, i := range pkt.%s {\n", name)))
w.Write([]byte("\t\t\tw.buf.Write(i.ToBytes())\n"))
w.Write([]byte("\t\t}\n"))
w.Write([]byte("\t}\n"))
}
func WriteJceStruct(w io.Writer, s IJceStruct) {
w.Write([]byte(fmt.Sprintf("\nfunc (pkt %s) ToBytes() []byte {\n", strings.ReplaceAll(reflect.TypeOf(s).String(), "main.", ""))))
w.Write([]byte("\tw := NewJceWriter()\n"))
writeJceStructRaw(w, s)
w.Write([]byte("\treturn w.Bytes()\n"))
w.Write([]byte("}\n"))
}

View File

@ -2,7 +2,11 @@ package jce
import (
"math/rand"
"reflect"
"strconv"
"sync"
"testing"
"unsafe"
"github.com/stretchr/testify/assert"
)
@ -15,7 +19,7 @@ func TestJceReader_ReadSlice(t *testing.T) {
s[i] = b
}
w := NewJceWriter()
w.WriteObject(s, 1)
w.WriteBytesSlice(s, 1)
r := NewJceReader(w.Bytes())
result := r.ReadByteArrArr(1)
assert.Equal(t, s, result)
@ -64,7 +68,7 @@ var req = RequestDataVersion2{
func TestRequestDataVersion2_ReadFrom(t *testing.T) {
// todo(wdv): fuzz test
w := NewJceWriter()
w.WriteObject(req.Map, 0)
w.writeMapStrMapStrBytes(req.Map, 0)
src := w.Bytes()
result := RequestDataVersion2{}
result.ReadFrom(NewJceReader(src))
@ -73,7 +77,7 @@ func TestRequestDataVersion2_ReadFrom(t *testing.T) {
func BenchmarkRequestDataVersion2_ReadFrom(b *testing.B) {
w := NewJceWriter()
w.WriteObject(req.Map, 0)
w.writeMapStrMapStrBytes(req.Map, 0)
src := w.Bytes()
b.SetBytes(int64(len(src)))
result := &RequestDataVersion2{}
@ -93,3 +97,210 @@ func TestJceReader_ReadBytes(t *testing.T) {
assert.Equal(t, b, rb)
}
func (w *JceWriter) WriteObject(i interface{}, tag byte) {
t := reflect.TypeOf(i)
if t.Kind() == reflect.Map {
w.WriteMap(i, tag)
return
}
if t.Kind() == reflect.Slice {
if b, ok := i.([]byte); ok {
w.WriteBytes(b, tag)
return
}
w.WriteSlice(i, tag)
return
}
switch o := i.(type) {
case byte:
w.WriteByte(o, tag)
case bool:
w.WriteBool(o, tag)
case int16:
w.WriteInt16(o, tag)
case int32:
w.WriteInt32(o, tag)
case int64:
w.WriteInt64(o, tag)
case float32:
w.WriteFloat32(o, tag)
case float64:
w.WriteFloat64(o, tag)
case string:
w.WriteString(o, tag)
case IJceStruct:
w.WriteJceStruct(o, tag)
}
}
func (w *JceWriter) writeObject(v reflect.Value, tag byte) {
k := v.Kind()
if k == reflect.Map {
switch o := v.Interface().(type) {
case map[string]string:
w.writeMapStrStr(o, tag)
case map[string][]byte:
w.writeMapStrBytes(o, tag)
case map[string]map[string][]byte:
w.writeMapStrMapStrBytes(o, tag)
default:
w.writeMap(v, tag)
}
return
}
if k == reflect.Slice {
switch o := v.Interface().(type) {
case []byte:
w.WriteBytes(o, tag)
case []IJceStruct:
w.WriteJceStructSlice(o, tag)
default:
w.writeSlice(v, tag)
}
return
}
switch k {
case reflect.Uint8, reflect.Int8:
w.WriteByte(*(*byte)(pointerOf(v)), tag)
case reflect.Uint16, reflect.Int16:
w.WriteInt16(*(*int16)(pointerOf(v)), tag)
case reflect.Uint32, reflect.Int32:
w.WriteInt32(*(*int32)(pointerOf(v)), tag)
case reflect.Uint64, reflect.Int64:
w.WriteInt64(*(*int64)(pointerOf(v)), tag)
case reflect.String:
w.WriteString(v.String(), tag)
default:
switch o := v.Interface().(type) {
case IJceStruct:
w.WriteJceStruct(o, tag)
case float32:
w.WriteFloat32(o, tag)
case float64:
w.WriteFloat64(o, tag)
}
}
}
type decoder struct {
index int
id int
}
var decoderCache = sync.Map{}
// WriteJceStructRaw 写入 Jce 结构体
func (w *JceWriter) WriteJceStructRaw(s interface{}) {
t := reflect.TypeOf(s)
if t.Kind() != reflect.Ptr {
return
}
t = t.Elem()
v := reflect.ValueOf(s).Elem()
var jceDec []decoder
dec, ok := decoderCache.Load(t)
if ok { // 从缓存中加载
jceDec = dec.([]decoder)
} else { // 初次反射
jceDec = make([]decoder, 0, t.NumField())
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
strId := field.Tag.Get("jceId")
if strId == "" {
continue
}
id, err := strconv.Atoi(strId)
if err != nil {
continue
}
jceDec = append(jceDec, decoder{
index: i,
id: id,
})
}
decoderCache.Store(t, jceDec) // 存入缓存
}
for _, dec := range jceDec {
obj := v.Field(dec.index)
w.writeObject(obj, byte(dec.id))
}
}
func (w *JceWriter) WriteJceStruct(s IJceStruct, tag byte) {
w.writeHead(10, tag)
w.WriteJceStructRaw(s)
w.writeHead(11, 0)
}
func (w *JceWriter) WriteSlice(i interface{}, tag byte) {
va := reflect.ValueOf(i)
if va.Kind() != reflect.Slice {
panic("JceWriter.WriteSlice: not a slice")
}
w.writeSlice(va, tag)
}
func (w *JceWriter) writeSlice(slice reflect.Value, tag byte) {
if slice.Kind() != reflect.Slice {
return
}
w.writeHead(9, tag)
if slice.Len() == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(slice.Len()), 0)
for i := 0; i < slice.Len(); i++ {
v := slice.Index(i)
w.writeObject(v, 0)
}
}
func (w *JceWriter) WriteJceStructSlice(l []IJceStruct, tag byte) {
w.writeHead(9, tag)
if len(l) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(len(l)), 0)
for _, v := range l {
w.WriteJceStruct(v, 0)
}
}
func (w *JceWriter) WriteMap(m interface{}, tag byte) {
va := reflect.ValueOf(m)
if va.Kind() != reflect.Map {
panic("JceWriter.WriteMap: not a map")
}
w.writeMap(va, tag)
}
func (w *JceWriter) writeMap(m reflect.Value, tag byte) {
if m.IsNil() {
w.writeHead(8, tag)
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
if m.Kind() != reflect.Map {
return
}
w.writeHead(8, tag)
w.WriteInt32(int32(m.Len()), 0)
iter := m.MapRange()
for iter.Next() {
w.writeObject(iter.Key(), 0)
w.writeObject(iter.Value(), 1)
}
}
type value struct {
typ unsafe.Pointer
data unsafe.Pointer
flag uintptr
}
func pointerOf(v reflect.Value) unsafe.Pointer {
return (*value)(unsafe.Pointer(&v)).data
}

View File

@ -1,16 +0,0 @@
package jce
import (
"reflect"
"unsafe"
)
type value struct {
typ unsafe.Pointer
data unsafe.Pointer
flag uintptr
}
func pointerOf(v reflect.Value) unsafe.Pointer {
return (*value)(unsafe.Pointer(&v)).data
}

View File

@ -1,10 +1,11 @@
package jce
type IJceStruct interface {
// ToBytes() []byte
ToBytes() []byte
ReadFrom(*JceReader)
}
//go:generate go run gen/structs_parser.go -f structs_tobytes.go -i structs.go
type (
RequestPacket struct {
IVersion int16 `jceId:"1"`
@ -539,12 +540,6 @@ type (
}
)
func (pkt *RequestPacket) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *RequestPacket) ReadFrom(r *JceReader) {
pkt.IVersion = r.ReadInt16(1)
pkt.CPacketType = r.ReadByte(2)
@ -560,22 +555,10 @@ func (pkt *RequestPacket) ReadFrom(r *JceReader) {
pkt.Status = r.ReadMapStrStr(10)
}
func (pkt *RequestDataVersion3) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) {
pkt.Map = r.ReadMapStrByte(0)
}
func (pkt *RequestDataVersion2) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) {
pkt.Map = r.ReadMapStrMapStrByte(0)
}
@ -625,12 +608,6 @@ func (pkt *BigDataIPInfo) ReadFrom(r *JceReader) {
pkt.Port = r.ReadInt64(2)
}
func (pkt *SvcReqRegister) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *SvcRespRegister) ReadFrom(r *JceReader) {
pkt.Uin = r.ReadInt64(0)
pkt.Bid = r.ReadInt64(1)
@ -652,24 +629,6 @@ func (pkt *SvcRespRegister) ReadFrom(r *JceReader) {
pkt.ExtOnlineStatus = r.ReadInt64(17)
}
func (pkt *FriendListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *SummaryCardReq) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *SummaryCardReqSearch) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *FriendInfo) ReadFrom(r *JceReader) {
pkt.FriendUin = r.ReadInt64(0)
pkt.GroupId = r.ReadByte(1)
@ -683,12 +642,6 @@ func (pkt *FriendInfo) ReadFrom(r *JceReader) {
pkt.CardID = r.ReadBytes(41)
}
func (pkt *TroopListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *TroopNumber) ReadFrom(r *JceReader) {
pkt.GroupUin = r.ReadInt64(0)
pkt.GroupCode = r.ReadInt64(1)
@ -699,12 +652,6 @@ func (pkt *TroopNumber) ReadFrom(r *JceReader) {
pkt.MaxGroupMemberNum = r.ReadInt64(29)
}
func (pkt *TroopMemberListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *TroopMemberInfo) ReadFrom(r *JceReader) {
pkt.MemberUin = r.ReadInt64(0)
pkt.FaceId = r.ReadInt16(1)
@ -800,33 +747,3 @@ func (pkt *InstanceInfo) ReadFrom(r *JceReader) {
pkt.ProductType = r.ReadInt64(3)
pkt.ClientType = r.ReadInt64(4)
}
func (pkt *SvcRespPushMsg) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *ModifyGroupCardRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *SvcReqGetDevLoginInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *SvcReqRegisterNew) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *DelFriendReq) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}

View File

@ -0,0 +1,688 @@
// Code generated by structs_parser; DO NOT EDIT.
package jce
func (pkt *RequestPacket) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt16(pkt.IVersion, 1)
w.WriteByte(pkt.CPacketType, 2)
w.WriteInt32(pkt.IMessageType, 3)
w.WriteInt32(pkt.IRequestId, 4)
w.WriteString(pkt.SServantName, 5)
w.WriteString(pkt.SFuncName, 6)
w.WriteBytes(pkt.SBuffer, 7)
w.WriteInt32(pkt.ITimeout, 8)
w.writeMapStrStr(pkt.Context, 9)
w.writeMapStrStr(pkt.Status, 10)
return w.Bytes()
}
func (pkt *RequestDataVersion3) ToBytes() []byte {
w := NewJceWriter()
w.writeMapStrBytes(pkt.Map, 0)
return w.Bytes()
}
func (pkt *RequestDataVersion2) ToBytes() []byte {
w := NewJceWriter()
w.writeMapStrMapStrBytes(pkt.Map, 0)
return w.Bytes()
}
func (pkt *SsoServerInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteString(pkt.Server, 1)
w.WriteInt32(pkt.Port, 2)
w.WriteString(pkt.Location, 8)
return w.Bytes()
}
func (pkt *FileStoragePushFSSvcList) ToBytes() []byte {
w := NewJceWriter()
w.writeHead(9, 0)
if len(pkt.UploadList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.UploadList)), 0)
for _, i := range pkt.UploadList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(9, 1)
if len(pkt.PicDownloadList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.PicDownloadList)), 0)
for _, i := range pkt.PicDownloadList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(9, 2)
if len(pkt.GPicDownloadList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.GPicDownloadList)), 0)
for _, i := range pkt.GPicDownloadList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(9, 3)
if len(pkt.QZoneProxyServiceList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.QZoneProxyServiceList)), 0)
for _, i := range pkt.QZoneProxyServiceList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(9, 4)
if len(pkt.UrlEncodeServiceList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.UrlEncodeServiceList)), 0)
for _, i := range pkt.UrlEncodeServiceList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(10, 5)
w.buf.Write(pkt.BigDataChannel.ToBytes())
w.writeHead(11, 0)
w.writeHead(9, 6)
if len(pkt.VipEmotionList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.VipEmotionList)), 0)
for _, i := range pkt.VipEmotionList {
w.buf.Write(i.ToBytes())
}
}
w.writeHead(9, 7)
if len(pkt.C2CPicDownList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.C2CPicDownList)), 0)
for _, i := range pkt.C2CPicDownList {
w.buf.Write(i.ToBytes())
}
}
w.WriteBytes(pkt.PttList, 10)
return w.Bytes()
}
func (pkt *FileStorageServerInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteString(pkt.Server, 1)
w.WriteInt32(pkt.Port, 2)
return w.Bytes()
}
func (pkt *BigDataChannel) ToBytes() []byte {
w := NewJceWriter()
w.writeHead(9, 0)
if len(pkt.IPLists) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.IPLists)), 0)
for _, i := range pkt.IPLists {
w.buf.Write(i.ToBytes())
}
}
w.WriteBytes(pkt.SigSession, 1)
w.WriteBytes(pkt.KeySession, 2)
w.WriteInt64(pkt.SigUin, 3)
w.WriteInt32(pkt.ConnectFlag, 4)
w.WriteBytes(pkt.PbBuf, 5)
return w.Bytes()
}
func (pkt *BigDataIPList) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.ServiceType, 0)
w.writeHead(9, 1)
if len(pkt.IPList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.IPList)), 0)
for _, i := range pkt.IPList {
w.buf.Write(i.ToBytes())
}
}
w.WriteInt64(pkt.FragmentSize, 3)
return w.Bytes()
}
func (pkt *BigDataIPInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Type, 0)
w.WriteString(pkt.Server, 1)
w.WriteInt64(pkt.Port, 2)
return w.Bytes()
}
func (pkt *SvcReqRegister) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt64(pkt.Bid, 1)
w.WriteByte(pkt.ConnType, 2)
w.WriteString(pkt.Other, 3)
w.WriteInt32(pkt.Status, 4)
w.WriteByte(pkt.OnlinePush, 5)
w.WriteByte(pkt.IsOnline, 6)
w.WriteByte(pkt.IsShowOnline, 7)
w.WriteByte(pkt.KickPC, 8)
w.WriteByte(pkt.KickWeak, 9)
w.WriteInt64(pkt.Timestamp, 10)
w.WriteInt64(pkt.IOSVersion, 11)
w.WriteByte(pkt.NetType, 12)
w.WriteString(pkt.BuildVer, 13)
w.WriteByte(pkt.RegType, 14)
w.WriteBytes(pkt.DevParam, 15)
w.WriteBytes(pkt.Guid, 16)
w.WriteInt32(pkt.LocaleId, 17)
w.WriteByte(pkt.SilentPush, 18)
w.WriteString(pkt.DevName, 19)
w.WriteString(pkt.DevType, 20)
w.WriteString(pkt.OSVer, 21)
w.WriteByte(pkt.OpenPush, 22)
w.WriteInt64(pkt.LargeSeq, 23)
w.WriteInt64(pkt.LastWatchStartTime, 24)
w.WriteInt64(pkt.OldSSOIp, 26)
w.WriteInt64(pkt.NewSSOIp, 27)
w.WriteString(pkt.ChannelNo, 28)
w.WriteInt64(pkt.CPID, 29)
w.WriteString(pkt.VendorName, 30)
w.WriteString(pkt.VendorOSName, 31)
w.WriteString(pkt.IOSIdfa, 32)
w.WriteBytes(pkt.B769, 33)
w.WriteByte(pkt.IsSetStatus, 34)
w.WriteBytes(pkt.ServerBuf, 35)
w.WriteByte(pkt.SetMute, 36)
w.WriteInt64(pkt.ExtOnlineStatus, 38)
w.WriteInt32(pkt.BatteryStatus, 39)
return w.Bytes()
}
func (pkt *SvcRespRegister) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt64(pkt.Bid, 1)
w.WriteByte(pkt.ReplyCode, 2)
w.WriteString(pkt.Result, 3)
w.WriteInt64(pkt.ServerTime, 4)
w.WriteByte(pkt.LogQQ, 5)
w.WriteByte(pkt.NeedKik, 6)
w.WriteByte(pkt.UpdateFlag, 7)
w.WriteInt64(pkt.Timestamp, 8)
w.WriteByte(pkt.CrashFlag, 9)
w.WriteString(pkt.ClientIp, 10)
w.WriteInt32(pkt.ClientPort, 11)
w.WriteInt32(pkt.HelloInterval, 12)
w.WriteInt32(pkt.LargeSeq, 13)
w.WriteByte(pkt.LargeSeqUpdate, 14)
w.WriteBytes(pkt.D769RspBody, 15)
w.WriteInt32(pkt.Status, 16)
w.WriteInt64(pkt.ExtOnlineStatus, 17)
w.WriteInt64(pkt.ClientBatteryGetInterval, 18)
w.WriteInt64(pkt.ClientAutoStatusInterval, 19)
return w.Bytes()
}
func (pkt *SvcReqRegisterNew) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.RequestOptional, 0)
w.WriteByte(pkt.DisGroupMsgFilter, 14)
w.WriteByte(pkt.GroupMask, 15)
w.WriteInt64(pkt.EndSeq, 16)
w.WriteBytes(pkt.O769Body, 20)
return w.Bytes()
}
func (pkt *SvcReqGetMsgV2) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt32(pkt.DateTime, 1)
w.WriteByte(pkt.RecivePic, 4)
w.WriteInt16(pkt.Ability, 6)
w.WriteByte(pkt.Channel, 9)
w.WriteByte(pkt.Inst, 16)
w.WriteByte(pkt.ChannelEx, 17)
w.WriteBytes(pkt.SyncCookie, 18)
w.WriteInt64(int64(pkt.SyncFlag), 19)
w.WriteByte(pkt.RambleFlag, 20)
w.WriteInt64(pkt.GeneralAbi, 26)
w.WriteBytes(pkt.PubAccountCookie, 27)
return w.Bytes()
}
func (pkt *SvcReqPullGroupMsgSeq) ToBytes() []byte {
w := NewJceWriter()
w.writeHead(9, 0)
if len(pkt.GroupInfo) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.GroupInfo)), 0)
for _, i := range pkt.GroupInfo {
w.buf.Write(i.ToBytes())
}
}
w.WriteByte(pkt.VerifyType, 1)
w.WriteInt32(pkt.Filter, 2)
return w.Bytes()
}
func (pkt *PullGroupSeqParam) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.GroupCode, 0)
w.WriteInt64(pkt.LastSeqId, 1)
return w.Bytes()
}
func (pkt *SvcRespParam) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt32(pkt.PCStat, 0)
w.WriteInt32(pkt.IsSupportC2CRoamMsg, 1)
w.WriteInt32(pkt.IsSupportDataLine, 2)
w.WriteInt32(pkt.IsSupportPrintable, 3)
w.WriteInt32(pkt.IsSupportViewPCFile, 4)
w.WriteInt32(pkt.PcVersion, 5)
w.WriteInt64(pkt.RoamFlag, 6)
w.writeHead(9, 7)
if len(pkt.OnlineInfos) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.OnlineInfos)), 0)
for _, i := range pkt.OnlineInfos {
w.buf.Write(i.ToBytes())
}
}
w.WriteInt32(pkt.PCClientType, 8)
return w.Bytes()
}
func (pkt *RequestPushNotify) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteByte(pkt.Type, 1)
w.WriteString(pkt.Service, 2)
w.WriteString(pkt.Cmd, 3)
w.WriteBytes(pkt.NotifyCookie, 4)
w.WriteInt32(pkt.MsgType, 5)
w.WriteInt32(pkt.UserActive, 6)
w.WriteInt32(pkt.GeneralFlag, 7)
w.WriteInt64(pkt.BindedUin, 8)
return w.Bytes()
}
func (pkt *OnlineInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt32(pkt.InstanceId, 0)
w.WriteInt32(pkt.ClientType, 1)
w.WriteInt32(pkt.OnlineStatus, 2)
w.WriteInt32(pkt.PlatformId, 3)
w.WriteString(pkt.SubPlatform, 4)
w.WriteInt64(pkt.UClientType, 5)
return w.Bytes()
}
func (pkt *SvcReqMSFLoginNotify) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.AppId, 0)
w.WriteByte(pkt.Status, 1)
w.WriteByte(pkt.Tablet, 2)
w.WriteInt64(pkt.Platform, 3)
w.WriteString(pkt.Title, 4)
w.WriteString(pkt.Info, 5)
w.WriteInt64(pkt.ProductType, 6)
w.WriteInt64(pkt.ClientType, 7)
w.writeHead(9, 8)
if len(pkt.InstanceList) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.InstanceList)), 0)
for _, i := range pkt.InstanceList {
w.buf.Write(i.ToBytes())
}
}
return w.Bytes()
}
func (pkt *InstanceInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt32(pkt.AppId, 0)
w.WriteByte(pkt.Tablet, 1)
w.WriteInt64(pkt.Platform, 2)
w.WriteInt64(pkt.ProductType, 3)
w.WriteInt64(pkt.ClientType, 4)
return w.Bytes()
}
func (pkt *PushMessageInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.FromUin, 0)
w.WriteInt64(pkt.MsgTime, 1)
w.WriteInt16(pkt.MsgType, 2)
w.WriteInt16(pkt.MsgSeq, 3)
w.WriteString(pkt.Msg, 4)
w.WriteInt32(pkt.RealMsgTime, 5)
w.WriteBytes(pkt.VMsg, 6)
w.WriteInt64(pkt.AppShareID, 7)
w.WriteBytes(pkt.MsgCookies, 8)
w.WriteBytes(pkt.AppShareCookie, 9)
w.WriteInt64(pkt.MsgUid, 10)
w.WriteInt64(pkt.LastChangeTime, 11)
w.WriteInt64(pkt.FromInstId, 14)
w.WriteBytes(pkt.RemarkOfSender, 15)
w.WriteString(pkt.FromMobile, 16)
w.WriteString(pkt.FromName, 17)
return w.Bytes()
}
func (pkt *SvcRespPushMsg) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.writeHead(9, 1)
if len(pkt.DelInfos) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.DelInfos)), 0)
for _, i := range pkt.DelInfos {
w.buf.Write(i.ToBytes())
}
}
w.WriteInt32(pkt.Svrip, 2)
w.WriteBytes(pkt.PushToken, 3)
w.WriteInt32(pkt.ServiceType, 4)
return w.Bytes()
}
func (pkt *SvcReqGetDevLoginInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteBytes(pkt.Guid, 0)
w.WriteString(pkt.AppName, 1)
w.WriteInt64(pkt.LoginType, 2)
w.WriteInt64(pkt.Timestamp, 3)
w.WriteInt64(pkt.NextItemIndex, 4)
w.WriteInt64(pkt.RequireMax, 5)
w.WriteInt64(pkt.GetDevListType, 6)
return w.Bytes()
}
func (pkt *SvcDevLoginInfo) ToBytes() []byte {
w := NewJceWriter()
return w.Bytes()
}
func (pkt *DelMsgInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.FromUin, 0)
w.WriteInt64(pkt.MsgTime, 1)
w.WriteInt16(pkt.MsgSeq, 2)
w.WriteBytes(pkt.MsgCookies, 3)
w.WriteInt16(pkt.Cmd, 4)
w.WriteInt64(pkt.MsgType, 5)
w.WriteInt64(pkt.AppId, 6)
w.WriteInt64(pkt.SendTime, 7)
w.WriteInt32(pkt.SsoSeq, 8)
w.WriteInt32(pkt.SsoIp, 9)
w.WriteInt32(pkt.ClientIp, 10)
return w.Bytes()
}
func (pkt *FriendListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt32(pkt.Reqtype, 0)
w.WriteByte(pkt.IfReflush, 1)
w.WriteInt64(pkt.Uin, 2)
w.WriteInt16(pkt.StartIndex, 3)
w.WriteInt16(pkt.FriendCount, 4)
w.WriteByte(pkt.GroupId, 5)
w.WriteByte(pkt.IfGetGroupInfo, 6)
w.WriteByte(pkt.GroupStartIndex, 7)
w.WriteByte(pkt.GroupCount, 8)
w.WriteByte(pkt.IfGetMSFGroup, 9)
w.WriteByte(pkt.IfShowTermType, 10)
w.WriteInt64(pkt.Version, 11)
w.WriteInt64Slice(pkt.UinList, 12)
w.WriteInt32(pkt.AppType, 13)
w.WriteByte(pkt.IfGetDOVId, 14)
w.WriteByte(pkt.IfGetBothFlag, 15)
w.WriteBytes(pkt.D50, 16)
w.WriteBytes(pkt.D6B, 17)
w.WriteInt64Slice(pkt.SnsTypeList, 18)
return w.Bytes()
}
func (pkt *FriendInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.FriendUin, 0)
w.WriteByte(pkt.GroupId, 1)
w.WriteInt16(pkt.FaceId, 2)
w.WriteString(pkt.Remark, 3)
w.WriteByte(pkt.QQType, 4)
w.WriteByte(pkt.Status, 5)
w.WriteByte(pkt.MemberLevel, 6)
w.WriteByte(pkt.IsMqqOnLine, 7)
w.WriteByte(pkt.QQOnlineState, 8)
w.WriteByte(pkt.IsIphoneOnline, 9)
w.WriteByte(pkt.DetailStatusFlag, 10)
w.WriteByte(pkt.QQOnlineStateV2, 11)
w.WriteString(pkt.ShowName, 12)
w.WriteByte(pkt.IsRemark, 13)
w.WriteString(pkt.Nick, 14)
w.WriteByte(pkt.SpecialFlag, 15)
w.WriteBytes(pkt.IMGroupID, 16)
w.WriteBytes(pkt.MSFGroupID, 17)
w.WriteInt32(pkt.TermType, 18)
w.WriteByte(pkt.Network, 20)
w.WriteBytes(pkt.Ring, 21)
w.WriteInt64(pkt.AbiFlag, 22)
w.WriteInt64(pkt.FaceAddonId, 23)
w.WriteInt32(pkt.NetworkType, 24)
w.WriteInt64(pkt.VipFont, 25)
w.WriteInt32(pkt.IconType, 26)
w.WriteString(pkt.TermDesc, 27)
w.WriteInt64(pkt.ColorRing, 28)
w.WriteByte(pkt.ApolloFlag, 29)
w.WriteInt64(pkt.ApolloTimestamp, 30)
w.WriteByte(pkt.Sex, 31)
w.WriteInt64(pkt.FounderFont, 32)
w.WriteString(pkt.EimId, 33)
w.WriteString(pkt.EimMobile, 34)
w.WriteByte(pkt.OlympicTorch, 35)
w.WriteInt64(pkt.ApolloSignTime, 36)
w.WriteInt64(pkt.LaviUin, 37)
w.WriteInt64(pkt.TagUpdateTime, 38)
w.WriteInt64(pkt.GameLastLoginTime, 39)
w.WriteInt64(pkt.GameAppId, 40)
w.WriteBytes(pkt.CardID, 41)
w.WriteInt64(pkt.BitSet, 42)
w.WriteByte(pkt.KingOfGloryFlag, 43)
w.WriteInt64(pkt.KingOfGloryRank, 44)
w.WriteString(pkt.MasterUin, 45)
w.WriteInt64(pkt.LastMedalUpdateTime, 46)
w.WriteInt64(pkt.FaceStoreId, 47)
w.WriteInt64(pkt.FontEffect, 48)
w.WriteString(pkt.DOVId, 49)
w.WriteInt64(pkt.BothFlag, 50)
w.WriteByte(pkt.CentiShow3DFlag, 51)
w.WriteBytes(pkt.IntimateInfo, 52)
w.WriteByte(pkt.ShowNameplate, 53)
w.WriteByte(pkt.NewLoverDiamondFlag, 54)
w.WriteBytes(pkt.ExtSnsFrdData, 55)
w.WriteBytes(pkt.MutualMarkData, 56)
return w.Bytes()
}
func (pkt *TroopListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteByte(pkt.GetMSFMsgFlag, 1)
w.WriteBytes(pkt.Cookies, 2)
w.WriteInt64Slice(pkt.GroupInfo, 3)
w.WriteByte(pkt.GroupFlagExt, 4)
w.WriteInt32(pkt.Version, 5)
w.WriteInt64(pkt.CompanyId, 6)
w.WriteInt64(pkt.VersionNum, 7)
w.WriteByte(pkt.GetLongGroupName, 8)
return w.Bytes()
}
func (pkt *TroopNumber) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.GroupUin, 0)
w.WriteInt64(pkt.GroupCode, 1)
w.WriteByte(pkt.Flag, 2)
w.WriteInt64(pkt.GroupInfoSeq, 3)
w.WriteString(pkt.GroupName, 4)
w.WriteString(pkt.GroupMemo, 5)
w.WriteInt64(pkt.GroupFlagExt, 6)
w.WriteInt64(pkt.GroupRankSeq, 7)
w.WriteInt64(pkt.CertificationType, 8)
w.WriteInt64(pkt.ShutUpTimestamp, 9)
w.WriteInt64(pkt.MyShutUpTimestamp, 10)
w.WriteInt64(pkt.CmdUinUinFlag, 11)
w.WriteInt64(pkt.AdditionalFlag, 12)
w.WriteInt64(pkt.GroupTypeFlag, 13)
w.WriteInt64(pkt.GroupSecType, 14)
w.WriteInt64(pkt.GroupSecTypeInfo, 15)
w.WriteInt64(pkt.GroupClassExt, 16)
w.WriteInt64(pkt.AppPrivilegeFlag, 17)
w.WriteInt64(pkt.SubscriptionUin, 18)
w.WriteInt64(pkt.MemberNum, 19)
w.WriteInt64(pkt.MemberNumSeq, 20)
w.WriteInt64(pkt.MemberCardSeq, 21)
w.WriteInt64(pkt.GroupFlagExt3, 22)
w.WriteInt64(pkt.GroupOwnerUin, 23)
w.WriteByte(pkt.IsConfGroup, 24)
w.WriteByte(pkt.IsModifyConfGroupFace, 25)
w.WriteByte(pkt.IsModifyConfGroupName, 26)
w.WriteInt64(pkt.CmdUinJoinTime, 27)
w.WriteInt64(pkt.CompanyId, 28)
w.WriteInt64(pkt.MaxGroupMemberNum, 29)
w.WriteInt64(pkt.CmdUinGroupMask, 30)
w.WriteInt64(pkt.GuildAppId, 31)
w.WriteInt64(pkt.GuildSubType, 32)
w.WriteInt64(pkt.CmdUinRingtoneID, 33)
w.WriteInt64(pkt.CmdUinFlagEx2, 34)
return w.Bytes()
}
func (pkt *TroopMemberListRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt64(pkt.GroupCode, 1)
w.WriteInt64(pkt.NextUin, 2)
w.WriteInt64(pkt.GroupUin, 3)
w.WriteInt64(pkt.Version, 4)
w.WriteInt64(pkt.ReqType, 5)
w.WriteInt64(pkt.GetListAppointTime, 6)
w.WriteByte(pkt.RichCardNameVer, 7)
return w.Bytes()
}
func (pkt *TroopMemberInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.MemberUin, 0)
w.WriteInt16(pkt.FaceId, 1)
w.WriteByte(pkt.Age, 2)
w.WriteByte(pkt.Gender, 3)
w.WriteString(pkt.Nick, 4)
w.WriteByte(pkt.Status, 5)
w.WriteString(pkt.ShowName, 6)
w.WriteString(pkt.Name, 8)
w.WriteString(pkt.Memo, 12)
w.WriteString(pkt.AutoRemark, 13)
w.WriteInt64(pkt.MemberLevel, 14)
w.WriteInt64(pkt.JoinTime, 15)
w.WriteInt64(pkt.LastSpeakTime, 16)
w.WriteInt64(pkt.CreditLevel, 17)
w.WriteInt64(pkt.Flag, 18)
w.WriteInt64(pkt.FlagExt, 19)
w.WriteInt64(pkt.Point, 20)
w.WriteByte(pkt.Concerned, 21)
w.WriteByte(pkt.Shielded, 22)
w.WriteString(pkt.SpecialTitle, 23)
w.WriteInt64(pkt.SpecialTitleExpireTime, 24)
w.WriteString(pkt.Job, 25)
w.WriteByte(pkt.ApolloFlag, 26)
w.WriteInt64(pkt.ApolloTimestamp, 27)
w.WriteInt64(pkt.GlobalGroupLevel, 28)
w.WriteInt64(pkt.TitleId, 29)
w.WriteInt64(pkt.ShutUpTimestap, 30)
w.WriteInt64(pkt.GlobalGroupPoint, 31)
w.WriteByte(pkt.RichCardNameVer, 33)
w.WriteInt64(pkt.VipType, 34)
w.WriteInt64(pkt.VipLevel, 35)
w.WriteInt64(pkt.BigClubLevel, 36)
w.WriteInt64(pkt.BigClubFlag, 37)
w.WriteInt64(pkt.Nameplate, 38)
w.WriteBytes(pkt.GroupHonor, 39)
return w.Bytes()
}
func (pkt *ModifyGroupCardRequest) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Zero, 0)
w.WriteInt64(pkt.GroupCode, 1)
w.WriteInt64(pkt.NewSeq, 2)
w.writeHead(9, 3)
if len(pkt.UinInfo) == 0 {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
} else {
w.WriteInt32(int32(len(pkt.UinInfo)), 0)
for _, i := range pkt.UinInfo {
w.buf.Write(i.ToBytes())
}
}
return w.Bytes()
}
func (pkt *UinInfo) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt64(pkt.Flag, 1)
w.WriteString(pkt.Name, 2)
w.WriteByte(pkt.Gender, 3)
w.WriteString(pkt.Phone, 4)
w.WriteString(pkt.Email, 5)
w.WriteString(pkt.Remark, 6)
return w.Bytes()
}
func (pkt *SummaryCardReq) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt32(pkt.ComeFrom, 1)
w.WriteInt64(pkt.QzoneFeedTimestamp, 2)
w.WriteByte(pkt.IsFriend, 3)
w.WriteInt64(pkt.GroupCode, 4)
w.WriteInt64(pkt.GroupUin, 5)
w.WriteInt64(pkt.GetControl, 8)
w.WriteInt32(pkt.AddFriendSource, 9)
w.WriteBytes(pkt.SecureSig, 10)
w.WriteBytesSlice(pkt.ReqServices, 14)
w.WriteInt64(pkt.TinyId, 15)
w.WriteInt64(pkt.LikeSource, 16)
w.WriteByte(pkt.ReqMedalWallInfo, 18)
w.WriteInt64Slice(pkt.Req0x5ebFieldId, 19)
w.WriteByte(pkt.ReqNearbyGodInfo, 20)
w.WriteByte(pkt.ReqExtendCard, 22)
return w.Bytes()
}
func (pkt *SummaryCardReqSearch) ToBytes() []byte {
w := NewJceWriter()
w.WriteString(pkt.Keyword, 0)
w.WriteString(pkt.CountryCode, 1)
w.WriteInt32(pkt.Version, 2)
w.WriteBytesSlice(pkt.ReqServices, 3)
return w.Bytes()
}
func (pkt *DelFriendReq) ToBytes() []byte {
w := NewJceWriter()
w.WriteInt64(pkt.Uin, 0)
w.WriteInt64(pkt.DelUin, 1)
w.WriteByte(pkt.DelType, 2)
w.WriteInt32(pkt.Version, 3)
return w.Bytes()
}

View File

@ -3,9 +3,7 @@ package jce
import (
"bytes"
goBinary "encoding/binary"
"reflect"
"strconv"
"sync"
"math"
)
type JceWriter struct {
@ -16,18 +14,16 @@ func NewJceWriter() *JceWriter {
return &JceWriter{buf: new(bytes.Buffer)}
}
func (w *JceWriter) writeHead(t byte, tag int) {
if tag < 15 {
b := byte(tag<<4) | t
w.buf.WriteByte(b)
} else if tag < 256 {
b := 0xF0 | t
w.buf.WriteByte(b)
w.buf.WriteByte(byte(tag))
func (w *JceWriter) writeHead(t, tag byte) {
if tag < 0xF {
w.buf.WriteByte(tag<<4 | t)
} else {
w.buf.WriteByte(0xF0 | t)
w.buf.WriteByte(tag)
}
}
func (w *JceWriter) WriteByte(b byte, tag int) *JceWriter {
func (w *JceWriter) WriteByte(b, tag byte) *JceWriter {
if b == 0 {
w.writeHead(12, tag)
} else {
@ -37,7 +33,7 @@ func (w *JceWriter) WriteByte(b byte, tag int) *JceWriter {
return w
}
func (w *JceWriter) WriteBool(b bool, tag int) {
func (w *JceWriter) WriteBool(b bool, tag byte) {
var by byte = 0
if b {
by = 1
@ -45,7 +41,7 @@ func (w *JceWriter) WriteBool(b bool, tag int) {
w.WriteByte(by, tag)
}
func (w *JceWriter) WriteInt16(n int16, tag int) {
func (w *JceWriter) WriteInt16(n int16, tag byte) {
switch {
case n >= -128 && n <= 127:
w.WriteByte(byte(n), tag)
@ -55,14 +51,14 @@ func (w *JceWriter) WriteInt16(n int16, tag int) {
}
//go:nosplit
func (w *JceWriter) putInt16(n int16, tag int) {
func (w *JceWriter) putInt16(n int16, tag byte) {
w.writeHead(1, tag)
var buf [2]byte
goBinary.BigEndian.PutUint16(buf[:], uint16(n))
w.buf.Write(buf[:])
}
func (w *JceWriter) WriteInt32(n int32, tag int) *JceWriter {
func (w *JceWriter) WriteInt32(n int32, tag byte) *JceWriter {
switch {
case n >= -128 && n <= 127:
w.WriteByte(byte(n), tag)
@ -75,14 +71,14 @@ func (w *JceWriter) WriteInt32(n int32, tag int) *JceWriter {
}
//go:nosplit
func (w *JceWriter) putInt32(n int32, tag int) {
func (w *JceWriter) putInt32(n int32, tag byte) {
w.writeHead(2, tag)
var buf [4]byte
goBinary.BigEndian.PutUint32(buf[:], uint32(n))
w.buf.Write(buf[:])
}
func (w *JceWriter) WriteInt64(n int64, tag int) *JceWriter {
func (w *JceWriter) WriteInt64(n int64, tag byte) *JceWriter {
switch {
case n >= -128 && n <= 127:
w.WriteByte(byte(n), tag)
@ -97,49 +93,56 @@ func (w *JceWriter) WriteInt64(n int64, tag int) *JceWriter {
}
//go:nosplit
func (w *JceWriter) putInt64(n int64, tag int) {
func (w *JceWriter) putInt64(n int64, tag byte) {
w.writeHead(3, tag)
var buf [8]byte
goBinary.BigEndian.PutUint64(buf[:], uint64(n))
w.buf.Write(buf[:])
}
func (w *JceWriter) WriteFloat32(n float32, tag int) {
//go:nosplit
func (w *JceWriter) WriteFloat32(n float32, tag byte) {
w.writeHead(4, tag)
_ = goBinary.Write(w.buf, goBinary.BigEndian, n)
var buf [4]byte
goBinary.BigEndian.PutUint32(buf[:], math.Float32bits(n))
w.buf.Write(buf[:])
}
func (w *JceWriter) WriteFloat64(n float64, tag int) {
//go:nosplit
func (w *JceWriter) WriteFloat64(n float64, tag byte) {
w.writeHead(5, tag)
_ = goBinary.Write(w.buf, goBinary.BigEndian, n)
var buf [8]byte
goBinary.BigEndian.PutUint64(buf[:], math.Float64bits(n))
w.buf.Write(buf[:])
}
func (w *JceWriter) WriteString(s string, tag int) *JceWriter {
by := []byte(s)
if len(by) > 255 {
func (w *JceWriter) WriteString(s string, tag byte) *JceWriter {
if len(s) > 255 {
w.writeHead(7, tag)
_ = goBinary.Write(w.buf, goBinary.BigEndian, int32(len(by)))
w.buf.Write(by)
var buf [4]byte
goBinary.BigEndian.PutUint32(buf[:], uint32(len(s)))
w.buf.Write(buf[:])
w.buf.WriteString(s)
return w
}
w.writeHead(6, tag)
w.buf.WriteByte(byte(len(by)))
w.buf.Write(by)
w.buf.WriteByte(byte(len(s)))
w.buf.WriteString(s)
return w
}
func (w *JceWriter) WriteBytes(l []byte, tag int) *JceWriter {
func (w *JceWriter) WriteBytes(l []byte, tag byte) *JceWriter {
w.writeHead(13, tag)
w.writeHead(0, 0)
w.buf.WriteByte(0) // w.writeHead(0, 0)
w.WriteInt32(int32(len(l)), 0)
w.buf.Write(l)
return w
}
func (w *JceWriter) WriteInt64Slice(l []int64, tag int) {
func (w *JceWriter) WriteInt64Slice(l []int64, tag byte) {
w.writeHead(9, tag)
if len(l) == 0 {
w.WriteInt32(0, 0)
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(len(l)), 0)
@ -148,190 +151,58 @@ func (w *JceWriter) WriteInt64Slice(l []int64, tag int) {
}
}
func (w *JceWriter) WriteSlice(i interface{}, tag int) {
va := reflect.ValueOf(i)
if va.Kind() != reflect.Slice {
panic("JceWriter.WriteSlice: not a slice")
}
w.writeSlice(va, tag)
}
func (w *JceWriter) writeSlice(slice reflect.Value, tag int) {
if slice.Kind() != reflect.Slice {
return
}
w.writeHead(9, tag)
if slice.Len() == 0 {
w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(slice.Len()), 0)
for i := 0; i < slice.Len(); i++ {
v := slice.Index(i)
w.writeObject(v, 0)
}
}
func (w *JceWriter) WriteJceStructSlice(l []IJceStruct, tag int) {
func (w *JceWriter) WriteBytesSlice(l [][]byte, tag byte) {
w.writeHead(9, tag)
if len(l) == 0 {
w.WriteInt32(0, 0)
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(len(l)), 0)
for _, v := range l {
w.WriteJceStruct(v, 0)
w.WriteBytes(v, 0)
}
}
func (w *JceWriter) WriteMap(m interface{}, tag int) {
va := reflect.ValueOf(m)
if va.Kind() != reflect.Map {
panic("JceWriter.WriteMap: not a map")
}
w.writeMap(va, tag)
}
func (w *JceWriter) writeMap(m reflect.Value, tag int) {
if m.IsNil() {
func (w *JceWriter) writeMapStrStr(m map[string]string, tag byte) {
if m == nil {
w.writeHead(8, tag)
w.WriteInt32(0, 0)
return
}
if m.Kind() != reflect.Map {
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
w.writeHead(8, tag)
w.WriteInt32(int32(m.Len()), 0)
iter := m.MapRange()
for iter.Next() {
w.writeObject(iter.Key(), 0)
w.writeObject(iter.Value(), 1)
w.WriteInt32(int32(len(m)), 0)
for k, v := range m {
w.WriteString(k, 0)
w.WriteString(v, 1)
}
}
func (w *JceWriter) WriteObject(i interface{}, tag int) {
t := reflect.TypeOf(i)
if t.Kind() == reflect.Map {
w.WriteMap(i, tag)
func (w *JceWriter) writeMapStrBytes(m map[string][]byte, tag byte) {
if m == nil {
w.writeHead(8, tag)
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
if t.Kind() == reflect.Slice {
if b, ok := i.([]byte); ok {
w.WriteBytes(b, tag)
return
}
w.WriteSlice(i, tag)
return
}
switch o := i.(type) {
case byte:
w.WriteByte(o, tag)
case bool:
w.WriteBool(o, tag)
case int16:
w.WriteInt16(o, tag)
case int32:
w.WriteInt32(o, tag)
case int64:
w.WriteInt64(o, tag)
case float32:
w.WriteFloat32(o, tag)
case float64:
w.WriteFloat64(o, tag)
case string:
w.WriteString(o, tag)
case IJceStruct:
w.WriteJceStruct(o, tag)
w.writeHead(8, tag)
w.WriteInt32(int32(len(m)), 0)
for k, v := range m {
w.WriteString(k, 0)
w.WriteBytes(v, 1)
}
}
func (w *JceWriter) writeObject(v reflect.Value, tag int) {
k := v.Kind()
if k == reflect.Map {
w.writeMap(v, tag)
func (w *JceWriter) writeMapStrMapStrBytes(m map[string]map[string][]byte, tag byte) {
if m == nil {
w.writeHead(8, tag)
w.writeHead(12, 0) // w.WriteInt32(0, 0)
return
}
if k == reflect.Slice {
if v.Type().Elem().Kind() == reflect.Uint8 {
w.WriteBytes(v.Bytes(), tag)
return
}
w.writeSlice(v, tag)
return
w.writeHead(8, tag)
w.WriteInt32(int32(len(m)), 0)
for k, v := range m {
w.WriteString(k, 0)
w.writeMapStrBytes(v, 1)
}
switch k {
case reflect.Uint8, reflect.Int8:
w.WriteByte(*(*byte)(pointerOf(v)), tag)
case reflect.Uint16, reflect.Int16:
w.WriteInt16(*(*int16)(pointerOf(v)), tag)
case reflect.Uint32, reflect.Int32:
w.WriteInt32(*(*int32)(pointerOf(v)), tag)
case reflect.Uint64, reflect.Int64:
w.WriteInt64(*(*int64)(pointerOf(v)), tag)
case reflect.String:
w.WriteString(v.String(), tag)
default:
switch o := v.Interface().(type) {
case IJceStruct:
w.WriteJceStruct(o, tag)
case float32:
w.WriteFloat32(o, tag)
case float64:
w.WriteFloat64(o, tag)
}
}
}
type decoder struct {
index int
id int
}
var decoderCache = sync.Map{}
// WriteJceStructRaw 写入 Jce 结构体
func (w *JceWriter) WriteJceStructRaw(s interface{}) {
t := reflect.TypeOf(s)
reflect.ValueOf(s).Interface()
if t.Kind() != reflect.Ptr {
return
}
t = t.Elem()
v := reflect.ValueOf(s).Elem()
var jceDec []decoder
dec, ok := decoderCache.Load(t)
if ok { // 从缓存中加载
jceDec = dec.([]decoder)
} else { // 初次反射
jceDec = make([]decoder, 0, t.NumField())
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
strId := field.Tag.Get("jceId")
if strId == "" {
continue
}
id, err := strconv.Atoi(strId)
if err != nil {
continue
}
jceDec = append(jceDec, decoder{
index: i,
id: id,
})
}
decoderCache.Store(t, jceDec) // 存入缓存
}
for _, dec := range jceDec {
obj := v.Field(dec.index)
w.writeObject(obj, dec.id)
}
}
func (w *JceWriter) WriteJceStruct(s IJceStruct, tag int) {
w.writeHead(10, tag)
w.WriteJceStructRaw(s)
w.writeHead(11, 0)
}
func (w *JceWriter) Bytes() []byte {

View File

@ -12,7 +12,7 @@ func BenchmarkJceWriter_WriteMap(b *testing.B) {
var x = globalBytes
for i := 0; i < b.N; i++ {
w := NewJceWriter()
w.WriteMap(req.Map, 0)
w.writeMapStrMapStrBytes(req.Map, 0)
x = w.Bytes()
}
globalBytes = x
@ -41,18 +41,14 @@ var reqPacket1 = &RequestPacket{
func BenchmarkJceWriter_WriteJceStructRaw(b *testing.B) {
var x = globalBytes
for i := 0; i < b.N; i++ {
w := NewJceWriter()
w.WriteJceStructRaw(reqPacket1)
x = w.Bytes()
_ = reqPacket1.ToBytes()
}
globalBytes = x
b.SetBytes(int64(len(globalBytes)))
}
func TestJceWriter_WriteJceStructRaw(t *testing.T) {
w := NewJceWriter()
w.WriteJceStructRaw(reqPacket1)
r := NewJceReader(w.Bytes())
r := NewJceReader(reqPacket1.ToBytes())
var reqPacket2 RequestPacket
reqPacket2.ReadFrom(r)
assert.Equal(t, reqPacket1, &reqPacket2)