From 1793054ef413a1cba1c0e3191f79525eaff8a699 Mon Sep 17 00:00:00 2001 From: flswld Date: Tue, 10 Jan 2023 19:21:56 +0800 Subject: [PATCH] =?UTF-8?q?Ai=E4=B8=96=E7=95=8C=E7=8E=A9=E5=AE=B6=E4=BA=BA?= =?UTF-8?q?=E6=95=B0=E8=B6=85=E8=BF=874=E4=BA=BA=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/mq/nats.go | 4 +- fight/engine/fight_engine.go | 28 ++-- gate/app/app.go | 4 +- gate/net/kcp_connect_manager.go | 5 +- gs/app/app.go | 10 +- gs/game/command_manager.go | 18 +-- gs/game/game_manager.go | 135 +++++++++++++--- gs/game/local_event_manager.go | 14 +- gs/game/tick_manager.go | 10 +- gs/game/user_fight_sync.go | 121 ++++++++++----- gs/game/user_login.go | 24 +-- gs/game/user_manager.go | 5 + gs/game/user_multiplayer.go | 3 + gs/game/user_scene.go | 12 +- gs/game/user_social.go | 20 ++- gs/game/user_stamina.go | 25 ++- gs/game/video_player.go | 2 +- gs/game/world_manager.go | 90 ++++++++--- node/api/api.natsrpc.pb.go | 9 ++ node/api/api.pb.go | 262 ++++++++++++++++++++------------ node/api/api.proto | 6 + node/service/discovery.go | 40 ++++- 22 files changed, 596 insertions(+), 251 deletions(-) diff --git a/common/mq/nats.go b/common/mq/nats.go index cc945b03..6116fdbd 100644 --- a/common/mq/nats.go +++ b/common/mq/nats.go @@ -61,8 +61,6 @@ func NewMessageQueue(serverType string, appId string, rpcClient *rpc.Client) (r r.cmdProtoMap = cmd.NewCmdProtoMap() r.serverType = serverType r.appId = appId - go r.recvHandler() - go r.sendHandler() r.gateTcpMqChan = make(chan []byte, 1000) r.gateTcpMqEventChan = make(chan *GateTcpMqEvent, 1000) r.rpcClient = rpcClient @@ -71,6 +69,8 @@ func NewMessageQueue(serverType string, appId string, rpcClient *rpc.Client) (r } else { r.initGateTcpMqClient() } + go r.recvHandler() + go r.sendHandler() return r } diff --git a/fight/engine/fight_engine.go b/fight/engine/fight_engine.go index 8b9a7484..77abccf1 100644 --- a/fight/engine/fight_engine.go +++ b/fight/engine/fight_engine.go @@ -228,14 +228,22 @@ func (f *FightRoutine) attackHandle(gameMsg *mq.GameMsg) { continue } hitInfo := new(proto.EvtBeingHitInfo) - clientProtoObj := GetClientProtoObjByName("EvtBeingHitInfo") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(hitInfo, clientProtoObj, entry.CombatData) - if !ok { - continue + if config.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := GetClientProtoObjByName("EvtBeingHitInfo") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(hitInfo, clientProtoObj, entry.CombatData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(entry.CombatData, hitInfo) + if err != nil { + logger.Error("parse EvtBeingHitInfo error: %v", err) + continue + } } attackResult := hitInfo.AttackResult if attackResult == nil { @@ -303,10 +311,6 @@ func initClientCmdProtoMap() { } func GetClientProtoObjByName(protoObjName string) pb.Message { - if !config.CONF.Hk4e.ClientProtoProxyEnable { - logger.Error("client proto proxy func not enable") - return nil - } fn := ClientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) obj := ret[0].Interface() diff --git a/gate/app/app.go b/gate/app/app.go index a9d856a2..b93c6656 100644 --- a/gate/app/app.go +++ b/gate/app/app.go @@ -66,10 +66,10 @@ func Run(ctx context.Context, configFile string) error { logger.Warn("gate start, appid: %v", APPID) messageQueue := mq.NewMessageQueue(api.GATE, APPID, client) + defer messageQueue.Close() connectManager := net.NewKcpConnectManager(messageQueue, client.Discovery) - connectManager.Start() - defer connectManager.Stop() + defer connectManager.Close() go func() { outputChan := connectManager.GetKcpEventOutputChan() diff --git a/gate/net/kcp_connect_manager.go b/gate/net/kcp_connect_manager.go index db531453..69e5218e 100644 --- a/gate/net/kcp_connect_manager.go +++ b/gate/net/kcp_connect_manager.go @@ -64,10 +64,11 @@ func NewKcpConnectManager(messageQueue *mq.MessageQueue, discovery *rpc.Discover r.localMsgOutput = make(chan *ProtoMsg, 1000) r.createSessionChan = make(chan *Session, 1000) r.destroySessionChan = make(chan *Session, 1000) + r.run() return r } -func (k *KcpConnectManager) Start() { +func (k *KcpConnectManager) run() { // 读取密钥相关文件 k.signRsaKey, k.encRsaKeyMap, _ = region.LoadRsaKey() // key @@ -97,7 +98,7 @@ func (k *KcpConnectManager) Start() { go k.acceptHandle(listener) } -func (k *KcpConnectManager) Stop() { +func (k *KcpConnectManager) Close() { k.closeAllKcpConn() time.Sleep(time.Second * 3) } diff --git a/gs/app/app.go b/gs/app/app.go index b0e5e9c0..a5932c1d 100644 --- a/gs/app/app.go +++ b/gs/app/app.go @@ -63,6 +63,10 @@ func Run(ctx context.Context, configFile string) error { AppId: APPID, }) }() + mainGsAppid, err := client.Discovery.GetMainGameServerAppId(context.TODO(), &api.NullMsg{}) + if err != nil { + return err + } logger.InitLogger("gs_" + APPID) logger.Warn("gs start, appid: %v, gsid: %v", APPID, GSID) @@ -74,15 +78,15 @@ func Run(ctx context.Context, configFile string) error { db, err := dao.NewDao() if err != nil { - panic(err) + return err } defer db.CloseDao() messageQueue := mq.NewMessageQueue(api.GS, APPID, client) defer messageQueue.Close() - gameManager := game.NewGameManager(db, messageQueue, GSID) - defer gameManager.Stop() + gameManager := game.NewGameManager(db, messageQueue, GSID, APPID, mainGsAppid.AppId) + defer gameManager.Close() // natsrpc server conn, err := nats.Connect(config.CONF.MQ.NatsUrl) diff --git a/gs/game/command_manager.go b/gs/game/command_manager.go index 3529ae7c..73c352af 100644 --- a/gs/game/command_manager.go +++ b/gs/game/command_manager.go @@ -6,7 +6,6 @@ import ( "hk4e/gs/model" "hk4e/pkg/logger" - "hk4e/protocol/proto" ) // 命令管理器 @@ -36,7 +35,7 @@ type CommandMessage struct { // CommandManager 命令管理器 type CommandManager struct { - system *model.Player // 机器人 目前负责收发消息 以及 大世界 + system *model.Player // GM指令聊天消息机器人 commandFuncRouter map[string]CommandFunc // 记录命令处理函数 commandPermMap map[string]CommandPerm // 记录命令对应的权限 commandTextInput chan *CommandMessage // 传输要处理的命令文本 @@ -45,22 +44,17 @@ type CommandManager struct { // NewCommandManager 新建命令管理器 func NewCommandManager() *CommandManager { r := new(CommandManager) - - // 创建AI世界 - GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0, "") - GAME_MANAGER.ServerAppidBindNotify(1, "", 0) - r.system = USER_MANAGER.GetOnlineUser(1) - r.system.DbState = model.DbNormal - r.system.SceneLoadState = model.SceneEnterDone - WORLD_MANAGER.InitBigWorld(r.system) - // 初始化 r.commandTextInput = make(chan *CommandMessage, 1000) r.InitRouter() // 初始化路由 - return r } +// SetSystem 设置GM指令聊天消息机器人 +func (c *CommandManager) SetSystem(system *model.Player) { + c.system = system +} + // InitRouter 初始化命令路由 func (c *CommandManager) InitRouter() { c.commandFuncRouter = make(map[string]CommandFunc) diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index f285e0ba..be72928d 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -1,6 +1,7 @@ package game import ( + "encoding/json" "reflect" "time" @@ -8,10 +9,12 @@ import ( "hk4e/common/mq" "hk4e/gate/client_proto" "hk4e/gate/kcp" + "hk4e/gdconf" "hk4e/gs/dao" "hk4e/gs/model" "hk4e/pkg/alg" "hk4e/pkg/logger" + "hk4e/pkg/random" "hk4e/pkg/reflection" "hk4e/protocol/cmd" "hk4e/protocol/proto" @@ -19,6 +22,15 @@ import ( pb "google.golang.org/protobuf/proto" ) +const ( + AiBaseUid = 10000 + AiName = "GM" + AiSign = "快捷指令" + BigWorldAiUid = 100 + BigWorldAiName = "小可爱" + BigWorldAiSign = "UnKownOwO" +) + var GAME_MANAGER *GameManager = nil var LOCAL_EVENT_MANAGER *LocalEventManager = nil var ROUTE_MANAGER *RouteManager = nil @@ -36,10 +48,18 @@ type GameManager struct { snowflake *alg.SnowflakeWorker clientCmdProtoMap *client_proto.ClientCmdProtoMap clientCmdProtoMapRefValue reflect.Value + gsId uint32 + gsAppid string + mainGsAppid string + ai *model.Player // 本服的Ai玩家对象 } -func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32) (r *GameManager) { +func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gsAppid string, mainGsAppid string) (r *GameManager) { r = new(GameManager) + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + // 反射调用的方法在启动时测试是否正常防止中途panic + r.GetClientProtoObjByName("PingReq") + } r.dao = dao MESSAGE_QUEUE = messageQueue r.snowflake = alg.NewSnowflakeWorker(int64(gsId)) @@ -47,6 +67,9 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32) (r r.clientCmdProtoMap = client_proto.NewClientCmdProtoMap() r.clientCmdProtoMapRefValue = reflect.ValueOf(r.clientCmdProtoMap) } + r.gsId = gsId + r.gsAppid = gsAppid + r.mainGsAppid = mainGsAppid GAME_MANAGER = r LOCAL_EVENT_MANAGER = NewLocalEventManager() ROUTE_MANAGER = NewRouteManager() @@ -55,10 +78,78 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32) (r TICK_MANAGER = NewTickManager() COMMAND_MANAGER = NewCommandManager() GCG_MANAGER = NewGCGManager() + // 创建本服的Ai世界 + uid := AiBaseUid + gsId + name := AiName + sign := AiSign + if r.IsMainGs() { + // 约定MainGameServer的Ai的AiWorld叫BigWorld + // 此世界会出现在全服的在线玩家列表中 所有的玩家都可以进入到此世界里来 + uid = BigWorldAiUid + name = BigWorldAiName + sign = BigWorldAiSign + } + r.ai = r.CreateRobot(uid, name, sign) + WORLD_MANAGER.InitAiWorld(r.ai) + COMMAND_MANAGER.SetSystem(r.ai) + USER_MANAGER.SetRemoteUserOnlineState(BigWorldAiUid, true, mainGsAppid) + if r.IsMainGs() { + // TODO 测试 + for i := 1; i < 8; i++ { + uid := 1000000 + uint32(i) + avatarId := uint32(0) + for _, avatarData := range gdconf.CONF.AvatarDataMap { + avatarId = uint32(avatarData.AvatarId) + break + } + robot := r.CreateRobot(uid, random.GetRandomStr(8), random.GetRandomStr(10)) + r.AddUserAvatar(uid, avatarId) + r.SetUpAvatarTeamReq(robot, &proto.SetUpAvatarTeamReq{ + TeamId: 1, + AvatarTeamGuidList: []uint64{robot.AvatarMap[avatarId].Guid}, + CurAvatarGuid: robot.AvatarMap[avatarId].Guid, + }) + robot.Pos.X += random.GetRandomFloat64(0.0, 1.0) + robot.Pos.Z += random.GetRandomFloat64(0.0, 1.0) + r.UserWorldAddPlayer(WORLD_MANAGER.GetAiWorld(), robot) + } + } r.run() return r } +func (g *GameManager) GetGsId() uint32 { + return g.gsId +} + +func (g *GameManager) GetGsAppid() string { + return g.gsAppid +} + +func (g *GameManager) GetMainGsAppid() string { + return g.mainGsAppid +} + +func (g *GameManager) IsMainGs() bool { + // 目前的实现逻辑是当前GsId最小的Gs做MainGs + return g.gsAppid == g.mainGsAppid +} + +// GetAi 获取本服的Ai玩家对象 +func (g *GameManager) GetAi() *model.Player { + return g.ai +} + +func (g *GameManager) CreateRobot(uid uint32, name string, sign string) *model.Player { + GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: name}, uid, 0, "") + GAME_MANAGER.ServerAppidBindNotify(uid, "", 0) + robot := USER_MANAGER.GetOnlineUser(uid) + robot.DbState = model.DbNormal + robot.SceneLoadState = model.SceneEnterDone + robot.Signature = sign + return robot +} + func (g *GameManager) run() { go g.gameMainLoopD() } @@ -72,12 +163,14 @@ func (g *GameManager) gameMainLoopD() { } func (g *GameManager) gameMainLoop() { + // panic捕获 defer func() { if err := recover(); err != nil { logger.Error("!!! GAME MAIN LOOP PANIC !!!") logger.Error("error: %v", err) logger.Error("stack: %v", logger.Stack()) - logger.Error("user: %v", SELF) + motherfuckerPlayerInfo, _ := json.Marshal(SELF) + logger.Error("the motherfucker player info: %v", motherfuckerPlayerInfo) if SELF != nil { GAME_MANAGER.DisconnectPlayer(SELF.PlayerID, kcp.EnetServerKick) } @@ -90,6 +183,7 @@ func (g *GameManager) gameMainLoop() { localEventCost := int64(0) commandCost := int64(0) for { + // 消耗CPU时间性能统计 now := time.Now().UnixNano() if now-lastTime > intervalTime { routeCost /= 1e6 @@ -134,7 +228,7 @@ func (g *GameManager) gameMainLoop() { end := time.Now().UnixNano() localEventCost += end - start case command := <-COMMAND_MANAGER.commandTextInput: - // 处理传入的命令 (普通玩家 GM命令) + // 处理传入的命令(普通玩家 GM命令) start := time.Now().UnixNano() COMMAND_MANAGER.HandleCommand(command) end := time.Now().UnixNano() @@ -143,24 +237,27 @@ func (g *GameManager) gameMainLoop() { } } -func (g *GameManager) Stop() { - // 下线玩家 - userList := USER_MANAGER.GetAllOnlineUserList() - for _, player := range userList { - g.DisconnectPlayer(player.PlayerID, kcp.EnetServerShutdown) - } - time.Sleep(time.Second * 3) +var EXIT_SAVE_FIN_CHAN chan bool + +func (g *GameManager) Close() { // 保存玩家数据 onlinePlayerMap := USER_MANAGER.GetAllOnlineUserList() saveUserIdList := make([]uint32, 0, len(onlinePlayerMap)) for userId := range onlinePlayerMap { saveUserIdList = append(saveUserIdList, userId) } + EXIT_SAVE_FIN_CHAN = make(chan bool) LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{ - EventId: RunUserCopyAndSave, + EventId: ExitRunUserCopyAndSave, Msg: saveUserIdList, } - time.Sleep(time.Second * 3) + <-EXIT_SAVE_FIN_CHAN + // 单纯的告诉网关下线玩家 + userList := USER_MANAGER.GetAllOnlineUserList() + for _, player := range userList { + g.DisconnectPlayer(player.PlayerID, kcp.EnetServerShutdown) + } + time.Sleep(time.Second) } // SendMsgToGate 发送消息给客户端 指定网关 @@ -169,7 +266,7 @@ func (g *GameManager) SendMsgToGate(cmdId uint16, userId uint32, clientSeq uint3 return } if payloadMsg == nil { - logger.Error("payload msg is nil") + logger.Error("payload msg is nil, stack: %v", logger.Stack()) return } gameMsg := &mq.GameMsg{ @@ -191,12 +288,12 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay return } if payloadMsg == nil { - logger.Error("payload msg is nil") + logger.Error("payload msg is nil, stack: %v", logger.Stack()) return } player := USER_MANAGER.GetOnlineUser(userId) if player == nil { - logger.Error("player not exist, uid: %v", userId) + logger.Error("player not exist, uid: %v, stack: %v", userId, logger.Stack()) return } gameMsg := new(mq.GameMsg) @@ -206,7 +303,7 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay // 在这里直接序列化成二进制数据 防止发送的消息内包含各种游戏数据指针 而造成并发读写的问题 payloadMessageData, err := pb.Marshal(payloadMsg) if err != nil { - logger.Error("parse payload msg to bin error: %v", err) + logger.Error("parse payload msg to bin error: %v, stack: %v", err, logger.Stack()) return } gameMsg.PayloadMessageData = payloadMessageData @@ -257,7 +354,7 @@ func (g *GameManager) SendToWorldA(world *World, cmdId uint16, seq uint32, msg p } } -// SendToWorldAEC 给世界内除自己以外的所有玩家发消息 +// SendToWorldAEC 给世界内除某玩家(一般是自己)以外的所有玩家发消息 func (g *GameManager) SendToWorldAEC(world *World, cmdId uint16, seq uint32, msg pb.Message, uid uint32) { for _, v := range world.GetAllPlayer() { if uid == v.PlayerID { @@ -293,10 +390,6 @@ func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) { } func (g *GameManager) GetClientProtoObjByName(protoObjName string) pb.Message { - if !appConfig.CONF.Hk4e.ClientProtoProxyEnable { - logger.Error("client proto proxy func not enable") - return nil - } fn := g.clientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName") ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)}) obj := ret[0].Interface() diff --git a/gs/game/local_event_manager.go b/gs/game/local_event_manager.go index 9446f7a5..09b21db5 100644 --- a/gs/game/local_event_manager.go +++ b/gs/game/local_event_manager.go @@ -15,6 +15,7 @@ const ( LoadLoginUserFromDbFinish = iota // 玩家登录从数据库加载完成回调 CheckUserExistOnRegFromDbFinish // 玩家注册从数据库查询是否已存在完成回调 RunUserCopyAndSave // 执行一次在线玩家内存数据复制到数据库写入协程 + ExitRunUserCopyAndSave UserOfflineSaveToDbFinish ) @@ -44,6 +45,8 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) { case CheckUserExistOnRegFromDbFinish: playerRegInfo := localEvent.Msg.(*PlayerRegInfo) GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq, playerRegInfo.GateAppId) + case ExitRunUserCopyAndSave: + fallthrough case RunUserCopyAndSave: saveUserIdList := localEvent.Msg.([]uint32) startTime := time.Now().UnixNano() @@ -90,13 +93,22 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) { updatePlayerList = append(updatePlayerList, playerCopy) } } - USER_MANAGER.saveUserChan <- &SaveUserData{ + saveUserData := &SaveUserData{ insertPlayerList: insertPlayerList, updatePlayerList: updatePlayerList, + exitSave: false, } + if localEvent.EventId == ExitRunUserCopyAndSave { + saveUserData.exitSave = true + } + USER_MANAGER.saveUserChan <- saveUserData endTime := time.Now().UnixNano() costTime := endTime - startTime logger.Info("run save user copy cost time: %v ns", costTime) + if localEvent.EventId == ExitRunUserCopyAndSave { + // 在此阻塞掉主协程 不再进行任何消息和任务的处理 + select {} + } case UserOfflineSaveToDbFinish: playerOfflineInfo := localEvent.Msg.(*PlayerOfflineInfo) USER_MANAGER.DeleteUser(playerOfflineInfo.Player.PlayerID) diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index 83848ecb..1f208faa 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -237,7 +237,7 @@ func (t *TickManager) onTick10Second(now int64) { func (t *TickManager) onTick5Second(now int64) { for _, world := range WORLD_MANAGER.GetAllWorld() { - if world.IsBigWorld() { + if WORLD_MANAGER.IsAiWorld(world) { for applyUid := range world.owner.CoopApplyMap { GAME_MANAGER.UserDealEnterWorld(world.owner, applyUid, true) } @@ -349,7 +349,7 @@ func (t *TickManager) onTickSecond(now int64) { } } // 刷怪 - if !world.IsBigWorld() && world.owner.SceneLoadState == model.SceneEnterDone { + if !WORLD_MANAGER.IsRobotWorld(world) && world.owner.SceneLoadState == model.SceneEnterDone { scene := world.GetSceneById(3) monsterEntityCount := 0 for _, entity := range scene.entityMap { @@ -386,10 +386,10 @@ func (t *TickManager) onTick100MilliSecond(now int64) { func (t *TickManager) onTick50MilliSecond(now int64) { // 音乐播放器 for i := 0; i < len(AUDIO_CHAN); i++ { - bigWorld := WORLD_MANAGER.GetBigWorld() - GAME_MANAGER.SendToWorldA(bigWorld, cmd.SceneAudioNotify, 0, &proto.SceneAudioNotify{ + world := WORLD_MANAGER.GetAiWorld() + GAME_MANAGER.SendToWorldA(world, cmd.SceneAudioNotify, 0, &proto.SceneAudioNotify{ Type: 5, - SourceUid: bigWorld.owner.PlayerID, + SourceUid: world.owner.PlayerID, Param1: []uint32{1, <-AUDIO_CHAN}, Param2: nil, Param3: nil, diff --git a/gs/game/user_fight_sync.go b/gs/game/user_fight_sync.go index b244edbe..55fc9f45 100644 --- a/gs/game/user_fight_sync.go +++ b/gs/game/user_fight_sync.go @@ -1,6 +1,7 @@ package game import ( + appConfig "hk4e/common/config" "hk4e/common/constant" "hk4e/common/utils" "hk4e/gs/model" @@ -103,14 +104,22 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p switch entry.ArgumentType { case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT: hitInfo := new(proto.EvtBeingHitInfo) - clientProtoObj := g.GetClientProtoObjByName("EvtBeingHitInfo") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(hitInfo, clientProtoObj, entry.CombatData) - if !ok { - continue + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("EvtBeingHitInfo") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(hitInfo, clientProtoObj, entry.CombatData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(entry.CombatData, hitInfo) + if err != nil { + logger.Error("parse EvtBeingHitInfo error: %v", err) + continue + } } attackResult := hitInfo.AttackResult if attackResult == nil { @@ -149,14 +158,22 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_ENTITY_MOVE: entityMoveInfo := new(proto.EntityMoveInfo) - clientProtoObj := g.GetClientProtoObjByName("EntityMoveInfo") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(entityMoveInfo, clientProtoObj, entry.CombatData) - if !ok { - continue + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("EntityMoveInfo") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(entityMoveInfo, clientProtoObj, entry.CombatData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(entry.CombatData, entityMoveInfo) + if err != nil { + logger.Error("parse EntityMoveInfo error: %v", err) + continue + } } motionInfo := entityMoveInfo.MotionInfo if motionInfo.Pos == nil || motionInfo.Rot == nil { @@ -202,14 +219,22 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_ANIMATOR_STATE_CHANGED: evtAnimatorStateChangedInfo := new(proto.EvtAnimatorStateChangedInfo) - clientProtoObj := g.GetClientProtoObjByName("EvtAnimatorStateChangedInfo") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(evtAnimatorStateChangedInfo, clientProtoObj, entry.CombatData) - if !ok { - continue + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("EvtAnimatorStateChangedInfo") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(evtAnimatorStateChangedInfo, clientProtoObj, entry.CombatData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(entry.CombatData, evtAnimatorStateChangedInfo) + if err != nil { + logger.Error("parse EvtAnimatorStateChangedInfo error: %v", err) + continue + } } logger.Debug("EvtAnimatorStateChangedInfo: %v", entry, player.PlayerID) player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) @@ -295,14 +320,22 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg switch abilityInvokeEntry.ArgumentType { case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_META_ADD_NEW_ABILITY: abilityMetaAddAbility := new(proto.AbilityMetaAddAbility) - clientProtoObj := g.GetClientProtoObjByName("AbilityMetaAddAbility") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(abilityMetaAddAbility, clientProtoObj, abilityInvokeEntry.AbilityData) - if !ok { - continue + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("AbilityMetaAddAbility") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(abilityMetaAddAbility, clientProtoObj, abilityInvokeEntry.AbilityData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(abilityInvokeEntry.AbilityData, abilityMetaAddAbility) + if err != nil { + logger.Error("parse AbilityMetaAddAbility error: %v", err) + continue + } } worldAvatar := world.GetWorldAvatarByEntityId(abilityInvokeEntry.EntityId) if worldAvatar == nil { @@ -314,14 +347,22 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg worldAvatar.abilityList = append(worldAvatar.abilityList, abilityMetaAddAbility.Ability) case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE: abilityMetaModifierChange := new(proto.AbilityMetaModifierChange) - clientProtoObj := g.GetClientProtoObjByName("AbilityMetaModifierChange") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(abilityMetaModifierChange, clientProtoObj, abilityInvokeEntry.AbilityData) - if !ok { - continue + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("AbilityMetaModifierChange") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + continue + } + ok := utils.UnmarshalProtoObj(abilityMetaModifierChange, clientProtoObj, abilityInvokeEntry.AbilityData) + if !ok { + continue + } + } else { + err := pb.Unmarshal(abilityInvokeEntry.AbilityData, abilityMetaModifierChange) + if err != nil { + logger.Error("parse AbilityMetaModifierChange error: %v", err) + continue + } } abilityAppliedModifier := &proto.AbilityAppliedModifier{ ModifierLocalId: abilityMetaModifierChange.ModifierLocalId, diff --git a/gs/game/user_login.go b/gs/game/user_login.go index 5a969811..ce028a1e 100644 --- a/gs/game/user_login.go +++ b/gs/game/user_login.go @@ -49,7 +49,6 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u // 初始化 player.InitAll() - // player.TeamConfig.UpdateTeam() // 确保玩家位置安全 player.Pos.X = player.SafePos.X @@ -65,18 +64,21 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]() player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]() + if userId < 100000000 { + return + } + g.LoginNotify(userId, player, clientSeq) - if userId >= 100000000 { - MESSAGE_QUEUE.SendToAll(&mq.NetMsg{ - MsgType: mq.MsgTypeServer, - EventId: mq.ServerUserOnlineStateChangeNotify, - ServerMsg: &mq.ServerMsg{ - UserId: userId, - IsOnline: true, - }, - }) - } + MESSAGE_QUEUE.SendToAll(&mq.NetMsg{ + MsgType: mq.MsgTypeServer, + EventId: mq.ServerUserOnlineStateChangeNotify, + ServerMsg: &mq.ServerMsg{ + UserId: userId, + IsOnline: true, + }, + }) + TICK_MANAGER.CreateUserGlobalTick(userId) TICK_MANAGER.CreateUserTimer(userId, UserTimerActionTest, 100) } diff --git a/gs/game/user_manager.go b/gs/game/user_manager.go index 631ba0f1..b2da37d6 100644 --- a/gs/game/user_manager.go +++ b/gs/game/user_manager.go @@ -353,6 +353,7 @@ func (u *UserManager) SaveTempOfflineUser(player *model.Player) { type SaveUserData struct { insertPlayerList []*model.Player updatePlayerList []*model.Player + exitSave bool } func (u *UserManager) saveUserHandle() { @@ -360,6 +361,10 @@ func (u *UserManager) saveUserHandle() { saveUserData := <-u.saveUserChan u.SaveUserListToDbSync(saveUserData) u.SaveUserListToRedisSync(saveUserData) + if saveUserData.exitSave { + // 停服落地玩家数据完毕 通知APP主协程关闭程序 + EXIT_SAVE_FIN_CHAN <- true + } } } diff --git a/gs/game/user_multiplayer.go b/gs/game/user_multiplayer.go index 5c0a6b94..ff598015 100644 --- a/gs/game/user_multiplayer.go +++ b/gs/game/user_multiplayer.go @@ -359,6 +359,9 @@ func (g *GameManager) UserLeaveWorld(player *model.Player) bool { } func (g *GameManager) UserWorldAddPlayer(world *World, player *model.Player) { + if !WORLD_MANAGER.IsBigWorld(world) && world.GetWorldPlayerNum() >= 4 { + return + } _, exist := world.playerMap[player.PlayerID] if exist { return diff --git a/gs/game/user_scene.go b/gs/game/user_scene.go index 167cec80..f9212320 100644 --- a/gs/game/user_scene.go +++ b/gs/game/user_scene.go @@ -417,8 +417,8 @@ func (g *GameManager) AddSceneEntityNotifyBroadcast(player *model.Player, scene continue } g.SendMsg(cmd.SceneEntityAppearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityAppearNotify) - logger.Debug("SceneEntityAppearNotify, uid: %v, type: %v, len: %v", - scenePlayer.PlayerID, sceneEntityAppearNotify.AppearType, len(sceneEntityAppearNotify.EntityList)) + // logger.Debug("SceneEntityAppearNotify, uid: %v, type: %v, len: %v", + // scenePlayer.PlayerID, sceneEntityAppearNotify.AppearType, len(sceneEntityAppearNotify.EntityList)) } } @@ -428,8 +428,8 @@ func (g *GameManager) RemoveSceneEntityNotifyToPlayer(player *model.Player, visi DisappearType: visionType, } g.SendMsg(cmd.SceneEntityDisappearNotify, player.PlayerID, player.ClientSeq, sceneEntityDisappearNotify) - logger.Debug("SceneEntityDisappearNotify, uid: %v, type: %v, len: %v", - player.PlayerID, sceneEntityDisappearNotify.DisappearType, len(sceneEntityDisappearNotify.EntityList)) + // logger.Debug("SceneEntityDisappearNotify, uid: %v, type: %v, len: %v", + // player.PlayerID, sceneEntityDisappearNotify.DisappearType, len(sceneEntityDisappearNotify.EntityList)) } func (g *GameManager) RemoveSceneEntityNotifyBroadcast(scene *Scene, visionType proto.VisionType, entityIdList []uint32) { @@ -459,8 +459,8 @@ func (g *GameManager) AddSceneEntityNotify(player *model.Player, visionType prot } entityList := make([]*proto.SceneEntityInfo, 0) for _, entityId := range entityIdList[begin:end] { - entity, ok := scene.entityMap[entityId] - if !ok { + entity, exist := scene.entityMap[entityId] + if !exist { logger.Error("get entity is nil, entityId: %v", entityId) continue } diff --git a/gs/game/user_social.go b/gs/game/user_social.go index 9a2f8fdd..d8f8546b 100644 --- a/gs/game/user_social.go +++ b/gs/game/user_social.go @@ -380,12 +380,29 @@ func (g *GameManager) GetOnlinePlayerListReq(player *model.Player, payloadMsg pb logger.Debug("user get online player list, uid: %v", player.PlayerID) count := 0 + getOnlinePlayerListRsp := &proto.GetOnlinePlayerListRsp{ + PlayerInfoList: make([]*proto.OnlinePlayerInfo, 0), + } + getOnlinePlayerListRsp.PlayerInfoList = append(getOnlinePlayerListRsp.PlayerInfoList, &proto.OnlinePlayerInfo{ + Uid: BigWorldAiUid, + Nickname: BigWorldAiName, + PlayerLevel: 1, + MpSettingType: proto.MpSettingType_MP_SETTING_TYPE_ENTER_AFTER_APPLY, + NameCardId: 210001, + Signature: BigWorldAiSign, + ProfilePicture: &proto.ProfilePicture{AvatarId: 10000007}, + CurPlayerNumInWorld: 1, + }) + count++ onlinePlayerList := make([]*model.Player, 0) // 优先获取本地的在线玩家 for _, onlinePlayer := range USER_MANAGER.GetAllOnlineUserList() { if onlinePlayer.PlayerID == player.PlayerID { continue } + if g.IsMainGs() && onlinePlayer.PlayerID == g.GetAi().PlayerID { + continue + } onlinePlayerList = append(onlinePlayerList, onlinePlayer) count++ if count >= 50 { @@ -406,9 +423,6 @@ func (g *GameManager) GetOnlinePlayerListReq(player *model.Player, payloadMsg pb } } - getOnlinePlayerListRsp := &proto.GetOnlinePlayerListRsp{ - PlayerInfoList: make([]*proto.OnlinePlayerInfo, 0), - } for _, onlinePlayer := range onlinePlayerList { onlinePlayerInfo := g.PacketOnlinePlayerInfo(onlinePlayer) getOnlinePlayerListRsp.PlayerInfoList = append(getOnlinePlayerListRsp.PlayerInfoList, onlinePlayerInfo) diff --git a/gs/game/user_stamina.go b/gs/game/user_stamina.go index b9ced1d9..dbf1b530 100644 --- a/gs/game/user_stamina.go +++ b/gs/game/user_stamina.go @@ -4,6 +4,7 @@ import ( "strings" "time" + appConfig "hk4e/common/config" "hk4e/common/constant" "hk4e/common/utils" "hk4e/gdconf" @@ -22,14 +23,22 @@ func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.Ab case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA: // 大剑重击 或 持续技能 耐力消耗 costStamina := new(proto.AbilityMixinCostStamina) - clientProtoObj := g.GetClientProtoObjByName("AbilityMixinCostStamina") - if clientProtoObj == nil { - logger.Error("get client proto obj is nil") - return - } - ok := utils.UnmarshalProtoObj(costStamina, clientProtoObj, entry.AbilityData) - if !ok { - return + if appConfig.CONF.Hk4e.ClientProtoProxyEnable { + clientProtoObj := g.GetClientProtoObjByName("AbilityMixinCostStamina") + if clientProtoObj == nil { + logger.Error("get client proto obj is nil") + return + } + ok := utils.UnmarshalProtoObj(costStamina, clientProtoObj, entry.AbilityData) + if !ok { + return + } + } else { + err := pb.Unmarshal(entry.AbilityData, costStamina) + if err != nil { + logger.Error("parse AbilityMixinCostStamina error: %v", err) + return + } } // 处理持续耐力消耗 g.SkillSustainStamina(player, costStamina.IsSwim) diff --git a/gs/game/video_player.go b/gs/game/video_player.go index d6eba1e4..1688a937 100644 --- a/gs/game/video_player.go +++ b/gs/game/video_player.go @@ -218,7 +218,7 @@ func (g *GameManager) VideoPlayerUpdate(rgb bool) { if err != nil { return } - world := WORLD_MANAGER.GetBigWorld() + world := WORLD_MANAGER.GetAiWorld() scene := world.GetSceneById(3) for _, v := range SCREEN_ENTITY_ID_LIST { scene.DestroyEntity(v) diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index d83ddbc5..d13ab679 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -18,7 +18,7 @@ import ( type WorldManager struct { worldMap map[uint32]*World snowflake *alg.SnowflakeWorker - bigWorld *World + aiWorld *World // 本服的Ai玩家世界 } func NewWorldManager(snowflake *alg.SnowflakeWorker) (r *WorldManager) { @@ -60,13 +60,6 @@ func (w *WorldManager) CreateWorld(owner *model.Player) *World { multiplayerTeam: CreateMultiplayerTeam(), peerList: make([]*model.Player, 0), } - if world.IsBigWorld() { - // world.aoiManager = aoi.NewAoiManager( - // -8000, 4000, 800, - // -2000, 2000, 1, - // -5500, 6500, 800, - // ) - } world.mpLevelEntityId = world.GetNextWorldEntityId(constant.EntityIdTypeConst.MPLEVEL) w.worldMap[worldId] = world return world @@ -81,20 +74,28 @@ func (w *WorldManager) DestroyWorld(worldId uint32) { delete(w.worldMap, worldId) } -// GetBigWorld 获取本服务器的AI世界 -func (w *WorldManager) GetBigWorld() *World { - return w.bigWorld +// GetAiWorld 获取本服务器的Ai世界 +func (w *WorldManager) GetAiWorld() *World { + return w.aiWorld } -// InitBigWorld 初始化AI世界 -func (w *WorldManager) InitBigWorld(owner *model.Player) { - w.bigWorld = w.GetWorldByID(owner.WorldId) - w.bigWorld.ChangeToMultiplayer() +// InitAiWorld 初始化Ai世界 +func (w *WorldManager) InitAiWorld(owner *model.Player) { + w.aiWorld = w.GetWorldByID(owner.WorldId) + w.aiWorld.ChangeToMultiplayer() go RunPlayAudio() } -func (w *World) IsBigWorld() bool { - return w.owner.PlayerID == 1 +func (w *WorldManager) IsAiWorld(world *World) bool { + return world.id == w.aiWorld.id +} + +func (w *WorldManager) IsRobotWorld(world *World) bool { + return world.owner.PlayerID < 100000000 +} + +func (w *WorldManager) IsBigWorld(world *World) bool { + return (world.id == w.aiWorld.id) && (w.aiWorld.owner.PlayerID == BigWorldAiUid) } // 世界数据结构 @@ -152,7 +153,7 @@ func (w *World) GetPlayerPeerId(player *model.Player) uint32 { peerId = uint32(peerIdIndex) + 1 } } - logger.Debug("get player peer id is: %v, uid: %v", peerId, player.PlayerID) + // logger.Debug("get player peer id is: %v, uid: %v", peerId, player.PlayerID) return peerId } @@ -181,7 +182,15 @@ func (w *World) AddPlayer(player *model.Player, sceneId uint32) { activeAvatarId := player.TeamConfig.GetActiveAvatarId() w.SetPlayerLocalTeam(player, []uint32{activeAvatarId}) } - w.UpdateMultiplayerTeam() + playerNum := w.GetWorldPlayerNum() + if playerNum > 4 { + if !WORLD_MANAGER.IsBigWorld(w) { + return + } + w.AddMultiplayerTeam(player) + } else { + w.UpdateMultiplayerTeam() + } for _, worldPlayer := range w.playerMap { list := w.GetPlayerWorldAvatarList(worldPlayer) maxIndex := len(list) - 1 @@ -207,7 +216,17 @@ func (w *World) RemovePlayer(player *model.Player) { delete(w.multiplayerTeam.localTeamMap, player.PlayerID) delete(w.multiplayerTeam.localAvatarIndexMap, player.PlayerID) delete(w.multiplayerTeam.localTeamEntityMap, player.PlayerID) - w.UpdateMultiplayerTeam() + playerNum := w.GetWorldPlayerNum() + if playerNum > 4 { + if !WORLD_MANAGER.IsBigWorld(w) { + return + } + w.RemoveMultiplayerTeam(player) + } else { + if player.PlayerID != w.owner.PlayerID { + w.UpdateMultiplayerTeam() + } + } } // WorldAvatar 世界角色 @@ -432,14 +451,37 @@ func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) { } } +// TODO 为了实现大世界无限人数写的 +// 现在看来把世界里所有人放进队伍里发给客户端超过8个客户端会崩溃 +// 看来还是不能简单的走通用逻辑 需要对大世界场景队伍做特殊处理 欺骗客户端其他玩家仅仅以场景角色实体的形式出现 + +func (w *World) AddMultiplayerTeam(player *model.Player) { + if !WORLD_MANAGER.IsBigWorld(w) { + return + } + localTeam := w.GetPlayerLocalTeam(player) + w.multiplayerTeam.worldTeam = append(w.multiplayerTeam.worldTeam, localTeam...) +} + +func (w *World) RemoveMultiplayerTeam(player *model.Player) { + worldTeam := make([]*WorldAvatar, 0) + for _, worldAvatar := range w.multiplayerTeam.worldTeam { + if worldAvatar.uid == player.PlayerID { + continue + } + worldTeam = append(worldTeam, worldAvatar) + } + w.multiplayerTeam.worldTeam = worldTeam +} + // UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍 func (w *World) UpdateMultiplayerTeam() { - _, exist := w.playerMap[w.owner.PlayerID] - if !exist { + playerNum := w.GetWorldPlayerNum() + if playerNum > 4 { return } w.multiplayerTeam.worldTeam = make([]*WorldAvatar, 4) - switch w.GetWorldPlayerNum() { + switch playerNum { case 1: // 1P*4 w.copyLocalTeamToWorld(0, 3, 1) @@ -458,8 +500,6 @@ func (w *World) UpdateMultiplayerTeam() { w.copyLocalTeamToWorld(1, 1, 2) w.copyLocalTeamToWorld(2, 2, 3) w.copyLocalTeamToWorld(3, 3, 4) - default: - break } } diff --git a/node/api/api.natsrpc.pb.go b/node/api/api.natsrpc.pb.go index 2dd71ffe..19c368c6 100644 --- a/node/api/api.natsrpc.pb.go +++ b/node/api/api.natsrpc.pb.go @@ -35,6 +35,8 @@ type DiscoveryNATSRPCServer interface { GetGateServerAddr(ctx context.Context, req *GetGateServerAddrReq) (*GateServerAddr, error) // 获取全部网关服务器信息列表 GetAllGateServerInfoList(ctx context.Context, req *NullMsg) (*GateServerInfoList, error) + // 获取主游戏服务器的appid + GetMainGameServerAppId(ctx context.Context, req *NullMsg) (*GetMainGameServerAppIdRsp, error) } // RegisterDiscoveryNATSRPCServer register Discovery service @@ -58,6 +60,8 @@ type DiscoveryNATSRPCClient interface { GetGateServerAddr(ctx context.Context, req *GetGateServerAddrReq, opt ...natsrpc.CallOption) (*GateServerAddr, error) // 获取全部网关服务器信息列表 GetAllGateServerInfoList(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*GateServerInfoList, error) + // 获取主游戏服务器的appid + GetMainGameServerAppId(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*GetMainGameServerAppIdRsp, error) } type _DiscoveryNATSRPCClient struct { @@ -110,3 +114,8 @@ func (c *_DiscoveryNATSRPCClient) GetAllGateServerInfoList(ctx context.Context, err := c.c.Request(ctx, "GetAllGateServerInfoList", req, rep, opt...) return rep, err } +func (c *_DiscoveryNATSRPCClient) GetMainGameServerAppId(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*GetMainGameServerAppIdRsp, error) { + rep := &GetMainGameServerAppIdRsp{} + err := c.c.Request(ctx, "GetMainGameServerAppId", req, rep, opt...) + return rep, err +} diff --git a/node/api/api.pb.go b/node/api/api.pb.go index a10d06a1..d846491f 100644 --- a/node/api/api.pb.go +++ b/node/api/api.pb.go @@ -427,6 +427,53 @@ func (x *GetGateServerAddrReq) GetVersion() string { return "" } +type GetMainGameServerAppIdRsp 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 *GetMainGameServerAppIdRsp) Reset() { + *x = GetMainGameServerAppIdRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMainGameServerAppIdRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMainGameServerAppIdRsp) ProtoMessage() {} + +func (x *GetMainGameServerAppIdRsp) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[8] + 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 GetMainGameServerAppIdRsp.ProtoReflect.Descriptor instead. +func (*GetMainGameServerAppIdRsp) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{8} +} + +func (x *GetMainGameServerAppIdRsp) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + type RegionEc2B struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -438,7 +485,7 @@ type RegionEc2B struct { func (x *RegionEc2B) Reset() { *x = RegionEc2B{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[8] + mi := &file_api_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -451,7 +498,7 @@ func (x *RegionEc2B) String() string { func (*RegionEc2B) ProtoMessage() {} func (x *RegionEc2B) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[8] + mi := &file_api_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -464,7 +511,7 @@ func (x *RegionEc2B) ProtoReflect() protoreflect.Message { // Deprecated: Use RegionEc2B.ProtoReflect.Descriptor instead. func (*RegionEc2B) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{8} + return file_api_proto_rawDescGZIP(), []int{9} } func (x *RegionEc2B) GetData() []byte { @@ -488,7 +535,7 @@ type GateServerAddr struct { func (x *GateServerAddr) Reset() { *x = GateServerAddr{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[9] + mi := &file_api_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -501,7 +548,7 @@ func (x *GateServerAddr) String() string { func (*GateServerAddr) ProtoMessage() {} func (x *GateServerAddr) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[9] + mi := &file_api_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -514,7 +561,7 @@ func (x *GateServerAddr) ProtoReflect() protoreflect.Message { // Deprecated: Use GateServerAddr.ProtoReflect.Descriptor instead. func (*GateServerAddr) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{9} + return file_api_proto_rawDescGZIP(), []int{10} } func (x *GateServerAddr) GetKcpAddr() string { @@ -558,7 +605,7 @@ type GateServerInfo struct { func (x *GateServerInfo) Reset() { *x = GateServerInfo{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[10] + mi := &file_api_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -571,7 +618,7 @@ func (x *GateServerInfo) String() string { func (*GateServerInfo) ProtoMessage() {} func (x *GateServerInfo) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[10] + mi := &file_api_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -584,7 +631,7 @@ func (x *GateServerInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use GateServerInfo.ProtoReflect.Descriptor instead. func (*GateServerInfo) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{10} + return file_api_proto_rawDescGZIP(), []int{11} } func (x *GateServerInfo) GetAppId() string { @@ -619,7 +666,7 @@ type GateServerInfoList struct { func (x *GateServerInfoList) Reset() { *x = GateServerInfoList{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[11] + mi := &file_api_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -632,7 +679,7 @@ func (x *GateServerInfoList) String() string { func (*GateServerInfoList) ProtoMessage() {} func (x *GateServerInfoList) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[11] + mi := &file_api_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -645,7 +692,7 @@ func (x *GateServerInfoList) ProtoReflect() protoreflect.Message { // Deprecated: Use GateServerInfoList.ProtoReflect.Descriptor instead. func (*GateServerInfoList) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{11} + return file_api_proto_rawDescGZIP(), []int{12} } func (x *GateServerInfoList) GetGateServerInfoList() []*GateServerInfo { @@ -692,63 +739,71 @@ var file_api_proto_rawDesc = []byte{ 0x64, 0x22, 0x30, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 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, 0x22, 0x78, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x63, 0x70, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x63, 0x70, 0x41, 0x64, - 0x64, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x63, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6b, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x6d, 0x71, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6d, 0x71, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, 0x5f, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6d, 0x71, 0x50, 0x6f, 0x72, 0x74, 0x22, - 0x59, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x71, 0x41, 0x64, 0x64, - 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x6d, 0x71, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x61, 0x0a, 0x12, 0x47, 0x61, - 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x4b, 0x0a, 0x15, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x67, 0x61, 0x74, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x89, 0x04, - 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, 0x3e, 0x0a, 0x0c, 0x43, 0x61, 0x6e, - 0x63, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0f, 0x4b, 0x65, 0x65, - 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6e, 0x6f, 0x64, - 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 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, + 0x69, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x47, 0x61, + 0x6d, 0x65, 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, 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, 0x22, 0x78, 0x0a, 0x0e, 0x47, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, + 0x63, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, + 0x63, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x63, 0x70, 0x5f, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6b, 0x63, 0x70, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6d, 0x71, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6d, 0x71, 0x50, + 0x6f, 0x72, 0x74, 0x22, 0x59, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, + 0x6d, 0x71, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, + 0x71, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x71, 0x5f, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6d, 0x71, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x61, + 0x0a, 0x12, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x15, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x67, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, + 0x74, 0x32, 0xdd, 0x04, 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, 0x3e, 0x0a, + 0x0c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x19, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 0x22, 0x00, 0x12, 0x44, 0x0a, + 0x0f, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x1c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4b, 0x65, 0x65, 0x70, + 0x61, 0x6c, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 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, 0x12, 0x4f, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1e, - 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, - 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x18, 0x47, 0x65, - 0x74, 0x41, 0x6c, 0x6c, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 0x1a, 0x1c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, - 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, 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, + 0x67, 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, 0x12, 0x4f, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x74, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x52, + 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x22, 0x00, 0x12, 0x4d, + 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 0x1a, 0x1c, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x52, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x12, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67, 0x1a, 0x23, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x47, 0x61, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x73, 0x70, 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 ( @@ -763,24 +818,25 @@ func file_api_proto_rawDescGZIP() []byte { return file_api_proto_rawDescData } -var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 13) 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 - (*CancelServerReq)(nil), // 5: node.api.CancelServerReq - (*KeepaliveServerReq)(nil), // 6: node.api.KeepaliveServerReq - (*GetGateServerAddrReq)(nil), // 7: node.api.GetGateServerAddrReq - (*RegionEc2B)(nil), // 8: node.api.RegionEc2b - (*GateServerAddr)(nil), // 9: node.api.GateServerAddr - (*GateServerInfo)(nil), // 10: node.api.GateServerInfo - (*GateServerInfoList)(nil), // 11: node.api.GateServerInfoList + (*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 + (*CancelServerReq)(nil), // 5: node.api.CancelServerReq + (*KeepaliveServerReq)(nil), // 6: node.api.KeepaliveServerReq + (*GetGateServerAddrReq)(nil), // 7: node.api.GetGateServerAddrReq + (*GetMainGameServerAppIdRsp)(nil), // 8: node.api.GetMainGameServerAppIdRsp + (*RegionEc2B)(nil), // 9: node.api.RegionEc2b + (*GateServerAddr)(nil), // 10: node.api.GateServerAddr + (*GateServerInfo)(nil), // 11: node.api.GateServerInfo + (*GateServerInfoList)(nil), // 12: node.api.GateServerInfoList } var file_api_proto_depIdxs = []int32{ - 9, // 0: node.api.RegisterServerReq.gate_server_addr:type_name -> node.api.GateServerAddr - 10, // 1: node.api.GateServerInfoList.gate_server_info_list:type_name -> node.api.GateServerInfo + 10, // 0: node.api.RegisterServerReq.gate_server_addr:type_name -> node.api.GateServerAddr + 11, // 1: node.api.GateServerInfoList.gate_server_info_list:type_name -> node.api.GateServerInfo 3, // 2: node.api.Discovery.RegisterServer:input_type -> node.api.RegisterServerReq 5, // 3: node.api.Discovery.CancelServer:input_type -> node.api.CancelServerReq 6, // 4: node.api.Discovery.KeepaliveServer:input_type -> node.api.KeepaliveServerReq @@ -788,15 +844,17 @@ var file_api_proto_depIdxs = []int32{ 0, // 6: node.api.Discovery.GetRegionEc2b:input_type -> node.api.NullMsg 7, // 7: node.api.Discovery.GetGateServerAddr:input_type -> node.api.GetGateServerAddrReq 0, // 8: node.api.Discovery.GetAllGateServerInfoList:input_type -> node.api.NullMsg - 4, // 9: node.api.Discovery.RegisterServer:output_type -> node.api.RegisterServerRsp - 0, // 10: node.api.Discovery.CancelServer:output_type -> node.api.NullMsg - 0, // 11: node.api.Discovery.KeepaliveServer:output_type -> node.api.NullMsg - 2, // 12: node.api.Discovery.GetServerAppId:output_type -> node.api.GetServerAppIdRsp - 8, // 13: node.api.Discovery.GetRegionEc2b:output_type -> node.api.RegionEc2b - 9, // 14: node.api.Discovery.GetGateServerAddr:output_type -> node.api.GateServerAddr - 11, // 15: node.api.Discovery.GetAllGateServerInfoList:output_type -> node.api.GateServerInfoList - 9, // [9:16] is the sub-list for method output_type - 2, // [2:9] is the sub-list for method input_type + 0, // 9: node.api.Discovery.GetMainGameServerAppId:input_type -> node.api.NullMsg + 4, // 10: node.api.Discovery.RegisterServer:output_type -> node.api.RegisterServerRsp + 0, // 11: node.api.Discovery.CancelServer:output_type -> node.api.NullMsg + 0, // 12: node.api.Discovery.KeepaliveServer:output_type -> node.api.NullMsg + 2, // 13: node.api.Discovery.GetServerAppId:output_type -> node.api.GetServerAppIdRsp + 9, // 14: node.api.Discovery.GetRegionEc2b:output_type -> node.api.RegionEc2b + 10, // 15: node.api.Discovery.GetGateServerAddr:output_type -> node.api.GateServerAddr + 12, // 16: node.api.Discovery.GetAllGateServerInfoList:output_type -> node.api.GateServerInfoList + 8, // 17: node.api.Discovery.GetMainGameServerAppId:output_type -> node.api.GetMainGameServerAppIdRsp + 10, // [10:18] is the sub-list for method output_type + 2, // [2:10] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name 2, // [2:2] is the sub-list for extension extendee 0, // [0:2] is the sub-list for field type_name @@ -905,7 +963,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegionEc2B); i { + switch v := v.(*GetMainGameServerAppIdRsp); i { case 0: return &v.state case 1: @@ -917,7 +975,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GateServerAddr); i { + switch v := v.(*RegionEc2B); i { case 0: return &v.state case 1: @@ -929,7 +987,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GateServerInfo); i { + switch v := v.(*GateServerAddr); i { case 0: return &v.state case 1: @@ -941,6 +999,18 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GateServerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GateServerInfoList); i { case 0: return &v.state @@ -959,7 +1029,7 @@ func file_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_proto_rawDesc, NumEnums: 0, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/node/api/api.proto b/node/api/api.proto index 59881f02..bc7e5d1b 100644 --- a/node/api/api.proto +++ b/node/api/api.proto @@ -19,6 +19,8 @@ service Discovery { rpc GetGateServerAddr (GetGateServerAddrReq) returns (GateServerAddr) {} // 获取全部网关服务器信息列表 rpc GetAllGateServerInfoList (NullMsg) returns (GateServerInfoList) {} + // 获取主游戏服务器的appid + rpc GetMainGameServerAppId (NullMsg) returns (GetMainGameServerAppIdRsp) {} } message NullMsg { @@ -57,6 +59,10 @@ message GetGateServerAddrReq { string version = 1; } +message GetMainGameServerAppIdRsp { + string app_id = 1; +} + message RegionEc2b { bytes data = 1; } diff --git a/node/service/discovery.go b/node/service/discovery.go index d11ac0b2..2acb2e3e 100644 --- a/node/service/discovery.go +++ b/node/service/discovery.go @@ -16,6 +16,10 @@ import ( "github.com/pkg/errors" ) +const ( + MaxGsId = 1000 +) + var _ api.DiscoveryNATSRPCServer = (*DiscoveryService)(nil) type ServerInstanceSortList []*ServerInstance @@ -41,6 +45,7 @@ type ServerInstance struct { gateServerMqPort uint32 version string lastAliveTime int64 + gsId uint32 } type DiscoveryService struct { @@ -100,7 +105,12 @@ func (s *DiscoveryService) RegisterServer(ctx context.Context, req *api.Register AppId: appId, } if req.ServerType == api.GS { - rsp.GsId = atomic.AddUint32(&s.gsIdCounter, 1) + gsId := atomic.AddUint32(&s.gsIdCounter, 1) + if gsId > MaxGsId { + return nil, errors.New("above max gs count") + } + inst.gsId = gsId + rsp.GsId = gsId } return rsp, nil } @@ -218,6 +228,34 @@ func (s *DiscoveryService) GetAllGateServerInfoList(ctx context.Context, req *ap }, nil } +// GetMainGameServerAppId 获取主游戏服务器的appid +func (s *DiscoveryService) GetMainGameServerAppId(ctx context.Context, req *api.NullMsg) (*api.GetMainGameServerAppIdRsp, error) { + logger.Debug("get main game server appid") + instMap, exist := s.serverInstanceMap[api.GS] + if !exist { + return nil, errors.New("game server not exist") + } + if s.getServerInstanceMapLen(instMap) == 0 { + return nil, errors.New("no game server found") + } + appid := "" + minGsId := uint32(MaxGsId) + instMap.Range(func(key, value any) bool { + serverInstance := value.(*ServerInstance) + if serverInstance.gsId < minGsId { + minGsId = serverInstance.gsId + appid = serverInstance.appId + } + return true + }) + if appid == "" { + return nil, errors.New("main game server not found") + } + return &api.GetMainGameServerAppIdRsp{ + AppId: appid, + }, nil +} + func (s *DiscoveryService) getRandomServerInstance(instMap *sync.Map) *ServerInstance { instList := make(ServerInstanceSortList, 0) instMap.Range(func(key, value any) bool {