Beispiel #1
0
        /// <summary>
        /// Fired when client fails to join game
        /// </summary>
        /// <param name="sender">DriverClient that caused this event</param>
        /// <param name="e">Failure information</param>
        void newClient_OnFailure(object sender, FailureArgs e)
        {
            ClientDriver source = sender as ClientDriver;

            FailedClientCounts[source.ClientIndex]++;

            if (FailedClientCounts[source.ClientIndex] <= 3)
            {
                if (!RecycleClient(source))
                {
                    return;
                }

                Output("Client failure #" + FailedClientCounts[source.ClientIndex]);
            }
            else
            {
                Output("Client failed too many times, ignoring it from now on");
            }

            if (e.Type == FailureArgs.FailureTypes.GameserverDeniedConnection)
            {
                TemporaryJoinDelay += 5000;
                Output("Adding a 5second temporary join delay");
            }
            else if (e.Type == FailureArgs.FailureTypes.FailedToJoinGame)
            {
                Output("Failed to join game, giving up");
                return;
            }

            Output("Attempting next client");
            PushBot();
        }
Beispiel #2
0
        /// <summary>
        /// Fired when client successfully enteres game
        /// </summary>
        /// <param name="sender">DriverClient that caused this event</param>
        /// <param name="e">Unused</param>
        void newClient_OnEnterGame(object sender, EventArgs e)
        {
            if (isShuttindDown)
            {
                PopBot();
                return;
            }

            ClientDriver source = sender as ClientDriver;

            Output("Client entered game");

            if (settings.IsSinglePlayerMode)
            {
                if (source.PlayerNames.Count + 1 < source.MaxPlayers)
                {
                    Output("Room for another bot, adding...");
                    PushBot();
                }
            }
            else
            {
                // PlayerNames doesn't include our bot's name yet
                if (source.PlayerNames.Count + 1 < source.MaxPlayers - 1)
                {
                    Output("Room for another bot, adding...");
                    PushBot();
                }
                else if (source.PlayerNames.Count + 1 == source.MaxPlayers && clients.Count > 0)
                {
                    Output("oops, this bot wasn't needed, removing...");
                    PopBot();
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Fired when client disconnects from game
        /// </summary>
        /// <param name="sender">DriverClient that caused this event</param>
        /// <param name="e">Unused</param>
        void newClient_OnClientDisconnect(object sender, EventArgs e)
        {
            ClientDriver source = sender as ClientDriver;

            Output("Client disconnected");

            RecycleClient(source);
        }
Beispiel #4
0
        /// <summary>
        /// Starts and new bot
        /// </summary>
        private void PushBot()
        {
            ClientDriver newClient = null;

            lock (availableClients)
            {
                if (availableClients.Count == 0)
                {
                    Output("PushBot(): No bots available!");
                    return;
                }

                newClient = availableClients.Dequeue();
            }

            Output("Waiting " + (settings.JoinDelay + TemporaryJoinDelay) + "ms...");
            for (int i = 0; i < (settings.JoinDelay + TemporaryJoinDelay) / 100; i++)
            {
                System.Threading.Thread.Sleep(100);

                if (isShuttindDown)
                {
                    TemporaryJoinDelay = 0;
                    Output("Canceling PushBot()");
                    FireOnCompletion();
                    return;
                }
            }

            TemporaryJoinDelay = 0;

            newClient.OnClientDisconnect += new EventHandler(newClient_OnClientDisconnect);
            newClient.OnEnterGame        += new EventHandler(newClient_OnEnterGame);
            newClient.OnFailure          += new EventHandler <FailureArgs>(newClient_OnFailure);
            newClient.OnShutdown         += new EventHandler(newClient_OnShutdown);

            lock (clients)
            {
                if (clients.Count == 0)
                {
                    // Only one client should handle player count change events since this is where we handle adding/removing bots
                    newClient.OnPlayerCountChanged += new EventHandler <PlayerCountArgs>(newClient_OnPlayerCountChanged);

                    // We only want to read game chat from one client
                    Logger.Instance.GameMessageFilter.Add(newClient.CharacterName);

                    // TODO: Why only one client for driver messages...?
                    Logger.Instance.DriverMessageFilter.Add(newClient.CharacterName);
                }

                clients.Add(newClient);
            }

            newClient.Start();
        }
Beispiel #5
0
        /// <summary>
        /// Moves specified client from pool of running clients to pool of available clients. Client itself
        /// isn't moved, but it's recreated using the same clientIndex so any values from deadClient will be
        /// lost.
        /// </summary>
        /// <param name="deadClient"></param>
        /// <returns>
        /// True if client was successfully recycled, false if this is the only active client and the
        /// driver needs to shut down. OnCompletion has been fired
        /// </returns>
        bool RecycleClient(ClientDriver deadClient)
        {
            lock (clients)
            {
                clients.Remove(deadClient);
                if (clients.Count == 0)
                {
                    // If the last client failed or disconnected then we can no longer operate
                    FireOnCompletion();
                    return(false);
                }
            }

            AddBotAsAvailable(deadClient);
            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Moves specified client from pool of running clients to pool of available clients. Client itself
        /// isn't moved, but it's recreated using the same clientIndex so any values from deadClient will be
        /// lost.
        /// </summary>
        /// <param name="deadClient"></param>
        /// <returns>
        /// True if client was successfully recycled, false if this is the only active client and the
        /// driver needs to shut down. OnCompletion has been fired
        /// </returns>
        bool RecycleClient(ClientDriver deadClient)
        {
            lock (clients)
            {
                clients.Remove(deadClient);
                if (clients.Count == 0)
                {
                    // If the last client failed or disconnected then we can no longer operate
                    FireOnCompletion();
                    return false;
                }
            }

            AddBotAsAvailable(deadClient);
            return true;
        }
Beispiel #7
0
 /// <summary>
 /// Adds client to list of available clients if it's not already present
 /// </summary>
 /// <param name="client">Bot to add</param>
 private void AddBotAsAvailable(ClientDriver client)
 {
     AddBotAsAvailable(client.ClientIndex);
 }
Beispiel #8
0
 /// <summary>
 /// Adds client to list of available clients if it's not already present
 /// </summary>
 /// <param name="client">Bot to add</param>
 private void AddBotAsAvailable(ClientDriver client)
 {
     AddBotAsAvailable(client.ClientIndex);
 }