Ejemplo n.º 1
0
        /// <summary>
        /// 创建一个匹配队伍,由玩家发起的本地消息
        /// 创建的队伍并不直接放入匹配队列,而是通过匹配系统进行管理
        /// 每个MatchTeam 有若干个状态进行控制
        /// </summary>
        private void OnCreateMatchTeam(string playerId)
        {
            S2C_CreateMatchTeamComplete.Types.State state = S2C_CreateMatchTeamComplete.Types.State.Complete;
            ulong teamId = default;

            if (m_teamDic.Values.Count > m_gameMatchTeamConfig.MaxCount)
            {
                Log.Error("服务器队伍容量过载");
                state = S2C_CreateMatchTeamComplete.Types.State.SystemError;
                goto Result;
            }
            if ((teamId = FindMatchTeamById(playerId)) != default)
            {
                Log.Info("创建队伍失败,因为玩家已经在队伍中了");
                state = S2C_CreateMatchTeamComplete.Types.State.HaveTeam;
                goto Result;
            }
            //创建队伍,返回队伍id
            UInt64    id        = m_roomIdFactory.AllocateSessionId();
            MatchTeam matchTeam = new MatchTeam(id, m_gameMatchTeamConfig.TeamCapacity);//生成一个房间,并通知对应的玩家队伍生成好了

            teamId = matchTeam.Id;
            //加入队伍字典中
            m_teamDic.TryAdd(id, matchTeam);
            matchTeam.Add(playerId);

Result:
            //向玩家发送 创建并且加入到队伍的消息
            PostLocalMessageToCtx(new SystemSendNetMessage {
                Message = new S2C_CreateMatchTeamComplete {
                    State = state, MatchTeamId = teamId
                }, PlayerId = playerId
            }, playerId);
            Log.Info($"创建房间Id = {teamId} 执行完毕 state = " + state.ToString());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 刷新队伍信息并且广播给队伍内玩家
        /// </summary>
        private void OnUpdateMatchTeam(ulong teamId)
        {
            S2C_UpdateMatchTeamInfo message = null;
            MatchTeam matchTeam             = null;

            if (!m_teamDic.TryGetValue(teamId, out matchTeam))
            {
                return;
            }
            //队伍状态检测
            if (matchTeam.State != MatchTeam.MatchTeamState.OPEN)
            {
                goto Result;
            }
            message                      = new S2C_UpdateMatchTeamInfo();
            message.TeamInfo             = new MatchTeamInfo();
            message.TeamInfo.MatchTeamId = teamId;
            message.MatchTeamId          = teamId;
            foreach (var item in matchTeam.GetMembers())
            {
                message.TeamInfo.PlayerIds.Add(item);
            }

Result:
            if (matchTeam != null && message != null)
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, matchTeam?.GetMembers());
            }
        }
