/// <summary> /// Add a bot to the runner. /// </summary> /// <param name="type"></param> /// <param name="username"></param> /// <param name="password"></param> public void AddBot(Type type, string username, string password) { List <VTankBot> bots = BotRunner.GetRunningBots(); // Remove old bot if it exists. for (int i = 0; i < bots.Count; ++i) { VTankBot bot = bots[i]; if (bot.AuthInfo.Username == username) { Print("Removed duplicate bot {0}.", username); BotRunner.Kill(bot); break; } } AuthInfo auth = new AuthInfo(username, password); BotRunner.Register(type, auth, null); BotRunner.Start(false); Print("Added new bot, {0}.", username); if (OnBotChange != null) { OnBotChange(null); } }
/// <summary> /// Gets a list of currently online players. /// </summary> /// <param name="includeBots">If true, the bots ran by this bot runner are /// included in the list. If false, they are excluded.</param> /// <returns>List of tank names of online players. The list is null if the /// online player list cannot be accessed.</returns> public List <Player> GetOnlinePlayers(bool includeBots) { List <VTankBot> bots = BotRunner.GetRunningBots(); List <Player> result = new List <Player>(); for (int i = 0; i < bots.Count; ++i) { VTankBot bot = bots[i]; if (bot.GameServer != null && bot.GameServer.Connected) { AIFramework.Util.GameTracker game = bot.Game; List <Player> playerList = game.GetPlayerList(); foreach (AIFramework.Bot.Game.Player player in playerList) { if (includeBots) { result.Add(player); } else { if (!ContainsTank(bots, player.Name)) { result.Add(player); } } } break; } } return(result); }
/// <summary> /// Move an online bot to the reserved bot list. /// </summary> /// <param name="username"></param> public void MoveBotToReserve(string username) { List <VTankBot> bots = BotRunner.GetRunningBots(); VTankBot bot = bots.Find((b) => { return(b.AuthInfo.Username == username); }); if (bot != null) { MoveBotToReserve(bot); } }
/// <summary> /// Gets all running bots on the bot runner. /// </summary> /// <returns>List of running bots.</returns> public List <VTankBot> GetBots() { return(BotRunner.GetRunningBots()); }
/// <summary> /// Do bot auto-balancing. /// </summary> private void AutoBalanceBots() { try { // Check the status. List <VTankBot> bots = BotRunner.GetRunningBots(); List <Player> onlinePlayers = GetOnlinePlayers(false); if (onlinePlayers.Count == 0) { // No non-bots are online. while (reservedList.Count > 0) { VTankBot bot = (VTankBot)reservedList[0]; Print("[AutoBalance]: Moving {0} from reserve.", bot.AuthInfo.Username); MoveBotFromReserve(bot); } return; } const int MINIMUM_SUM = 4; int botCount = bots.Count; int playerCount = onlinePlayers.Count; int reservedCount = reservedList.Count; int totalBots = botCount + reservedCount; int sum = botCount + playerCount; bool teams = bots[0].Player.Team != GameSession.Alliance.NONE; // Case 1: too many bots. if (sum > totalBots && sum > MINIMUM_SUM && bots.Count != 1) { // Remove one bot keeping fair teams in mind. VTankBot bot = null; if (teams) { List <Player> fullPlayerList = GetOnlinePlayers(true); int redCount = fullPlayerList.FindAll((x) => { return(x.Team == GameSession.Alliance.RED); }).Count; int blueCount = fullPlayerList.Count - redCount; if (redCount > blueCount) { bot = bots.Find((x) => { return(x.Player.Team == GameSession.Alliance.RED); }); } else if (blueCount > redCount) { bot = bots.Find((x) => { return(x.Player.Team == GameSession.Alliance.BLUE); }); } else { // Doesn't matter. Remove first bot. bot = bots[0]; } } else { bot = bots[0]; } if (bot != null) { Print(String.Format("[AutoBalance]: Removing bot {0}.", bot.AuthInfo.Username, sum, totalBots)); MoveBotToReserve(bot); } } // Case 2: not enough bots. else if (sum < totalBots || (sum < MINIMUM_SUM && reservedCount > 0)) { VTankBot bot = (VTankBot)reservedList[0]; Print("[AutoBalance]: Adding bot " + bot.AuthInfo.Username); MoveBotFromReserve(bot); NeedsBalance = false; } } catch (Exception ex) { Print(ex.ToString()); } }