mproto.go
package mproto import ( "bytes" "encoding/binary" "fmt" "reflect" "strconv" ) const ( PT_GR_LUACOMMAND uint32 = 9299 PT_GC_CLEARFACEBOOKBIND uint32 = 32689 PT_GC_CLEARDEVICEBIND uint32 = 7445 PT_GR_BANDACCOUNT uint32 = 29536 ) type GR_LuaCommand struct { LuaCommand string `key:"21868"` } type GC_ClearFacebookBind struct { AccountId int32 `key:"512"` } func (o *GC_ClearFacebookBind) DecoStruct(dat []byte) { buffer := bytes.NewBuffer(dat) var fKey int16 var fLen int16 // 取KEY for nil == binary.Read(buffer, binary.LittleEndian, &fKey) { switch fKey { case 512: { binary.Read(buffer, binary.LittleEndian, &fLen) binary.Read(buffer, binary.LittleEndian, &o.AccountId) } break } } } type GR_BandAccount struct { //AccountId int32 `key:"24137"` BandTime int64 `key:"23911"` Result string `key:"27966"` NetIndex int8 `key:"11487"` NetOrder int16 `key:"585"` Something GC_ClearFacebookBind `key:"1585"` Array []GC_ClearFacebookBind `key:"1024"` } func (o *GR_BandAccount) DecoStruct(dat []byte) { buffer := bytes.NewBuffer(dat) var fKey int16 var fLen int16 // 取KEY for nil == binary.Read(buffer, binary.LittleEndian, &fKey) { switch fKey { case 1024: { binary.Read(buffer, binary.LittleEndian, &fLen) f := make([]byte, fLen) binary.Read(buffer, binary.LittleEndian, &f) var aGC_ClearFacebookBind GC_ClearFacebookBind = GC_ClearFacebookBind{} aGC_ClearFacebookBind.DecoStruct(f) o.Array = append(o.Array, aGC_ClearFacebookBind) } case 1585: { binary.Read(buffer, binary.LittleEndian, &fLen) f := make([]byte, fLen) binary.Read(buffer, binary.LittleEndian, &f) var aGC_ClearFacebookBind GC_ClearFacebookBind = GC_ClearFacebookBind{} aGC_ClearFacebookBind.DecoStruct(f) o.Something = aGC_ClearFacebookBind } case 23911: { binary.Read(buffer, binary.LittleEndian, &fLen) binary.Read(buffer, binary.LittleEndian, &o.BandTime) } case 27966: { binary.Read(buffer, binary.LittleEndian, &fLen) f := make([]byte, fLen) binary.Read(buffer, binary.LittleEndian, &f) o.Result = string(f) } case 11487: { binary.Read(buffer, binary.LittleEndian, &fLen) binary.Read(buffer, binary.LittleEndian, &o.NetIndex) } case 585: { binary.Read(buffer, binary.LittleEndian, &fLen) binary.Read(buffer, binary.LittleEndian, &o.NetOrder) } } } } func EncoStructSize(o interface{}) int32 { t := reflect.TypeOf(o) v := reflect.ValueOf(o) var size int32 = 0 for i := 0; i < t.NumField(); i++ { f := t.Field(i) if f.Type.Kind() == reflect.Array || f.Type.Kind() == reflect.Slice { for j := 0; j < v.Field(i).Len(); j++ { if v.Field(i).Index(j).Kind() == reflect.String { strval, _ := v.Field(i).Index(j).Interface().(string) size += int32(len([]byte(strval))) } else if v.Field(i).Index(j).Kind() == reflect.Int8 { size += 5 } else if v.Field(i).Index(j).Kind() == reflect.Int16 { size += 6 } else if v.Field(i).Index(j).Kind() == reflect.Int32 { size += 8 } else if v.Field(i).Index(j).Kind() == reflect.Int64 { size += 12 } else if v.Field(i).Index(j).Kind() == reflect.Struct { size += (EncoStructSize(v.Field(i).Index(j).Interface())) } else { fmt.Printf("nothing2 %6s: %v = %v tag:%s \n", f.Name, f.Type, v.Field(i).Index(j).Interface(), f.Tag) } } } else { if f.Type.Kind() == reflect.String { strval, _ := v.Field(i).Interface().(string) size += int32(len([]byte(strval))) } else if f.Type.Kind() == reflect.Int8 { size += 5 } else if f.Type.Kind() == reflect.Int16 { size += 6 } else if f.Type.Kind() == reflect.Int32 { size += 8 } else if f.Type.Kind() == reflect.Int64 { size += 12 } else if f.Type.Kind() == reflect.Struct { size += (EncoStructSize(v.Field(i).Interface())) } else { fmt.Printf("nothing1 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, v.Field(i).Interface(), f.Tag, f.Type.Kind().String()) } } } return size } func EncoStruct(o interface{}) []byte { t := reflect.TypeOf(o) v := reflect.ValueOf(o) buffer := bytes.NewBuffer([]byte{}) for i := 0; i < t.NumField(); i++ { f := t.Field(i) // KEY k, _ := strconv.Atoi(f.Tag.Get("key")) if f.Type.Kind() == reflect.Array || f.Type.Kind() == reflect.Slice { for j := 0; j < v.Field(i).Len(); j++ { binary.Write(buffer, binary.LittleEndian, int16(k)) if v.Field(i).Index(j).Kind() == reflect.String { strval, _ := v.Field(i).Index(j).Interface().(string) // 长度 binary.Write(buffer, binary.LittleEndian, int16(len([]byte(strval)))) // 内容 binary.Write(buffer, binary.LittleEndian, []byte(strval)) } else if v.Field(i).Index(j).Kind() == reflect.Int8 { int8val, _ := v.Field(i).Index(j).Interface().(int8) // 长度 binary.Write(buffer, binary.LittleEndian, int16(1)) // 内容 binary.Write(buffer, binary.LittleEndian, int8(int8val)) } else if v.Field(i).Index(j).Kind() == reflect.Int16 { int16val, _ := v.Field(i).Index(j).Interface().(int16) // 长度 binary.Write(buffer, binary.LittleEndian, int16(2)) // 内容 binary.Write(buffer, binary.LittleEndian, int16(int16val)) } else if v.Field(i).Index(j).Kind() == reflect.Int32 { int32val, _ := v.Field(i).Index(j).Interface().(int32) // 长度 binary.Write(buffer, binary.LittleEndian, int16(4)) // 内容 binary.Write(buffer, binary.LittleEndian, int32(int32val)) } else if v.Field(i).Index(j).Kind() == reflect.Int64 { int64val, _ := v.Field(i).Index(j).Interface().(int64) // 长度 binary.Write(buffer, binary.LittleEndian, int16(8)) // 内容 binary.Write(buffer, binary.LittleEndian, int64(int64val)) } else if v.Field(i).Index(j).Kind() == reflect.Struct { // 长度 binary.Write(buffer, binary.LittleEndian, int16(EncoStructSize(v.Field(i).Index(j).Interface()))) // 内容 binary.Write(buffer, binary.LittleEndian, EncoStruct(v.Field(i).Index(j).Interface())) } else { fmt.Printf("nothing3 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, v.Field(i).Index(j).Interface(), f.Tag, f.Type.Kind().String()) } } } else { binary.Write(buffer, binary.LittleEndian, int16(k)) val := v.Field(i).Interface() if f.Type.Kind() == reflect.String { strval, _ := val.(string) // 长度 binary.Write(buffer, binary.LittleEndian, int16(len([]byte(strval)))) // 内容 binary.Write(buffer, binary.LittleEndian, []byte(strval)) } else if f.Type.Kind() == reflect.Int8 { int8val, _ := val.(int8) // 长度 binary.Write(buffer, binary.LittleEndian, int16(1)) // 内容 binary.Write(buffer, binary.LittleEndian, int8(int8val)) } else if f.Type.Kind() == reflect.Int16 { int16val, _ := val.(int16) // 长度 binary.Write(buffer, binary.LittleEndian, int16(2)) // 内容 binary.Write(buffer, binary.LittleEndian, int16(int16val)) } else if f.Type.Kind() == reflect.Int32 { int32val, _ := val.(int32) // 长度 binary.Write(buffer, binary.LittleEndian, int16(4)) // 内容 binary.Write(buffer, binary.LittleEndian, int32(int32val)) } else if f.Type.Kind() == reflect.Int64 { int64val, _ := val.(int64) // 长度 binary.Write(buffer, binary.LittleEndian, int16(8)) // 内容 binary.Write(buffer, binary.LittleEndian, int64(int64val)) } else if f.Type.Kind() == reflect.Struct { // 长度 binary.Write(buffer, binary.LittleEndian, int16(EncoStructSize(val))) // 内容 binary.Write(buffer, binary.LittleEndian, EncoStruct(val)) } else { fmt.Printf("nothing4 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, val, f.Tag, f.Type.Kind().String()) } } } return buffer.Bytes() }
main.go
package main import ( "./mproto" "fmt" ) func main() { var gr mproto.GR_BandAccount var gc mproto.GC_ClearFacebookBind var t mproto.GR_BandAccount = mproto.GR_BandAccount{} gc.AccountId = 4096 gr.BandTime = 111 gr.Something.AccountId = 32 gr.NetIndex = 4 gr.NetOrder = 5 gr.Result = "abc中车" gr.Array = append(gr.Array, gc) fmt.Println(gr) b := mproto.EncoStruct(gr) t.DecoStruct(b) fmt.Println(t) }