Ejemplo n.º 3
0
 public bool IsContain(MatchTeam matchTeam)
 {
     if (m_matchingQue.Contains(matchTeam))
     {
         return(true);
     }
     return(false);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// 查找队伍的匹配队列
 /// </summary>
 /// <param name="matchTeam"></param>
 /// <returns></returns>
 private GameMatchPlayerContextQueue FindMatchTeamQueue(MatchTeam matchTeam)
 {
     foreach (var item in m_gameMatchPlayerCtxQueDic.Values)
     {
         if (item.IsContain(matchTeam))
         {
             return(item);
         }
     }
     return(null);
 }
Ejemplo n.º 5
0
        public void OnJoinMatchQueue(MatchTeam matchTeam)
        {
            OnEnterLock();
            //先做状态检查  再执行逻辑
            if (matchTeam.State != MatchTeam.MatchTeamState.OPEN)
            {
                return;
            }
            //将队伍添加到队列中  这个状态属于中间态  客户端感知不到这个状态的存在
            m_matchingQue.Add(matchTeam);
            matchTeam.State = MatchTeam.MatchTeamState.Matching;


            LeaveLock();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 队伍进入匹配队列
        /// 保证是队长发起 保证队伍人数大于0人
        /// </summary>
        public void OnJoinMatchQueue(ulong teamId, string playerId, int barrierId)
        {
            S2CM_JoinMatchQueueComplete message = new S2CM_JoinMatchQueueComplete();

            message.State = S2CM_JoinMatchQueueComplete.Types.State.Fail;
            //1 验证 队伍是否存在
            MatchTeam matchTeam = null;
            GameMatchPlayerContextQueue gameMatchPlayerContextQueue = null;

            if (!m_teamDic.TryGetValue(teamId, out matchTeam))
            {
                goto Result;
            }
            //2 验证队长是否合法
            if (matchTeam.GetCaptainId() != playerId)
            {
                goto Result;
            }
            //3 验证team状态是否满足
            if (matchTeam.State != MatchTeam.MatchTeamState.OPEN)
            {
                goto Result;
            }
            //4 验证是否有对应的关卡匹配队列

            if (!m_gameMatchPlayerCtxQueDic.TryGetValue(barrierId, out gameMatchPlayerContextQueue))
            {
                goto Result;
            }
            //5 向匹配队列加入该队伍  方法内修改matchTeam的状态
            gameMatchPlayerContextQueue.OnJoinMatchQueue(matchTeam);
            message.State       = S2CM_JoinMatchQueueComplete.Types.State.Ok;
            message.BarrierId   = barrierId;
            message.MatchTeamId = teamId;
Result:
            if (message.State == S2CM_JoinMatchQueueComplete.Types.State.Ok)
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, matchTeam.GetMembers());
            }
            else
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, playerId);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 由于队伍的主动退出或者异常状态,导致队伍离开匹配队列
        /// 队列所有操作进行上锁
        ///
        /// </summary>
        /// <param name="playerId"></param>
        public void OnExitMatchQueue(MatchTeam matchTeam)
        {
            OnEnterLock();
            switch (matchTeam.State)
            {
            case MatchTeam.MatchTeamState.Matching:
                //这个状态是客户端能够感知
                m_matchingQue.Remove(matchTeam);

                matchTeam.State = MatchTeam.MatchTeamState.OPEN;    //退出匹配队列后 队伍开放

                break;

            default: break;
            }



            LeaveLock();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// TODO:关闭一个玩家现场在匹配系统的存在
        /// 安全操作,尽管退出
        /// </summary>
        /// <param name="toMatchPlayerShutdownMessage"></param>
        private void OnShutdownPlayer(ToMatchPlayerShutdownMessage message)
        {
            Log.Info("收到了玩家现场发来的关闭消息");
            var       playerId  = message.playerId;
            var       teamId    = FindMatchTeamById(playerId);
            MatchTeam matchTeam = null;

            if (teamId == default)
            {
                return;
            }
            if (!m_teamDic.TryGetValue(teamId, out matchTeam))
            {
                return;
            }

            lock (matchTeam)
            {
                if (matchTeam.State == MatchTeam.MatchTeamState.INBATTLE)
                {
                    Log.Info("玩家掉线,重连超时,退出队伍  TeamId" + matchTeam.Id + "Team State = " + matchTeam.State);
                    OnExitMatchTeam(teamId, playerId);
                    return;
                }
                //匹配队列正在匹配,需要将队伍从匹配队列中删除
                if (matchTeam.State == MatchTeam.MatchTeamState.Matching)
                {
                    Log.Info("玩家掉线,重连超时,退出队伍  TeamId" + matchTeam.Id + "Team State = " + matchTeam.State);

                    OnExitMatchTeam(teamId, playerId);
                    return;
                }
                //最简单的退出 直接交给退出队伍执行
                if (matchTeam.State == MatchTeam.MatchTeamState.OPEN)
                {
                    Log.Info("玩家掉线,重连超时,退出队伍  TeamId" + matchTeam.Id + "Team State = " + matchTeam.State);
                    OnExitMatchTeam(teamId, playerId);
                    return;
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 队伍离开匹配队列
        /// 任何队伍中的玩家都能发起队伍离开匹配队列
        /// </summary>
        public void OnExitMatchQueue(ulong teamId, string playerId)
        {
            //1 验证 队伍是否存在
            MatchTeam matchTeam = null;

            if (!m_teamDic.TryGetValue(teamId, out matchTeam))
            {
                return;
            }
            //2 验证队伍是否包含该玩家
            if (!matchTeam.IsContain(playerId))
            {
                return;
            }
            //3 检查队伍状态是否合法
            if (matchTeam.State != MatchTeam.MatchTeamState.Matching)
            {
                return;
            }
            //4 获取匹配队列
            var matchQueue = FindMatchTeamQueue(matchTeam);

            if (matchQueue == null)
            {
                return;
            }
            //5 从匹配队列中删除
            matchQueue.OnExitMatchQueue(matchTeam);
            //6 向队伍内人广播退出匹配队列
            if (matchTeam.State == MatchTeam.MatchTeamState.OPEN)
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = new S2CM_ExitMatchQueue {
                        LaunchPlayerId = playerId, MatchTeamId = teamId, State = S2CM_ExitMatchQueue.Types.State.Client
                    }
                }, matchTeam?.GetMembers());
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 玩家加入队伍
        /// </summary>
        /// <param name="teamId"></param>
        /// <param name="playerId"></param>
        private void OnJoinMatchTeam(UInt64 teamId, string playerId)
        {
            MatchTeam matchTeam = null;
            S2CM_JoinMatchTeamComplete message = new S2CM_JoinMatchTeamComplete();

            message.State          = S2CM_JoinMatchTeamComplete.Types.State.Complete;
            message.LaunchPlayerId = playerId;

            ulong realTeamId = 0;

            if ((realTeamId = FindMatchTeamById(playerId)) != default)
            {
                Log.Error("加入队伍失败,因为玩家已经在队伍中了");
                message.State       = S2CM_JoinMatchTeamComplete.Types.State.HaveTeam;
                message.MatchTeamId = realTeamId;
                goto Result;
            }

            if (!m_teamDic.TryGetValue(teamId, out matchTeam))
            {
                message.State = S2CM_JoinMatchTeamComplete.Types.State.SystemError;
                goto Result;
            }
            //队伍状态检测
            if (matchTeam.State != MatchTeam.MatchTeamState.OPEN)
            {
                message.State = S2CM_JoinMatchTeamComplete.Types.State.SystemError;
                goto Result;
            }

            //检测队伍容量
            if (!matchTeam.IsFull())
            {
                message.State = S2CM_JoinMatchTeamComplete.Types.State.SystemError;
                goto Result;
            }
            matchTeam.Add(playerId);//向队伍内添加玩家
            message.LaunchPlayerId = playerId;
            message.MatchTeamId    = matchTeam.Id;
Result:
            if (matchTeam == null)
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, playerId);
            }
            else
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, matchTeam?.GetMembers());
                if (matchTeam.CurrentCount <= 0)//如果这时候队伍的人数为空 则执行清除工作 并设置队伍的状态为关闭
                {
                    //可以执行清除任务了
                    if (m_teamDic.TryRemove(matchTeam.Id, out matchTeam))
                    {
                        matchTeam.State = MatchTeam.MatchTeamState.CLOSE;
                    }
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 玩家离开队伍
        /// </summary>
        private void OnExitMatchTeam(UInt64 teamId, string playerId)
        {
            //如果离开队伍后 房间人数为0 那么就执行清除任务 并设置房间的状态为Close
            S2CM_ExitMatchTeamComplete message = new S2CM_ExitMatchTeamComplete {
                State = S2CM_ExitMatchTeamComplete.Types.State.Ok
            };

            message.LaunchPlayerId = playerId;
            message.MatchTeamId    = teamId;
            MatchTeam matchTeam  = null;
            ulong     realTeamId = FindMatchTeamById(playerId); //首先不信任客户端 在服务器内找到玩家

            if (realTeamId == default)                          //找不到说明是个野消息
            {
                message.State = S2CM_ExitMatchTeamComplete.Types.State.Fail;
                goto Result;
            }
            else
            {
                if (realTeamId == teamId)                              //如果队伍一样 说明是真实消息
                {
                    if (!m_teamDic.TryGetValue(teamId, out matchTeam)) //没有队伍
                    {
                        message.State = S2CM_ExitMatchTeamComplete.Types.State.Fail;
                        goto Result;
                    }
                }
                else//否则 就是虚假消息,目前决策是这个用户是个脏用户,也需要被清除,直接从找到的真是队伍中删除
                {
                    if (!m_teamDic.TryGetValue(realTeamId, out matchTeam))//没有队伍
                    {
                        message.State = S2CM_ExitMatchTeamComplete.Types.State.Fail;
                        goto Result;
                    }
                }
            }

            if (matchTeam.State == MatchTeam.MatchTeamState.CLOSE) //队伍不开放暂时不能退出,脏的也不让退
            {
                message.State = S2CM_ExitMatchTeamComplete.Types.State.Fail;
                Log.Info("由于队伍已经处于关闭所以退出失败 = " + playerId);
                goto Result;
            }

            OnExitMatchQueue(matchTeam.Id, playerId);
            if (!matchTeam.Remove(playerId))//从队伍中移除
            {
                message.State = S2CM_ExitMatchTeamComplete.Types.State.Fail;
                goto Result;
            }
            message.LaunchPlayerId = playerId;
            message.MatchTeamId    = matchTeam.Id;
            //TODO:还要向战斗系统发送玩家退出的请求


Result:
            PostLocalMessageToCtx(new SystemSendNetMessage {
                Message = message
            }, playerId);                                                                   //向发起者发送
            if (matchTeam != null)
            {
                PostLocalMessageToCtx(new SystemSendNetMessage {
                    Message = message
                }, matchTeam.GetMembers());
                if (matchTeam.CurrentCount <= 0)//如果这时候队伍的人数为空 则执行清除工作 并设置队伍的状态为关闭
                {
                    //可以执行清除任务了
                    if (m_teamDic.TryRemove(matchTeam.Id, out matchTeam))
                    {
                        matchTeam.State = MatchTeam.MatchTeamState.CLOSE;
                    }
                }
            }
        }