From 7e866696286966368ba0bae93c0fc72292b6e91b Mon Sep 17 00:00:00 2001 From: flswld Date: Sat, 24 Dec 2022 04:14:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E5=90=84=E4=B8=AA=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E4=B9=8B=E9=97=B4=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 6 +- README.md | 17 +- cmd/dispatch/main.go | 8 +- cmd/fight/main.go | 5 +- cmd/gate/main.go | 4 +- cmd/gm/main.go | 8 + cmd/gs/main.go | 4 +- cmd/hk4e/node.go | 23 ++ cmd/node/application.toml | 12 + cmd/node/main.go | 31 ++ cmd/pathfinding/main.go | 5 +- {gs => common}/constant/action_reason.go | 0 {gs => common}/constant/climate_type.go | 0 {gs => common}/constant/constant.go | 0 {gs => common}/constant/element_type.go | 0 {gs => common}/constant/enter_reason.go | 0 {gs => common}/constant/entity_id_type.go | 0 {gs => common}/constant/entity_type.go | 0 {gs => common}/constant/equip_type.go | 0 {gs => common}/constant/fetter_state.go | 0 {gs => common}/constant/fight_property.go | 0 {gs => common}/constant/game_constant.go | 0 {gs => common}/constant/grow_curve.go | 0 {gs => common}/constant/item_type.go | 0 {gs => common}/constant/life_state.go | 0 {gs => common}/constant/material_type.go | 0 {gs => common}/constant/open_state.go | 0 {gs => common}/constant/player_prop.go | 0 {gs => common}/constant/scene_type.go | 0 {gs => common}/constant/stamina_cost.go | 0 {gs => common}/constant/weapon_type.go | 0 common/mq/nats.go | 10 + common/mq/net_msg.go | 37 +- common/mq/topic.go | 35 +- common/region/region.go | 5 +- common/rpc/client.go | 81 ++++ dispatch/app/app.go | 8 +- dispatch/controller/controller.go | 22 +- dispatch/controller/gate_controller.go | 11 - fight/app/app.go | 29 +- fight/engine/fight_engine.go | 52 ++- gate/app/app.go | 29 +- gate/net/forward.go | 61 ++- gate/net/kcp_connect_manager.go | 52 ++- gm/app/app.go | 14 +- gm/controller/controller.go | 8 +- gm/controller/gm_controller.go | 2 +- gm/rpc_client/client.go | 29 -- go.mod | 11 +- gs/api/api.pb.go | 2 +- gs/app/app.go | 48 ++- gs/config/avatar_skill_data.go | 2 +- gs/config/avatar_skill_depot_data.go | 2 +- gs/config/gadget_data.go | 2 +- gs/config/item_data.go | 2 +- gs/game/command_gm.go | 2 +- gs/game/command_manager.go | 3 +- gs/game/game_manager.go | 44 +- gs/game/local_event_manager.go | 4 +- gs/game/route_manager.go | 13 +- gs/game/tick_manager.go | 2 +- gs/game/user_avatar.go | 2 +- gs/game/user_common_handler.go | 32 +- gs/game/user_item.go | 2 +- gs/game/user_login.go | 46 +-- gs/game/user_manager.go | 8 +- gs/game/user_map.go | 3 +- gs/game/user_multiplayer.go | 10 +- gs/game/user_scene.go | 2 +- gs/game/user_shop.go | 2 +- gs/game/user_social.go | 2 +- gs/game/user_stamina.go | 6 +- gs/game/user_team.go | 2 +- gs/game/user_weapon.go | 2 +- gs/game/world_manager.go | 22 +- gs/model/Item.go | 2 +- gs/model/avatar.go | 2 +- gs/model/player.go | 2 + gs/model/stamina.go | 2 +- gs/model/team.go | 2 +- gs/service/service.go | 1 - node/api/api.natsrpc.pb.go | 70 ++++ node/api/api.pb.go | 466 ++++++++++++++++++++++ node/api/api.proto | 34 ++ node/api/server_type.go | 8 + node/app/app.go | 56 +++ node/service/discovery.go | 94 +++++ node/service/service.go | 32 ++ pathfinding/app/app.go | 27 +- pathfinding/handle/handle.go | 12 +- pathfinding/handle/query_path.go | 12 +- pkg/statsviz_serve/statsviz_serve.go | 8 +- 92 files changed, 1429 insertions(+), 287 deletions(-) create mode 100644 cmd/hk4e/node.go create mode 100644 cmd/node/application.toml create mode 100644 cmd/node/main.go rename {gs => common}/constant/action_reason.go (100%) rename {gs => common}/constant/climate_type.go (100%) rename {gs => common}/constant/constant.go (100%) rename {gs => common}/constant/element_type.go (100%) rename {gs => common}/constant/enter_reason.go (100%) rename {gs => common}/constant/entity_id_type.go (100%) rename {gs => common}/constant/entity_type.go (100%) rename {gs => common}/constant/equip_type.go (100%) rename {gs => common}/constant/fetter_state.go (100%) rename {gs => common}/constant/fight_property.go (100%) rename {gs => common}/constant/game_constant.go (100%) rename {gs => common}/constant/grow_curve.go (100%) rename {gs => common}/constant/item_type.go (100%) rename {gs => common}/constant/life_state.go (100%) rename {gs => common}/constant/material_type.go (100%) rename {gs => common}/constant/open_state.go (100%) rename {gs => common}/constant/player_prop.go (100%) rename {gs => common}/constant/scene_type.go (100%) rename {gs => common}/constant/stamina_cost.go (100%) rename {gs => common}/constant/weapon_type.go (100%) create mode 100644 common/rpc/client.go delete mode 100644 gm/rpc_client/client.go create mode 100644 node/api/api.natsrpc.pb.go create mode 100644 node/api/api.pb.go create mode 100644 node/api/api.proto create mode 100644 node/api/server_type.go create mode 100644 node/app/app.go create mode 100644 node/service/discovery.go create mode 100644 node/service/service.go diff --git a/Makefile b/Makefile index 35491979..03f1f9eb 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,10 @@ gen: --go_out=paths=source_relative:gs/api \ --natsrpc_out=paths=source_relative:gs/api \ gs/api/*.proto + protoc \ + --proto_path=node/api \ + --go_out=paths=source_relative:node/api \ + --natsrpc_out=paths=source_relative:node/api \ + node/api/*.proto #cd protocol/proto && make gen - diff --git a/README.md b/README.md index e1adb0e2..aedf648f 100644 --- a/README.md +++ b/README.md @@ -4,19 +4,20 @@ hk4e game server ## 开发快速上手 -* Go >= 1.19 +* Go >= 1.18 1. 首次需要安装工具 `make dev_tool` -1. 生成协议 `make gen` +2. 生成协议 `make gen` ## 快速运行 * mongodb * nats-server -1. 启动http登录服务器 `cmd/dispatch && go run .` -2. 启动网关服务器 `cd cmd/gate && go run .` -3. 启动游戏服务器 `cd cmd/gs && go run .` -4. 启动游戏管理服务器 `cmd/gm && go run .` -5. 启动战斗服务器 `cmd/fight && go run .` -6. 启动寻路服务器 `cmd/pathfinding && go run .` +1. 启动节点服务器 `cmd/node && go run .` +2. 启动http登录服务器 `cmd/dispatch && go run .` +3. 启动网关服务器 `cd cmd/gate && go run .` +4. 启动战斗服务器 `cmd/fight && go run .` +5. 启动寻路服务器 `cmd/pathfinding && go run .` +6. 启动游戏服务器 `cd cmd/gs && go run .` +7. 启动游戏管理服务器 `cmd/gm && go run .` diff --git a/cmd/dispatch/main.go b/cmd/dispatch/main.go index bc703677..1ee7a757 100644 --- a/cmd/dispatch/main.go +++ b/cmd/dispatch/main.go @@ -8,6 +8,7 @@ import ( "os" "hk4e/dispatch/app" + "hk4e/pkg/statsviz_serve" ) var ( @@ -16,7 +17,12 @@ var ( func main() { flag.Parse() - // go statsviz_serve.Serve("0.0.0.0:2345") + go func() { + err := statsviz_serve.Serve("0.0.0.0:2345") + if err != nil { + panic(err) + } + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/cmd/fight/main.go b/cmd/fight/main.go index e3424363..c46728dd 100644 --- a/cmd/fight/main.go +++ b/cmd/fight/main.go @@ -8,6 +8,7 @@ import ( "os" "hk4e/fight/app" + "hk4e/pkg/statsviz_serve" ) var ( @@ -16,7 +17,9 @@ var ( func main() { flag.Parse() - // go statsviz_serve.Serve("0.0.0.0:2345") + go func() { + _ = statsviz_serve.Serve("0.0.0.0:5678") + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/cmd/gate/main.go b/cmd/gate/main.go index 093cbf69..72a99820 100644 --- a/cmd/gate/main.go +++ b/cmd/gate/main.go @@ -17,7 +17,9 @@ var ( func main() { flag.Parse() - go statsviz_serve.Serve("0.0.0.0:2345") + go func() { + _ = statsviz_serve.Serve("0.0.0.0:3456") + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/cmd/gm/main.go b/cmd/gm/main.go index 198a1e84..3b0f231d 100644 --- a/cmd/gm/main.go +++ b/cmd/gm/main.go @@ -4,9 +4,11 @@ import ( "context" "flag" "fmt" + _ "net/http/pprof" "os" "hk4e/gm/app" + "hk4e/pkg/statsviz_serve" ) var ( @@ -15,6 +17,12 @@ var ( func main() { flag.Parse() + go func() { + err := statsviz_serve.Serve("0.0.0.0:7890") + if err != nil { + panic(err) + } + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/cmd/gs/main.go b/cmd/gs/main.go index c671e18e..f6deeb0f 100644 --- a/cmd/gs/main.go +++ b/cmd/gs/main.go @@ -17,7 +17,9 @@ var ( func main() { flag.Parse() - go statsviz_serve.Serve("0.0.0.0:3456") + go func() { + _ = statsviz_serve.Serve("0.0.0.0:4567") + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/cmd/hk4e/node.go b/cmd/hk4e/node.go new file mode 100644 index 00000000..55eef015 --- /dev/null +++ b/cmd/hk4e/node.go @@ -0,0 +1,23 @@ +package main + +import ( + "context" + + "hk4e/node/app" + + "github.com/spf13/cobra" +) + +// NodeCmd 检查配表命令 +func NodeCmd() *cobra.Command { + var cfg string + c := &cobra.Command{ + Use: "node", + Short: "node server", + RunE: func(cmd *cobra.Command, args []string) error { + return app.Run(context.Background(), cfg) + }, + } + c.Flags().StringVar(&cfg, "config", "application.toml", "config file") + return c +} diff --git a/cmd/node/application.toml b/cmd/node/application.toml new file mode 100644 index 00000000..f19adaf2 --- /dev/null +++ b/cmd/node/application.toml @@ -0,0 +1,12 @@ +[hk4e] +kcp_addr = "127.0.0.1" +kcp_port = 22103 + +[logger] +level = "DEBUG" +mode = "BOTH" +track = true +max_size = 10485760 + +[mq] +nats_url = "nats://nats:4222" diff --git a/cmd/node/main.go b/cmd/node/main.go new file mode 100644 index 00000000..c60d2655 --- /dev/null +++ b/cmd/node/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "flag" + "fmt" + _ "net/http/pprof" + "os" + + "hk4e/node/app" + "hk4e/pkg/statsviz_serve" +) + +var ( + config = flag.String("config", "application.toml", "config file") +) + +func main() { + flag.Parse() + go func() { + err := statsviz_serve.Serve("0.0.0.0:1234") + if err != nil { + panic(err) + } + }() + err := app.Run(context.TODO(), *config) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/cmd/pathfinding/main.go b/cmd/pathfinding/main.go index 005cf18f..94428424 100644 --- a/cmd/pathfinding/main.go +++ b/cmd/pathfinding/main.go @@ -8,6 +8,7 @@ import ( "os" "hk4e/pathfinding/app" + "hk4e/pkg/statsviz_serve" ) var ( @@ -16,7 +17,9 @@ var ( func main() { flag.Parse() - // go statsviz_serve.Serve("0.0.0.0:2345") + go func() { + _ = statsviz_serve.Serve("0.0.0.0:6789") + }() err := app.Run(context.TODO(), *config) if err != nil { fmt.Println(err) diff --git a/gs/constant/action_reason.go b/common/constant/action_reason.go similarity index 100% rename from gs/constant/action_reason.go rename to common/constant/action_reason.go diff --git a/gs/constant/climate_type.go b/common/constant/climate_type.go similarity index 100% rename from gs/constant/climate_type.go rename to common/constant/climate_type.go diff --git a/gs/constant/constant.go b/common/constant/constant.go similarity index 100% rename from gs/constant/constant.go rename to common/constant/constant.go diff --git a/gs/constant/element_type.go b/common/constant/element_type.go similarity index 100% rename from gs/constant/element_type.go rename to common/constant/element_type.go diff --git a/gs/constant/enter_reason.go b/common/constant/enter_reason.go similarity index 100% rename from gs/constant/enter_reason.go rename to common/constant/enter_reason.go diff --git a/gs/constant/entity_id_type.go b/common/constant/entity_id_type.go similarity index 100% rename from gs/constant/entity_id_type.go rename to common/constant/entity_id_type.go diff --git a/gs/constant/entity_type.go b/common/constant/entity_type.go similarity index 100% rename from gs/constant/entity_type.go rename to common/constant/entity_type.go diff --git a/gs/constant/equip_type.go b/common/constant/equip_type.go similarity index 100% rename from gs/constant/equip_type.go rename to common/constant/equip_type.go diff --git a/gs/constant/fetter_state.go b/common/constant/fetter_state.go similarity index 100% rename from gs/constant/fetter_state.go rename to common/constant/fetter_state.go diff --git a/gs/constant/fight_property.go b/common/constant/fight_property.go similarity index 100% rename from gs/constant/fight_property.go rename to common/constant/fight_property.go diff --git a/gs/constant/game_constant.go b/common/constant/game_constant.go similarity index 100% rename from gs/constant/game_constant.go rename to common/constant/game_constant.go diff --git a/gs/constant/grow_curve.go b/common/constant/grow_curve.go similarity index 100% rename from gs/constant/grow_curve.go rename to common/constant/grow_curve.go diff --git a/gs/constant/item_type.go b/common/constant/item_type.go similarity index 100% rename from gs/constant/item_type.go rename to common/constant/item_type.go diff --git a/gs/constant/life_state.go b/common/constant/life_state.go similarity index 100% rename from gs/constant/life_state.go rename to common/constant/life_state.go diff --git a/gs/constant/material_type.go b/common/constant/material_type.go similarity index 100% rename from gs/constant/material_type.go rename to common/constant/material_type.go diff --git a/gs/constant/open_state.go b/common/constant/open_state.go similarity index 100% rename from gs/constant/open_state.go rename to common/constant/open_state.go diff --git a/gs/constant/player_prop.go b/common/constant/player_prop.go similarity index 100% rename from gs/constant/player_prop.go rename to common/constant/player_prop.go diff --git a/gs/constant/scene_type.go b/common/constant/scene_type.go similarity index 100% rename from gs/constant/scene_type.go rename to common/constant/scene_type.go diff --git a/gs/constant/stamina_cost.go b/common/constant/stamina_cost.go similarity index 100% rename from gs/constant/stamina_cost.go rename to common/constant/stamina_cost.go diff --git a/gs/constant/weapon_type.go b/common/constant/weapon_type.go similarity index 100% rename from gs/constant/weapon_type.go rename to common/constant/weapon_type.go diff --git a/common/mq/nats.go b/common/mq/nats.go index 9d624cd8..5b2cf5b7 100644 --- a/common/mq/nats.go +++ b/common/mq/nats.go @@ -10,12 +10,20 @@ import ( pb "google.golang.org/protobuf/proto" ) +// 用于服务器之间传输游戏协议 +// 仅用于传递数据平面(client<--->server)和控制平面(server<--->server)的消息 +// 目前是全部消息都走NATS 之后可以做优化服务器之间socket直连 +// 请不要用这个来搞RPC写一大堆异步回调!!! +// 要用RPC有专门的NATSRPC + type MessageQueue struct { natsConn *nats.Conn natsMsgChan chan *nats.Msg netMsgInput chan *NetMsg netMsgOutput chan *NetMsg cmdProtoMap *cmd.CmdProtoMap + serverType string + appId string } func NewMessageQueue(serverType string, appId string) (r *MessageQueue) { @@ -35,6 +43,8 @@ func NewMessageQueue(serverType string, appId string) (r *MessageQueue) { r.netMsgInput = make(chan *NetMsg, 1000) r.netMsgOutput = make(chan *NetMsg, 1000) r.cmdProtoMap = cmd.NewCmdProtoMap() + r.serverType = serverType + r.appId = appId go r.recvHandler() go r.sendHandler() return r diff --git a/common/mq/net_msg.go b/common/mq/net_msg.go index ff73266f..cda505da 100644 --- a/common/mq/net_msg.go +++ b/common/mq/net_msg.go @@ -9,12 +9,14 @@ const ( ) type NetMsg struct { - MsgType uint8 `msgpack:"MsgType"` - EventId uint16 `msgpack:"EventId"` - Topic string `msgpack:"-"` - GameMsg *GameMsg `msgpack:"GameMsg"` - FightMsg *FightMsg `msgpack:"FightMsg"` - ConnCtrlMsg *ConnCtrlMsg `msgpack:"ConnCtrlMsg"` + MsgType uint8 `msgpack:"MsgType"` + EventId uint16 `msgpack:"EventId"` + Topic string `msgpack:"-"` + GameMsg *GameMsg `msgpack:"GameMsg"` + FightMsg *FightMsg `msgpack:"FightMsg"` + ConnCtrlMsg *ConnCtrlMsg `msgpack:"ConnCtrlMsg"` + OriginServerType string `msgpack:"OriginServerType"` + OriginServerAppId string `msgpack:"OriginServerAppId"` } const ( @@ -33,15 +35,17 @@ type GameMsg struct { const ( ClientRttNotify = iota ClientTimeNotify + FightServerSelectNotify KickPlayerNotify ) type ConnCtrlMsg struct { - UserId uint32 `msgpack:"UserId"` - ClientRtt uint32 `msgpack:"ClientRtt"` - ClientTime uint32 `msgpack:"ClientTime"` - KickUserId uint32 `msgpack:"KickUserId"` - KickReason uint32 `msgpack:"KickReason"` + UserId uint32 `msgpack:"UserId"` + ClientRtt uint32 `msgpack:"ClientRtt"` + ClientTime uint32 `msgpack:"ClientTime"` + FightServerAppId string `msgpack:"FightServerAppId"` + KickUserId uint32 `msgpack:"KickUserId"` + KickReason uint32 `msgpack:"KickReason"` } const ( @@ -52,9 +56,10 @@ const ( ) type FightMsg struct { - FightRoutineId uint32 `msgpack:"FightRoutineId"` - EntityId uint32 `msgpack:"EntityId"` - FightPropMap map[uint32]float32 `msgpack:"FightPropMap"` - Uid uint32 `msgpack:"Uid"` - AvatarGuid uint64 `msgpack:"AvatarGuid"` + FightRoutineId uint32 `msgpack:"FightRoutineId"` + EntityId uint32 `msgpack:"EntityId"` + FightPropMap map[uint32]float32 `msgpack:"FightPropMap"` + Uid uint32 `msgpack:"Uid"` + AvatarGuid uint64 `msgpack:"AvatarGuid"` + GateServerAppId string `msgpack:"GateServerAppId"` } diff --git a/common/mq/topic.go b/common/mq/topic.go index 2e6d7088..d4a92a94 100644 --- a/common/mq/topic.go +++ b/common/mq/topic.go @@ -1,37 +1,48 @@ package mq import ( - "strings" + "hk4e/node/api" ) -const ( - GATE = "GATE_${APPID}_HK4E" - GS = "GS_${APPID}_HK4E" - FIGHT = "FIGHT_${APPID}_HK4E" - PATHFINDING = "PATHFINDING_${APPID}_HK4E" -) +func (m *MessageQueue) getOriginServer() (originServerType string, originServerAppId string) { + originServerType = m.serverType + originServerAppId = m.appId + return originServerType, originServerAppId +} func (m *MessageQueue) getTopic(serverType string, appId string) string { - topic := strings.ReplaceAll(serverType, "${APPID}", appId) + topic := serverType + "_" + appId + "_" + "HK4E" return topic } func (m *MessageQueue) SendToGate(appId string, netMsg *NetMsg) { - netMsg.Topic = m.getTopic(GATE, appId) + netMsg.Topic = m.getTopic(api.GATE, appId) + originServerType, originServerAppId := m.getOriginServer() + netMsg.OriginServerType = originServerType + netMsg.OriginServerAppId = originServerAppId m.netMsgInput <- netMsg } func (m *MessageQueue) SendToGs(appId string, netMsg *NetMsg) { - netMsg.Topic = m.getTopic(GS, appId) + netMsg.Topic = m.getTopic(api.GS, appId) + originServerType, originServerAppId := m.getOriginServer() + netMsg.OriginServerType = originServerType + netMsg.OriginServerAppId = originServerAppId m.netMsgInput <- netMsg } func (m *MessageQueue) SendToFight(appId string, netMsg *NetMsg) { - netMsg.Topic = m.getTopic(FIGHT, appId) + netMsg.Topic = m.getTopic(api.FIGHT, appId) + originServerType, originServerAppId := m.getOriginServer() + netMsg.OriginServerType = originServerType + netMsg.OriginServerAppId = originServerAppId m.netMsgInput <- netMsg } func (m *MessageQueue) SendToPathfinding(appId string, netMsg *NetMsg) { - netMsg.Topic = m.getTopic(PATHFINDING, appId) + netMsg.Topic = m.getTopic(api.PATHFINDING, appId) + originServerType, originServerAppId := m.getOriginServer() + netMsg.OriginServerType = originServerType + netMsg.OriginServerAppId = originServerAppId m.netMsgInput <- netMsg } diff --git a/common/region/region.go b/common/region/region.go index d6b43f54..4ef4a5c8 100644 --- a/common/region/region.go +++ b/common/region/region.go @@ -33,8 +33,11 @@ func LoadRsaKey() (signRsaKey []byte, encRsaKeyMap map[string][]byte, pwdRsaKey return signRsaKey, encRsaKeyMap, pwdRsaKey } -func InitRegion(kcpAddr string, kcpPort int32) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) { +func InitRegion(kcpAddr string, kcpPort int32, ec2b *random.Ec2b) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) { dispatchEc2b := random.NewEc2b() + if ec2b != nil { + dispatchEc2b = ec2b + } dispatchEc2bData := dispatchEc2b.Bytes() dispatchXorKey := dispatchEc2b.XorKey() // RegionCurr diff --git a/common/rpc/client.go b/common/rpc/client.go new file mode 100644 index 00000000..15a996e5 --- /dev/null +++ b/common/rpc/client.go @@ -0,0 +1,81 @@ +package rpc + +import ( + "hk4e/common/config" + gsapi "hk4e/gs/api" + nodeapi "hk4e/node/api" + + "github.com/nats-io/nats.go" + "github.com/nats-io/nats.go/encoders/protobuf" +) + +// Client natsrpc客户端 +type Client struct { + conn *nats.Conn + Discovery *DiscoveryClient + GM *GMClient +} + +// NewClient 构造 +func NewClient() (*Client, error) { + r := new(Client) + conn, err := nats.Connect(config.CONF.MQ.NatsUrl) + if err != nil { + return nil, err + } + r.conn = conn + discoveryClient, err := newDiscoveryClient(conn) + if err != nil { + return nil, err + } + r.Discovery = discoveryClient + gmClient, err := newGmClient(conn) + if err != nil { + return nil, err + } + r.GM = gmClient + return r, nil +} + +// Close 销毁 +func (c *Client) Close() { + c.conn.Close() +} + +// DiscoveryClient node的discovery服务 +type DiscoveryClient struct { + nodeapi.DiscoveryNATSRPCClient +} + +func newDiscoveryClient(conn *nats.Conn) (*DiscoveryClient, error) { + enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER) + if err != nil { + return nil, err + } + cli, err := nodeapi.NewDiscoveryNATSRPCClient(enc) + if err != nil { + return nil, err + } + return &DiscoveryClient{ + DiscoveryNATSRPCClient: cli, + }, nil +} + +// GMClient gs的gm服务 +type GMClient struct { + gsapi.GMNATSRPCClient +} + +func newGmClient(conn *nats.Conn) (*GMClient, error) { + enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER) + if err != nil { + return nil, err + } + cli, err := gsapi.NewGMNATSRPCClient(enc) + if err != nil { + return nil, err + } + return &GMClient{ + GMNATSRPCClient: cli, + }, nil +} diff --git a/dispatch/app/app.go b/dispatch/app/app.go index c289b805..3d6e778f 100644 --- a/dispatch/app/app.go +++ b/dispatch/app/app.go @@ -9,6 +9,7 @@ import ( "time" "hk4e/common/config" + "hk4e/common/rpc" "hk4e/dispatch/controller" "hk4e/dispatch/dao" "hk4e/pkg/logger" @@ -23,7 +24,12 @@ func Run(ctx context.Context, configFile string) error { db := dao.NewDao() defer db.CloseDao() - _ = controller.NewController(db) + client, err := rpc.NewClient() + if err != nil { + return err + } + + _ = controller.NewController(db, client.Discovery) c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) diff --git a/dispatch/controller/controller.go b/dispatch/controller/controller.go index ce0ea65a..c1ff034c 100644 --- a/dispatch/controller/controller.go +++ b/dispatch/controller/controller.go @@ -1,13 +1,16 @@ package controller import ( + "context" "encoding/base64" "net/http" "strconv" "hk4e/common/config" "hk4e/common/region" + "hk4e/common/rpc" "hk4e/dispatch/dao" + "hk4e/node/api" "hk4e/pkg/logger" "hk4e/pkg/random" @@ -17,22 +20,32 @@ import ( type Controller struct { dao *dao.Dao + discovery *rpc.DiscoveryClient regionListBase64 string regionCurrBase64 string signRsaKey []byte encRsaKeyMap map[string][]byte pwdRsaKey []byte - dispatchEc2b *random.Ec2b } -func NewController(dao *dao.Dao) (r *Controller) { +func NewController(dao *dao.Dao, discovery *rpc.DiscoveryClient) (r *Controller) { r = new(Controller) r.dao = dao + r.discovery = discovery r.regionListBase64 = "" r.regionCurrBase64 = "" - regionCurr, regionList, dispatchEc2b := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort) - r.dispatchEc2b = dispatchEc2b r.signRsaKey, r.encRsaKeyMap, r.pwdRsaKey = region.LoadRsaKey() + rsp, err := r.discovery.GetRegionEc2B(context.TODO(), &api.NullMsg{}) + if err != nil { + logger.Error("get region ec2b error: %v", err) + return nil + } + ec2b, err := random.LoadEc2bKey(rsp.Data) + if err != nil { + logger.Error("parse region ec2b error: %v", err) + return nil + } + regionCurr, regionList, _ := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort, ec2b) regionCurrModify, err := pb.Marshal(regionCurr) if err != nil { logger.Error("Marshal QueryCurrRegionHttpRsp error") @@ -143,7 +156,6 @@ func (c *Controller) registerRouter() { } engine.Use(c.authorize()) engine.POST("/gate/token/verify", c.gateTokenVerify) - engine.GET("/dispatch/ec2b/seed", c.getDispatchEc2bSeed) port := config.CONF.HttpPort addr := ":" + strconv.Itoa(int(port)) err := engine.Run(addr) diff --git a/dispatch/controller/gate_controller.go b/dispatch/controller/gate_controller.go index dd94ddca..62b1ee30 100644 --- a/dispatch/controller/gate_controller.go +++ b/dispatch/controller/gate_controller.go @@ -49,14 +49,3 @@ func (c *Controller) gateTokenVerify(context *gin.Context) { PlayerID: uint32(account.PlayerID), }) } - -type DispatchEc2bSeedRsp struct { - Seed string `json:"seed"` -} - -func (c *Controller) getDispatchEc2bSeed(context *gin.Context) { - dispatchEc2bSeed := c.dispatchEc2b.Seed() - context.JSON(http.StatusOK, &DispatchEc2bSeedRsp{ - Seed: strconv.FormatUint(dispatchEc2bSeed, 10), - }) -} diff --git a/fight/app/app.go b/fight/app/app.go index 9c392ca3..7e4e4f44 100644 --- a/fight/app/app.go +++ b/fight/app/app.go @@ -9,21 +9,40 @@ import ( "time" "hk4e/common/config" + "hk4e/common/constant" "hk4e/common/mq" + "hk4e/common/rpc" "hk4e/fight/engine" - "hk4e/gs/constant" + "hk4e/node/api" "hk4e/pkg/logger" ) +var APPID string + func Run(ctx context.Context, configFile string) error { config.InitConfig(configFile) - logger.InitLogger("fight") - logger.Warn("fight start") + // natsrpc client + client, err := rpc.NewClient() + if err != nil { + return err + } + + // 注册到节点服务器 + rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{ + ServerType: api.FIGHT, + }) + if err != nil { + return err + } + APPID = rsp.GetAppId() + + logger.InitLogger("fight_" + APPID) + logger.Warn("fight start, appid: %v", APPID) constant.InitConstant() - messageQueue := mq.NewMessageQueue(mq.FIGHT, "1") + messageQueue := mq.NewMessageQueue(api.FIGHT, APPID) defer messageQueue.Close() _ = engine.NewFightEngine(messageQueue) @@ -38,7 +57,7 @@ func Run(ctx context.Context, configFile string) error { logger.Warn("get a signal %s", s.String()) switch s { case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: - logger.Warn("fight exit") + logger.Warn("fight exit, appid: %v", APPID) time.Sleep(time.Second) return nil case syscall.SIGHUP: diff --git a/fight/engine/fight_engine.go b/fight/engine/fight_engine.go index 4c0c7aa6..a9ce4269 100644 --- a/fight/engine/fight_engine.go +++ b/fight/engine/fight_engine.go @@ -3,8 +3,8 @@ package engine import ( "time" + "hk4e/common/constant" "hk4e/common/mq" - "hk4e/gs/constant" "hk4e/pkg/logger" "hk4e/protocol/cmd" "hk4e/protocol/proto" @@ -29,16 +29,24 @@ func (f *FightEngine) fightHandle() { userIdFightRoutineIdMap := make(map[uint32]uint32) for { netMsg := <-f.messageQueue.GetNetMsg() - // logger.Debug("recv net msg, netMsg: %v", netMsg) + logger.Debug("recv net msg, netMsg: %v", netMsg) switch netMsg.MsgType { case mq.MsgTypeGame: gameMsg := netMsg.GameMsg if netMsg.EventId != mq.NormalMsg { continue } - // logger.Debug("recv game msg, gameMsg: %v", gameMsg) - fightRoutineId := userIdFightRoutineIdMap[gameMsg.UserId] - fightRoutineMsgChan := fightRoutineMsgChanMap[fightRoutineId] + logger.Debug("recv game msg, gameMsg: %v", gameMsg) + fightRoutineId, exist := userIdFightRoutineIdMap[gameMsg.UserId] + if !exist { + logger.Error("could not found fight routine id by uid: %v", gameMsg.UserId) + continue + } + fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightRoutineId] + if !exist { + logger.Error("could not found fight routine msg chan by fight routine id: %v", fightRoutineId) + continue + } fightRoutineMsgChan <- netMsg case mq.MsgTypeFight: fightMsg := netMsg.FightMsg @@ -49,21 +57,33 @@ func (f *FightEngine) fightHandle() { fightRoutineMsgChanMap[fightMsg.FightRoutineId] = fightRoutineMsgChan fightRoutineCloseChan := make(chan bool, 1) fightRoutineCloseChanMap[fightMsg.FightRoutineId] = fightRoutineCloseChan - go runFightRoutine(fightMsg.FightRoutineId, fightRoutineMsgChan, fightRoutineCloseChan, f.messageQueue) + go runFightRoutine(fightMsg.FightRoutineId, fightMsg.GateServerAppId, fightRoutineMsgChan, fightRoutineCloseChan, f.messageQueue) case mq.DelFightRoutine: - fightRoutineCloseChan := fightRoutineCloseChanMap[fightMsg.FightRoutineId] + fightRoutineCloseChan, exist := fightRoutineCloseChanMap[fightMsg.FightRoutineId] + if !exist { + logger.Error("could not found fight routine close chan by fight routine id: %v", fightMsg.FightRoutineId) + continue + } fightRoutineCloseChan <- true case mq.FightRoutineAddEntity: if fightMsg.Uid != 0 { userIdFightRoutineIdMap[fightMsg.Uid] = fightMsg.FightRoutineId } - fightRoutineMsgChan := fightRoutineMsgChanMap[fightMsg.FightRoutineId] + fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightMsg.FightRoutineId] + if !exist { + logger.Error("could not found fight routine msg chan by fight routine id: %v", fightMsg.FightRoutineId) + continue + } fightRoutineMsgChan <- netMsg case mq.FightRoutineDelEntity: if fightMsg.Uid != 0 { delete(userIdFightRoutineIdMap, fightMsg.Uid) } - fightRoutineMsgChan := fightRoutineMsgChanMap[fightMsg.FightRoutineId] + fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightMsg.FightRoutineId] + if !exist { + logger.Error("could not found fight routine msg chan by fight routine id: %v", fightMsg.FightRoutineId) + continue + } fightRoutineMsgChan <- netMsg } } @@ -71,7 +91,7 @@ func (f *FightEngine) fightHandle() { } // SendMsg 发送消息给客户端 -func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, payloadMsg pb.Message) { +func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, gateAppId string, payloadMsg pb.Message) { if userId < 100000000 || payloadMsg == nil { return } @@ -86,7 +106,7 @@ func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, payload return } gameMsg.PayloadMessageData = payloadMessageData - messageQueue.SendToGate("1", &mq.NetMsg{ + messageQueue.SendToGate(gateAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, @@ -106,14 +126,16 @@ type FightRoutine struct { entityMap map[uint32]*Entity combatInvokeEntryList []*proto.CombatInvokeEntry tickCount uint64 + gateAppId string } -func runFightRoutine(fightRoutineId uint32, fightRoutineMsgChan chan *mq.NetMsg, fightRoutineCloseChan chan bool, messageQueue *mq.MessageQueue) { +func runFightRoutine(fightRoutineId uint32, gateAppId string, fightRoutineMsgChan chan *mq.NetMsg, fightRoutineCloseChan chan bool, messageQueue *mq.MessageQueue) { f := new(FightRoutine) f.messageQueue = messageQueue f.entityMap = make(map[uint32]*Entity) f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0) f.tickCount = 0 + f.gateAppId = gateAppId logger.Debug("create fight routine, fightRoutineId: %v", fightRoutineId) ticker := time.NewTicker(time.Millisecond * 10) for { @@ -162,7 +184,7 @@ func (f *FightRoutine) onTick50MilliSecond(now int64) { combatInvocationsNotifyAll := new(proto.CombatInvocationsNotify) combatInvocationsNotifyAll.InvokeList = f.combatInvokeEntryList for _, uid := range f.getAllPlayer(f.entityMap) { - SendMsg(f.messageQueue, cmd.CombatInvocationsNotify, uid, combatInvocationsNotifyAll) + SendMsg(f.messageQueue, cmd.CombatInvocationsNotify, uid, f.gateAppId, combatInvocationsNotifyAll) } f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0) } @@ -180,7 +202,7 @@ func (f *FightRoutine) onTickSecond(now int64) { AvatarGuid: entity.avatarGuid, FightPropMap: entity.fightPropMap, } - SendMsg(f.messageQueue, cmd.AvatarFightPropNotify, entity.uid, avatarFightPropNotify) + SendMsg(f.messageQueue, cmd.AvatarFightPropNotify, entity.uid, f.gateAppId, avatarFightPropNotify) } } @@ -231,7 +253,7 @@ func (f *FightRoutine) attackHandle(gameMsg *mq.GameMsg) { entityFightPropUpdateNotify.FightPropMap = make(map[uint32]float32) entityFightPropUpdateNotify.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)] = currHp for _, uid := range f.getAllPlayer(f.entityMap) { - SendMsg(f.messageQueue, cmd.EntityFightPropUpdateNotify, uid, entityFightPropUpdateNotify) + SendMsg(f.messageQueue, cmd.EntityFightPropUpdateNotify, uid, f.gateAppId, entityFightPropUpdateNotify) } combatData, err := pb.Marshal(hitInfo) if err != nil { diff --git a/gate/app/app.go b/gate/app/app.go index 0f66700d..082118c6 100644 --- a/gate/app/app.go +++ b/gate/app/app.go @@ -10,19 +10,38 @@ import ( "hk4e/common/config" "hk4e/common/mq" + "hk4e/common/rpc" "hk4e/gate/net" + "hk4e/node/api" "hk4e/pkg/logger" ) +var APPID string + func Run(ctx context.Context, configFile string) error { config.InitConfig(configFile) - logger.InitLogger("gate") - logger.Warn("gate start") + // natsrpc client + client, err := rpc.NewClient() + if err != nil { + return err + } - messageQueue := mq.NewMessageQueue(mq.GATE, "1") + // 注册到节点服务器 + rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{ + ServerType: api.GATE, + }) + if err != nil { + return err + } + APPID = rsp.GetAppId() - connectManager := net.NewKcpConnectManager(messageQueue) + logger.InitLogger("gate_" + APPID) + logger.Warn("gate start, appid: %v", APPID) + + messageQueue := mq.NewMessageQueue(api.GATE, APPID) + + connectManager := net.NewKcpConnectManager(messageQueue, client.Discovery) connectManager.Start() defer connectManager.Stop() @@ -43,7 +62,7 @@ func Run(ctx context.Context, configFile string) error { logger.Warn("get a signal %s", s.String()) switch s { case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: - logger.Warn("gate exit") + logger.Warn("gate exit, appid: %v", APPID) time.Sleep(time.Second) return nil case syscall.SIGHUP: diff --git a/gate/net/forward.go b/gate/net/forward.go index 35c5445f..05ad5f6c 100644 --- a/gate/net/forward.go +++ b/gate/net/forward.go @@ -2,6 +2,7 @@ package net import ( "bytes" + "context" "encoding/base64" "encoding/binary" "fmt" @@ -13,6 +14,7 @@ import ( "hk4e/common/mq" "hk4e/dispatch/controller" "hk4e/gate/kcp" + "hk4e/node/api" "hk4e/pkg/endec" "hk4e/pkg/httpclient" "hk4e/pkg/logger" @@ -80,25 +82,25 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session) if connState != ConnActive { return } - // 通知GS玩家客户端的本地时钟 - connCtrlMsg := new(mq.ConnCtrlMsg) - connCtrlMsg.UserId = userId - connCtrlMsg.ClientTime = pingReq.ClientTime - k.messageQueue.SendToGs("1", &mq.NetMsg{ - MsgType: mq.MsgTypeConnCtrl, - EventId: mq.ClientTimeNotify, - ConnCtrlMsg: connCtrlMsg, - }) // 通知GS玩家客户端往返时延 rtt := session.conn.GetSRTT() - connCtrlMsg = new(mq.ConnCtrlMsg) + connCtrlMsg := new(mq.ConnCtrlMsg) connCtrlMsg.UserId = userId connCtrlMsg.ClientRtt = uint32(rtt) - k.messageQueue.SendToGs("1", &mq.NetMsg{ + k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{ MsgType: mq.MsgTypeConnCtrl, EventId: mq.ClientRttNotify, ConnCtrlMsg: connCtrlMsg, }) + // 通知GS玩家客户端的本地时钟 + connCtrlMsg = new(mq.ConnCtrlMsg) + connCtrlMsg.UserId = userId + connCtrlMsg.ClientTime = pingReq.ClientTime + k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{ + MsgType: mq.MsgTypeConnCtrl, + EventId: mq.ClientTimeNotify, + ConnCtrlMsg: connCtrlMsg, + }) default: if connState != ConnActive && !(protoMsg.CmdId == cmd.PlayerLoginReq || protoMsg.CmdId == cmd.SetPlayerBornDataReq) { logger.Error("conn not active so drop packet, cmdId: %v, userId: %v, convId: %v", protoMsg.CmdId, userId, protoMsg.ConvId) @@ -106,12 +108,15 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session) } // 只转发到寻路服务器 if protoMsg.CmdId == cmd.QueryPathReq || protoMsg.CmdId == cmd.ObstacleModifyNotify { + if session.pathfindingServerAppId == "" { + return + } gameMsg := new(mq.GameMsg) gameMsg.UserId = userId gameMsg.CmdId = protoMsg.CmdId gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId gameMsg.PayloadMessage = protoMsg.PayloadMessage - k.messageQueue.SendToPathfinding("1", &mq.NetMsg{ + k.messageQueue.SendToPathfinding(session.pathfindingServerAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, @@ -119,13 +124,13 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session) return } // 同时转发到战斗服务器 - if protoMsg.CmdId == cmd.CombatInvocationsNotify { + if protoMsg.CmdId == cmd.CombatInvocationsNotify && session.fightServerAppId != "" { gameMsg := new(mq.GameMsg) gameMsg.UserId = userId gameMsg.CmdId = protoMsg.CmdId gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId gameMsg.PayloadMessage = protoMsg.PayloadMessage - k.messageQueue.SendToFight("1", &mq.NetMsg{ + k.messageQueue.SendToFight(session.fightServerAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, @@ -137,7 +142,7 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session) gameMsg.CmdId = protoMsg.CmdId gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId gameMsg.PayloadMessage = protoMsg.PayloadMessage - k.messageQueue.SendToGs("1", &mq.NetMsg{ + k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, @@ -269,6 +274,32 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session session.userId = tokenVerifyRsp.PlayerID k.SetSession(session, session.conn.GetConv(), session.userId) k.createSessionChan <- session + // 绑定各个服务器appid + gsServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{ + ServerType: api.GS, + }) + if err != nil { + logger.Error("get gs server appid error: %v", err) + return nil + } + session.gsServerAppId = gsServerAppId.AppId + fightServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{ + ServerType: api.FIGHT, + }) + if err != nil { + logger.Error("get fight server appid error: %v", err) + } + session.fightServerAppId = fightServerAppId.AppId + pathfindingServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{ + ServerType: api.PATHFINDING, + }) + if err != nil { + logger.Error("get pathfinding server appid error: %v", err) + } + session.pathfindingServerAppId = pathfindingServerAppId.AppId + logger.Debug("session gs appid: %v", session.gsServerAppId) + logger.Debug("session fight appid: %v", session.fightServerAppId) + logger.Debug("session pathfinding appid: %v", session.pathfindingServerAppId) // 返回响应 rsp = new(proto.GetPlayerTokenRsp) rsp.Uid = tokenVerifyRsp.PlayerID diff --git a/gate/net/kcp_connect_manager.go b/gate/net/kcp_connect_manager.go index 7bd24a42..5d6a9216 100644 --- a/gate/net/kcp_connect_manager.go +++ b/gate/net/kcp_connect_manager.go @@ -2,6 +2,7 @@ package net import ( "bytes" + "context" "encoding/binary" "strconv" "sync" @@ -10,9 +11,9 @@ import ( "hk4e/common/config" "hk4e/common/mq" "hk4e/common/region" - "hk4e/dispatch/controller" + "hk4e/common/rpc" "hk4e/gate/kcp" - "hk4e/pkg/httpclient" + "hk4e/node/api" "hk4e/pkg/logger" "hk4e/pkg/random" "hk4e/protocol/cmd" @@ -21,6 +22,7 @@ import ( const PacketFreqLimit = 1000 type KcpConnectManager struct { + discovery *rpc.DiscoveryClient openState bool sessionConvIdMap map[uint64]*Session sessionUserIdMap map[uint32]*Session @@ -38,8 +40,9 @@ type KcpConnectManager struct { encRsaKeyMap map[string][]byte } -func NewKcpConnectManager(messageQueue *mq.MessageQueue) (r *KcpConnectManager) { +func NewKcpConnectManager(messageQueue *mq.MessageQueue, discovery *rpc.DiscoveryClient) (r *KcpConnectManager) { r = new(KcpConnectManager) + r.discovery = discovery r.openState = true r.sessionConvIdMap = make(map[uint64]*Session) r.sessionUserIdMap = make(map[uint32]*Session) @@ -57,20 +60,19 @@ func (k *KcpConnectManager) Start() { // 读取密钥相关文件 k.signRsaKey, k.encRsaKeyMap, _ = region.LoadRsaKey() // key - dispatchEc2bSeedRsp, err := httpclient.Get[controller.DispatchEc2bSeedRsp]("http://127.0.0.1:8080/dispatch/ec2b/seed", "") + rsp, err := k.discovery.GetRegionEc2B(context.TODO(), &api.NullMsg{}) if err != nil { - logger.Error("get dispatch ec2b seed error: %v", err) + logger.Error("get region ec2b error: %v", err) return } - dispatchEc2bSeed, err := strconv.ParseUint(dispatchEc2bSeedRsp.Seed, 10, 64) + ec2b, err := random.LoadEc2bKey(rsp.Data) if err != nil { - logger.Error("parse dispatch ec2b seed error: %v", err) + logger.Error("parse region ec2b error: %v", err) return } - logger.Debug("get dispatch ec2b seed: %v", dispatchEc2bSeed) - gateDispatchEc2b := random.NewEc2b() - gateDispatchEc2b.SetSeed(dispatchEc2bSeed) - k.dispatchKey = gateDispatchEc2b.XorKey() + regionEc2b := random.NewEc2b() + regionEc2b.SetSeed(ec2b.Seed()) + k.dispatchKey = regionEc2b.XorKey() // kcp port := strconv.Itoa(int(config.CONF.Hk4e.KcpPort)) listener, err := kcp.ListenWithOptions(config.CONF.Hk4e.KcpAddr+":"+port, nil, 0, 0) @@ -201,13 +203,16 @@ func (k *KcpConnectManager) enetHandle(listener *kcp.Listener) { } type Session struct { - conn *kcp.UDPSession - connState uint8 - userId uint32 - kcpRawSendChan chan *ProtoMsg - seed uint64 - xorKey []byte - changeXorKeyFin bool + conn *kcp.UDPSession + connState uint8 + userId uint32 + kcpRawSendChan chan *ProtoMsg + seed uint64 + xorKey []byte + changeXorKeyFin bool + gsServerAppId string + fightServerAppId string + pathfindingServerAppId string } // 接收 @@ -288,6 +293,15 @@ func (k *KcpConnectManager) sendHandle(session *Session) { if protoMsg.CmdId == cmd.PlayerLoginRsp { logger.Debug("session active, convId: %v", convId) session.connState = ConnActive + // 通知GS玩家战斗服务器的appid + connCtrlMsg := new(mq.ConnCtrlMsg) + connCtrlMsg.UserId = session.userId + connCtrlMsg.FightServerAppId = session.fightServerAppId + k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{ + MsgType: mq.MsgTypeConnCtrl, + EventId: mq.FightServerSelectNotify, + ConnCtrlMsg: connCtrlMsg, + }) } } } @@ -328,7 +342,7 @@ func (k *KcpConnectManager) closeKcpConn(session *Session, enetType uint32) { // 通知GS玩家下线 gameMsg := new(mq.GameMsg) gameMsg.UserId = session.userId - k.messageQueue.SendToGs("1", &mq.NetMsg{ + k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.UserOfflineNotify, GameMsg: gameMsg, diff --git a/gm/app/app.go b/gm/app/app.go index dc5d52cc..f18ccc42 100644 --- a/gm/app/app.go +++ b/gm/app/app.go @@ -8,11 +8,9 @@ import ( "time" "hk4e/common/config" + "hk4e/common/rpc" "hk4e/gm/controller" - "hk4e/gm/rpc_client" "hk4e/pkg/logger" - - "github.com/nats-io/nats.go" ) func Run(ctx context.Context, configFile string) error { @@ -21,18 +19,12 @@ func Run(ctx context.Context, configFile string) error { logger.InitLogger("gm") logger.Warn("gm start") - conn, err := nats.Connect(config.CONF.MQ.NatsUrl) + client, err := rpc.NewClient() if err != nil { - logger.Error("connect nats error: %v", err) return err } - defer conn.Close() - rpc, err := rpc_client.New(conn) - if err != nil { - return err - } - _ = controller.NewController(rpc) + _ = controller.NewController(client.GM) c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) diff --git a/gm/controller/controller.go b/gm/controller/controller.go index e7013b68..146998e6 100644 --- a/gm/controller/controller.go +++ b/gm/controller/controller.go @@ -5,19 +5,19 @@ import ( "strconv" "hk4e/common/config" - "hk4e/gm/rpc_client" + "hk4e/common/rpc" "hk4e/pkg/logger" "github.com/gin-gonic/gin" ) type Controller struct { - rpc *rpc_client.Client + gm *rpc.GMClient } -func NewController(rpc *rpc_client.Client) (r *Controller) { +func NewController(gm *rpc.GMClient) (r *Controller) { r = new(Controller) - r.rpc = rpc + r.gm = gm go r.registerRouter() return r } diff --git a/gm/controller/gm_controller.go b/gm/controller/gm_controller.go index f4906653..be72e811 100644 --- a/gm/controller/gm_controller.go +++ b/gm/controller/gm_controller.go @@ -20,7 +20,7 @@ func (c *Controller) gmCmd(context *gin.Context) { if err != nil { return } - rep, err := c.rpc.Cmd(context.Request.Context(), &api.CmdRequest{ + rep, err := c.gm.Cmd(context.Request.Context(), &api.CmdRequest{ FuncName: gmCmdReq.FuncName, Param: gmCmdReq.Param, }) diff --git a/gm/rpc_client/client.go b/gm/rpc_client/client.go deleted file mode 100644 index 388591ec..00000000 --- a/gm/rpc_client/client.go +++ /dev/null @@ -1,29 +0,0 @@ -// Package rpc_client rpc客户端 -package rpc_client - -import ( - "hk4e/gs/api" - - "github.com/nats-io/nats.go" - "github.com/nats-io/nats.go/encoders/protobuf" -) - -// Client rpc客户端 -type Client struct { - api.GMNATSRPCClient -} - -// New 构造 -func New(conn *nats.Conn) (*Client, error) { - enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER) - if err != nil { - return nil, err - } - cli, err := api.NewGMNATSRPCClient(enc) - if err != nil { - return nil, err - } - return &Client{ - GMNATSRPCClient: cli, - }, nil -} diff --git a/go.mod b/go.mod index 7d387a97..c2572395 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module hk4e -go 1.19 +go 1.18 // toml require github.com/BurntSushi/toml v0.3.1 @@ -44,10 +44,11 @@ require github.com/jszwec/csvutil v1.7.1 // hjson require github.com/hjson/hjson-go/v4 v4.2.0 -require ( - github.com/byebyebruce/natsrpc v0.5.5-0.20221125150611-56cd29a4e335 - github.com/spf13/cobra v1.6.1 -) +// natsrpc +require github.com/byebyebruce/natsrpc v0.5.5-0.20221125150611-56cd29a4e335 + +// cobra +require github.com/spf13/cobra v1.6.1 require ( github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/gs/api/api.pb.go b/gs/api/api.pb.go index b0f70d44..701ccee6 100644 --- a/gs/api/api.pb.go +++ b/gs/api/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.14.0 +// protoc v3.7.0 // source: api.proto package api diff --git a/gs/app/app.go b/gs/app/app.go index 332a13f1..fb657315 100644 --- a/gs/app/app.go +++ b/gs/app/app.go @@ -9,57 +9,75 @@ import ( "time" "hk4e/common/config" + "hk4e/common/constant" "hk4e/common/mq" + "hk4e/common/rpc" "hk4e/gdconf" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/gs/dao" "hk4e/gs/game" "hk4e/gs/service" + "hk4e/node/api" "hk4e/pkg/logger" "github.com/nats-io/nats.go" ) +var APPID string + func Run(ctx context.Context, configFile string) error { config.InitConfig(configFile) - logger.InitLogger("gs") - logger.Warn("gs start") + // natsrpc client + client, err := rpc.NewClient() + if err != nil { + return err + } + + // 注册到节点服务器 + rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{ + ServerType: api.GS, + }) + if err != nil { + return err + } + APPID = rsp.GetAppId() + + logger.InitLogger("gs_" + APPID) + logger.Warn("gs start, appid: %v", APPID) constant.InitConstant() gdc.InitGameDataConfig() gdconf.InitGameDataConfig() - conn, err := nats.Connect(config.CONF.MQ.NatsUrl) - if err != nil { - logger.Error("connect nats error: %v", err) - return err - } - defer conn.Close() - db, err := dao.NewDao() if err != nil { panic(err) } defer db.CloseDao() - messageQueue := mq.NewMessageQueue(mq.GS, "1") + messageQueue := mq.NewMessageQueue(api.GS, APPID) defer messageQueue.Close() gameManager := game.NewGameManager(db, messageQueue) defer gameManager.Stop() - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) - + // natsrpc server + conn, err := nats.Connect(config.CONF.MQ.NatsUrl) + if err != nil { + logger.Error("connect nats error: %v", err) + return err + } + defer conn.Close() s, err := service.NewService(conn) if err != nil { return err } defer s.Close() + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) for { select { case <-ctx.Done(): @@ -68,7 +86,7 @@ func Run(ctx context.Context, configFile string) error { logger.Warn("get a signal %s", s.String()) switch s { case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: - logger.Warn("gs exit") + logger.Warn("gs exit, appid: %v", APPID) time.Sleep(time.Second) return nil case syscall.SIGHUP: diff --git a/gs/config/avatar_skill_data.go b/gs/config/avatar_skill_data.go index e9b4b7a8..d00ee27a 100644 --- a/gs/config/avatar_skill_data.go +++ b/gs/config/avatar_skill_data.go @@ -4,7 +4,7 @@ import ( "encoding/json" "os" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/pkg/logger" ) diff --git a/gs/config/avatar_skill_depot_data.go b/gs/config/avatar_skill_depot_data.go index 0f4fdb03..a0695568 100644 --- a/gs/config/avatar_skill_depot_data.go +++ b/gs/config/avatar_skill_depot_data.go @@ -4,7 +4,7 @@ import ( "encoding/json" "os" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/pkg/endec" "hk4e/pkg/logger" ) diff --git a/gs/config/gadget_data.go b/gs/config/gadget_data.go index f773252f..9030454c 100644 --- a/gs/config/gadget_data.go +++ b/gs/config/gadget_data.go @@ -4,7 +4,7 @@ import ( "encoding/json" "os" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/pkg/logger" ) diff --git a/gs/config/item_data.go b/gs/config/item_data.go index f33439ac..5ddf75c3 100644 --- a/gs/config/item_data.go +++ b/gs/config/item_data.go @@ -4,7 +4,7 @@ import ( "encoding/json" "os" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/pkg/logger" ) diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index 5407cdd9..768fe3e7 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -1,7 +1,7 @@ package game import ( - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/gs/model" "hk4e/pkg/logger" ) diff --git a/gs/game/command_manager.go b/gs/game/command_manager.go index 211a598f..164fc96d 100644 --- a/gs/game/command_manager.go +++ b/gs/game/command_manager.go @@ -47,7 +47,8 @@ func NewCommandManager() *CommandManager { r := new(CommandManager) // 创建AI世界 - GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0) + GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0, "") + GAME_MANAGER.FightServerSelectNotify(1, "") r.system = USER_MANAGER.GetOnlineUser(1) r.system.DbState = model.DbNormal r.system.SceneLoadState = model.SceneEnterDone diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index 059c9b86..6aefc172 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -134,17 +134,47 @@ func (g *GameManager) Stop() { for _, player := range userList { g.DisconnectPlayer(player.PlayerID, kcp.EnetServerShutdown) } - time.Sleep(time.Second * 5) + time.Sleep(time.Second * 3) // 保存玩家数据 LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{ EventId: RunUserCopyAndSave, } - time.Sleep(time.Second * 5) + time.Sleep(time.Second * 3) +} + +func (g *GameManager) SendMsgEx(cmdId uint16, userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) { + if userId < 100000000 { + return + } + if payloadMsg == nil { + logger.Error("payload msg is nil") + return + } + gameMsg := &mq.GameMsg{ + UserId: userId, + CmdId: cmdId, + ClientSeq: clientSeq, + PayloadMessage: payloadMsg, + } + g.messageQueue.SendToGate(gateAppId, &mq.NetMsg{ + MsgType: mq.MsgTypeGame, + EventId: mq.NormalMsg, + GameMsg: gameMsg, + }) } // SendMsg 发送消息给客户端 func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, payloadMsg pb.Message) { - if userId < 100000000 || payloadMsg == nil { + if userId < 100000000 { + return + } + if payloadMsg == nil { + logger.Error("payload msg is nil") + return + } + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player not exist, uid: %v", userId) return } gameMsg := new(mq.GameMsg) @@ -158,7 +188,7 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay return } gameMsg.PayloadMessageData = payloadMessageData - g.messageQueue.SendToGate("1", &mq.NetMsg{ + g.messageQueue.SendToGate(player.GateAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, @@ -222,7 +252,11 @@ func (g *GameManager) ReconnectPlayer(userId uint32) { } func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) { - g.messageQueue.SendToGate("1", &mq.NetMsg{ + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + return + } + g.messageQueue.SendToGate(player.GateAppId, &mq.NetMsg{ MsgType: mq.MsgTypeConnCtrl, EventId: mq.KickPlayerNotify, ConnCtrlMsg: &mq.ConnCtrlMsg{ diff --git a/gs/game/local_event_manager.go b/gs/game/local_event_manager.go index bf68668c..4dee0f40 100644 --- a/gs/game/local_event_manager.go +++ b/gs/game/local_event_manager.go @@ -38,10 +38,10 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) { if playerLoginInfo.Player != nil { USER_MANAGER.playerMap[playerLoginInfo.Player.PlayerID] = playerLoginInfo.Player } - GAME_MANAGER.OnLoginOk(playerLoginInfo.UserId, playerLoginInfo.Player, playerLoginInfo.ClientSeq) + GAME_MANAGER.OnLoginOk(playerLoginInfo.UserId, playerLoginInfo.Player, playerLoginInfo.ClientSeq, playerLoginInfo.GateAppId) case CheckUserExistOnRegFromDbFinish: playerRegInfo := localEvent.Msg.(*PlayerRegInfo) - GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq) + GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq, playerRegInfo.GateAppId) case RunUserCopyAndSave: startTime := time.Now().UnixNano() // 拷贝一份数据避免并发访问 diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index 48387a17..f7b23271 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -4,6 +4,7 @@ import ( "hk4e/common/mq" "hk4e/gate/kcp" "hk4e/gs/model" + "hk4e/node/api" "hk4e/pkg/logger" "hk4e/protocol/cmd" @@ -120,15 +121,18 @@ func (r *RouteManager) InitRoute() { func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { switch netMsg.MsgType { case mq.MsgTypeGame: + if netMsg.OriginServerType != api.GATE { + return + } gameMsg := netMsg.GameMsg switch netMsg.EventId { case mq.NormalMsg: if gameMsg.CmdId == cmd.PlayerLoginReq { - GAME_MANAGER.PlayerLoginReq(gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage) + GAME_MANAGER.PlayerLoginReq(gameMsg.UserId, gameMsg.ClientSeq, netMsg.OriginServerAppId, gameMsg.PayloadMessage) return } if gameMsg.CmdId == cmd.SetPlayerBornDataReq { - GAME_MANAGER.SetPlayerBornDataReq(gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage) + GAME_MANAGER.SetPlayerBornDataReq(gameMsg.UserId, gameMsg.ClientSeq, netMsg.OriginServerAppId, gameMsg.PayloadMessage) return } r.doRoute(gameMsg.CmdId, gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage) @@ -136,12 +140,17 @@ func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { GAME_MANAGER.OnUserOffline(gameMsg.UserId) } case mq.MsgTypeConnCtrl: + if netMsg.OriginServerType != api.GATE { + return + } connCtrlMsg := netMsg.ConnCtrlMsg switch netMsg.EventId { case mq.ClientRttNotify: GAME_MANAGER.ClientRttNotify(connCtrlMsg.UserId, connCtrlMsg.ClientRtt) case mq.ClientTimeNotify: GAME_MANAGER.ClientTimeNotify(connCtrlMsg.UserId, connCtrlMsg.ClientTime) + case mq.FightServerSelectNotify: + GAME_MANAGER.FightServerSelectNotify(connCtrlMsg.UserId, connCtrlMsg.FightServerAppId) } } } diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index 14d22223..c49c9c89 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -3,7 +3,7 @@ package game import ( "time" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/random" diff --git a/gs/game/user_avatar.go b/gs/game/user_avatar.go index 1f96c5cf..1ed47a6a 100644 --- a/gs/game/user_avatar.go +++ b/gs/game/user_avatar.go @@ -1,8 +1,8 @@ package game import ( + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/object" diff --git a/gs/game/user_common_handler.go b/gs/game/user_common_handler.go index 9bf514de..d3334b16 100644 --- a/gs/game/user_common_handler.go +++ b/gs/game/user_common_handler.go @@ -3,6 +3,7 @@ package game import ( "time" + "hk4e/common/mq" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/protocol/cmd" @@ -56,6 +57,16 @@ func (g *GameManager) EntityAiSyncNotify(player *model.Player, payloadMsg pb.Mes g.SendMsg(cmd.EntityAiSyncNotify, player.PlayerID, player.ClientSeq, entityAiSyncNotify) } +func (g *GameManager) ClientRttNotify(userId uint32, clientRtt uint32) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + logger.Debug("client rtt notify, uid: %v, rtt: %v", userId, clientRtt) + player.ClientRTT = clientRtt +} + func (g *GameManager) ClientTimeNotify(userId uint32, clientTime uint32) { player := USER_MANAGER.GetOnlineUser(userId) if player == nil { @@ -66,14 +77,29 @@ func (g *GameManager) ClientTimeNotify(userId uint32, clientTime uint32) { player.ClientTime = clientTime } -func (g *GameManager) ClientRttNotify(userId uint32, clientRtt uint32) { +func (g *GameManager) FightServerSelectNotify(userId uint32, fightAppId string) { player := USER_MANAGER.GetOnlineUser(userId) if player == nil { logger.Error("player is nil, uid: %v", userId) return } - logger.Debug("client rtt notify, uid: %v, rtt: %v", userId, clientRtt) - player.ClientRTT = clientRtt + logger.Debug("fight server select notify, uid: %v, fightAppId: %v", userId, fightAppId) + player.FightAppId = fightAppId + // 创建世界 + world := WORLD_MANAGER.CreateWorld(player) + GAME_MANAGER.messageQueue.SendToFight(fightAppId, &mq.NetMsg{ + MsgType: mq.MsgTypeFight, + EventId: mq.AddFightRoutine, + FightMsg: &mq.FightMsg{ + FightRoutineId: world.id, + GateServerAppId: player.GateAppId, + }, + }) + world.AddPlayer(player, player.SceneId) + player.WorldId = world.id + // 进入场景 + player.SceneLoadState = model.SceneNone + g.SendMsg(cmd.PlayerEnterSceneNotify, userId, player.ClientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF)) } func (g *GameManager) ServerAnnounceNotify(announceId uint32, announceMsg string) { diff --git a/gs/game/user_item.go b/gs/game/user_item.go index a07eef97..4effa9de 100644 --- a/gs/game/user_item.go +++ b/gs/game/user_item.go @@ -1,8 +1,8 @@ package game import ( + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/pkg/logger" "hk4e/protocol/cmd" "hk4e/protocol/proto" diff --git a/gs/game/user_login.go b/gs/game/user_login.go index 35c22d8e..fc0351e9 100644 --- a/gs/game/user_login.go +++ b/gs/game/user_login.go @@ -3,8 +3,8 @@ package game import ( "time" + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/reflection" @@ -14,36 +14,38 @@ import ( pb "google.golang.org/protobuf/proto" ) -func (g *GameManager) PlayerLoginReq(userId uint32, clientSeq uint32, payloadMsg pb.Message) { - logger.Info("user login req, uid: %v", userId) +func (g *GameManager) PlayerLoginReq(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) { + logger.Info("user login req, uid: %v, gateAppId: %v", userId, gateAppId) req := payloadMsg.(*proto.PlayerLoginReq) logger.Debug("login data: %v", req) - g.OnLogin(userId, clientSeq) + g.OnLogin(userId, clientSeq, gateAppId) } -func (g *GameManager) SetPlayerBornDataReq(userId uint32, clientSeq uint32, payloadMsg pb.Message) { - logger.Info("user reg req, uid: %v", userId) +func (g *GameManager) SetPlayerBornDataReq(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) { + logger.Info("user reg req, uid: %v, gateAppId: %v", userId, gateAppId) req := payloadMsg.(*proto.SetPlayerBornDataReq) logger.Debug("reg data: %v", req) - g.OnReg(userId, clientSeq, req) + g.OnReg(userId, clientSeq, gateAppId, req) } -func (g *GameManager) OnLogin(userId uint32, clientSeq uint32) { +func (g *GameManager) OnLogin(userId uint32, clientSeq uint32, gateAppId string) { logger.Info("user login, uid: %v", userId) - player, asyncWait := USER_MANAGER.OnlineUser(userId, clientSeq) + player, asyncWait := USER_MANAGER.OnlineUser(userId, clientSeq, gateAppId) if !asyncWait { - g.OnLoginOk(userId, player, clientSeq) + g.OnLoginOk(userId, player, clientSeq, gateAppId) } } -func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq uint32) { +func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq uint32, gateAppId string) { if player == nil { - g.SendMsg(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, new(proto.DoSetPlayerBornDataNotify)) + g.SendMsgEx(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, gateAppId, new(proto.DoSetPlayerBornDataNotify)) return } player.OnlineTime = uint32(time.Now().UnixMilli()) player.Online = true + player.GateAppId = gateAppId + // 初始化 player.InitAll() // player.TeamConfig.UpdateTeam() @@ -53,32 +55,24 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u player.Pos.Y = player.SafePos.Y player.Pos.Z = player.SafePos.Z - // 创建世界 - world := WORLD_MANAGER.CreateWorld(player) - world.AddPlayer(player, player.SceneId) - player.WorldId = world.id - player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]() player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]() g.LoginNotify(userId, player, clientSeq) - - player.SceneLoadState = model.SceneNone - g.SendMsg(cmd.PlayerEnterSceneNotify, userId, clientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF)) } -func (g *GameManager) OnReg(userId uint32, clientSeq uint32, payloadMsg pb.Message) { +func (g *GameManager) OnReg(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) { logger.Debug("user reg, uid: %v", userId) req := payloadMsg.(*proto.SetPlayerBornDataReq) logger.Debug("avatar id: %v, nickname: %v", req.AvatarId, req.NickName) - exist, asyncWait := USER_MANAGER.CheckUserExistOnReg(userId, req, clientSeq) + exist, asyncWait := USER_MANAGER.CheckUserExistOnReg(userId, req, clientSeq, gateAppId) if !asyncWait { - g.OnRegOk(exist, req, userId, clientSeq) + g.OnRegOk(exist, req, userId, clientSeq, gateAppId) } } -func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userId uint32, clientSeq uint32) { +func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userId uint32, clientSeq uint32, gateAppId string) { if exist { logger.Error("recv reg req, but user is already exist, userId: %v", userId) return @@ -98,8 +92,8 @@ func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userI } USER_MANAGER.AddUser(player) - g.SendMsg(cmd.SetPlayerBornDataRsp, userId, clientSeq, new(proto.SetPlayerBornDataRsp)) - g.OnLogin(userId, clientSeq) + g.SendMsgEx(cmd.SetPlayerBornDataRsp, userId, clientSeq, gateAppId, new(proto.SetPlayerBornDataRsp)) + g.OnLogin(userId, clientSeq, gateAppId) } func (g *GameManager) OnUserOffline(userId uint32) { diff --git a/gs/game/user_manager.go b/gs/game/user_manager.go index 1651a593..8eb2de62 100644 --- a/gs/game/user_manager.go +++ b/gs/game/user_manager.go @@ -66,9 +66,10 @@ type PlayerRegInfo struct { Req *proto.SetPlayerBornDataReq UserId uint32 ClientSeq uint32 + GateAppId string } -func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32) (exist bool, asyncWait bool) { +func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32, gateAppId string) (exist bool, asyncWait bool) { _, exist = u.playerMap[userId] if exist { return true, false @@ -86,6 +87,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor Req: req, UserId: userId, ClientSeq: clientSeq, + GateAppId: gateAppId, }, } }() @@ -137,9 +139,10 @@ type PlayerLoginInfo struct { UserId uint32 Player *model.Player ClientSeq uint32 + GateAppId string } -func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player, bool) { +func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32, gateAppId string) (*model.Player, bool) { player, exist := u.playerMap[userId] if exist { u.ChangeUserDbState(player, model.DbNormal) @@ -158,6 +161,7 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player UserId: userId, Player: player, ClientSeq: clientSeq, + GateAppId: gateAppId, }, } }() diff --git a/gs/game/user_map.go b/gs/game/user_map.go index 348683e8..48027657 100644 --- a/gs/game/user_map.go +++ b/gs/game/user_map.go @@ -3,8 +3,7 @@ package game import ( "strconv" - "hk4e/gs/constant" - + "hk4e/common/constant" gdc "hk4e/gs/config" "hk4e/gs/model" "hk4e/pkg/logger" diff --git a/gs/game/user_multiplayer.go b/gs/game/user_multiplayer.go index 1d32c65a..6ecf0d5f 100644 --- a/gs/game/user_multiplayer.go +++ b/gs/game/user_multiplayer.go @@ -3,7 +3,8 @@ package game import ( "time" - "hk4e/gs/constant" + "hk4e/common/constant" + "hk4e/common/mq" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/object" @@ -320,6 +321,13 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player) if world.owner.PlayerID == player.PlayerID { // 房主离开销毁世界 WORLD_MANAGER.DestroyWorld(world.id) + GAME_MANAGER.messageQueue.SendToFight(world.owner.FightAppId, &mq.NetMsg{ + MsgType: mq.MsgTypeFight, + EventId: mq.DelFightRoutine, + FightMsg: &mq.FightMsg{ + FightRoutineId: world.id, + }, + }) return } if world.multiplayer && world.GetWorldPlayerNum() > 0 { diff --git a/gs/game/user_scene.go b/gs/game/user_scene.go index 1967c40a..c07276e4 100644 --- a/gs/game/user_scene.go +++ b/gs/game/user_scene.go @@ -5,8 +5,8 @@ import ( "strconv" "time" + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/object" diff --git a/gs/game/user_shop.go b/gs/game/user_shop.go index 2ba19416..0f952c6e 100644 --- a/gs/game/user_shop.go +++ b/gs/game/user_shop.go @@ -3,7 +3,7 @@ package game import ( "time" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/protocol/cmd" diff --git a/gs/game/user_social.go b/gs/game/user_social.go index c7a44b28..02f4e5d7 100644 --- a/gs/game/user_social.go +++ b/gs/game/user_social.go @@ -5,7 +5,7 @@ import ( "time" "unicode/utf8" - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/object" diff --git a/gs/game/user_stamina.go b/gs/game/user_stamina.go index 66d088e6..437db0b7 100644 --- a/gs/game/user_stamina.go +++ b/gs/game/user_stamina.go @@ -4,8 +4,8 @@ import ( "strings" "time" + "hk4e/common/constant" "hk4e/gdconf" - "hk4e/gs/constant" "hk4e/gs/model" "hk4e/pkg/endec" "hk4e/pkg/logger" @@ -462,7 +462,7 @@ func (g *GameManager) DrownBackHandler(player *model.Player) { } // 获取最近角色实体的锚点 // TODO 阻塞优化 16ms我感觉有点慢 - //for _, entry := range gdc.CONF.ScenePointEntries { + // for _, entry := range gdc.CONF.ScenePointEntries { // if entry.PointData == nil || entry.PointData.TranPos == nil { // continue // } @@ -475,7 +475,7 @@ func (g *GameManager) DrownBackHandler(player *model.Player) { // if player.SafePos.Distance(pointPos) < player.SafePos.Distance(pos) { // pos = pointPos // } - //} + // } // 传送玩家至安全位置 g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, pos) } diff --git a/gs/game/user_team.go b/gs/game/user_team.go index f015a5c9..8fa41d38 100644 --- a/gs/game/user_team.go +++ b/gs/game/user_team.go @@ -1,8 +1,8 @@ package game import ( + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/gs/model" "hk4e/pkg/endec" "hk4e/pkg/logger" diff --git a/gs/game/user_weapon.go b/gs/game/user_weapon.go index bfe87f53..7d19070e 100644 --- a/gs/game/user_weapon.go +++ b/gs/game/user_weapon.go @@ -1,8 +1,8 @@ package game import ( + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/pkg/logger" "hk4e/protocol/cmd" "hk4e/protocol/proto" diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index 7d5ba64f..c3ab5858 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -4,10 +4,10 @@ import ( "math" "time" + "hk4e/common/constant" "hk4e/protocol/cmd" "hk4e/common/mq" - "hk4e/gs/constant" "hk4e/gs/game/aoi" "hk4e/gs/model" "hk4e/pkg/alg" @@ -71,13 +71,6 @@ func (w *WorldManager) CreateWorld(owner *model.Player) *World { } world.mpLevelEntityId = world.GetNextWorldEntityId(constant.EntityIdTypeConst.MPLEVEL) w.worldMap[worldId] = world - GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{ - MsgType: mq.MsgTypeFight, - EventId: mq.AddFightRoutine, - FightMsg: &mq.FightMsg{ - FightRoutineId: world.id, - }, - }) return world } @@ -88,13 +81,6 @@ func (w *WorldManager) DestroyWorld(worldId uint32) { player.WorldId = 0 } delete(w.worldMap, worldId) - GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{ - MsgType: mq.MsgTypeFight, - EventId: mq.DelFightRoutine, - FightMsg: &mq.FightMsg{ - FightRoutineId: world.id, - }, - }) } // GetBigWorld 获取本服务器的AI世界 @@ -715,7 +701,7 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32 if avatarId == s.world.GetPlayerActiveAvatarId(player) { s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z)) } - GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{ + GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{ MsgType: mq.MsgTypeFight, EventId: mq.FightRoutineAddEntity, FightMsg: &mq.FightMsg{ @@ -765,7 +751,7 @@ func (s *Scene) CreateEntityMonster(pos *model.Vector, level uint8, fightProp ma } s.entityMap[entity.id] = entity s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z)) - GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{ + GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{ MsgType: mq.MsgTypeFight, EventId: mq.FightRoutineAddEntity, FightMsg: &mq.FightMsg{ @@ -915,7 +901,7 @@ func (s *Scene) DestroyEntity(entityId uint32) { } s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z)) delete(s.entityMap, entityId) - GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{ + GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{ MsgType: mq.MsgTypeFight, EventId: mq.FightRoutineDelEntity, FightMsg: &mq.FightMsg{ diff --git a/gs/model/Item.go b/gs/model/Item.go index b812cb16..f4cd0be0 100644 --- a/gs/model/Item.go +++ b/gs/model/Item.go @@ -1,7 +1,7 @@ package model import ( - "hk4e/gs/constant" + "hk4e/common/constant" ) type Item struct { diff --git a/gs/model/avatar.go b/gs/model/avatar.go index 9ebdc360..27f6c8ee 100644 --- a/gs/model/avatar.go +++ b/gs/model/avatar.go @@ -3,8 +3,8 @@ package model import ( "time" + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" "hk4e/pkg/logger" ) diff --git a/gs/model/player.go b/gs/model/player.go index 578f503d..907842ba 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -71,6 +71,8 @@ type Player struct { ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号 CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器 AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器 + GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid + FightAppId string `bson:"-" msgpack:"-"` // 战斗服务器的appid } func (p *Player) GetNextGameObjectGuid() uint64 { diff --git a/gs/model/stamina.go b/gs/model/stamina.go index 9b6f483f..b44c5291 100644 --- a/gs/model/stamina.go +++ b/gs/model/stamina.go @@ -1,7 +1,7 @@ package model import ( - "hk4e/gs/constant" + "hk4e/common/constant" "hk4e/protocol/proto" ) diff --git a/gs/model/team.go b/gs/model/team.go index 72c7c773..d7d81733 100644 --- a/gs/model/team.go +++ b/gs/model/team.go @@ -1,8 +1,8 @@ package model import ( + "hk4e/common/constant" gdc "hk4e/gs/config" - "hk4e/gs/constant" ) type Team struct { diff --git a/gs/service/service.go b/gs/service/service.go index ab2f3807..08451e46 100644 --- a/gs/service/service.go +++ b/gs/service/service.go @@ -30,5 +30,4 @@ func NewService(conn *nats.Conn) (*Service, error) { // Close 关闭 func (s *Service) Close() { // TODO - } diff --git a/node/api/api.natsrpc.pb.go b/node/api/api.natsrpc.pb.go new file mode 100644 index 00000000..baf4a99a --- /dev/null +++ b/node/api/api.natsrpc.pb.go @@ -0,0 +1,70 @@ +// Code generated by protoc-gen-natsrpc. DO NOT EDIT. +// versions: +// - protoc-gen-natsrpc v0.5.0 +// source: api.proto + +package api + +import ( + context "context" + fmt "fmt" + natsrpc "github.com/byebyebruce/natsrpc" + nats_go "github.com/nats-io/nats.go" + proto "google.golang.org/protobuf/proto" +) + +var _ = new(context.Context) +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = natsrpc.Version +var _ = nats_go.Version + +// 节点服务器注册发现服务 +type DiscoveryNATSRPCServer interface { + RegisterServer(ctx context.Context, req *RegisterServerReq) (*RegisterServerRsp, error) + GetServerAppId(ctx context.Context, req *GetServerAppIdReq) (*GetServerAppIdRsp, error) + GetRegionEc2B(ctx context.Context, req *NullMsg) (*RegionEc2B, error) +} + +// RegisterDiscoveryNATSRPCServer register Discovery service +func RegisterDiscoveryNATSRPCServer(server *natsrpc.Server, s DiscoveryNATSRPCServer, opts ...natsrpc.ServiceOption) (natsrpc.IService, error) { + return server.Register("hk4e.node.api.Discovery", s, opts...) +} + +// 节点服务器注册发现服务 +type DiscoveryNATSRPCClient interface { + RegisterServer(ctx context.Context, req *RegisterServerReq, opt ...natsrpc.CallOption) (*RegisterServerRsp, error) + GetServerAppId(ctx context.Context, req *GetServerAppIdReq, opt ...natsrpc.CallOption) (*GetServerAppIdRsp, error) + GetRegionEc2B(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*RegionEc2B, error) +} + +type _DiscoveryNATSRPCClient struct { + c *natsrpc.Client +} + +// NewDiscoveryNATSRPCClient +func NewDiscoveryNATSRPCClient(enc *nats_go.EncodedConn, opts ...natsrpc.ClientOption) (DiscoveryNATSRPCClient, error) { + c, err := natsrpc.NewClient(enc, "hk4e.node.api.Discovery", opts...) + if err != nil { + return nil, err + } + ret := &_DiscoveryNATSRPCClient{ + c: c, + } + return ret, nil +} +func (c *_DiscoveryNATSRPCClient) RegisterServer(ctx context.Context, req *RegisterServerReq, opt ...natsrpc.CallOption) (*RegisterServerRsp, error) { + rep := &RegisterServerRsp{} + err := c.c.Request(ctx, "RegisterServer", req, rep, opt...) + return rep, err +} +func (c *_DiscoveryNATSRPCClient) GetServerAppId(ctx context.Context, req *GetServerAppIdReq, opt ...natsrpc.CallOption) (*GetServerAppIdRsp, error) { + rep := &GetServerAppIdRsp{} + err := c.c.Request(ctx, "GetServerAppId", req, rep, opt...) + return rep, err +} +func (c *_DiscoveryNATSRPCClient) GetRegionEc2B(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*RegionEc2B, error) { + rep := &RegionEc2B{} + err := c.c.Request(ctx, "GetRegionEc2B", req, rep, opt...) + return rep, err +} diff --git a/node/api/api.pb.go b/node/api/api.pb.go new file mode 100644 index 00000000..69d4f98b --- /dev/null +++ b/node/api/api.pb.go @@ -0,0 +1,466 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.7.0 +// source: api.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type NullMsg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NullMsg) Reset() { + *x = NullMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NullMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullMsg) ProtoMessage() {} + +func (x *NullMsg) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NullMsg.ProtoReflect.Descriptor instead. +func (*NullMsg) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{0} +} + +type GetServerAppIdReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerType string `protobuf:"bytes,1,opt,name=server_type,json=serverType,proto3" json:"server_type,omitempty"` +} + +func (x *GetServerAppIdReq) Reset() { + *x = GetServerAppIdReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetServerAppIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServerAppIdReq) ProtoMessage() {} + +func (x *GetServerAppIdReq) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetServerAppIdReq.ProtoReflect.Descriptor instead. +func (*GetServerAppIdReq) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{1} +} + +func (x *GetServerAppIdReq) GetServerType() string { + if x != nil { + return x.ServerType + } + return "" +} + +type GetServerAppIdRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` +} + +func (x *GetServerAppIdRsp) Reset() { + *x = GetServerAppIdRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetServerAppIdRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServerAppIdRsp) ProtoMessage() {} + +func (x *GetServerAppIdRsp) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetServerAppIdRsp.ProtoReflect.Descriptor instead. +func (*GetServerAppIdRsp) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{2} +} + +func (x *GetServerAppIdRsp) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +type RegisterServerReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerType string `protobuf:"bytes,1,opt,name=server_type,json=serverType,proto3" json:"server_type,omitempty"` +} + +func (x *RegisterServerReq) Reset() { + *x = RegisterServerReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterServerReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterServerReq) ProtoMessage() {} + +func (x *RegisterServerReq) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterServerReq.ProtoReflect.Descriptor instead. +func (*RegisterServerReq) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{3} +} + +func (x *RegisterServerReq) GetServerType() string { + if x != nil { + return x.ServerType + } + return "" +} + +type RegisterServerRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` +} + +func (x *RegisterServerRsp) Reset() { + *x = RegisterServerRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterServerRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterServerRsp) ProtoMessage() {} + +func (x *RegisterServerRsp) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterServerRsp.ProtoReflect.Descriptor instead. +func (*RegisterServerRsp) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{4} +} + +func (x *RegisterServerRsp) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +type RegionEc2B struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *RegionEc2B) Reset() { + *x = RegionEc2B{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegionEc2B) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegionEc2B) ProtoMessage() {} + +func (x *RegionEc2B) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegionEc2B.ProtoReflect.Descriptor instead. +func (*RegionEc2B) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{5} +} + +func (x *RegionEc2B) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +var File_api_proto protoreflect.FileDescriptor + +var file_api_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x22, 0x09, 0x0a, 0x07, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, + 0x22, 0x34, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, + 0x49, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x73, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x61, + 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, + 0x49, 0x64, 0x22, 0x34, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x15, 0x0a, + 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, + 0x70, 0x70, 0x49, 0x64, 0x22, 0x20, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63, + 0x32, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0xe3, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x12, 0x4c, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x73, 0x70, + 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, + 0x70, 0x70, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65, + 0x71, 0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x3a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x32, + 0x62, 0x12, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c, + 0x6c, 0x4d, 0x73, 0x67, 0x1a, 0x14, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x32, 0x62, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, + 0x68, 0x6b, 0x34, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, + 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_proto_rawDescOnce sync.Once + file_api_proto_rawDescData = file_api_proto_rawDesc +) + +func file_api_proto_rawDescGZIP() []byte { + file_api_proto_rawDescOnce.Do(func() { + file_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_proto_rawDescData) + }) + return file_api_proto_rawDescData +} + +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_api_proto_goTypes = []interface{}{ + (*NullMsg)(nil), // 0: node.api.NullMsg + (*GetServerAppIdReq)(nil), // 1: node.api.GetServerAppIdReq + (*GetServerAppIdRsp)(nil), // 2: node.api.GetServerAppIdRsp + (*RegisterServerReq)(nil), // 3: node.api.RegisterServerReq + (*RegisterServerRsp)(nil), // 4: node.api.RegisterServerRsp + (*RegionEc2B)(nil), // 5: node.api.RegionEc2b +} +var file_api_proto_depIdxs = []int32{ + 3, // 0: node.api.Discovery.RegisterServer:input_type -> node.api.RegisterServerReq + 1, // 1: node.api.Discovery.GetServerAppId:input_type -> node.api.GetServerAppIdReq + 0, // 2: node.api.Discovery.GetRegionEc2b:input_type -> node.api.NullMsg + 4, // 3: node.api.Discovery.RegisterServer:output_type -> node.api.RegisterServerRsp + 2, // 4: node.api.Discovery.GetServerAppId:output_type -> node.api.GetServerAppIdRsp + 5, // 5: node.api.Discovery.GetRegionEc2b:output_type -> node.api.RegionEc2b + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_proto_init() } +func file_api_proto_init() { + if File_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NullMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetServerAppIdReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetServerAppIdRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterServerReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterServerRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegionEc2B); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_proto_goTypes, + DependencyIndexes: file_api_proto_depIdxs, + MessageInfos: file_api_proto_msgTypes, + }.Build() + File_api_proto = out.File + file_api_proto_rawDesc = nil + file_api_proto_goTypes = nil + file_api_proto_depIdxs = nil +} diff --git a/node/api/api.proto b/node/api/api.proto new file mode 100644 index 00000000..d7e3b5a7 --- /dev/null +++ b/node/api/api.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package node.api; +option go_package = "hk4e/node/api;api"; + +// 节点服务器注册发现服务 +service Discovery { + rpc RegisterServer (RegisterServerReq) returns (RegisterServerRsp) {} // 服务器启动注册获取appid + rpc GetServerAppId (GetServerAppIdReq) returns (GetServerAppIdRsp) {} // 随机获取某服务器的appid + rpc GetRegionEc2b (NullMsg) returns (RegionEc2b) {} // 获取区服密钥信息 +} + +message NullMsg { +} + +message GetServerAppIdReq { + string server_type = 1; +} + +message GetServerAppIdRsp { + string app_id = 1; +} + +message RegisterServerReq { + string server_type = 1; +} + +message RegisterServerRsp { + string app_id = 1; +} + +message RegionEc2b { + bytes data = 1; +} diff --git a/node/api/server_type.go b/node/api/server_type.go new file mode 100644 index 00000000..61fb8add --- /dev/null +++ b/node/api/server_type.go @@ -0,0 +1,8 @@ +package api + +const ( + GATE = "GATE" + GS = "GS" + FIGHT = "FIGHT" + PATHFINDING = "PATHFINDING" +) diff --git a/node/app/app.go b/node/app/app.go new file mode 100644 index 00000000..3f7fc8c0 --- /dev/null +++ b/node/app/app.go @@ -0,0 +1,56 @@ +package app + +import ( + "context" + _ "net/http/pprof" + "os" + "os/signal" + "syscall" + "time" + + "hk4e/common/config" + "hk4e/node/service" + "hk4e/pkg/logger" + + "github.com/nats-io/nats.go" +) + +func Run(ctx context.Context, configFile string) error { + config.InitConfig(configFile) + + logger.InitLogger("node") + logger.Warn("node start") + + // natsrpc server + conn, err := nats.Connect(config.CONF.MQ.NatsUrl) + if err != nil { + logger.Error("connect nats error: %v", err) + return err + } + defer conn.Close() + s, err := service.NewService(conn) + if err != nil { + return err + } + defer s.Close() + + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) + for { + select { + case <-ctx.Done(): + return nil + case s := <-c: + logger.Warn("get a signal %s", s.String()) + switch s { + case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: + logger.Warn("node exit") + time.Sleep(time.Second) + return nil + case syscall.SIGHUP: + default: + return nil + } + } + } +} diff --git a/node/service/discovery.go b/node/service/discovery.go new file mode 100644 index 00000000..1db7b2c4 --- /dev/null +++ b/node/service/discovery.go @@ -0,0 +1,94 @@ +package service + +import ( + "context" + "strings" + + "hk4e/common/config" + "hk4e/common/region" + "hk4e/node/api" + "hk4e/pkg/logger" + "hk4e/pkg/random" + + "github.com/pkg/errors" +) + +var _ api.DiscoveryNATSRPCServer = (*DiscoveryService)(nil) + +type ServerInstance struct { + serverType string + appId string +} + +type DiscoveryService struct { + regionEc2b *random.Ec2b + // TODO 加锁 + serverInstanceMap map[string]map[string]*ServerInstance + serverAppIdMap map[string]bool +} + +func NewDiscoveryService() *DiscoveryService { + r := new(DiscoveryService) + _, _, r.regionEc2b = region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort, nil) + logger.Info("region ec2b create ok, seed: %v", r.regionEc2b.Seed()) + r.serverInstanceMap = map[string]map[string]*ServerInstance{ + api.GATE: make(map[string]*ServerInstance), + api.GS: make(map[string]*ServerInstance), + api.FIGHT: make(map[string]*ServerInstance), + api.PATHFINDING: make(map[string]*ServerInstance), + } + r.serverAppIdMap = make(map[string]bool) + return r +} + +func (s *DiscoveryService) RegisterServer(ctx context.Context, req *api.RegisterServerReq) (*api.RegisterServerRsp, error) { + logger.Info("register new server, server type: %v", req.ServerType) + instMap, exist := s.serverInstanceMap[req.ServerType] + if !exist { + return nil, errors.New("server type not exist") + } + var appId string + for { + appId = strings.ToLower(random.GetRandomStr(8)) + _, exist := s.serverAppIdMap[appId] + if !exist { + s.serverAppIdMap[appId] = true + break + } + } + instMap[appId] = &ServerInstance{ + serverType: req.ServerType, + appId: appId, + } + logger.Info("new server appid is: %v", appId) + return &api.RegisterServerRsp{ + AppId: appId, + }, nil +} + +func (s *DiscoveryService) GetServerAppId(ctx context.Context, req *api.GetServerAppIdReq) (*api.GetServerAppIdRsp, error) { + logger.Info("get server instance, server type: %v", req.ServerType) + instMap, exist := s.serverInstanceMap[req.ServerType] + if !exist { + return nil, errors.New("server type not exist") + } + if len(instMap) == 0 { + return nil, errors.New("no server found") + } + var inst *ServerInstance = nil + for _, v := range instMap { + inst = v + break + } + logger.Info("get server appid is: %v", inst.appId) + return &api.GetServerAppIdRsp{ + AppId: inst.appId, + }, nil +} + +func (s *DiscoveryService) GetRegionEc2B(ctx context.Context, req *api.NullMsg) (*api.RegionEc2B, error) { + logger.Info("get region ec2b ok") + return &api.RegionEc2B{ + Data: s.regionEc2b.Bytes(), + }, nil +} diff --git a/node/service/service.go b/node/service/service.go new file mode 100644 index 00000000..a9038475 --- /dev/null +++ b/node/service/service.go @@ -0,0 +1,32 @@ +package service + +import ( + "hk4e/node/api" + + "github.com/byebyebruce/natsrpc" + "github.com/nats-io/nats.go" + "github.com/nats-io/nats.go/encoders/protobuf" +) + +type Service struct { +} + +func NewService(conn *nats.Conn) (*Service, error) { + enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER) + if err != nil { + return nil, err + } + svr, err := natsrpc.NewServer(enc) + if err != nil { + return nil, err + } + discoveryService := NewDiscoveryService() + _, err = api.RegisterDiscoveryNATSRPCServer(svr, discoveryService) + if err != nil { + return nil, err + } + return &Service{}, nil +} + +func (s *Service) Close() { +} diff --git a/pathfinding/app/app.go b/pathfinding/app/app.go index acf6362e..e10d71bb 100644 --- a/pathfinding/app/app.go +++ b/pathfinding/app/app.go @@ -10,17 +10,36 @@ import ( "hk4e/common/config" "hk4e/common/mq" + "hk4e/common/rpc" + "hk4e/node/api" "hk4e/pathfinding/handle" "hk4e/pkg/logger" ) +var APPID string + func Run(ctx context.Context, configFile string) error { config.InitConfig(configFile) - logger.InitLogger("pathfinding") - logger.Warn("pathfinding start") + // natsrpc client + client, err := rpc.NewClient() + if err != nil { + return err + } - messageQueue := mq.NewMessageQueue(mq.PATHFINDING, "1") + // 注册到节点服务器 + rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{ + ServerType: api.PATHFINDING, + }) + if err != nil { + return err + } + APPID = rsp.GetAppId() + + logger.InitLogger("pathfinding_" + APPID) + logger.Warn("pathfinding start, appid: %v", APPID) + + messageQueue := mq.NewMessageQueue(api.PATHFINDING, APPID) defer messageQueue.Close() _ = handle.NewHandle(messageQueue) @@ -35,7 +54,7 @@ func Run(ctx context.Context, configFile string) error { logger.Warn("get a signal %s", s.String()) switch s { case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: - logger.Warn("pathfinding exit") + logger.Warn("pathfinding exit, appid: %v", APPID) time.Sleep(time.Second) return nil case syscall.SIGHUP: diff --git a/pathfinding/handle/handle.go b/pathfinding/handle/handle.go index de0b8af4..9deb2ea5 100644 --- a/pathfinding/handle/handle.go +++ b/pathfinding/handle/handle.go @@ -2,6 +2,7 @@ package handle import ( "hk4e/common/mq" + "hk4e/node/api" "hk4e/pathfinding/world" "hk4e/pkg/logger" "hk4e/protocol/cmd" @@ -34,12 +35,15 @@ func (h *Handle) run() { if netMsg.EventId != mq.NormalMsg { continue } + if netMsg.OriginServerType != api.GATE { + continue + } gameMsg := netMsg.GameMsg switch gameMsg.CmdId { case cmd.QueryPathReq: - h.QueryPath(gameMsg.UserId, gameMsg.PayloadMessage) + h.QueryPath(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage) case cmd.ObstacleModifyNotify: - h.ObstacleModifyNotify(gameMsg.UserId, gameMsg.PayloadMessage) + h.ObstacleModifyNotify(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage) } } }() @@ -47,7 +51,7 @@ func (h *Handle) run() { } // SendMsg 发送消息给客户端 -func (h *Handle) SendMsg(cmdId uint16, userId uint32, payloadMsg pb.Message) { +func (h *Handle) SendMsg(cmdId uint16, userId uint32, gateAppId string, payloadMsg pb.Message) { if userId < 100000000 || payloadMsg == nil { return } @@ -62,7 +66,7 @@ func (h *Handle) SendMsg(cmdId uint16, userId uint32, payloadMsg pb.Message) { return } gameMsg.PayloadMessageData = payloadMessageData - h.messageQueue.SendToGate("1", &mq.NetMsg{ + h.messageQueue.SendToGate(gateAppId, &mq.NetMsg{ MsgType: mq.MsgTypeGame, EventId: mq.NormalMsg, GameMsg: gameMsg, diff --git a/pathfinding/handle/query_path.go b/pathfinding/handle/query_path.go index 32d05c4b..27c5512f 100644 --- a/pathfinding/handle/query_path.go +++ b/pathfinding/handle/query_path.go @@ -41,9 +41,9 @@ func (h *Handle) ConvMeshVecListToPbVecList(meshVecList []pfalg.MeshVector) []*p return ret } -func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) { +func (h *Handle) QueryPath(userId uint32, gateAppId string, payloadMsg pb.Message) { req := payloadMsg.(*proto.QueryPathReq) - logger.Debug("query path req: %v, uid: %v", req, userId) + logger.Debug("query path req: %v, uid: %v, gateAppId: %v", req, userId, gateAppId) var ok = false var path []pfalg.MeshVector = nil for _, destinationPos := range req.DestinationPos { @@ -57,7 +57,7 @@ func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) { QueryId: req.QueryId, QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_FAIL, } - h.SendMsg(cmd.QueryPathRsp, userId, queryPathRsp) + h.SendMsg(cmd.QueryPathRsp, userId, gateAppId, queryPathRsp) return } queryPathRsp := &proto.QueryPathRsp{ @@ -65,10 +65,10 @@ func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) { QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_SUCC, Corners: h.ConvMeshVecListToPbVecList(path), } - h.SendMsg(cmd.QueryPathRsp, userId, queryPathRsp) + h.SendMsg(cmd.QueryPathRsp, userId, gateAppId, queryPathRsp) } -func (h *Handle) ObstacleModifyNotify(userId uint32, payloadMsg pb.Message) { +func (h *Handle) ObstacleModifyNotify(userId uint32, gateAppId string, payloadMsg pb.Message) { req := payloadMsg.(*proto.ObstacleModifyNotify) - logger.Debug("obstacle modify req: %v, uid: %v", req, userId) + logger.Debug("obstacle modify req: %v, uid: %v, gateAppId: %v", req, userId, gateAppId) } diff --git a/pkg/statsviz_serve/statsviz_serve.go b/pkg/statsviz_serve/statsviz_serve.go index 159d0af8..2488e422 100644 --- a/pkg/statsviz_serve/statsviz_serve.go +++ b/pkg/statsviz_serve/statsviz_serve.go @@ -3,21 +3,19 @@ package statsviz_serve import ( "net/http" - "hk4e/pkg/logger" - "github.com/arl/statsviz" ) +// Serve 性能检测 +// 原生pprof /debug/pprof +// 可视化图表 /debug/statsviz func Serve(addr string) error { - // 性能检测 err := statsviz.RegisterDefault() if err != nil { - logger.Error("statsviz init error: %v", err) return err } err = http.ListenAndServe(addr, nil) if err != nil { - logger.Error("perf debug http start error: %v", err) return err } return nil