示例#1
0
 internal void AddUser(MatchUser user)
 {
     if (this.users.Contains(user))
     {
         return;
     }
     this.users.Add(user);
     user.grading = this;
     this.system.RaiseEvent(MatchUserEvent.Type.AddToGrading, user, null);
 }
示例#2
0
        public MatchUser CreateUser(ulong id, int rank)
        {
            Grading grading = this.SelectGrading(rank);

            if (grading == null)
            {
                return(null);
            }
            MatchUser user = new MatchUser(id, rank);

            grading.AddUser(user);
            return(user);
        }
示例#3
0
 internal void RemoveUser(MatchUser user)
 {
     //从等候室中移除玩家
     if (user.lounge != null)
     {
         MatchingLounge lounge = user.lounge;
         user.lounge.RemoveUser(user);
         //添加事件
         this.system.RaiseEvent(MatchUserEvent.Type.RemoveFromLounge, user, lounge.GetState());
     }
     this.users.Remove(user);
     user.grading = null;
     this.system.RaiseEvent(MatchUserEvent.Type.RemoveFromGrading, user, null);
 }
示例#4
0
        public string Dump()
        {
            StringBuilder sb    = new StringBuilder();
            int           count = this.users.Length;

            for (int i = 0; i < count; i++)
            {
                MatchUser user = this.users[i];
                sb.Append(user == null ? $"{i}:null" : $"{i}:{user.Dump()}");
                if (i < count - 1)
                {
                    sb.AppendLine();
                }
            }
            return(sb.ToString());
        }
示例#5
0
 /// <summary>
 /// 匹配成功后清理
 /// </summary>
 internal void Clear()
 {
     //从分段中移除这些玩家
     for (int i = 0; i < this._users.Length; i++)
     {
         MatchUser user = this._users[i];
         if (user == null)
         {
             continue;
         }
         user.grading.RemoveUser(user);
         user.lounge = null;
     }
     Array.Clear(this._users, 0, this._users.Length);
     this.numUsers = 0;
 }
示例#6
0
        private void BeginBattle(MatchState state)
        {
            BSInfo appropriateBSInfo = CS.instance.appropriateBSInfo;

            //没有找到合适的bs,通知客户端匹配失败
            if (appropriateBSInfo == null)
            {
                this.NotifyGCEnterBattleFailed(state.users, Protos.CS2GC_EnterBattle.Types.Result.BsnotFound);
                return;
            }

            //todo 现在先随机一张地图
            Random rnd      = new Random();
            int    mapCount = Defs.GetMapCount();
            int    mapID    = rnd.Next(0, mapCount);

            Protos.CS2BS_BattleInfo battleInfo = ProtoCreator.Q_CS2BS_BattleInfo();
            battleInfo.MapID       = mapID;
            battleInfo.ConnTimeout = ( int )Consts.WAITING_ROOM_TIME_OUT;
            for (int i = 0; i < state.numTeam; i++)
            {
                Protos.CS2BS_TeamInfo ti = new Protos.CS2BS_TeamInfo();
                battleInfo.TeamInfos.Add(ti);
                MatchUser[] matchUsers = state.tUsers[i];
                for (int j = 0; j < state.numUserPerTeam; j++)
                {
                    MatchUser matchUser        = matchUsers[j];
                    CSUser    user             = CS.instance.userMgr.GetUser(matchUser.id);
                    Protos.CS2BS_PlayerInfo pi = new Protos.CS2BS_PlayerInfo
                    {
                        GcNID        = user.ukey | ( ulong )appropriateBSInfo.lid << 32,
                            ActorID  = user.actorID,
                            Avatar   = user.avatar,
                            Nickname = user.nickname,
                            Gender   = user.gender,
                            Money    = user.money,
                            Diamoned = user.diamoned,
                            Rank     = user.rank,
                            Exp      = user.exp
                    };
                    ti.PlayerInfos.Add(pi);
                }
            }
            CS.instance.netSessionMgr.Send(appropriateBSInfo.sessionID, battleInfo, RPCEntry.Pop(this.OnBattleInfoRet, state,
                                                                                                 appropriateBSInfo.ip, appropriateBSInfo.port,
                                                                                                 appropriateBSInfo.sessionID, appropriateBSInfo.lid));
        }
示例#7
0
        /// <summary>
        /// 从等候室中移除玩家
        /// </summary>
        internal bool RemoveUser(MatchUser user)
        {
            if (user.lounge == null)
            {
                return(false);
            }
            int index = Array.IndexOf(this._users, user);

            if (index < 0)
            {
                return(false);
            }
            this._users[index] = null;
            --this.numUsers;
            user.lounge = null;
            return(true);
        }
