public static bool UpdateVillages(HtmlAgilityPack.HtmlDocument htmlDoc, Account acc) { List <VillageChecked> foundVills = RightBarParser.GetVillages(htmlDoc); if (foundVills.Count == 0) { return(false); //some problem in GetVillages function! } for (int i = 0; i < acc.Villages.Count; i++) { var oldVill = acc.Villages[i]; var foundVill = foundVills.Where(x => x.Id == oldVill.Id).FirstOrDefault(); //Village was not found -> destroyed/chiefed if (foundVill == null) { acc.Villages.RemoveAt(i); i--; continue; } oldVill.Name = foundVill.Name; oldVill.Active = foundVill.Active; if (oldVill.UnderAttack != foundVill.UnderAttack && foundVill.UnderAttack && oldVill.Deffing.AlertType != Models.VillageModels.AlertTypeEnum.Disabled) { TaskExecutor.AddTaskIfNotExistInVillage(acc, oldVill, new CheckAttacks() { Vill = oldVill, Priority = Tasks.BotTask.TaskPriority.High }); } oldVill.UnderAttack = foundVill.UnderAttack; foundVills.Remove(foundVill); } //Any villages found and were not previously in acc.Villages should be added (new villages) foreach (var newVill in foundVills) { NewVillageFound(acc, newVill); } return(true); }
public static void ReStartBuilding(Account acc, Village vill) { RemoveCompletedTasks(vill, acc); //remove ongoing building task for this village acc.Tasks.RemoveAll(x => x.Vill == vill && x.GetType() == typeof(UpgradeBuilding) ); if (vill.Build.Tasks.Count == 0) { return; //No build tasks } var(_, nextExecution) = UpgradeBuildingHelper.NextBuildingTask(acc, vill); TaskExecutor.AddTask(acc, new UpgradeBuilding() { Vill = vill, ExecuteAt = nextExecution, }); }
public static void StartAccountTasks(Account acc) { // If we don't know server speed, go and get it if (acc.AccInfo.ServerSpeed == 0) { TaskExecutor.AddTaskIfNotExists(acc, new GetServerSpeed() { ExecuteAt = DateTime.MinValue.AddHours(2) }); } if (acc.AccInfo.MapSize == 0) { TaskExecutor.AddTaskIfNotExists(acc, new GetMapSize() { ExecuteAt = DateTime.MinValue.AddHours(2) }); } //FL if (acc.Farming.Enabled) { TaskExecutor.AddTaskIfNotExists(acc, new SendFLs() { ExecuteAt = DateTime.Now }); } //research / improve / train troops foreach (var vill in acc.Villages) { //if (vill.Troops.Researched.Count == 0) TaskExecutor.AddTask(acc, new UpdateTroops() { ExecuteAt = DateTime.Now, vill = vill }); TroopsHelper.ReStartResearchAndImprovement(acc, vill); if (!TroopsHelper.EverythingFilled(acc, vill)) { TroopsHelper.ReStartTroopTraining(acc, vill); } BuildingHelper.ReStartBuilding(acc, vill); BuildingHelper.ReStartDemolishing(acc, vill); MarketHelper.ReStartSendingToMain(acc, vill); //todo } }
/// <summary> /// Called PageLoaded (after navigating to a specific url) or from /// Task timer, if there is no url/bot is already on the url /// </summary> /// <param name="acc">Account</param> /// <param name="task">Task to be executed</param> /// <returns></returns> public static async Task Execute(Account acc, BotTask task) { // Before every execution, wait a random delay if (acc.AccInfo.ServerVersion == Classificator.ServerVersionEnum.T4_5) { await Task.Delay(AccountHelper.Delay()); } if (acc.Wb?.CurrentUrl == null && task.GetType() != typeof(CheckProxy)) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf1.php"); } if (task.Vill == null) { task.Vill = acc.Villages.FirstOrDefault(x => x.Active); } try { acc.Wb.Log($"Executing task {task.GetName()}" + (task.Vill == null ? "" : $" in village {task.Vill.Name}")); switch (await task.Execute(acc)) { case TaskRes.Retry: task.RetryCounter++; if (task.NextExecute == null) { task.NextExecute = DateTime.Now.AddMinutes(3); } break; default: task.RetryCounter = 0; if (task.NextTask != null) { task.NextTask.ExecuteAt = DateTime.MinValue.AddHours(5); task.NextTask.Stage = TaskStage.Start; TaskExecutor.AddTask(acc, task.NextTask); task.NextTask = null; } break; } } catch (Exception e) { if (acc.Wb != null) { acc.Wb.Log($"Error executing task {task.GetName()}! Vill {task.Vill?.Name}", e); } task.RetryCounter++; if (task.NextExecute == null) { task.NextExecute = DateTime.Now.AddMinutes(3); } } //We want to re-execute the same task later if (task.NextExecute != null && task.RetryCounter < 3) { task.ExecuteAt = task.NextExecute ?? default; task.NextExecute = null; ReorderTaskList(acc); task.Stage = TaskStage.Start; return; } // Remove the task from the task list acc.Tasks.Remove(task); }
/// <summary> /// Initializes a new village model and creates the task to update the village /// </summary> /// <param name="acc">Account</param> /// <param name="newVill">new village</param> public static void NewVillageFound(Account acc, VillageChecked newVill) { var vill = new Village() { Active = newVill.Active, Coordinates = newVill.Coordinates, Id = newVill.Id, Name = newVill.Name, UnderAttack = newVill.UnderAttack, UnfinishedTasks = new List <VillUnfinishedTask>() // Move this inside Init()? }; vill.Init(acc); acc.Villages.Add(vill); // Update the village TaskExecutor.AddTaskIfNotExistInVillage(acc, vill, new UpdateVillage() { ExecuteAt = DateTime.Now.AddHours(-2), Vill = vill, ImportTasks = true }); DefaultConfigurations.SetDefaultTransitConfiguration(acc, vill); // Copy default settings to the new village. TODO: use automapper for this. //var defaultSettings = acc.NewVillages.DefaultSettings; //vill.Settings = new VillSettings() //{ // Type = defaultSettings.Type, // BarracksTrain = defaultSettings.BarracksTrain, // StableTrain = defaultSettings.StableTrain, // WorkshopTrain = defaultSettings.WorkshopTrain, // GreatBarracksTrain = defaultSettings.GreatBarracksTrain, // GreatStableTrain = defaultSettings.GreatStableTrain, // SendRes = defaultSettings.SendRes, // GetRes = defaultSettings.GetRes, //}; // Change village name var newVillageFromList = acc.NewVillages.Locations .FirstOrDefault(x => x.SettlersSent && x.Coordinates.x == vill.Coordinates.x && x.Coordinates.y == vill.Coordinates.y ); if (newVillageFromList != null) { if (string.IsNullOrEmpty(newVillageFromList.Name)) { newVillageFromList.Name = NewVillageHelper.GenerateName(acc); } acc.NewVillages.Locations.Remove(newVillageFromList); TaskExecutor.AddTaskIfNotExists(acc, new ChangeVillageName() { ExecuteAt = DateTime.Now, ChangeList = new List <(int, string)> { (vill.Id, newVillageFromList.Name) } });
/// <summary> /// Will (re)start troop training for all buildings (barracks,stable,gs...) /// </summary> /// <param name="acc">Account</param> /// <param name="vill">Village to start troops training</param> public static void ReStartTroopTraining(Account acc, Village vill) { //remove training tasks acc.Tasks?.RemoveAll(x => x.Vill == vill && x.GetType() == typeof(TrainTroops) ); //start training tasks if (vill.Settings.BarracksTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.BarracksTrain)) { var barracksTrain = DateTime.Now; if (vill.Troops.CurrentlyTraining.Barracks.Count > 0) { barracksTrain = vill.Troops.CurrentlyTraining.Barracks.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance); } TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = barracksTrain, Great = false, Vill = vill, Troop = vill.Settings.BarracksTrain }); if (vill.Settings.GreatBarracksTrain) { var gbTrain = DateTime.Now; if (vill.Troops.CurrentlyTraining.GB.Count > 0) { gbTrain = vill.Troops.CurrentlyTraining.GB.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance); } TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = gbTrain, Great = true, Vill = vill, Troop = vill.Settings.BarracksTrain }); } } //stable if (vill.Settings.StableTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.StableTrain)) { var stableTrain = DateTime.Now; if (vill.Troops.CurrentlyTraining.Stable.Count > 0) { stableTrain = vill.Troops.CurrentlyTraining.Stable.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance); } TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = stableTrain, Great = false, Vill = vill, Troop = vill.Settings.StableTrain }); if (vill.Settings.GreatStableTrain) { var gsTrain = DateTime.Now; if (vill.Troops.CurrentlyTraining.GS.Count > 0) { gsTrain = vill.Troops.CurrentlyTraining.GS.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance); } TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = gsTrain, Great = true, Vill = vill, Troop = vill.Settings.StableTrain }); } } //workshop if (vill.Settings.WorkshopTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.WorkshopTrain)) { var wsTrain = DateTime.Now; if (vill.Troops.CurrentlyTraining.Workshop.Count > 0) { wsTrain = vill.Troops.CurrentlyTraining.Workshop.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance); } TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = wsTrain, Vill = vill, Troop = vill.Settings.WorkshopTrain }); } }
/// <summary> /// Will send resources from main village to the target village /// </summary> /// <param name="vill">(target) Village to get the resources</param> /// <returns>Returns DateTime when approximately will resources get transited to target village </returns> public static DateTime TransitResourcesFromMain(Account acc, Village vill) { // Transit resources for this village is disabled. if (!vill.Market.Settings.Configuration.Enabled) { return(DateTime.MaxValue); } // There already is a sendResources BotTask for this village var transitTask = (SendResources)acc.Tasks.FirstOrDefault(x => x.GetType() == typeof(SendResources) && ((SendResources)x).Coordinates == vill.Coordinates ); //vill.Market.Settings.Configuration. if (transitTask != null) { return(transitTask.Configuration.TransitArrival); } //Less than 5min ago we already sent resources. Just to catch bugs. //if(vill.Market.) // Merchants are on their way if (vill.Market.Settings.Configuration.TransitArrival > DateTime.Now) { return(vill.Market.Settings.Configuration.TransitArrival); } //send resources var sendRes = new Resources(); var conf = vill.Market.Settings.Configuration; var currentRes = vill.Res.Stored.Resources; var cap = vill.Res.Capacity; var woodNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Wood / 100.0); sendRes.Wood = (woodNeeded > conf.FillLimit.Wood ? conf.FillLimit.Wood : woodNeeded) - currentRes.Wood; sendRes.Wood = (sendRes.Wood < 0 ? 0 : sendRes.Wood); var clayNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Clay / 100.0); sendRes.Clay = (clayNeeded > conf.FillLimit.Clay ? conf.FillLimit.Clay : clayNeeded) - currentRes.Clay; sendRes.Clay = (sendRes.Clay < 0 ? 0 : sendRes.Clay); var ironNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Iron / 100.0); sendRes.Iron = (ironNeeded > conf.FillLimit.Iron ? conf.FillLimit.Iron : ironNeeded) - currentRes.Iron; sendRes.Iron = (sendRes.Iron < 0 ? 0 : sendRes.Iron); var cropNeeded = (long)(cap.GranaryCapacity * conf.TargetLimit.Crop / 100.0); sendRes.Crop = (cropNeeded > conf.FillLimit.Crop ? conf.FillLimit.Crop : cropNeeded) - currentRes.Crop; sendRes.Crop = (sendRes.Crop < 0 ? 0 : sendRes.Crop); if (ResourcesHelper.IsZeroResources(sendRes)) //we have enough res :) { return(DateTime.MinValue); } // Send resources to a village only once per 5 minutes TimeSpan transitAfter = vill.Market.LastTransit.AddMinutes(5) - DateTime.Now; if (transitAfter < TimeSpan.Zero) { transitAfter = TimeSpan.Zero; } var sendResTask = new SendResources { Configuration = conf, Coordinates = vill.Coordinates, ExecuteAt = DateTime.Now + transitAfter, Vill = AccountHelper.GetMainVillage(acc), Resources = sendRes }; TaskExecutor.AddTask(acc, sendResTask); //AddMinutes(1) since bot has to wait for the SendResources task and then //go to the marketplace and send resources //TransitArrival will get updated to more specific time return(DateTime.Now.Add(transitAfter + CalculateTransitTimeMainVillage(acc, vill)).AddMinutes(1)); }
/// <summary> /// Method will create EquipHero BotTasks that will use resources needed /// </summary> /// <param name="acc">Account</param> /// <param name="vill">Village to use resources in</param> /// <param name="neededRes">Needed resources</param> /// <param name="heroRes">Hero resources</param /// <param name="task">Potential BuildingTask that requires the resources</param> private static HeroEquip UseHeroResources(Account acc, Village vill, ref long[] neededRes, long[] heroRes, BuildingTask task = null) { var useRes = new List <(Classificator.HeroItemEnum, int)>(); for (int i = 0; i < 4; i++) { if (neededRes[i] == 0 || heroRes[i] == 0) { continue; } long resToBeUsed = RoundUpTo100(neededRes[i]); if (heroRes[i] < resToBeUsed) { resToBeUsed = heroRes[i]; } neededRes[i] -= resToBeUsed; HeroItemEnum item = HeroItemEnum.Others_Wood_0; switch (i) { case 0: item = HeroItemEnum.Others_Wood_0; break; case 1: item = HeroItemEnum.Others_Clay_0; break; case 2: item = HeroItemEnum.Others_Iron_0; break; case 3: item = HeroItemEnum.Others_Crop_0; break; } useRes.Add((item, (int)resToBeUsed)); } var heroEquip = new HeroEquip() { Items = useRes, ExecuteAt = DateTime.Now.AddHours(-2), // -2 since sendRes is -1 Vill = vill }; TaskExecutor.AddTask(acc, heroEquip); // A BuildTask needed the resources. If it was auto-build res fields task, make a new // general building task - so resources actually get used for intended building upgrade if (task != null && task.TaskType == Classificator.BuildingType.AutoUpgradeResFields) { var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == task.BuildingId); var lvl = building.Level; if (building.UnderConstruction) { lvl++; } BuildingHelper.AddBuildingTask(acc, vill, new BuildingTask() { TaskType = Classificator.BuildingType.General, Building = task.Building, BuildingId = task.BuildingId, Level = ++lvl }, false); } return(heroEquip); }
/// <summary> /// Initializes a new village model and creates the task to update the village /// </summary> /// <param name="acc">Account</param> /// <param name="newVill">new village</param> public static void NewVillageFound(Account acc, VillageChecked newVill) { var vill = new Village() { Active = newVill.Active, Coordinates = newVill.Coordinates, Id = newVill.Id, Name = newVill.Name, UnderAttack = newVill.UnderAttack }; vill.Init(acc); acc.Villages.Add(vill); //on new village set the tasks if (string.IsNullOrEmpty(acc.NewVillages.BuildingTasksLocationNewVillage)) { DefaultConfigurations.FarmVillagePlan(acc, vill); } else { IoHelperCore.AddBuildTasksFromFile(acc, vill, acc.NewVillages.BuildingTasksLocationNewVillage); } DefaultConfigurations.SetDefaultTransitConfiguration(acc, vill); vill.Build.AutoBuildResourceBonusBuildings = true; vill.Troops.TroopToTrain = (Classificator.TroopsEnum)((int)(acc.AccInfo.Tribe ?? Classificator.TribeEnum.Any) * 10); //change to acc wide setting // Copy default settings to the new village. TODO: use automapper for this. var defaultSettings = acc.NewVillages.DefaultSettings; vill.Settings = new Models.Settings.VillSettings() { Type = defaultSettings.Type, BarracksTrain = defaultSettings.BarracksTrain, StableTrain = defaultSettings.StableTrain, WorkshopTrain = defaultSettings.WorkshopTrain, GreatBarracksTrain = defaultSettings.GreatBarracksTrain, GreatStableTrain = defaultSettings.GreatStableTrain, SendRes = defaultSettings.SendRes, GetRes = defaultSettings.GetRes, }; // Update the village UpdateDorfs(acc, vill); // Change village name var newVillageFromList = acc.NewVillages.Locations .FirstOrDefault(x => x.SettlersSent && x.coordinates.x == vill.Coordinates.x && x.coordinates.y == vill.Coordinates.y ); if (newVillageFromList != null) { if (string.IsNullOrEmpty(newVillageFromList.Name)) { newVillageFromList.Name = NewVillageHelper.GenerateName(acc); } acc.NewVillages.Locations.Remove(newVillageFromList); TaskExecutor.AddTaskIfNotExists(acc, new ChangeVillageName() { ExecuteAt = DateTime.Now, ChangeList = new List <(int, string)> { (vill.Id, newVillageFromList.Name) } });
public static void StartAccountTasks(Account acc) { // Get the server info (on first running the account) if (acc.AccInfo.ServerSpeed == 0 || acc.AccInfo.MapSize == 0) { TaskExecutor.AddTaskIfNotExists(acc, new GetServerInfo() { ExecuteAt = DateTime.MinValue.AddHours(2) }); } if (acc.AccInfo.Tribe == null) { TaskExecutor.AddTaskIfNotExists(acc, new GetTribe() { ExecuteAt = DateTime.MinValue.AddHours(3) }); } //FL if (acc.Farming.Enabled) { TaskExecutor.AddTaskIfNotExists(acc, new SendFLs() { ExecuteAt = DateTime.Now }); } // Bot sleep TaskExecutor.AddTaskIfNotExists(acc, new Sleep() { ExecuteAt = DateTime.Now + TimeHelper.GetWorkTime(acc), AutoSleep = true }); // Access change var nextAccessChange = TimeHelper.GetNextProxyChange(acc); if (nextAccessChange != TimeSpan.MaxValue) { TaskExecutor.AddTaskIfNotExists(acc, new ChangeAccess() { ExecuteAt = DateTime.Now + nextAccessChange }); } //research / improve / train troops foreach (var vill in acc.Villages) { //if (vill.Troops.Researched.Count == 0) TaskExecutor.AddTask(acc, new UpdateTroops() { ExecuteAt = DateTime.Now, vill = vill }); TroopsHelper.ReStartResearchAndImprovement(acc, vill); TroopsHelper.ReStartTroopTraining(acc, vill); BuildingHelper.ReStartBuilding(acc, vill); BuildingHelper.ReStartDemolishing(acc, vill); MarketHelper.ReStartSendingToMain(acc, vill); ReStartCelebration(acc, vill); VillageHelper.SetNextRefresh(acc, vill); if (vill.FarmingNonGold.OasisFarmingEnabled) { TaskExecutor.AddTaskIfNotExistInVillage(acc, vill, new AttackOasis() { Vill = vill }); } // Remove in later updates! if (vill.Settings.RefreshMin == 0) { vill.Settings.RefreshMin = 30; } if (vill.Settings.RefreshMax == 0) { vill.Settings.RefreshMax = 60; } } // Remove in later updates! if (acc.Hero.Settings.MinUpdate == 0) { acc.Hero.Settings.MinUpdate = 40; } if (acc.Hero.Settings.MaxUpdate == 0) { acc.Hero.Settings.MaxUpdate = 80; } // Hero update info if (acc.Hero.Settings.AutoRefreshInfo) { Random ran = new Random(); TaskExecutor.AddTask(acc, new HeroUpdateInfo() { ExecuteAt = DateTime.Now.AddMinutes(ran.Next(40, 80)), Priority = Tasks.BotTask.TaskPriority.Low }); } }
/// <summary> /// Will be called before each task to update resources/msg?,villages,quests,hero health, adventures num, gold/silver /// </summary> /// <param name="acc">Account</param> /// <returns>True if successful, false if error</returns> private static bool PreTaskRefresh(Account acc) { var html = acc.Wb.Html; try { //check & update dorf1/dorf2 if (!UpdateAccountObject.UpdateVillages(html, acc)) { return(false); //Web browser not initiali } var activeVill = acc.Villages.FirstOrDefault(x => x.Active); //update dorf1/dorf2 if (acc.Wb.CurrentUrl.Contains("dorf1")) { UpdateDorf1Info(acc); } else if (acc.Wb.CurrentUrl.Contains("dorf2")) { UpdateDorf2Info(acc); } acc.AccInfo.CulturePoints = RightBarParser.GetCulurePoints(html, acc.AccInfo.ServerVersion); var villExpansionReady = acc.Villages.FirstOrDefault(x => x.Expansion.ExpensionAvailable); if (acc.AccInfo.CulturePoints.MaxVillages > acc.AccInfo.CulturePoints.VillageCount && villExpansionReady != null) { villExpansionReady.Expansion.ExpensionAvailable = false; TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers() { ExecuteAt = DateTime.Now, vill = villExpansionReady }); } acc.AccInfo.Tribe = LeftBarParser.GetAccountTribe(acc, html); acc.Quests = RightBarParser.GetQuests(html); var goldSilver = RightBarParser.GetGoldAndSilver(html, acc.AccInfo.ServerVersion); acc.AccInfo.Gold = goldSilver[0]; acc.AccInfo.Silver = goldSilver[1]; acc.AccInfo.PlusAccount = RightBarParser.HasPlusAccount(html, acc.AccInfo.ServerVersion); //Check reports/msg count if (MsgParser.UnreadMessages(html, acc.AccInfo.ServerVersion) > 0 && !acc.Wb.CurrentUrl.Contains("messages.php") && !IsTaskOnQueue(acc, typeof(ReadMessage))) { TaskExecutor.AddTask(acc, new ReadMessage() { ExecuteAt = DateTime.Now.AddMilliseconds(AccountHelper.Delay() * 30) }); } //update loyalty of village activeVill.Res.FreeCrop = RightBarParser.GetFreeCrop(html); activeVill.Res.Capacity = ResourceParser.GetResourceCapacity(html, acc.AccInfo.ServerVersion); activeVill.Res.Stored = ResourceParser.GetResources(html); float ratio = (float)activeVill.Res.Stored.Resources.Crop / activeVill.Res.Capacity.GranaryCapacity; if (ratio >= 0.99 && acc.AccInfo.Gold >= 3 && activeVill.Market.Npc.Enabled && (activeVill.Market.Npc.NpcIfOverflow || !MarketHelper.NpcWillOverflow(activeVill))) { //npc crop! TaskExecutor.AddTaskIfNotExistInVillage(acc, activeVill, new NPC() { ExecuteAt = DateTime.MinValue, vill = activeVill }); } if (acc.Settings.AutoActivateProductionBoost && CheckProductionBoost(acc)) { TaskExecutor.AddTask(acc, new TTWarsPlusAndBoost() { ExecuteAt = DateTime.Now.AddSeconds(1) }); } acc.Hero.AdventureNum = HeroParser.GetAdventureNum(html, acc.AccInfo.ServerVersion); acc.Hero.Status = HeroParser.HeroStatus(html, acc.AccInfo.ServerVersion); acc.Hero.HeroInfo.Health = HeroParser.GetHeroHealth(html, acc.AccInfo.ServerVersion); bool heroReady = (acc.Hero.HeroInfo.Health > acc.Hero.Settings.MinHealth && acc.Hero.Settings.AutoSendToAdventure && acc.Hero.Status == Hero.StatusEnum.Home && acc.Hero.NextHeroSend < DateTime.Now); // Update adventures if (heroReady && (acc.Hero.AdventureNum != acc.Hero.Adventures.Count() || HeroHelper.AdventureInRange(acc))) //update adventures { AddTaskIfNotExists(acc, new StartAdventure() { ExecuteAt = DateTime.Now.AddSeconds(10) }); } if (acc.Hero.AdventureNum == 0 && acc.Hero.Settings.BuyAdventures) //for UNL servers, buy adventures { AddTaskIfNotExists(acc, new TTWarsBuyAdventure() { ExecuteAt = DateTime.Now.AddSeconds(5) }); } if (acc.Hero.Status == Hero.StatusEnum.Dead && acc.Hero.Settings.AutoReviveHero) //if hero is dead, revive him { AddTaskIfNotExists(acc, new ReviveHero() { ExecuteAt = DateTime.Now.AddSeconds(5), vill = AccountHelper.GetHeroReviveVillage(acc) }); } if (HeroParser.LeveledUp(html) && acc.Hero.Settings.AutoSetPoints) { AddTaskIfNotExists(acc, new HeroSetPoints() { ExecuteAt = DateTime.Now }); } return(true); } catch (Exception e) { Console.WriteLine("Error in PreTask " + e.Message + "\n\nStack Trace: " + e.StackTrace + "\n-----------------------"); return(false); } }