コード例 #1
0
ファイル: MatchmakingQueue.cs プロジェクト: jonbonne/OCTGN
        private void Run()
        {
            Log.InfoFormat("[{0}] Queue Running",this);
            var sendStatusUpdatesBlock = new TimeBlock(TimeSpan.FromSeconds(30));
            var readyTimeout = new TimeBlock(TimeSpan.FromSeconds(60));
            var disposeThis = new TimeBlock(TimeSpan.FromHours(1));
            disposeThis.SetRun();
            while (_runCancelToken.IsCancellationRequested == false && Disposed == false)
            {
                lock (_users)
                {
                    try
                    {
                        if (_users.Count > 0)
                        {
                            disposeThis.SetRun();
                        }
                        if (disposeThis.IsTime)
                        {
                            Log.InfoFormat("[{0}] Dispose timer timed out",this);
                            Disposed = true;
                            this.Dispose();
                            break;
                        }
                        switch (State)
                        {
                            case MatchmakingQueueState.WaitingForUsers:
                                if (_users.Count >= MaxPlayers)
                                {
                                    Log.InfoFormat("[{0}] Got enough players for ready queue.",this);
                                    State = MatchmakingQueueState.WaitingForReadyUsers;
                                    var readyMessage = new MatchmakingReadyRequest(null, this.QueueId);
                                    foreach (var p in _users)
                                    {
                                        p.IsReady = false;
                                        p.IsInReadyQueue = false;
                                    }
                                    for (var i = 0; i < MaxPlayers; i++)
                                    {
                                        readyMessage.To = _users[i];
                                        _users[i].IsInReadyQueue = true;
                                        Bot.Messanger.Send(readyMessage);
                                    }
                                    readyTimeout.SetRun();
                                }
                                break;
                            case MatchmakingQueueState.WaitingForReadyUsers:
                                if (readyTimeout.IsTime)
                                {
                                    Log.InfoFormat("[{0}] Timed out waiting for users to ready up.",this);
                                    // This happens if 60 seconds has passed since ready messages were sent out.
                                    // This shouldn't happen unless someone didn't respond back with a ready response.
                                    foreach (var p in _users.Where(x => x.IsInReadyQueue).ToArray())
                                    {
                                        // If player didn't signal ready throw them in the back of the queue.
                                        if (p.IsReady == false)
                                        {
                                            p.FailedReadyCount++;
                                            _users.Remove(p);
                                            // If they've been knocked to the back of the queue 4 or more times, kick them.
                                            if (p.FailedReadyCount < 4)
                                            {
                                                Log.InfoFormat("[{0}] {1} User failed ready 4 times, getting kicked.",this,p);
                                                _users.Add(p);
                                            }
                                        }
                                        p.IsInReadyQueue = false;
                                        p.IsReady = false;
                                    }
                                }
                                break;
                            case MatchmakingQueueState.WaitingForHostedGame:
                                if (_hostGameTimeout.IsTime)
                                {
                                    Log.WarnFormat("[{0}] Timed out waiting for hosted game to be created...Oh Noes!",this);
                                    State = MatchmakingQueueState.WaitingForUsers;
                                    foreach (var u in _users)
                                    {
                                        u.IsInReadyQueue = false;
                                        u.IsReady = false;
                                    }
                                }
                                break;
                        }

                        // Send status messages
                        if (sendStatusUpdatesBlock.IsTime)
                        {
                            var mess = new MatchmakingInLineUpdateMessage(AverageTime.Time, null, QueueId);
                            foreach (var u in _users.Where(x => x.IsInReadyQueue == false))
                            {
                                mess.To = u.JidUser;
                                mess.GenerateId();
                                Bot.Messanger.Send(mess);
                            }
                        }

                    }
                    catch (Exception e)
                    {
                        Log.Error ("[" + this + "] Run",e);
                    }
                }
                if (_runCancelToken.IsCancellationRequested == false && !Disposed)
                    Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            Log.InfoFormat("[{0}] Queue done running",this);
        }
コード例 #2
0
ファイル: MatchmakingQueue.cs プロジェクト: jonbonne/OCTGN
 public void UserLeave(Jid user)
 {
     lock (_users)
     {
         Log.InfoFormat("[{0}] {1} User Left",this, user);
         var usr = _users.FirstOrDefault(x => x == user);
         if (usr == null)
             return;
         switch (State)
         {
             case MatchmakingQueueState.WaitingForReadyUsers:
             case MatchmakingQueueState.WaitingForHostedGame:
                 if (usr.IsInReadyQueue)
                 {
                     Log.InfoFormat("[{0}] {1} User was in ready queue, so cancel that.",this,usr);
                     State = MatchmakingQueueState.WaitingForUsers;
                     foreach (var u in _users)
                     {
                         u.IsInReadyQueue = false;
                         u.IsReady = false;
                     }
                     var msg = new MatchmakingReadyFail(null, this.QueueId);
                     Log.InfoFormat("[{0}] {1} Tell everyone ready queue failed.",this,usr);
                     foreach (var u in _users.Where(x => x.IsInReadyQueue && x != usr))
                     {
                         msg.To = u.JidUser;
                         this.Bot.Messanger.Send(msg);
                     }
                 }
                 break;
         }
         Log.InfoFormat("[{0}] {1} Actually remove the user",this,usr);
         _users.Remove(usr);
     }
 }
コード例 #3
0
ファイル: MatchmakingQueue.cs プロジェクト: jonbonne/OCTGN
        private void OnMatchmakingReadyResponse(MatchmakingReadyResponse obj)
        {
            if (obj.QueueId != this.QueueId)
                return;
            lock (_users)
            {
                Log.InfoFormat("[{0}]{1} Got Ready Response from user",this,obj.From);
                if (State != MatchmakingQueueState.WaitingForReadyUsers)
                {
                    Log.InfoFormat("[{0}] Not in ready queue anymore, so forget it.",this);
                    return;
                }
                var user = _users.FirstOrDefault(x => x == obj.From);
                if (user != null)
                    user.IsReady = true;

                if (_users.Where(x => x.IsInReadyQueue).All(x => x.IsReady))
                {
                    Log.InfoFormat("[{0}] All users are ready, spin up a game",this);
                    // All users are ready.
                    // Spin up a gameserver for them to join
                    var agamename = string.Format("Matchmaking: {0}[{1}]", this.GameName, this.GameMode);
                    _waitingRequestId = Bot.BeginHostGame(this.GameId, this.GameVersion, agamename,obj.QueueId.ToString().ToLower(), this.GameName, typeof(XmppClient).Assembly.GetName().Version, true);
                    State = MatchmakingQueueState.WaitingForHostedGame;
                    _hostGameTimeout.SetRun();
                }
            }
        }
コード例 #4
0
ファイル: MatchmakingQueue.cs プロジェクト: jonbonne/OCTGN
 public void OnGameHostResponse(HostedGameData data)
 {
     if (_waitingRequestId != data.Id)
         return;
     lock (_users)
     {
         Log.InfoFormat("[{0}] Got Hosted Game Data {1}",this,data);
         if (State != MatchmakingQueueState.WaitingForHostedGame)
         {
             // Actually this can happen if someone cancels out of the queue
             //Log.Fatal("Timeed out before hosted game could be returned. Need to increase timeout.");
             //this._hostGameTimeout.When = new TimeSpan(0,0,(int)_hostGameTimeout.When.TotalSeconds + 5);
             return;
         }
         // Send all users a message telling them the info they need to connect to game server
         // Kick all the users from the queue.
         var message = new Message(new Jid("*****@*****.**"), MessageType.normal, "", "gameready");
         message.ChildNodes.Add(data);
         Log.InfoFormat("[{0}] Sending users game data",this);
         foreach (var u in _users.Where(x => x.IsInReadyQueue).ToArray())
         {
             message.To = u.JidUser;
             message.GenerateId();
             this.Bot.Xmpp.Send(message);
             _users.Remove(u);
         }
         // set time to game
         AverageTime.Cycle();
         State = MatchmakingQueueState.WaitingForUsers;
     }
 }