Beispiel #1
0
        /// <summary>
        /// Kill the given bot and the thread running the bot.
        /// </summary>
        /// <param name="username">Username of the bot.</param>
        public bool Kill(string username)
        {
            lock (botLock)
            {
                bool       found   = false;
                BotPackage package = threads.Find((b) =>
                {
                    return(b.Bot.AuthInfo.Username == username);
                });
                if (package != null)
                {
                    found = true;
                }

                if (found)
                {
                    try
                    {
                        if (package.Thread.IsAlive)
                        {
                            package.Thread.Abort();
                        }
                        else
                        {
                            package.Bot.Dispose();
                        }
                    }
                    catch (Exception) { }

                    threads.Remove(package);
                }

                return(found);
            }
        }
Beispiel #2
0
 private void SetState(BotPackage bot, BotRunnerState state)
 {
     bot.State = state;
     if (OnBotStateChange != null)
     {
         OnBotStateChange(bot.Bot, state);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Runs the bot on a separate thread.
        /// </summary>
        /// <param name="botKlass"></param>
        private void HandleBot(object botObj)
        {
            BotPackage package = (BotPackage)botObj;

            package.State = BotRunnerState.Offline;
            VTankBot       bot    = package.Bot;
            GameServerInfo server = package.Server;

            try
            {
                if (!bot.MainServer.Connected)
                {
                    bot.MainServer.Connect();
                }

                SetState(package, BotRunnerState.SelectingTank);

                // TODO: Let the user pick their own tank..
                if (string.IsNullOrEmpty(bot.TankName))
                {
                    VTankObject.TankAttributes[] tanks = bot.MainServer.GetTankList();
                    if (tanks.Length == 0)
                    {
                        Console.Error.WriteLine("Error: Bot {0} cannot play: he has no tanks.",
                                                bot.ToString());
                        SetState(package, BotRunnerState.Offline);
                        return;
                    }
                    bot.SelectTank(tanks[0].name);
                }
                else
                {
                    bot.SelectTank(bot.TankName);
                }

                ConnectToServer(bot, server);
                SetState(package, BotRunnerState.Playing);

                DoLoop(package, bot);
            }
            catch (Exception e)
            {
                using (Logger logger = new Logger("error.log", FileMode.Append))
                {
                    logger.Exception(e);
                }

                Console.Error.WriteLine(e);
            }
            finally
            {
                package.IsShuttingDown = true;
                Kill(bot);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Start the bot runner, letting every bot connect to a game server.
        /// </summary>
        /// <param name="mainLoopMode">If true, loops forever.</param>
        public void Start(bool mainLoopMode)
        {
            CullOfflineBots();

            if (bots.Count == 0)
            {
                throw new InvalidOperationException(
                          "Cannot start without registered bots.");
            }

            // TODO: Perhaps in the future the bots can selected their preferred server.
            GameServerInfo[] servers = bots[0].MainServer.GetGameServerList();
            if (servers.Length == 0)
            {
                throw new Exception("No game servers available.");
            }

            foreach (VTankBot bot in bots)
            {
                Thread     thread  = new Thread(new ParameterizedThreadStart(HandleBot));
                BotPackage package = new BotPackage(bot, servers[0], thread);
                thread.Start(package);
                threads.Add(package);

                Thread.Sleep(250);
            }

            while (mainLoopMode)
            {
                for (int j = 0; j < threads.Count; ++j)
                {
                    BotPackage package = threads[j];
                    Thread     thread  = package.Thread;
                    if (thread.Join(5000))
                    {
                        // Restart the thread.
                        Console.WriteLine("<<< Restarting bot thread. >>>");
                        thread = new Thread(new ParameterizedThreadStart(HandleBot));
                        thread.Start(threads[j]);
                    }
                }

                Thread.Sleep(5000);
            }

            bots.Clear();
        }
Beispiel #5
0
        /// <summary>
        /// Remove all offline bots from the bot list.
        /// </summary>
        private void CullOfflineBots()
        {
            lock (this)
            {
                List <BotPackage> offlineBots = threads.FindAll((bot) =>
                {
                    return(bot.State == BotRunnerState.Offline);
                });

                while (offlineBots.Count > 0)
                {
                    BotPackage bot = offlineBots[0];
                    offlineBots.RemoveAt(0);
                    threads.Remove(bot);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Do the main game loop.
        /// </summary>
        /// <param name="bot"></param>
        private void DoLoop(BotPackage package, VTankBot bot)
        {
            bool      crash     = false;
            const int WAIT_TIME = 14; // ms

            try
            {
                while (true)
                {
                    Thread.Sleep(WAIT_TIME);

                    bot.InvokeUpdate();
                }
            }
            catch (System.Threading.ThreadInterruptedException)
            {
                Console.WriteLine("Bot {0} was interrupted.", bot.AuthInfo.Username);
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("Bot {0} was aborted.", bot.AuthInfo.Username);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                crash = true;
            }

            if (crash && OnCrash != null)
            {
                package.State = BotRunnerState.Offline;
                OnCrash(bot);
            }
            else
            {
                SetState(package, BotRunnerState.Offline);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Kill the given bot and the thread running the bot.
        /// </summary>
        /// <param name="bot">Bot to kill.</param>
        public void Kill(VTankBot bot)
        {
            if (bot == null)
            {
                return;
            }

            lock (botLock)
            {
                for (int i = 0; i < threads.Count; ++i)
                {
                    BotPackage package = threads[i];
                    if (package.Bot == bot)
                    {
                        try
                        {
                            if (!package.IsShuttingDown)
                            {
                                package.Thread.Abort();
                            }

                            package.Bot.Dispose();
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine(e);
                        }

                        threads.RemoveAt(i);
                        break;
                    }
                }
            }

            CullOfflineBots();
        }
Beispiel #8
0
 private void SetState(BotPackage bot, BotRunnerState state)
 {
     bot.State = state;
     if (OnBotStateChange != null)
         OnBotStateChange(bot.Bot, state);
 }
Beispiel #9
0
        /// <summary>
        /// Do the main game loop.
        /// </summary>
        /// <param name="bot"></param>
        private void DoLoop(BotPackage package, VTankBot bot)
        {
            bool crash = false;
            const int WAIT_TIME = 14; // ms
            try
            {
                while (true)
                {
                    Thread.Sleep(WAIT_TIME);

                    bot.InvokeUpdate();
                }
            }
            catch (System.Threading.ThreadInterruptedException)
            {
                Console.WriteLine("Bot {0} was interrupted.", bot.AuthInfo.Username);
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("Bot {0} was aborted.", bot.AuthInfo.Username);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                crash = true;
            }

            if (crash && OnCrash != null)
            {
                package.State = BotRunnerState.Offline;
                OnCrash(bot);
            }
            else
            {
                SetState(package, BotRunnerState.Offline);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Start the bot runner, letting every bot connect to a game server.
        /// </summary>
        /// <param name="mainLoopMode">If true, loops forever.</param>
        public void Start(bool mainLoopMode)
        {
            CullOfflineBots();

            if (bots.Count == 0)
            {
                throw new InvalidOperationException(
                    "Cannot start without registered bots.");
            }

            // TODO: Perhaps in the future the bots can selected their preferred server.
            GameServerInfo[] servers = bots[0].MainServer.GetGameServerList();
            if (servers.Length == 0)
            {
                throw new Exception("No game servers available.");
            }

            foreach (VTankBot bot in bots)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(HandleBot));
                BotPackage package = new BotPackage(bot, servers[0], thread);
                thread.Start(package);
                threads.Add(package);

                Thread.Sleep(250);
            }

            while (mainLoopMode)
            {
                for (int j = 0; j < threads.Count; ++j)
                {
                    BotPackage package = threads[j];
                    Thread thread = package.Thread;
                    if (thread.Join(5000))
                    {
                        // Restart the thread.
                        Console.WriteLine("<<< Restarting bot thread. >>>");
                        thread = new Thread(new ParameterizedThreadStart(HandleBot));
                        thread.Start(threads[j]);
                    }
                }

                Thread.Sleep(5000);
            }

            bots.Clear();
        }