public async Task <bool> TTWarsTryFastUpgrade(Account acc, string url) { var building = Vill.Build.Buildings.FirstOrDefault(x => x.Id == this.Task.BuildingId); var lvl = building.Level; if (building.UnderConstruction) { lvl++; } var neededRes = BuildingsData.GetBuildingCost(building.Type, lvl + 1); if (ResourcesHelper.IsEnoughRes(Vill, neededRes) && lvl != 0 && lvl < Task.Level) { await acc.Wb.Navigate(url + "&fastUP=1"); CheckIfTaskFinished(++lvl); acc.Wb.Log($"Started (fast) upgrading {building.Type} to level {lvl} in {this.Vill?.Name}"); await PostTaskCheckDorf(acc); ConfigNextExecute(acc); return(true); } return(false); }
public static bool EnoughResForCelebration(Village vill, bool big) { var cost = CelebrationCost(big); var res = vill.Res.Stored.Resources.ToArray(); return(ResourcesHelper.IsEnoughRes(res, cost)); }
//If Troop == null, just update the troop levels public override async Task <TaskRes> Execute(Account acc) { await base.Execute(acc); // Navigate to dorf2 if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Academy)) { return(TaskRes.Executed); } var troop = Vill.Troops.ToResearch.FirstOrDefault(); if (troop == TroopsEnum.None) { return(TaskRes.Executed); //We have researched all troops that were on the list } var troopNode = acc.Wb.Html.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop)); if (troopNode == null) { acc.Wb.Log($"Researching {troop} was not possible! Bot assumes you already have it researched"); Vill.Troops.Researched.Add(troop); return(TaskRes.Retry); } while (!troopNode.HasClass("research")) { troopNode = troopNode.ParentNode; } var button = troopNode.Descendants("button").FirstOrDefault(x => x.HasClass("green")); if (button == null) { RepeatTask(Vill, troop, DateTime.Now); } (TimeSpan dur, Resources cost) = TroopsParser.AcademyResearchCost(acc.Wb.Html, troop); // Check if we have enough resources to research the troop if (!ResourcesHelper.IsEnoughRes(Vill, cost.ToArray())) { ResourcesHelper.NotEnoughRes(acc, Vill, cost, this); return(TaskRes.Executed); } await DriverHelper.ClickById(acc, button.Id); var executeNext = DateTime.Now.Add(dur).AddMilliseconds(10 * AccountHelper.Delay()); if (Vill.Settings.AutoImprove) { TaskExecutor.AddTask(acc, new ImproveTroop() { Vill = this.Vill, ExecuteAt = DateTime.Now.Add(dur) }); } RepeatTask(Vill, troop, executeNext); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { await base.Execute(acc); if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace, "&t=5")) { return(TaskRes.Executed); } //get troop resource/time cost var troopCost = TroopCost.GetResourceCost(TrainTask.Troop, TrainTask.Great); var trainNum = TroopsHelper.TroopsToFill(acc, TargetVill, TrainTask.Troop, TrainTask.Great); //how many troops we can train with resources that we have var mainVillResStored = Vill.Res.Stored.Resources.ToArray(); var targetVillStoredRes = TargetVill.Res.Stored.Resources.ToArray(); // Max troops we can train with resources that we have var maxTroopsToTrain = ResourcesHelper.MaxTroopsToTrain(mainVillResStored, targetVillStoredRes, troopCost); // If we don't have enough rsoruces to train the number of troops that we want, we will train max number of troops that we can if (maxTroopsToTrain < trainNum) { trainNum = maxTroopsToTrain; } //calculate how many resources we need to train trainNum of troops long[] neededRes = troopCost.Select(x => x * trainNum).ToArray(); //if we have already enough resources in the target village, no need to send anything if (ResourcesHelper.IsEnoughRes(targetVillStoredRes, neededRes)) { this.TrainTask.ExecuteAt = DateTime.Now; TaskExecutor.ReorderTaskList(acc); return(TaskRes.Executed); } //amount of resources we want to transit to target village var sendRes = ResourcesHelper.SendAmount(targetVillStoredRes, neededRes); // Check how many merchants we have. If we have 0, wait till some come back. var transitTimespan = await MarketHelper.MarketSendResource(acc, sendRes, TargetVill, this); //train the troops in the target village after we send the needed this.TrainTask.ExecuteAt = DateTime.Now.Add(transitTimespan).AddSeconds(5); TaskExecutor.ReorderTaskList(acc); //TODO: Update marketplace sending return(TaskRes.Executed); }
/// <summary> /// Checks if we have enough resources to build the building. If we don't have enough resources, /// method sets NextExecute DateTime. /// </summary> /// <param name="node">Node of the contract</param> /// <returns>Whether we have enough resources</returns> private bool IsEnoughRes(Account acc, HtmlNode node) { var resWrapper = node.Descendants().FirstOrDefault(x => x.HasClass("resourceWrapper")); var cost = ResourceParser.GetResourceCost(resWrapper).ToArray(); // We have enough resources, go on and build it if (ResourcesHelper.IsEnoughRes(Vill.Res.Stored.Resources.ToArray(), cost)) { return(true); } ResourcesHelper.NotEnoughRes(acc, Vill, cost, this, this.Task); return(false); }
public override async Task <TaskRes> Execute(Account acc) { // Check if the account has enough culture points if (acc.AccInfo.CulturePoints.MaxVillages <= acc.AccInfo.CulturePoints.VillageCount) { // TODO: this shouldn't be here? acc.Wb.Log("Don't have enough culture points"); this.Vill.Expansion.ExpansionAvailable = true; return(TaskRes.Executed); } if (acc.NewVillages.Locations.Count == 0) { if (acc.NewVillages.AutoFindVillages) // Find new village to settle { TaskExecutor.AddTaskIfNotExists(acc, new FindVillageToSettle() { Vill = AccountHelper.GetMainVillage(acc), ExecuteAt = DateTime.MinValue.AddHours(10), Priority = TaskPriority.High }); this.NextExecute = DateTime.MinValue.AddHours(11); } return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/karte.php"); await Task.Delay(AccountHelper.Delay() * 3); var newVillage = acc.NewVillages.Locations.FirstOrDefault(); //acc.NewVillage.NewVillages.Remove(coords); //remove it after settling and changing the vill name?? string kid = MapHelper.KidFromCoordinates(newVillage.Coordinates, acc).ToString(); string url = $"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2"; switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: // https://low4.ttwars.com/build.php?id=39&tt=2&kid=7274&a=6 url += $"&kid={kid}&a=6"; break; case Classificator.ServerVersionEnum.T4_5: // https://tx3.travian.com/build.php?id=39&tt=2&mapid=123&s=1&gid=16 url += $"&mapid={kid}&s=1&gid=16"; break; } await acc.Wb.Navigate(url); // Check if we have enough resource var costNode = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("resourceWrapper")); var cost = ResourceParser.GetResourceCost(costNode); if (!ResourcesHelper.IsEnoughRes(Vill, cost.ToArray())) { ResourcesHelper.NotEnoughRes(acc, Vill, cost, this); return(TaskRes.Executed); } if (!await DriverHelper.ClickById(acc, "btn_ok")) { return(TaskRes.Retry); } newVillage.SettlersSent = true; this.Vill.Expansion.ExpansionAvailable = false; return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var building = Vill.Build.Buildings .FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Residence || x.Type == Classificator.BuildingEnum.Palace || x.Type == Classificator.BuildingEnum.CommandCenter ); if (!await VillageHelper.EnterBuilding(acc, building, "&s=1")) { return(TaskRes.Executed); } var settler = TroopsData.TribeSettler(acc.AccInfo.Tribe); var troopNode = acc.Wb.Html.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)settler)); if (troopNode == null) { acc.Wb.Log("No new settler can be trained, probably because 3 settlers are already (being) trained"); SendSettlersTask(acc); return(TaskRes.Executed); } while (!troopNode.HasClass("details")) { troopNode = troopNode.ParentNode; } var div = troopNode.Descendants("div"); Vill.Troops.Settlers = (int)Parser.RemoveNonNumeric(div.FirstOrDefault(x => x.HasClass("tit")).Descendants("span").FirstOrDefault().InnerText); string innertext = ""; switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: innertext = troopNode.ChildNodes.First(x => x.Name == "a").InnerText; break; case Classificator.ServerVersionEnum.T4_5: // no expansion slot if (div.FirstOrDefault(x => x.HasClass("noExpansionSlot")) != null) { if (Vill.Troops.Settlers >= 3) { if (acc.NewVillages.AutoSettleNewVillages) { TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers() { ExecuteAt = DateTime.Now.AddHours(-3), Vill = this.Vill, // For high speed servers, you want to train settlers asap Priority = 1000 < acc.AccInfo.ServerSpeed ? TaskPriority.High : TaskPriority.Medium, }); } acc.Wb.Log("Have enoung settlers"); } else { acc.Wb.Log("Don't have enough expansion slot or settlers are training."); } return(TaskRes.Executed); } innertext = div.FirstOrDefault(x => x.HasClass("cta")).Descendants("a").FirstOrDefault().InnerText; break; } var maxNum = Parser.RemoveNonNumeric(innertext); Vill.Troops.Settlers = (int)TroopsParser.ParseAvailable(troopNode); var costNode = troopNode.Descendants("div").FirstOrDefault(x => x.HasClass("resourceWrapper")); var cost = ResourceParser.GetResourceCost(costNode); if (!ResourcesHelper.IsEnoughRes(Vill, cost.ToArray())) { ResourcesHelper.NotEnoughRes(acc, Vill, cost, this); return(TaskRes.Executed); } acc.Wb.Driver.ExecuteScript($"document.getElementsByName('t10')[0].value='{maxNum}'"); await Task.Delay(AccountHelper.Delay()); // Click Train button await TbsCore.Helpers.DriverHelper.ExecuteScript(acc, "document.getElementById('s1').click()"); Vill.Troops.Settlers += (int)maxNum; if (Vill.Troops.Settlers < 3) { // random train next settlers after 30 - 60 mins var ran = new Random(); this.NextExecute = DateTime.Now.AddMinutes(ran.Next(30, 60)); } else { if (acc.NewVillages.AutoSettleNewVillages) { SendSettlersTask(acc); } } return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var building = Vill.Build.Buildings .FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Residence || x.Type == Classificator.BuildingEnum.Palace || x.Type == Classificator.BuildingEnum.CommandCenter ); if (!await VillageHelper.EnterBuilding(acc, Vill, building, "&s=1")) { return(TaskRes.Executed); } var settler = TroopsData.TribeSettler(acc.AccInfo.Tribe); var troopNode = acc.Wb.Html.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)settler)); if (troopNode == null) { acc.Wb.Log("No new settler can be trained, probably because 3 settlers are already (being) trained"); SendSettlersTask(acc); return(TaskRes.Executed); } while (!troopNode.HasClass("details")) { troopNode = troopNode.ParentNode; } var maxNum = Parser.RemoveNonNumeric(troopNode.ChildNodes.First(x => x.Name == "a").InnerText); var available = TroopsParser.ParseAvailable(troopNode); var costNode = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("resourceWrapper")); var cost = ResourceParser.GetResourceCost(costNode); if (!ResourcesHelper.IsEnoughRes(Vill, cost.ToArray())) { ResourcesHelper.NotEnoughRes(acc, Vill, cost, this); return(TaskRes.Executed); } acc.Wb.Driver.ExecuteScript($"document.getElementsByName('t10')[0].value='{maxNum}'"); await Task.Delay(AccountHelper.Delay()); // Click Train button await TbsCore.Helpers.DriverHelper.ExecuteScript(acc, "document.getElementById('s1').click()"); Vill.Troops.Settlers = (int)available + (int)maxNum; var training = TroopsHelper.TrainingDuration(acc.Wb.Html); if (training < DateTime.Now) { training = DateTime.Now; } if (Vill.Troops.Settlers < 3) { //In 1 minute, do the same task (to get total of 3 settlers) this.NextExecute = training.AddSeconds(3); } else { if (acc.NewVillages.AutoSettleNewVillages) { SendSettlersTask(acc); } } return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { await base.Execute(acc); // Navigate to dorf2 if (Vill == null) { Vill = acc.Villages.First(x => x.Active); } if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Smithy)) { return(TaskRes.Executed); } var levels = TroopsParser.GetTroopLevels(acc.Wb.Html); if (levels == null) { acc.Wb.Log("There was an error at getting Smithy troop levels"); return(TaskRes.Executed); } Vill.Troops.Levels = levels; TroopsHelper.UpdateResearchedTroops(Vill); var currentlyImproving = TroopsParser.GetImprovingTroops(acc.Wb.Html); var troop = TroopToImprove(Vill, currentlyImproving); if (troop == Classificator.TroopsEnum.None) { return(TaskRes.Executed); } //If we have plus account we can improve 2 troops at the same time int maxImproving = acc.AccInfo.PlusAccount ? 2 : 1; if (maxImproving <= currentlyImproving.Count()) { this.NextExecute = DateTime.Now.Add(currentlyImproving.Last().Time); return(TaskRes.Executed); } //call NextImprove() after enough res OR when this improvement finishes. var cost = Vill.Troops.Levels.FirstOrDefault(x => x.Troop == troop); // Check if we have enough resources to improve the troop if (!ResourcesHelper.IsEnoughRes(Vill, cost.UpgradeCost.ToArray())) { ResourcesHelper.NotEnoughRes(acc, Vill, cost.UpgradeCost, this); return(TaskRes.Executed); } //Click on the button var troopNode = acc.Wb.Html.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop)); while (!troopNode.HasClass("research")) { troopNode = troopNode.ParentNode; } var button = troopNode.Descendants("button").FirstOrDefault(x => x.HasClass("green")); if (button == null) { acc.Wb.Log($"Could not find Upgrade button to improve {troop}"); this.NextExecute = DateTime.Now.AddMinutes(1); return(TaskRes.Retry); } acc.Wb.Driver.ExecuteScript($"document.getElementById('{button.Id}').click()"); // If we have plus account and there is currently no other troop to improve, go ahead and improve the unit again this.NextExecute = (currentlyImproving.Count() == 0 && maxImproving == 2) ? DateTime.MinValue : DateTime.Now.Add(cost.TimeCost).AddMilliseconds(5 * AccountHelper.Delay()); return(TaskRes.Executed); }