public override void OnResult() { m_response = new S2C_LoginMessage { PlayerGameId = m_gameServerContext.ContextStringName, State = m_state? S2C_LoginMessage.Types.State.Ok:S2C_LoginMessage.Types.State.Fail }; Log.Info("Login 回调:" + m_response.ToJson()); m_reply(m_response); //gameServerContext.Send(); }
/// <summary> /// 验证信息 登陆 /// 这是我们规定的硬登陆 无论服务器有无应用层的现场关闭否,都将覆盖之 /// </summary> /// <returns></returns> public async Task OnAuthByLogin(C2S_LoginMessage message, Action <S2C_LoginMessage> reply) { string account = message.Account; string password = message.Password; S2C_LoginMessage response; S2C_LoginMessage.Types.State result = S2C_LoginMessage.Types.State.Ok; //设置现场状态 if (m_csm.SetStateCheck(PlayerContextStateMachine.EventOnAuthLoginReq) == -1) { Log.Trace("OnAuthByLogin::PlayerContextStateMachine switch Fail to LoginReq "); result = S2C_LoginMessage.Types.State.Fail; //PostLocalMessage(new LocalMessageShutdownContext { m_shutdownRightNow = true }); goto RETURN; } // 进行数据库验证 var authDB = await ValidateAuthLogin(account, password); //验证失败则通知客户端 if (!authDB) { //设置现场状态 if (m_csm.SetStateCheck(PlayerContextStateMachine.EventOnAuthLoginFail) == -1) { Log.Info("OnAuthByLogin::PlayerContextStateMachine switch Fail to LoginFail"); return; } Log.Info(account + " 验证失败"); result = S2C_LoginMessage.Types.State.Fail; goto RETURN; } //获取数据库player的实体 m_gameServerDBPlayer = await GetPlayerFromDBAsync(account); if (m_gameServerDBPlayer == null) { Log.Info("gameServerDBPlayer is NULL"); result = S2C_LoginMessage.Types.State.Fail; goto RETURN; } //DB的唯一标识符代表着这个玩家应用层的Id m_gameUserId = m_gameServerDBPlayer.userName; //将玩家现场注册到应用层上 var brpc = GameServer.Instance.PlayerCtxManager.RegisterPlayerContextByString(m_gameUserId, this); //表示已有旧的玩家现场在服务器中 需要对旧玩家现场的状态进行迁移和销毁 if (!brpc) { var oldCtx = GameServer.Instance.PlayerCtxManager.FindPlayerContextByString(m_gameUserId); if (oldCtx != null) { oldCtx.PostLocalMessage(new LocalMessageShutdownContext { m_shutdownRightNow = true }); var loginMsg = "用户已登录,服务器关闭旧用户,请重新登录"; result = S2C_LoginMessage.Types.State.Fail; Log.Debug("userName = "******"\nMessage = " + loginMsg); goto RETURN; } } //修改玩家现场状态机 if (m_csm.SetStateCheck(PlayerContextStateMachine.EventOnAuthLoginOK) == -1) { Log.Info("OnAuthByLogin::PlayerContextStateMachine switch Fail To LoginOk"); result = S2C_LoginMessage.Types.State.Fail; goto RETURN; } //由于目前是单服 所以直接将玩家现场状态设置成验证成功状态 if (m_csm.SetStateCheck(PlayerContextStateMachine.EventOnSessionLoginOK) == -1) { Log.Info("OnAuthByLogin::PlayerContextStateMachine switch Fail To SessuibLoginOk"); result = S2C_LoginMessage.Types.State.Fail; goto RETURN; } //向客户端发送登陆验证成功 RETURN: if (result == S2C_LoginMessage.Types.State.Ok) { response = new S2C_LoginMessage { PlayerGameId = this.m_gameUserId, State = result }; await OnLoginOk();//TODO:通知应用层登录流程完成 } else { response = new S2C_LoginMessage { PlayerGameId = message.Account, State = result } }; reply(response); }
/// <summary> /// 软登陆,由于玩家掉线延迟导致断网,选择重连进行验证时候的登陆 /// 如果存在旧现场需要恢复,则进行恢复现场上下文 /// </summary> /// <returns></returns> public async Task OnAuthReCByLogin(C2S_ReConnectByLogin message) { string account = message.Account; string password = message.Password; #pragma warning disable CS0219 // 变量“response”已被赋值,但从未使用过它的值 S2C_LoginMessage response = null; #pragma warning restore CS0219 // 变量“response”已被赋值,但从未使用过它的值 //设置现场状态 if (m_csm.SetStateCheck(PlayerContextStateMachine.EventOnSessionLoginReq) == -1) { Log.Info("OnAuthByLogin::PlayerContextStateMachine switch Fail to SessionLoginReq"); return; } // 进行数据库验证 var authDB = await ValidateAuthLogin(account, password); if (!authDB) { Log.Info("OnAuthReCByLogin::FAIL TO authDB"); //验证Session失败先不理会 goto RETURN; } //获取数据库player的实体 m_gameServerDBPlayer = await GetPlayerFromDBAsync(account); if (m_gameServerDBPlayer == null) { Log.Info("gameServerDBPlayer is NULL"); goto RETURN; } //DB的唯一标识符代表着这个玩家应用层的Id m_gameUserId = m_gameServerDBPlayer.userName.ToString(); //开始验证是否已经存在userid对应的玩家现场 GameServerPlayerContext oldCtx = (GameServerPlayerContext)GameServer. Instance.PlayerCtxManager.FindPlayerContextByString(m_gameUserId); //如果存在 则判定为需要重连 需要恢复现场状态 //这里可以判断设备Id 判断是否需要重连 或者是挤掉原来老的现场设备 //PS:以后Session验证要更加完全 不能只验证账号密码 if (oldCtx != null) { bool ret = await ContextTransform(oldCtx); if (!ret) { } // 在现场转移之后不能执行任何代码了,立刻退出 return; } //当前玩家验证成功且不存在断线则设置正确的玩家状态 RETURN: if (authDB) { m_csm.SetStateCheck(PlayerContextStateMachine.EventOnSessionLoginOK); } //TODO:添加发给客户端的验证成功且不重连的消息 //Send(null); return; }