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); }
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); }
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); }
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()); }
/// <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; }
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)); }
/// <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); }
/// <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); }
/// <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); } }
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()); }
/// <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); }
internal void RaiseEvent(MatchUserEvent.Type type, MatchUser user, MatchState state) { this.eventHandler?.Invoke(type, user, state); }
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); }
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; } }