diff --git a/Makefile b/Makefile index 2f7db23b..2878fc29 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,15 @@ CUR_DIR=$(shell pwd) VERSION=1.0.0 +.PHONY: all +all: build + # 清理 .PHONY: clean clean: rm -rf ./bin rm -rf ./protocol/proto + rm -rf ./gate/client_proto/client_proto_gen.go # 构建服务器二进制文件 .PHONY: build @@ -92,4 +96,4 @@ gen_csv: # 生成客户端协议代理功能所需的代码 .PHONY: 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 . diff --git a/fight/engine/fight_engine.go b/fight/engine/fight_engine.go index 035cbf2c..baacdb85 100644 --- a/fight/engine/fight_engine.go +++ b/fight/engine/fight_engine.go @@ -301,17 +301,15 @@ func (f *FightRoutine) getAllPlayer(entityMap map[uint32]*Entity) []uint32 { } var ClientCmdProtoMap *client_proto.ClientCmdProtoMap -var ClientCmdProtoMapRefValue reflect.Value func initClientCmdProtoMap() { if config.CONF.Hk4e.ClientProtoProxyEnable { ClientCmdProtoMap = client_proto.NewClientCmdProtoMap() - ClientCmdProtoMapRefValue = reflect.ValueOf(ClientCmdProtoMap) } } func GetClientProtoObjByName(protoObjName string) pb.Message { - fn := ClientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") + fn := ClientCmdProtoMap.RefValue.MethodByName("GetClientProtoObjByName") ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) obj := ret[0].Interface() if obj == nil { diff --git a/gate/client_proto/client_proto.go b/gate/client_proto/client_proto.go index 89d083be..e7f6176c 100644 --- a/gate/client_proto/client_proto.go +++ b/gate/client_proto/client_proto.go @@ -1,9 +1,7 @@ package client_proto import ( - "os" - "strconv" - "strings" + "reflect" "hk4e/pkg/logger" ) @@ -11,31 +9,16 @@ import ( type ClientCmdProtoMap struct { clientCmdIdCmdNameMap map[uint16]string clientCmdNameCmdIdMap map[string]uint16 + RefValue reflect.Value } func NewClientCmdProtoMap() (r *ClientCmdProtoMap) { r = new(ClientCmdProtoMap) r.clientCmdIdCmdNameMap = make(map[uint16]string) r.clientCmdNameCmdIdMap = make(map[string]uint16) - clientCmdFile, err := os.ReadFile("./client_cmd.csv") - if err != nil { - panic(err) - } - 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) - } + r.RefValue = reflect.ValueOf(r) + fn := r.RefValue.MethodByName("LoadClientCmdIdAndCmdName") + fn.Call([]reflect.Value{}) return r } diff --git a/gate/client_proto/client_proto_gen_test.go b/gate/client_proto/client_proto_gen_test.go index 7446a9d3..c696d881 100644 --- a/gate/client_proto/client_proto_gen_test.go +++ b/gate/client_proto/client_proto_gen_test.go @@ -12,7 +12,7 @@ func TestClientProtoGen(t *testing.T) { if err != nil { panic(err) } - nameList := make([]string, 0) + protoObjNameList := make([]string, 0) for _, entry := range dir { if entry.IsDir() { continue @@ -21,17 +21,41 @@ func TestClientProtoGen(t *testing.T) { if len(split) < 2 || split[len(split)-1] != "proto" { 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 += "\n" fileData += "import (\n" fileData += "\t\"hk4e/gate/client_proto/proto\"\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 += "\tswitch protoObjName {\n" - for _, protoObjName := range nameList { + for _, protoObjName := range protoObjNameList { fileData += "\tcase \"" + protoObjName + "\":\n\t\treturn new(proto." + protoObjName + ")\n" } fileData += "\tdefault:\n" @@ -62,6 +86,7 @@ func TestClientProtoGen(t *testing.T) { continue } enumName := split[1] + // 从protocol/proto_hk4e下复制同名的枚举类替换掉原proto文件里的内容 refEnum := FindEnumInDirFile("../../protocol/proto_hk4e", enumName) if refEnum == nil { continue diff --git a/gate/net/kcp_connect_manager.go b/gate/net/kcp_connect_manager.go index 692bee7e..960d9aab 100644 --- a/gate/net/kcp_connect_manager.go +++ b/gate/net/kcp_connect_manager.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/binary" - "reflect" "strconv" "sync" "time" @@ -29,20 +28,19 @@ const ( ) type KcpConnectManager struct { - discovery *rpc.DiscoveryClient - openState bool - sessionConvIdMap map[uint64]*Session - sessionUserIdMap map[uint32]*Session - sessionMapLock sync.RWMutex - kcpEventInput chan *KcpEvent - kcpEventOutput chan *KcpEvent - serverCmdProtoMap *cmd.CmdProtoMap - clientCmdProtoMap *client_proto.ClientCmdProtoMap - clientCmdProtoMapRefValue reflect.Value - messageQueue *mq.MessageQueue - localMsgOutput chan *ProtoMsg - createSessionChan chan *Session - destroySessionChan chan *Session + discovery *rpc.DiscoveryClient + openState bool + sessionConvIdMap map[uint64]*Session + sessionUserIdMap map[uint32]*Session + sessionMapLock sync.RWMutex + kcpEventInput chan *KcpEvent + kcpEventOutput chan *KcpEvent + serverCmdProtoMap *cmd.CmdProtoMap + clientCmdProtoMap *client_proto.ClientCmdProtoMap + messageQueue *mq.MessageQueue + localMsgOutput chan *ProtoMsg + createSessionChan chan *Session + destroySessionChan chan *Session // 密钥相关 dispatchKey []byte signRsaKey []byte @@ -60,7 +58,6 @@ func NewKcpConnectManager(messageQueue *mq.MessageQueue, discovery *rpc.Discover r.serverCmdProtoMap = cmd.NewCmdProtoMap() if config.CONF.Hk4e.ClientProtoProxyEnable { r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap() - r.clientCmdProtoMapRefValue = reflect.ValueOf(r.clientCmdProtoMap) } r.messageQueue = messageQueue r.localMsgOutput = make(chan *ProtoMsg, 1000) diff --git a/gate/net/proto_endecode.go b/gate/net/proto_endecode.go index acd4798f..000c37dd 100644 --- a/gate/net/proto_endecode.go +++ b/gate/net/proto_endecode.go @@ -295,7 +295,7 @@ func (k *KcpConnectManager) encodeProtoToPayload(protoObj pb.Message) (cmdId uin } 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)}) obj := ret[0].Interface() if obj == nil { diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index 48c6307a..b3010402 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -6,7 +6,7 @@ import ( "runtime" "time" - appConfig "hk4e/common/config" + "hk4e/common/config" "hk4e/common/mq" "hk4e/gate/client_proto" "hk4e/gate/kcp" @@ -45,14 +45,13 @@ var MESSAGE_QUEUE *mq.MessageQueue var SELF *model.Player type GameManager struct { - dao *dao.Dao - snowflake *alg.SnowflakeWorker - clientCmdProtoMap *client_proto.ClientCmdProtoMap - clientCmdProtoMapRefValue reflect.Value - gsId uint32 - gsAppid string - mainGsAppid string - ai *model.Player // 本服的Ai玩家对象 + dao *dao.Dao + snowflake *alg.SnowflakeWorker + clientCmdProtoMap *client_proto.ClientCmdProtoMap + gsId uint32 + gsAppid string + mainGsAppid string + ai *model.Player // 本服的Ai玩家对象 } func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gsAppid string, mainGsAppid string) (r *GameManager) { @@ -60,9 +59,8 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gs r.dao = dao MESSAGE_QUEUE = messageQueue r.snowflake = alg.NewSnowflakeWorker(int64(gsId)) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap() - r.clientCmdProtoMapRefValue = reflect.ValueOf(r.clientCmdProtoMap) // 反射调用的方法在启动时测试是否正常防止中途panic r.GetClientProtoObjByName("PingReq") } @@ -394,7 +392,7 @@ func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) { } 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)}) obj := ret[0].Interface() if obj == nil { diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index 35c03850..7bc61ead 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -1,7 +1,7 @@ package game import ( - appConfig "hk4e/common/config" + "hk4e/common/config" "hk4e/common/constant" "hk4e/common/utils" "hk4e/gs/model" @@ -104,7 +104,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p switch entry.ArgumentType { case proto.CombatTypeArgument_COMBAT_EVT_BEING_HIT: hitInfo := new(proto.EvtBeingHitInfo) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("EvtBeingHitInfo") if clientProtoObj == 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) case proto.CombatTypeArgument_ENTITY_MOVE: entityMoveInfo := new(proto.EntityMoveInfo) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("EntityMoveInfo") if clientProtoObj == 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) case proto.CombatTypeArgument_COMBAT_ANIMATOR_STATE_CHANGED: evtAnimatorStateChangedInfo := new(proto.EvtAnimatorStateChangedInfo) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("EvtAnimatorStateChangedInfo") if clientProtoObj == nil { logger.Error("get client proto obj is nil") @@ -386,7 +386,7 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg switch abilityInvokeEntry.ArgumentType { case proto.AbilityInvokeArgument_ABILITY_META_ADD_NEW_ABILITY: abilityMetaAddAbility := new(proto.AbilityMetaAddAbility) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("AbilityMetaAddAbility") if clientProtoObj == 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) case proto.AbilityInvokeArgument_ABILITY_META_MODIFIER_CHANGE: abilityMetaModifierChange := new(proto.AbilityMetaModifierChange) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("AbilityMetaModifierChange") if clientProtoObj == nil { logger.Error("get client proto obj is nil") diff --git a/gs/game/player_stamina.go b/gs/game/player_stamina.go index b733fd07..ba438a4e 100644 --- a/gs/game/player_stamina.go +++ b/gs/game/player_stamina.go @@ -4,7 +4,7 @@ import ( "strings" "time" - appConfig "hk4e/common/config" + "hk4e/common/config" "hk4e/common/constant" "hk4e/common/utils" "hk4e/gdconf" @@ -23,7 +23,7 @@ func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.Ab case proto.AbilityInvokeArgument_ABILITY_MIXIN_COST_STAMINA: // 大剑重击 或 持续技能 耐力消耗 costStamina := new(proto.AbilityMixinCostStamina) - if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + if config.CONF.Hk4e.ClientProtoProxyEnable { clientProtoObj := g.GetClientProtoObjByName("AbilityMixinCostStamina") if clientProtoObj == nil { logger.Error("get client proto obj is nil")