示例#8
0
        /// <summary>
        /// 把玩家添加到等候室,已存在的将会忽略并返回失败
        /// </summary>
        internal bool AddUser(MatchUser user)
        {
            if (user.lounge != null)
            {
                return(false);
            }
            int index = Array.IndexOf(this._users, null);

            if (index < 0)
            {
                return(false);
            }
            this._users[index] = user;
            ++this.numUsers;
            user.lounge = this;
            return(true);
        }
示例#9
0
        /// <summary>
        /// 处理回应
        /// </summary>
        private void OnBattleInfoRet(NetSessionBase session_, Google.Protobuf.IMessage ret, object[] args)
        {
            MatchState state  = ( MatchState )args[0];
            string     bsIP   = ( string )args[1];
            int        bsPort = ( int )args[2];
            uint       bsSID  = ( uint )args[3];
            uint       bsLID  = ( uint )args[4];

            Protos.BS2CS_BattleInfoRet battleInfoRet = (Protos.BS2CS_BattleInfoRet)ret;
            //检查是否成功创建战场
            if (battleInfoRet.Result != Protos.Global.Types.ECommon.Success)
            {
                this.NotifyGCEnterBattleFailed(state.users, Protos.CS2GC_EnterBattle.Types.Result.BattleCreateFailed);
                return;
            }

            Logger.Log($"battle:{battleInfoRet.Bid} created");

            CS.instance.battleStaging.OnBattleCreated(bsLID, battleInfoRet.Bid);

            //把所有玩家移动到战场暂存器里
            int count = state.numTeam * state.numUserPerTeam;

            for (int i = 0; i < count; i++)
            {
                MatchUser matchUser = state.users[i];
                CSUser    user      = CS.instance.userMgr.GetUser(matchUser.id);
                CS.instance.battleStaging.Add(user, bsLID, bsSID, battleInfoRet.Bid);
            }

            //广播给玩家
            Protos.CS2GC_EnterBattle enterBattle = ProtoCreator.Q_CS2GC_EnterBattle();
            enterBattle.Ip   = bsIP;
            enterBattle.Port = bsPort;
            for (int i = 0; i < count; i++)
            {
                MatchUser matchUser = state.users[i];
                CSUser    user      = CS.instance.userMgr.GetUser(matchUser.id);
                enterBattle.GcNID = user.ukey | ( ulong )bsLID << 32;
                user.Send(enterBattle);
            }
        }
示例#10
0
        public override string ToString()
        {
            StringBuilder sb    = new StringBuilder();
            int           count = this._users.Length;

            for (int i = 0; i < count; i++)
            {
                MatchUser user = this._users[i];
                if (user == null)
                {
                    continue;
                }
                sb.Append($"{i}:{user.Dump()}");
                if (i < count - 1)
                {
                    sb.AppendLine();
                }
            }
            return(sb.ToString());
        }
示例#11
0
        /// <summary>
        /// 创建匹配玩家
        /// </summary>
        /// <param name="mode">模式(高4位代表队伍数量,低4位代表每个队伍的玩家数量)</param>
        /// <param name="user">玩家实例</param>
        /// <param name="matchParams">匹配参数</param>
        /// <returns>是否创建成功</returns>
        internal bool CreateUser(Protos.GC2CS_BeginMatch.Types.EMode mode, CSUser user, BattleUserData matchParams)
        {
            if (this._userToMatchUser.ContainsKey(user))
            {
                return(false);
            }

            byte mode2;

            switch (mode)
            {
            case Protos.GC2CS_BeginMatch.Types.EMode.T1P1:
                mode2 = (1 << 4) | 1;
                break;

            case Protos.GC2CS_BeginMatch.Types.EMode.T2P1:
                mode2 = (2 << 4) | 1;
                break;

            case Protos.GC2CS_BeginMatch.Types.EMode.T2P2:
                mode2 = (2 << 4) | 2;
                break;

            default:
                Logger.Warn($"not support mode:{mode}");
                return(false);
            }
            this._matchingSystems.TryGetValue(mode2, out MatchSystem3 matchingSystem);
            MatchUser matchUser = matchingSystem?.CreateUser(user.gcNID, user.rank);

            if (matchUser == null)
            {
                return(false);
            }

            this._userToMatchUser[user] = matchUser;
            return(true);
        }
示例#12
0
 internal void RaiseEvent(MatchUserEvent.Type type, MatchUser user, MatchState state)
 {
     this.eventHandler?.Invoke(type, user, state);
 }
