mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
binary/jce: use go/parser
generator
This commit is contained in:
parent
45692b75f8
commit
5ff69f3c3a
@ -1,92 +0,0 @@
|
|||||||
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")
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
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)))
|
|
||||||
case reflect.Interface, reflect.Ptr:
|
|
||||||
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"))
|
|
||||||
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)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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"))
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ type IJceStruct interface {
|
|||||||
ReadFrom(*JceReader)
|
ReadFrom(*JceReader)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run gen/structs_parser.go -f structs_tobytes.go -i structs.go
|
//go:generate go run github.com/Mrs4s/MiraiGo/internal/generator/jce_gen -file=structs.go -o structs_tobytes.go
|
||||||
type (
|
type (
|
||||||
RequestPacket struct {
|
RequestPacket struct {
|
||||||
IVersion int16 `jceId:"1"`
|
IVersion int16 `jceId:"1"`
|
||||||
@ -75,7 +75,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SvcReqRegister struct {
|
SvcReqRegister struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
Bid int64 `jceId:"1"`
|
Bid int64 `jceId:"1"`
|
||||||
ConnType byte `jceId:"2"`
|
ConnType byte `jceId:"2"`
|
||||||
@ -140,7 +139,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SvcReqRegisterNew struct {
|
SvcReqRegisterNew struct {
|
||||||
IJceStruct
|
|
||||||
RequestOptional int64 `jceId:"0"`
|
RequestOptional int64 `jceId:"0"`
|
||||||
C2CMsg IJceStruct `jceId:"1"` // SvcReqGetMsgV2
|
C2CMsg IJceStruct `jceId:"1"` // SvcReqGetMsgV2
|
||||||
GroupMsg IJceStruct `jceId:"2"` // SvcReqPullGroupMsgSeq
|
GroupMsg IJceStruct `jceId:"2"` // SvcReqPullGroupMsgSeq
|
||||||
@ -174,7 +172,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
PullGroupSeqParam struct {
|
PullGroupSeqParam struct {
|
||||||
IJceStruct
|
|
||||||
GroupCode int64 `jceId:"0"`
|
GroupCode int64 `jceId:"0"`
|
||||||
LastSeqId int64 `jceId:"1"`
|
LastSeqId int64 `jceId:"1"`
|
||||||
}
|
}
|
||||||
@ -252,7 +249,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SvcRespPushMsg struct {
|
SvcRespPushMsg struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
DelInfos []IJceStruct `jceId:"1"`
|
DelInfos []IJceStruct `jceId:"1"`
|
||||||
Svrip int32 `jceId:"2"`
|
Svrip int32 `jceId:"2"`
|
||||||
@ -300,7 +296,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
FriendListRequest struct {
|
FriendListRequest struct {
|
||||||
IJceStruct
|
|
||||||
Reqtype int32 `jceId:"0"`
|
Reqtype int32 `jceId:"0"`
|
||||||
IfReflush byte `jceId:"1"`
|
IfReflush byte `jceId:"1"`
|
||||||
Uin int64 `jceId:"2"`
|
Uin int64 `jceId:"2"`
|
||||||
@ -382,7 +377,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
TroopListRequest struct {
|
TroopListRequest struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
GetMSFMsgFlag byte `jceId:"1"`
|
GetMSFMsgFlag byte `jceId:"1"`
|
||||||
Cookies []byte `jceId:"2"`
|
Cookies []byte `jceId:"2"`
|
||||||
@ -433,7 +427,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
TroopMemberListRequest struct {
|
TroopMemberListRequest struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
GroupCode int64 `jceId:"1"`
|
GroupCode int64 `jceId:"1"`
|
||||||
NextUin int64 `jceId:"2"`
|
NextUin int64 `jceId:"2"`
|
||||||
@ -483,7 +476,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
ModifyGroupCardRequest struct {
|
ModifyGroupCardRequest struct {
|
||||||
IJceStruct
|
|
||||||
Zero int64 `jceId:"0"`
|
Zero int64 `jceId:"0"`
|
||||||
GroupCode int64 `jceId:"1"`
|
GroupCode int64 `jceId:"1"`
|
||||||
NewSeq int64 `jceId:"2"`
|
NewSeq int64 `jceId:"2"`
|
||||||
@ -502,7 +494,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SummaryCardReq struct {
|
SummaryCardReq struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
ComeFrom int32 `jceId:"1"`
|
ComeFrom int32 `jceId:"1"`
|
||||||
QzoneFeedTimestamp int64 `jceId:"2"`
|
QzoneFeedTimestamp int64 `jceId:"2"`
|
||||||
@ -524,7 +515,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SummaryCardReqSearch struct {
|
SummaryCardReqSearch struct {
|
||||||
IJceStruct
|
|
||||||
Keyword string `jceId:"0"`
|
Keyword string `jceId:"0"`
|
||||||
CountryCode string `jceId:"1"`
|
CountryCode string `jceId:"1"`
|
||||||
Version int32 `jceId:"2"`
|
Version int32 `jceId:"2"`
|
||||||
@ -532,7 +522,6 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
DelFriendReq struct {
|
DelFriendReq struct {
|
||||||
IJceStruct
|
|
||||||
Uin int64 `jceId:"0"`
|
Uin int64 `jceId:"0"`
|
||||||
DelUin int64 `jceId:"1"`
|
DelUin int64 `jceId:"1"`
|
||||||
DelType byte `jceId:"2"`
|
DelType byte `jceId:"2"`
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Code generated by structs_parser; DO NOT EDIT.
|
// Code generated by internal/generator/jce_gen; DO NOT EDIT.
|
||||||
|
|
||||||
package jce
|
package jce
|
||||||
|
|
||||||
func (pkt *RequestPacket) ToBytes() []byte {
|
func (pkt *RequestPacket) ToBytes() []byte {
|
||||||
@ -38,70 +39,100 @@ func (pkt *SsoServerInfo) ToBytes() []byte {
|
|||||||
|
|
||||||
func (pkt *FileStoragePushFSSvcList) ToBytes() []byte {
|
func (pkt *FileStoragePushFSSvcList) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
|
{ // write pkt.UploadList tag=0
|
||||||
w.writeHead(9, 0)
|
w.writeHead(9, 0)
|
||||||
if len(pkt.UploadList) == 0 {
|
if len(pkt.UploadList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.UploadList)), 0)
|
w.WriteInt32(int32(len(pkt.UploadList)), 0)
|
||||||
for _, i := range pkt.UploadList {
|
for _, i := range pkt.UploadList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write pkt.PicDownloadList tag=1
|
||||||
w.writeHead(9, 1)
|
w.writeHead(9, 1)
|
||||||
if len(pkt.PicDownloadList) == 0 {
|
if len(pkt.PicDownloadList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.PicDownloadList)), 0)
|
w.WriteInt32(int32(len(pkt.PicDownloadList)), 0)
|
||||||
for _, i := range pkt.PicDownloadList {
|
for _, i := range pkt.PicDownloadList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write pkt.GPicDownloadList tag=2
|
||||||
w.writeHead(9, 2)
|
w.writeHead(9, 2)
|
||||||
if len(pkt.GPicDownloadList) == 0 {
|
if len(pkt.GPicDownloadList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.GPicDownloadList)), 0)
|
w.WriteInt32(int32(len(pkt.GPicDownloadList)), 0)
|
||||||
for _, i := range pkt.GPicDownloadList {
|
for _, i := range pkt.GPicDownloadList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write pkt.QZoneProxyServiceList tag=3
|
||||||
w.writeHead(9, 3)
|
w.writeHead(9, 3)
|
||||||
if len(pkt.QZoneProxyServiceList) == 0 {
|
if len(pkt.QZoneProxyServiceList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.QZoneProxyServiceList)), 0)
|
w.WriteInt32(int32(len(pkt.QZoneProxyServiceList)), 0)
|
||||||
for _, i := range pkt.QZoneProxyServiceList {
|
for _, i := range pkt.QZoneProxyServiceList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write pkt.UrlEncodeServiceList tag=4
|
||||||
w.writeHead(9, 4)
|
w.writeHead(9, 4)
|
||||||
if len(pkt.UrlEncodeServiceList) == 0 {
|
if len(pkt.UrlEncodeServiceList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.UrlEncodeServiceList)), 0)
|
w.WriteInt32(int32(len(pkt.UrlEncodeServiceList)), 0)
|
||||||
for _, i := range pkt.UrlEncodeServiceList {
|
for _, i := range pkt.UrlEncodeServiceList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write BigDataChannel tag=5
|
||||||
w.writeHead(10, 5)
|
w.writeHead(10, 5)
|
||||||
w.buf.Write(pkt.BigDataChannel.ToBytes())
|
w.buf.Write(pkt.BigDataChannel.ToBytes())
|
||||||
w.writeHead(11, 0)
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
|
{ // write pkt.VipEmotionList tag=6
|
||||||
w.writeHead(9, 6)
|
w.writeHead(9, 6)
|
||||||
if len(pkt.VipEmotionList) == 0 {
|
if len(pkt.VipEmotionList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.VipEmotionList)), 0)
|
w.WriteInt32(int32(len(pkt.VipEmotionList)), 0)
|
||||||
for _, i := range pkt.VipEmotionList {
|
for _, i := range pkt.VipEmotionList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
{ // write pkt.C2CPicDownList tag=7
|
||||||
w.writeHead(9, 7)
|
w.writeHead(9, 7)
|
||||||
if len(pkt.C2CPicDownList) == 0 {
|
if len(pkt.C2CPicDownList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.C2CPicDownList)), 0)
|
w.WriteInt32(int32(len(pkt.C2CPicDownList)), 0)
|
||||||
for _, i := range pkt.C2CPicDownList {
|
for _, i := range pkt.C2CPicDownList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteBytes(pkt.PttList, 10)
|
w.WriteBytes(pkt.PttList, 10)
|
||||||
@ -117,13 +148,17 @@ func (pkt *FileStorageServerInfo) ToBytes() []byte {
|
|||||||
|
|
||||||
func (pkt *BigDataChannel) ToBytes() []byte {
|
func (pkt *BigDataChannel) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
|
{ // write pkt.IPLists tag=0
|
||||||
w.writeHead(9, 0)
|
w.writeHead(9, 0)
|
||||||
if len(pkt.IPLists) == 0 {
|
if len(pkt.IPLists) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.IPLists)), 0)
|
w.WriteInt32(int32(len(pkt.IPLists)), 0)
|
||||||
for _, i := range pkt.IPLists {
|
for _, i := range pkt.IPLists {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteBytes(pkt.SigSession, 1)
|
w.WriteBytes(pkt.SigSession, 1)
|
||||||
@ -137,13 +172,17 @@ func (pkt *BigDataChannel) ToBytes() []byte {
|
|||||||
func (pkt *BigDataIPList) ToBytes() []byte {
|
func (pkt *BigDataIPList) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
w.WriteInt64(pkt.ServiceType, 0)
|
w.WriteInt64(pkt.ServiceType, 0)
|
||||||
|
{ // write pkt.IPList tag=1
|
||||||
w.writeHead(9, 1)
|
w.writeHead(9, 1)
|
||||||
if len(pkt.IPList) == 0 {
|
if len(pkt.IPList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.IPList)), 0)
|
w.WriteInt32(int32(len(pkt.IPList)), 0)
|
||||||
for _, i := range pkt.IPList {
|
for _, i := range pkt.IPList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteInt64(pkt.FragmentSize, 3)
|
w.WriteInt64(pkt.FragmentSize, 3)
|
||||||
@ -229,12 +268,16 @@ func (pkt *SvcRespRegister) ToBytes() []byte {
|
|||||||
func (pkt *SvcReqRegisterNew) ToBytes() []byte {
|
func (pkt *SvcReqRegisterNew) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
w.WriteInt64(pkt.RequestOptional, 0)
|
w.WriteInt64(pkt.RequestOptional, 0)
|
||||||
|
{ // write C2CMsg tag=1
|
||||||
w.writeHead(10, 1)
|
w.writeHead(10, 1)
|
||||||
w.buf.Write(pkt.C2CMsg.ToBytes())
|
w.buf.Write(pkt.C2CMsg.ToBytes())
|
||||||
w.writeHead(11, 0)
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
|
{ // write GroupMsg tag=2
|
||||||
w.writeHead(10, 2)
|
w.writeHead(10, 2)
|
||||||
w.buf.Write(pkt.GroupMsg.ToBytes())
|
w.buf.Write(pkt.GroupMsg.ToBytes())
|
||||||
w.writeHead(11, 0)
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
w.WriteByte(pkt.DisGroupMsgFilter, 14)
|
w.WriteByte(pkt.DisGroupMsgFilter, 14)
|
||||||
w.WriteByte(pkt.GroupMask, 15)
|
w.WriteByte(pkt.GroupMask, 15)
|
||||||
w.WriteInt64(pkt.EndSeq, 16)
|
w.WriteInt64(pkt.EndSeq, 16)
|
||||||
@ -261,13 +304,17 @@ func (pkt *SvcReqGetMsgV2) ToBytes() []byte {
|
|||||||
|
|
||||||
func (pkt *SvcReqPullGroupMsgSeq) ToBytes() []byte {
|
func (pkt *SvcReqPullGroupMsgSeq) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
|
{ // write pkt.GroupInfo tag=0
|
||||||
w.writeHead(9, 0)
|
w.writeHead(9, 0)
|
||||||
if len(pkt.GroupInfo) == 0 {
|
if len(pkt.GroupInfo) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.GroupInfo)), 0)
|
w.WriteInt32(int32(len(pkt.GroupInfo)), 0)
|
||||||
for _, i := range pkt.GroupInfo {
|
for _, i := range pkt.GroupInfo {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteByte(pkt.VerifyType, 1)
|
w.WriteByte(pkt.VerifyType, 1)
|
||||||
@ -291,13 +338,17 @@ func (pkt *SvcRespParam) ToBytes() []byte {
|
|||||||
w.WriteInt32(pkt.IsSupportViewPCFile, 4)
|
w.WriteInt32(pkt.IsSupportViewPCFile, 4)
|
||||||
w.WriteInt32(pkt.PcVersion, 5)
|
w.WriteInt32(pkt.PcVersion, 5)
|
||||||
w.WriteInt64(pkt.RoamFlag, 6)
|
w.WriteInt64(pkt.RoamFlag, 6)
|
||||||
|
{ // write pkt.OnlineInfos tag=7
|
||||||
w.writeHead(9, 7)
|
w.writeHead(9, 7)
|
||||||
if len(pkt.OnlineInfos) == 0 {
|
if len(pkt.OnlineInfos) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.OnlineInfos)), 0)
|
w.WriteInt32(int32(len(pkt.OnlineInfos)), 0)
|
||||||
for _, i := range pkt.OnlineInfos {
|
for _, i := range pkt.OnlineInfos {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteInt32(pkt.PCClientType, 8)
|
w.WriteInt32(pkt.PCClientType, 8)
|
||||||
@ -339,13 +390,17 @@ func (pkt *SvcReqMSFLoginNotify) ToBytes() []byte {
|
|||||||
w.WriteString(pkt.Info, 5)
|
w.WriteString(pkt.Info, 5)
|
||||||
w.WriteInt64(pkt.ProductType, 6)
|
w.WriteInt64(pkt.ProductType, 6)
|
||||||
w.WriteInt64(pkt.ClientType, 7)
|
w.WriteInt64(pkt.ClientType, 7)
|
||||||
|
{ // write pkt.InstanceList tag=8
|
||||||
w.writeHead(9, 8)
|
w.writeHead(9, 8)
|
||||||
if len(pkt.InstanceList) == 0 {
|
if len(pkt.InstanceList) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.InstanceList)), 0)
|
w.WriteInt32(int32(len(pkt.InstanceList)), 0)
|
||||||
for _, i := range pkt.InstanceList {
|
for _, i := range pkt.InstanceList {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
@ -385,13 +440,17 @@ func (pkt *PushMessageInfo) ToBytes() []byte {
|
|||||||
func (pkt *SvcRespPushMsg) ToBytes() []byte {
|
func (pkt *SvcRespPushMsg) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
w.WriteInt64(pkt.Uin, 0)
|
w.WriteInt64(pkt.Uin, 0)
|
||||||
|
{ // write pkt.DelInfos tag=1
|
||||||
w.writeHead(9, 1)
|
w.writeHead(9, 1)
|
||||||
if len(pkt.DelInfos) == 0 {
|
if len(pkt.DelInfos) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.DelInfos)), 0)
|
w.WriteInt32(int32(len(pkt.DelInfos)), 0)
|
||||||
for _, i := range pkt.DelInfos {
|
for _, i := range pkt.DelInfos {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteInt32(pkt.Svrip, 2)
|
w.WriteInt32(pkt.Svrip, 2)
|
||||||
@ -412,11 +471,6 @@ func (pkt *SvcReqGetDevLoginInfo) ToBytes() []byte {
|
|||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *SvcDevLoginInfo) ToBytes() []byte {
|
|
||||||
w := NewJceWriter()
|
|
||||||
return w.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *DelMsgInfo) ToBytes() []byte {
|
func (pkt *DelMsgInfo) ToBytes() []byte {
|
||||||
w := NewJceWriter()
|
w := NewJceWriter()
|
||||||
w.WriteInt64(pkt.FromUin, 0)
|
w.WriteInt64(pkt.FromUin, 0)
|
||||||
@ -630,13 +684,17 @@ func (pkt *ModifyGroupCardRequest) ToBytes() []byte {
|
|||||||
w.WriteInt64(pkt.Zero, 0)
|
w.WriteInt64(pkt.Zero, 0)
|
||||||
w.WriteInt64(pkt.GroupCode, 1)
|
w.WriteInt64(pkt.GroupCode, 1)
|
||||||
w.WriteInt64(pkt.NewSeq, 2)
|
w.WriteInt64(pkt.NewSeq, 2)
|
||||||
|
{ // write pkt.UinInfo tag=3
|
||||||
w.writeHead(9, 3)
|
w.writeHead(9, 3)
|
||||||
if len(pkt.UinInfo) == 0 {
|
if len(pkt.UinInfo) == 0 {
|
||||||
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteInt32(int32(len(pkt.UinInfo)), 0)
|
w.WriteInt32(int32(len(pkt.UinInfo)), 0)
|
||||||
for _, i := range pkt.UinInfo {
|
for _, i := range pkt.UinInfo {
|
||||||
|
w.writeHead(10, 0)
|
||||||
w.buf.Write(i.ToBytes())
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
//go:generate go run cmd/c2c_switcher.go
|
//go:generate go run github.com/Mrs4s/MiraiGo/internal/generator/c2c_switcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by client/c2c_switcher.go DO NOT EDIT.
|
// Code generated by internal/generator/c2c_switcher DO NOT EDIT.
|
||||||
|
|
||||||
package client
|
package client
|
||||||
|
|
||||||
@ -9,10 +9,10 @@ import (
|
|||||||
const (
|
const (
|
||||||
UnknownDecoder = iota
|
UnknownDecoder = iota
|
||||||
nonSvcNotifyTroopSystemMsgDecoders
|
nonSvcNotifyTroopSystemMsgDecoders
|
||||||
troopSystemMsgDecoders
|
|
||||||
sysMsgDecoders
|
|
||||||
otherDecoders
|
otherDecoders
|
||||||
privateMsgDecoders
|
privateMsgDecoders
|
||||||
|
sysMsgDecoders
|
||||||
|
troopSystemMsgDecoders
|
||||||
)
|
)
|
||||||
|
|
||||||
func peekC2CDecoder(msgType int32) (decoder func(*QQClient, *msg.Message, *incomingPacketInfo), decoderType uint8) {
|
func peekC2CDecoder(msgType int32) (decoder func(*QQClient, *msg.Message, *incomingPacketInfo), decoderType uint8) {
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
const codeTemplate = `// Code generated by client/c2c_switcher.go DO NOT EDIT.
|
const codeTemplate = `// Code generated by internal/generator/c2c_switcher DO NOT EDIT.
|
||||||
|
|
||||||
package client
|
package client
|
||||||
|
|
||||||
@ -93,6 +93,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sort.Slice(sf.Consts, func(i, j int) bool {
|
||||||
|
return sf.Consts[i] < sf.Consts[j]
|
||||||
|
})
|
||||||
sort.Sort(sf.Decoders)
|
sort.Sort(sf.Decoders)
|
||||||
|
|
||||||
f, _ := os.OpenFile("c2c_switch.go", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_TRUNC, 0o644)
|
f, _ := os.OpenFile("c2c_switch.go", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_TRUNC, 0o644)
|
197
internal/generator/jce_gen/main.go
Normal file
197
internal/generator/jce_gen/main.go
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/format"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type JceField struct {
|
||||||
|
Name string
|
||||||
|
Type ast.Expr
|
||||||
|
Id int
|
||||||
|
}
|
||||||
|
|
||||||
|
type JceStruct struct {
|
||||||
|
Name string
|
||||||
|
Fields []JceField
|
||||||
|
}
|
||||||
|
|
||||||
|
type Generator struct {
|
||||||
|
JceStructs []JceStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
file := flag.String("file", "structs.txt", "file to parse")
|
||||||
|
output := flag.String("o", "", "output file")
|
||||||
|
flag.Parse()
|
||||||
|
f, err := parser.ParseFile(token.NewFileSet(), *file, nil, parser.ParseComments)
|
||||||
|
assert(err == nil, err)
|
||||||
|
g := Generator{}
|
||||||
|
ast.Inspect(f, func(n ast.Node) bool {
|
||||||
|
switch n := n.(type) {
|
||||||
|
case *ast.FuncDecl:
|
||||||
|
return false
|
||||||
|
case *ast.TypeSpec:
|
||||||
|
x, ok := n.Type.(*ast.StructType)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if x.Fields != nil {
|
||||||
|
var jce JceStruct
|
||||||
|
for _, f := range x.Fields.List {
|
||||||
|
if f.Tag == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
unquoted, _ := strconv.Unquote(f.Tag.Value)
|
||||||
|
tag, ok := reflect.StructTag(unquoted).Lookup("jceId")
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
id, _ := strconv.Atoi(tag)
|
||||||
|
if len(f.Names) != 1 {
|
||||||
|
panic("unexpected name count")
|
||||||
|
}
|
||||||
|
jce.Fields = append(jce.Fields, JceField{
|
||||||
|
Name: f.Names[0].Name,
|
||||||
|
Type: f.Type,
|
||||||
|
Id: id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
jce.Name = n.Name.Name
|
||||||
|
g.JceStructs = append(g.JceStructs, jce)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
assert(err == nil, err)
|
||||||
|
g.Generate(buf)
|
||||||
|
formated, err := format.Source(buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s\n", buf.Bytes())
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
_ = os.WriteFile(*output, formated, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Generator) Generate(w io.Writer) {
|
||||||
|
io.WriteString(w, "// Code generated by internal/generator/jce_gen; DO NOT EDIT.\n\npackage jce\n\n")
|
||||||
|
for _, jce := range g.JceStructs {
|
||||||
|
if jce.Name == "" || len(jce.Fields) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var generate func(typ ast.Expr, i int)
|
||||||
|
generate = func(typ ast.Expr, i int) {
|
||||||
|
field := jce.Fields[i]
|
||||||
|
switch typ := typ.(type) {
|
||||||
|
case *ast.Ident:
|
||||||
|
switch typ.Name {
|
||||||
|
case "uint8", "uint16", "uint32", "uint64":
|
||||||
|
typename := []byte(typ.Name)[1:]
|
||||||
|
casted := fmt.Sprintf("%s(pkt.%s)", typename, field.Name)
|
||||||
|
typename[0] ^= ' '
|
||||||
|
fmt.Fprintf(w, "w.Write%s(%s, %d)\n", typename, casted, field.Id)
|
||||||
|
|
||||||
|
case "int8", "int16", "int32", "int64",
|
||||||
|
"byte", "string":
|
||||||
|
typename := []byte(typ.Name)
|
||||||
|
typename[0] ^= ' '
|
||||||
|
fmt.Fprintf(w, "w.Write%s(pkt.%s, %d)\n", typename, field.Name, field.Id)
|
||||||
|
|
||||||
|
case "int":
|
||||||
|
fmt.Fprintf(w, "w.WriteInt64(int64(pkt.%s), %d)\n", field.Name, field.Id)
|
||||||
|
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(w, `{ // write %s tag=%d
|
||||||
|
w.writeHead(10, %d)
|
||||||
|
w.buf.Write(pkt.%s.ToBytes())
|
||||||
|
w.writeHead(11, 0)}`+"\n", field.Name, field.Id, field.Id, field.Name)
|
||||||
|
}
|
||||||
|
case *ast.StarExpr:
|
||||||
|
_ = typ.X.(*ast.Ident) // assert
|
||||||
|
generate(typ.X, i)
|
||||||
|
case *ast.ArrayType:
|
||||||
|
assert(typ.Len == nil, "unexpected array len")
|
||||||
|
var method string
|
||||||
|
switch typeName(typ) {
|
||||||
|
case "[]byte":
|
||||||
|
method = "WriteBytes"
|
||||||
|
case "[]int64":
|
||||||
|
method = "WriteInt64Slice"
|
||||||
|
case "[][]byte":
|
||||||
|
method = "WriteBytesSlice"
|
||||||
|
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(w,
|
||||||
|
"\t"+`{ // write pkt.%s tag=%d
|
||||||
|
w.writeHead(9, %d)
|
||||||
|
if len(pkt.%s) == 0 {
|
||||||
|
w.writeHead(12, 0) // w.WriteInt32(0, 0)
|
||||||
|
} else {
|
||||||
|
w.WriteInt32(int32(len(pkt.%s)), 0)
|
||||||
|
for _, i := range pkt.%s {
|
||||||
|
w.writeHead(10, 0)
|
||||||
|
w.buf.Write(i.ToBytes())
|
||||||
|
w.writeHead(11, 0)
|
||||||
|
}
|
||||||
|
}}`+"\n", field.Name, field.Id, field.Id, field.Name, field.Name, field.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert(method != "", typeName(typ))
|
||||||
|
fmt.Fprintf(w, "w.%s(pkt.%s, %d)\n", method, field.Name, field.Id)
|
||||||
|
case *ast.MapType:
|
||||||
|
var method string
|
||||||
|
typName := typeName(typ)
|
||||||
|
switch typName {
|
||||||
|
case "map[string]string":
|
||||||
|
method = "writeMapStrStr"
|
||||||
|
case "map[string][]byte":
|
||||||
|
method = "writeMapStrBytes"
|
||||||
|
case "map[string]map[string][]byte":
|
||||||
|
method = "writeMapStrMapStrBytes"
|
||||||
|
}
|
||||||
|
assert(method != "", typName)
|
||||||
|
fmt.Fprintf(w, "w.%s(pkt.%s, %d)\n", method, field.Name, field.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "func (pkt *%s) ToBytes() []byte {\nw := NewJceWriter()\n", jce.Name)
|
||||||
|
for i := range jce.Fields {
|
||||||
|
generate(jce.Fields[i].Type, i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "return w.Bytes()\n}\n\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func assert(cond bool, val interface{}) {
|
||||||
|
if !cond {
|
||||||
|
panic("assertion failed: " + fmt.Sprint(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func typeName(typ ast.Expr) string {
|
||||||
|
switch typ := typ.(type) {
|
||||||
|
case *ast.Ident:
|
||||||
|
return typ.Name
|
||||||
|
case *ast.StarExpr:
|
||||||
|
return "*" + typeName(typ.X)
|
||||||
|
case *ast.ArrayType:
|
||||||
|
if typ.Len != nil {
|
||||||
|
panic("unexpected array type")
|
||||||
|
}
|
||||||
|
return "[]" + typeName(typ.Elt)
|
||||||
|
case *ast.MapType:
|
||||||
|
return "map[" + typeName(typ.Key) + "]" + typeName(typ.Value)
|
||||||
|
}
|
||||||
|
panic("unexpected type")
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user