protostostruct.go 3 KB
//弃用 使用python3重写了。
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
)

var (
	ProtoCode        = "syntax = \"proto3\";\noption go_package = \"../pb;pb\";\n\npackage protocode;\n\nenum ProtoCode\n{\n  UNKNOWN = 0;\n %s\n}"
	ProtoCodeLineReq = "\t%sReq = %d;\n"
	ProtoCodeLineRsp = "\t%sRsp = %d;\n"

	GoProtoCodeStr = "package action\n\nimport (\n\t\"pro2d/common/logger\"\n\t\"pro2d/pb\"\n)\n\nfunc GetActionMap() map[interface{}]interface{} {\n\tlogger.Debug(\"init protocode...\")\n\tam := make(map[interface{}]interface{})\n%s\n\treturn am\n}"

	GoProtoCodeLine = "\tam[uint32(pb.ProtoCode_%sReq)] = %sRpc\n"
)

func ProtoToCode(readPath, filename string) (string, string) {
	protofile, err := os.Open(readPath + filename)
	code := 0x000
	protoData := ""
	goProtoData := ""
	if err != nil {
		fmt.Errorf("ReadExcel|xlsx.OpenFile is err :%v", err)
		return "", ""
	}
	defer protofile.Close()

	r := bufio.NewReader(protofile)
	for {
		line, isPrefix, err := r.ReadLine()
		if len(line) > 0 && err != nil {
			fmt.Errorf("ReadLine returned both data and error: %s", err)
			return "", ""

		}
		if isPrefix {
			fmt.Errorf("ReadLine returned prefix")
			return "", ""
		}
		if err != nil {
			if err != io.EOF {
				fmt.Errorf("Got unknown error: %s", err)
				return "", ""
			}
			break
		}
		n := bytes.Index(line, []byte("message"))
		if n < 0 {
			continue
		}
		lb := bytes.Split(line, []byte(" "))
		for _, v := range lb {
			n1 := bytes.Index(v, []byte("Req"))
			n2 := bytes.Index(v, []byte("Rsp"))
			if n1 < 0 && n2 < 0 {
				continue
			}
			if n1 >= 0 {
				code++
				protoData += fmt.Sprintf(ProtoCodeLineReq, v[:n1], code)
				goProtoData += fmt.Sprintf(GoProtoCodeLine, v[:n1], v[:n1])
			}
			if n2 >= 0 {
				code++
				protoData += fmt.Sprintf(ProtoCodeLineRsp, v[:n2], code)
			}
		}
	}

	return protoData, goProtoData
}

func ReadProtos(readPath, OutPath string) error {
	files, err := ioutil.ReadDir(readPath)
	if err != nil {
		return fmt.Errorf("ReadExcel|ReadDir is err:%v", err)
	}

	protoData, goProtoData := "", ""
	for _, file := range files {
		if path.Ext(file.Name()) != ".proto" {
			continue
		}
		tprotoData, tgoProtoData := ProtoToCode(readPath, file.Name())
		if tprotoData == "" || tgoProtoData == "" {
			continue
		}
		protoData += tprotoData
		goProtoData += tgoProtoData

	}
	fw, err := os.OpenFile(OutPath+"protos/protocode.proto", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err)
	}
	defer fw.Close()

	_, err = fw.Write([]byte(fmt.Sprintf(ProtoCode, protoData)))
	if err != nil {
		return fmt.Errorf("WriteNewFile|Write is err:%v", err)
	}

	fw, err = os.OpenFile(OutPath+"cmd/gameserver/action/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err)
	}
	defer fw.Close()

	_, err = fw.Write([]byte(fmt.Sprintf(GoProtoCodeStr, goProtoData)))
	if err != nil {
		return fmt.Errorf("WriteNewFile|Write is err:%v", err)
	}
	return nil
}