示例#13
0
文件: Matcher.cs 项目: niuniuzhu/KOW
        internal bool ProcessMatch(long dt)
        {
            int c1 = this._searchSpace.Count;

            if (c1 == 0)
            {
                return(false);
            }

            Grading grading = null;

            for (int i = 0; i < c1; i++)
            {
                //搜索第i层
                grading = this._searchSpace[i];
                int numUsers = grading.system.numUsers;
                int c2       = grading.users.Count;
                for (int j = 0; j < c2; j++)
                {
                    MatchUser user = grading.users[j];
                    //添加到等候室
                    if (this._matchingLounge.AddUser(user))
                    {
                        //添加事件
                        this._owner.system.RaiseEvent(MatchUserEvent.Type.AddToLounge, user, user.lounge.GetState());

                        if (this._matchingLounge.numUsers == numUsers)
                        {
                            //匹配成功
                            MatchState state = this._matchingLounge.GetState();
                            this._owner.system.RaiseEvent(MatchUserEvent.Type.MatchSuccess, null, state);
                            this.Clear();
                            return(true);
                        }
                    }
                }
            }

            //超过搜索时间,扩大搜索空间
            if (this._time >= this._expireTime && this._searchSpace.Count <= grading.maxExtends)
            {
                grading = this._searchSpace[0];
                Grading prev = null, next = null;
                //找到需要扩展的分段
                for (int i = 0; i < this._level; i++)
                {
                    prev = grading.prev;
                    if (prev == null)
                    {
                        break;
                    }
                }
                for (int i = 0; i < this._level; i++)
                {
                    next = grading.next;
                    if (next == null)
                    {
                        break;
                    }
                }
                if (prev != null && next != null)
                {
                    //随机顺序加入到搜索空间
                    double rnd = this._rnd.NextDouble();
                    if (rnd < 0.5)
                    {
                        this.ExtendSearchGrading(prev);
                        this.ExtendSearchGrading(next);
                    }
                    else
                    {
                        this.ExtendSearchGrading(next);
                        this.ExtendSearchGrading(prev);
                    }
                }
                else if (prev != null || next != null)
                {
                    this.ExtendSearchGrading(prev ?? next);
                }
            }
            this._time += dt;
            return(false);
        }
示例#14
0
        private void OnEvent(MatchUserEvent.Type type, MatchUser sender, MatchState state)
        {
            switch (type)
            {
            case MatchUserEvent.Type.AddToGrading:
                //{
                //	Protos.CS2GC_AddToMatch response = ProtoCreator.Q_CS2GC_AddToMatch();
                //	CS.instance.userMgr.GetUser( e.user.id ).Send( response );
                //}
                break;

            case MatchUserEvent.Type.RemoveFromGrading:
            {
                CSUser user = CS.instance.userMgr.GetUser(sender.id);
                this._userToMatchUser.Remove(user);
                Protos.CS2GC_RemoveFromMatch response = ProtoCreator.Q_CS2GC_RemoveFromMatch();
                user.Send(response);
            }
            break;

            case MatchUserEvent.Type.AddToLounge:
            case MatchUserEvent.Type.RemoveFromLounge:
            {
                Protos.CS2GC_MatchState pMatchState = ProtoCreator.Q_CS2GC_MatchState();
                for (int i = 0; i < state.numTeam; i++)
                {
                    MatchUser[] matchUsers = state.tUsers[i];
                    for (int j = 0; j < state.numUserPerTeam; j++)
                    {
                        MatchUser matchUser = matchUsers[j];
                        if (matchUser == null)
                        {
                            Protos.CS2GC_PlayerInfo playerInfo = new Protos.CS2GC_PlayerInfo
                            {
                                Vaild = false,
                            };
                            pMatchState.PlayerInfos.Add(playerInfo);
                        }
                        else
                        {
                            CSUser user = CS.instance.userMgr.GetUser(matchUser.id);
                            Protos.CS2GC_PlayerInfo playerInfo = new Protos.CS2GC_PlayerInfo
                            {
                                Vaild    = true,
                                GcNID    = user.gcNID,
                                Team     = i,
                                ActorID  = user.actorID,
                                Nickname = user.nickname,
                                Avatar   = user.avatar,
                                Gender   = user.gender,
                                Money    = user.money,
                                Diamoned = user.diamoned,
                                Rank     = user.rank
                            };
                            pMatchState.PlayerInfos.Add(playerInfo);
                        }
                    }
                }
                this.Broadcast(state.users, pMatchState);
            }
            break;

            case MatchUserEvent.Type.MatchSuccess:
                this.BeginBattle(state);
                break;
            }
        }