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;
        }