优化协议代理代码生成

This commit is contained in:
flswld
2023-01-30 21:30:04 +08:00
parent c753dc53cd
commit 5a175722d7
9 changed files with 71 additions and 66 deletions
+5 -1
View File
@@ -2,11 +2,15 @@ CUR_DIR=$(shell pwd)
VERSION=1.0.0 VERSION=1.0.0
.PHONY: all
all: build
# 清理 # 清理
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf ./bin rm -rf ./bin
rm -rf ./protocol/proto rm -rf ./protocol/proto
rm -rf ./gate/client_proto/client_proto_gen.go
# 构建服务器二进制文件 # 构建服务器二进制文件
.PHONY: build .PHONY: build
@@ -92,4 +96,4 @@ gen_csv:
# 生成客户端协议代理功能所需的代码 # 生成客户端协议代理功能所需的代码
.PHONY: gen_client_proto .PHONY: gen_client_proto
gen_client_proto: gen_client_proto:
cd gate/client_proto && go test -v -run TestClientProtoGen . cd gate/client_proto && rm -rf client_proto_gen.go && go test -v -run TestClientProtoGen .
+1 -3
View File
@@ -301,17 +301,15 @@ func (f *FightRoutine) getAllPlayer(entityMap map[uint32]*Entity) []uint32 {
} }
var ClientCmdProtoMap *client_proto.ClientCmdProtoMap var ClientCmdProtoMap *client_proto.ClientCmdProtoMap
var ClientCmdProtoMapRefValue reflect.Value
func initClientCmdProtoMap() { func initClientCmdProtoMap() {
if config.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
ClientCmdProtoMap = client_proto.NewClientCmdProtoMap() ClientCmdProtoMap = client_proto.NewClientCmdProtoMap()
ClientCmdProtoMapRefValue = reflect.ValueOf(ClientCmdProtoMap)
} }
} }
func GetClientProtoObjByName(protoObjName string) pb.Message { func GetClientProtoObjByName(protoObjName string) pb.Message {
fn := ClientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") fn := ClientCmdProtoMap.RefValue.MethodByName("GetClientProtoObjByName")
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
obj := ret[0].Interface() obj := ret[0].Interface()
if obj == nil { if obj == nil {
+5 -22
View File
@@ -1,9 +1,7 @@
package client_proto package client_proto
import ( import (
"os" "reflect"
"strconv"
"strings"
"hk4e/pkg/logger" "hk4e/pkg/logger"
) )
@@ -11,31 +9,16 @@ import (
type ClientCmdProtoMap struct { type ClientCmdProtoMap struct {
clientCmdIdCmdNameMap map[uint16]string clientCmdIdCmdNameMap map[uint16]string
clientCmdNameCmdIdMap map[string]uint16 clientCmdNameCmdIdMap map[string]uint16
RefValue reflect.Value
} }
func NewClientCmdProtoMap() (r *ClientCmdProtoMap) { func NewClientCmdProtoMap() (r *ClientCmdProtoMap) {
r = new(ClientCmdProtoMap) r = new(ClientCmdProtoMap)
r.clientCmdIdCmdNameMap = make(map[uint16]string) r.clientCmdIdCmdNameMap = make(map[uint16]string)
r.clientCmdNameCmdIdMap = make(map[string]uint16) r.clientCmdNameCmdIdMap = make(map[string]uint16)
clientCmdFile, err := os.ReadFile("./client_cmd.csv") r.RefValue = reflect.ValueOf(r)
if err != nil { fn := r.RefValue.MethodByName("LoadClientCmdIdAndCmdName")
panic(err) fn.Call([]reflect.Value{})
}
clientCmdData := string(clientCmdFile)
lineList := strings.Split(clientCmdData, "\n")
for _, line := range lineList {
item := strings.Split(line, ",")
if len(item) != 2 {
panic("parse client cmd file error")
}
cmdName := item[0]
cmdId, err := strconv.Atoi(item[1])
if err != nil {
panic(err)
}
r.clientCmdIdCmdNameMap[uint16(cmdId)] = cmdName
r.clientCmdNameCmdIdMap[cmdName] = uint16(cmdId)
}
return r return r
} }
+28 -3
View File
@@ -12,7 +12,7 @@ func TestClientProtoGen(t *testing.T) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
nameList := make([]string, 0) protoObjNameList := make([]string, 0)
for _, entry := range dir { for _, entry := range dir {
if entry.IsDir() { if entry.IsDir() {
continue continue
@@ -21,17 +21,41 @@ func TestClientProtoGen(t *testing.T) {
if len(split) < 2 || split[len(split)-1] != "proto" { if len(split) < 2 || split[len(split)-1] != "proto" {
continue continue
} }
nameList = append(nameList, split[len(split)-2]) protoObjNameList = append(protoObjNameList, split[len(split)-2])
} }
// 生成初始化cmdId和cmdName的方法
clientCmdFile, err := os.ReadFile("./proto/client_cmd.csv")
if err != nil {
panic(err)
}
clientCmdData := string(clientCmdFile)
clientCmdLineList := strings.Split(clientCmdData, "\n")
// 生成代码文件
fileData := "package client_proto\n" fileData := "package client_proto\n"
fileData += "\n" fileData += "\n"
fileData += "import (\n" fileData += "import (\n"
fileData += "\t\"hk4e/gate/client_proto/proto\"\n" fileData += "\t\"hk4e/gate/client_proto/proto\"\n"
fileData += ")\n" fileData += ")\n"
fileData += "\n" fileData += "\n"
fileData += "func (c *ClientCmdProtoMap) LoadClientCmdIdAndCmdName() {\n"
for _, clientCmdLine := range clientCmdLineList {
if clientCmdLine == "" {
continue
}
item := strings.Split(clientCmdLine, ",")
if len(item) != 2 {
panic("parse client cmd file error")
}
cmdName := item[0]
cmdId := item[1]
fileData += "\tc.clientCmdIdCmdNameMap[uint16(" + cmdId + ")] = \"" + cmdName + "\"\n"
fileData += "\tc.clientCmdNameCmdIdMap[\"" + cmdName + "\"] = uint16(" + cmdId + ")\n"
}
fileData += "}\n"
fileData += "\n"
fileData += "func (c *ClientCmdProtoMap) GetClientProtoObjByName(protoObjName string) any {\n" fileData += "func (c *ClientCmdProtoMap) GetClientProtoObjByName(protoObjName string) any {\n"
fileData += "\tswitch protoObjName {\n" fileData += "\tswitch protoObjName {\n"
for _, protoObjName := range nameList { for _, protoObjName := range protoObjNameList {
fileData += "\tcase \"" + protoObjName + "\":\n\t\treturn new(proto." + protoObjName + ")\n" fileData += "\tcase \"" + protoObjName + "\":\n\t\treturn new(proto." + protoObjName + ")\n"
} }
fileData += "\tdefault:\n" fileData += "\tdefault:\n"
@@ -62,6 +86,7 @@ func TestClientProtoGen(t *testing.T) {
continue continue
} }
enumName := split[1] enumName := split[1]
// 从protocol/proto_hk4e下复制同名的枚举类替换掉原proto文件里的内容
refEnum := FindEnumInDirFile("../../protocol/proto_hk4e", enumName) refEnum := FindEnumInDirFile("../../protocol/proto_hk4e", enumName)
if refEnum == nil { if refEnum == nil {
continue continue
-3
View File
@@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/binary" "encoding/binary"
"reflect"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@@ -38,7 +37,6 @@ type KcpConnectManager struct {
kcpEventOutput chan *KcpEvent kcpEventOutput chan *KcpEvent
serverCmdProtoMap *cmd.CmdProtoMap serverCmdProtoMap *cmd.CmdProtoMap
clientCmdProtoMap *client_proto.ClientCmdProtoMap clientCmdProtoMap *client_proto.ClientCmdProtoMap
clientCmdProtoMapRefValue reflect.Value
messageQueue *mq.MessageQueue messageQueue *mq.MessageQueue
localMsgOutput chan *ProtoMsg localMsgOutput chan *ProtoMsg
createSessionChan chan *Session createSessionChan chan *Session
@@ -60,7 +58,6 @@ func NewKcpConnectManager(messageQueue *mq.MessageQueue, discovery *rpc.Discover
r.serverCmdProtoMap = cmd.NewCmdProtoMap() r.serverCmdProtoMap = cmd.NewCmdProtoMap()
if config.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap() r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap()
r.clientCmdProtoMapRefValue = reflect.ValueOf(r.clientCmdProtoMap)
} }
r.messageQueue = messageQueue r.messageQueue = messageQueue
r.localMsgOutput = make(chan *ProtoMsg, 1000) r.localMsgOutput = make(chan *ProtoMsg, 1000)
+1 -1
View File
@@ -295,7 +295,7 @@ func (k *KcpConnectManager) encodeProtoToPayload(protoObj pb.Message) (cmdId uin
} }
func (k *KcpConnectManager) getClientProtoObjByName(protoObjName string) pb.Message { func (k *KcpConnectManager) getClientProtoObjByName(protoObjName string) pb.Message {
fn := k.clientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") fn := k.clientCmdProtoMap.RefValue.MethodByName("GetClientProtoObjByName")
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
obj := ret[0].Interface() obj := ret[0].Interface()
if obj == nil { if obj == nil {
+3 -5
View File
@@ -6,7 +6,7 @@ import (
"runtime" "runtime"
"time" "time"
appConfig "hk4e/common/config" "hk4e/common/config"
"hk4e/common/mq" "hk4e/common/mq"
"hk4e/gate/client_proto" "hk4e/gate/client_proto"
"hk4e/gate/kcp" "hk4e/gate/kcp"
@@ -48,7 +48,6 @@ type GameManager struct {
dao *dao.Dao dao *dao.Dao
snowflake *alg.SnowflakeWorker snowflake *alg.SnowflakeWorker
clientCmdProtoMap *client_proto.ClientCmdProtoMap clientCmdProtoMap *client_proto.ClientCmdProtoMap
clientCmdProtoMapRefValue reflect.Value
gsId uint32 gsId uint32
gsAppid string gsAppid string
mainGsAppid string mainGsAppid string
@@ -60,9 +59,8 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gs
r.dao = dao r.dao = dao
MESSAGE_QUEUE = messageQueue MESSAGE_QUEUE = messageQueue
r.snowflake = alg.NewSnowflakeWorker(int64(gsId)) r.snowflake = alg.NewSnowflakeWorker(int64(gsId))
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap() r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap()
r.clientCmdProtoMapRefValue = reflect.ValueOf(r.clientCmdProtoMap)
// 反射调用的方法在启动时测试是否正常防止中途panic // 反射调用的方法在启动时测试是否正常防止中途panic
r.GetClientProtoObjByName("PingReq") r.GetClientProtoObjByName("PingReq")
} }
@@ -394,7 +392,7 @@ func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) {
} }
func (g *GameManager) GetClientProtoObjByName(protoObjName string) pb.Message { func (g *GameManager) GetClientProtoObjByName(protoObjName string) pb.Message {
fn := g.clientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") fn := g.clientCmdProtoMap.RefValue.MethodByName("GetClientProtoObjByName")
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
obj := ret[0].Interface() obj := ret[0].Interface()
if obj == nil { if obj == nil {
+6 -6
View File
@@ -1,7 +1,7 @@
package game package game
import ( import (
appConfig "hk4e/common/config" "hk4e/common/config"
"hk4e/common/constant" "hk4e/common/constant"
"hk4e/common/utils" "hk4e/common/utils"
"hk4e/gs/model" "hk4e/gs/model"
@@ -104,7 +104,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
switch entry.ArgumentType { switch entry.ArgumentType {
case proto.CombatTypeArgument_COMBAT_EVT_BEING_HIT: case proto.CombatTypeArgument_COMBAT_EVT_BEING_HIT:
hitInfo := new(proto.EvtBeingHitInfo) hitInfo := new(proto.EvtBeingHitInfo)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("EvtBeingHitInfo") clientProtoObj := g.GetClientProtoObjByName("EvtBeingHitInfo")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")
@@ -161,7 +161,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
case proto.CombatTypeArgument_ENTITY_MOVE: case proto.CombatTypeArgument_ENTITY_MOVE:
entityMoveInfo := new(proto.EntityMoveInfo) entityMoveInfo := new(proto.EntityMoveInfo)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("EntityMoveInfo") clientProtoObj := g.GetClientProtoObjByName("EntityMoveInfo")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")
@@ -227,7 +227,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
case proto.CombatTypeArgument_COMBAT_ANIMATOR_STATE_CHANGED: case proto.CombatTypeArgument_COMBAT_ANIMATOR_STATE_CHANGED:
evtAnimatorStateChangedInfo := new(proto.EvtAnimatorStateChangedInfo) evtAnimatorStateChangedInfo := new(proto.EvtAnimatorStateChangedInfo)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("EvtAnimatorStateChangedInfo") clientProtoObj := g.GetClientProtoObjByName("EvtAnimatorStateChangedInfo")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")
@@ -386,7 +386,7 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg
switch abilityInvokeEntry.ArgumentType { switch abilityInvokeEntry.ArgumentType {
case proto.AbilityInvokeArgument_ABILITY_META_ADD_NEW_ABILITY: case proto.AbilityInvokeArgument_ABILITY_META_ADD_NEW_ABILITY:
abilityMetaAddAbility := new(proto.AbilityMetaAddAbility) abilityMetaAddAbility := new(proto.AbilityMetaAddAbility)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("AbilityMetaAddAbility") clientProtoObj := g.GetClientProtoObjByName("AbilityMetaAddAbility")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")
@@ -413,7 +413,7 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg
worldAvatar.abilityList = append(worldAvatar.abilityList, abilityMetaAddAbility.Ability) worldAvatar.abilityList = append(worldAvatar.abilityList, abilityMetaAddAbility.Ability)
case proto.AbilityInvokeArgument_ABILITY_META_MODIFIER_CHANGE: case proto.AbilityInvokeArgument_ABILITY_META_MODIFIER_CHANGE:
abilityMetaModifierChange := new(proto.AbilityMetaModifierChange) abilityMetaModifierChange := new(proto.AbilityMetaModifierChange)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("AbilityMetaModifierChange") clientProtoObj := g.GetClientProtoObjByName("AbilityMetaModifierChange")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"strings" "strings"
"time" "time"
appConfig "hk4e/common/config" "hk4e/common/config"
"hk4e/common/constant" "hk4e/common/constant"
"hk4e/common/utils" "hk4e/common/utils"
"hk4e/gdconf" "hk4e/gdconf"
@@ -23,7 +23,7 @@ func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.Ab
case proto.AbilityInvokeArgument_ABILITY_MIXIN_COST_STAMINA: case proto.AbilityInvokeArgument_ABILITY_MIXIN_COST_STAMINA:
// 大剑重击 或 持续技能 耐力消耗 // 大剑重击 或 持续技能 耐力消耗
costStamina := new(proto.AbilityMixinCostStamina) costStamina := new(proto.AbilityMixinCostStamina)
if appConfig.CONF.Hk4e.ClientProtoProxyEnable { if config.CONF.Hk4e.ClientProtoProxyEnable {
clientProtoObj := g.GetClientProtoObjByName("AbilityMixinCostStamina") clientProtoObj := g.GetClientProtoObjByName("AbilityMixinCostStamina")
if clientProtoObj == nil { if clientProtoObj == nil {
logger.Error("get client proto obj is nil") logger.Error("get client proto obj is nil")