private static void UpdateCurrentlyBuilding(Account acc, Village vill) { vill.Build.CurrentlyBuilding.Clear(); var cb = InfrastructureParser.CurrentlyBuilding(acc.Wb.Html, acc); if (cb == null) { return; // Nothing is currently building } var bldJson = DriverHelper.GetJsObj <string>(acc, "JSON.stringify(bld);"); if (string.IsNullOrEmpty(bldJson)) { return; } var bldJs = JsonConvert.DeserializeObject <List <Bld> >(bldJson); // Combine data from two sources about currently building (JS object and HTML table) // We get time duration and level from HTML // and build location, level and building (type) from JSON for (int i = 0; i < cb.Count; i++) { cb[i].Building = bldJs[i].Building; cb[i].Location = bldJs[i].Location; cb[i].Level = (byte)bldJs[i].Level; vill.Build.CurrentlyBuilding.Add(cb[i]); } }
public static void UpdateDorf2Info(Account acc) { //update buildings, currentlyBuilding, resources, capacity var activeVill = acc.Villages.FirstOrDefault(x => x.Active); if (activeVill == null) { return; } //remove any further UpdateDorf1 BotTasks for this village (if below 5min) acc.Tasks.RemoveAll(x => x.GetType() == typeof(UpdateDorf2) && x.Vill == activeVill && x.ExecuteAt < DateTime.Now.AddMinutes(5) ); UpdateCurrentlyBuilding(acc, activeVill); var buildings = InfrastructureParser.GetBuildings(acc, acc.Wb.Html); foreach (var field in buildings) { var building = activeVill.Build.Buildings.FirstOrDefault(x => x.Id == field.Id); building.Level = field.Level; building.Type = field.Type; building.UnderConstruction = field.UnderConstruction; } }
private static void UpdateDorf2Info(Account acc) { //update server version acc.AccInfo.ServerVersion = (acc.Wb.Html.GetElementbyId("sidebarBoxDailyquests") == null ? Classificator.ServerVersionEnum.T4_5 : Classificator.ServerVersionEnum.T4_4); //update buildings, currentlyBuilding, resources, capacity var activeVill = acc.Villages.FirstOrDefault(x => x.Active); if (activeVill == null) { return; } //remove any further UpdateDorf1 BotTasks for this village (if below 5min) acc.Tasks.RemoveAll(x => x.GetType() == typeof(UpdateDorf2) && x.vill == activeVill && x.ExecuteAt < DateTime.Now.AddMinutes(5) ); UpdateCurrentlyBuilding(acc, activeVill); var buildings = InfrastructureParser.GetBuildings(acc, acc.Wb.Html); foreach (var field in buildings) { var building = activeVill.Build.Buildings.FirstOrDefault(x => x.Id == field.Id); building.Level = field.Level; building.Type = field.Type; building.UnderConstruction = field.UnderConstruction; } }
public static void UpdateDorf2Info(Account acc) { //update buildings, currentlyBuilding, resources, capacity var vill = acc.Villages.FirstOrDefault(x => x.Active); if (vill == null) { return; } //remove any further UpdateDorf2 BotTasks for this village (if below 5min) acc.Tasks.Remove(typeof(UpdateDorf2), vill, 5); UpdateCurrentlyBuilding(acc, vill); var buildings = InfrastructureParser.GetBuildings(acc, acc.Wb.Html); foreach (var field in buildings) { var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == field.Id); building.Level = field.Level; building.Type = field.Type; building.UnderConstruction = field.UnderConstruction; } }
private static void UpdateCurrentlyBuilding(Account acc, Village vill) { vill.Build.CurrentlyBuilding.Clear(); var currentlyb = InfrastructureParser.CurrentlyBuilding(acc.Wb.Html, acc); if (currentlyb != null) { foreach (var b in currentlyb) { vill.Build.CurrentlyBuilding.Add(b); } } }
public override async Task <TaskRes> Execute(Account acc) { if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.TownHall)) { return(TaskRes.Executed); } var celebrationEnd = TimeParser.GetCelebrationTime(acc.Wb.Html); if (DateTime.Now <= celebrationEnd) { // We already have a celebration running Vill.Expansion.CelebrationEnd = celebrationEnd; this.NextExecute = celebrationEnd; return(TaskRes.Executed); } var buildingNode = acc.Wb.Html.GetElementbyId("build"); (_, var level) = InfrastructureParser.UpgradeBuildingGetInfo(buildingNode); var bigCeleb = Vill.Expansion.Celebrations == CelebrationEnum.Big && 10 <= level; // Check if enough resources to start a celebration if (!MiscCost.EnoughResForCelebration(Vill, bigCeleb)) { ResourcesHelper.NotEnoughRes(acc, Vill, MiscCost.CelebrationCost(bigCeleb), this); return(TaskRes.Executed); } await StartCelebration(acc, bigCeleb); // Post task check for celebration duration Vill.Expansion.CelebrationEnd = TimeParser.GetCelebrationTime(acc.Wb.Html); if (Vill.Expansion.Celebrations != CelebrationEnum.None) { this.NextExecute = Vill.Expansion.CelebrationEnd; } return(TaskRes.Executed); }
/// <summary> /// Building is already constructed, upgrade it /// </summary> /// <param name="acc">Account</param> /// <returns>TaskResult</returns> private async Task <TaskRes> Upgrade(Account acc, HtmlNode node) { (var buildingEnum, var lvl) = InfrastructureParser.UpgradeBuildingGetInfo(node); if (buildingEnum == BuildingEnum.Site || lvl == -1) { acc.Wb.Log($"Can't upgrade building {this.Task.Building} in village {this.Vill.Name}. Will be removed from the queue."); RemoveCurrentTask(); return(TaskRes.Executed); } // If there is already a different building in this spot, find a new id to construct it. if (buildingEnum != Task.Building) { acc.Wb.Log($"We wanted to upgrade {Task.Building}, but there's already {buildingEnum} on this id ({Task.BuildingId})."); if (!BuildingHelper.FindBuildingId(Vill, this.Task)) { acc.Wb.Log($"Found another Id to build {Task.Building}, new id: {Task.BuildingId}"); return(TaskRes.Retry); } acc.Wb.Log($"Failed to find another Id to build {Task.Building}! No space in village. Building task will be removed"); RemoveCurrentTask(); return(TaskRes.Executed); } // Basic task already on/above desired level, don't upgrade further var building = Vill.Build.Buildings.FirstOrDefault(x => x.Id == this.Task.BuildingId); lvl = building.Level; if (building.UnderConstruction) { lvl++; } if (Task.Level <= lvl) { acc.Wb.Log($"{this.Task.Building} is on level {lvl}, on/above desired {Task.Level}. Removing it from queue."); RemoveCurrentTask(); RemoveCompletedTasks(this.Vill, acc); return(TaskRes.Executed); } var container = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("upgradeButtonsContainer")); var buttons = container?.Descendants("button"); if (buttons == null) { acc.Wb.Log($"We wanted to upgrade {Task.Building}, but no 'upgrade' button was found! Url={acc.Wb.CurrentUrl}"); return(TaskRes.Retry); } var errorMessage = acc.Wb.Html.GetElementbyId("build") .Descendants("div") .FirstOrDefault(x => x.HasClass("upgradeBuilding"))? .Descendants("div")? .FirstOrDefault(x => x.HasClass("errorMessage")); HtmlNode upgradeButton = buttons.FirstOrDefault(x => x.HasClass("build")); if (upgradeButton == null) { acc.Wb.Log($"We wanted to upgrade {Task.Building}, but no 'upgrade' button was found!"); return(TaskRes.Retry); } // Not enough resources? if (acc.AccInfo.ServerVersion == ServerVersionEnum.T4_5 && errorMessage != null) { acc.Wb.Log($"We wanted to upgrade {Task.Building}, but there was an error message:\n{errorMessage.InnerText}"); return(TaskRes.Retry); } var buildDuration = InfrastructureParser.GetBuildDuration(container, acc.AccInfo.ServerVersion); if (IsTaskCompleted(Vill, acc, this.Task)) { acc.Wb.Log($"Building {this.Task.Building} in village {this.Vill.Name} is already on desired level. Will be removed from the queue."); RemoveCurrentTask(); return(TaskRes.Executed); } if (acc.AccInfo.ServerVersion == ServerVersionEnum.T4_4 || buildDuration.TotalMinutes <= acc.Settings.WatchAdAbove || !await TryFastUpgrade(acc)) // +25% speed upgrade { await DriverHelper.ClickById(acc, upgradeButton.Id); // Normal upgrade } lvl++; CheckIfTaskFinished(lvl); acc.Wb.Log($"Started upgrading {this.Task.Building} to level {lvl} in {this.Vill?.Name}"); await PostTaskCheckDorf(acc); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { if (this.task == null) { ConfigNextExecute(acc.Wb.Html, acc); this.NextExecute = DateTime.Now.AddMinutes(2); if (this.task == null) { // There is no building task left. Remove the BotTask acc.Tasks.Remove(this); return(TaskRes.Executed); } } // Check if the task is complete var urlId = BuildingHelper.GetUrlForBuilding(vill, task); if (urlId == null) { //no space for this building vill.Build.Tasks.Remove(this.task); this.task = null; return(await Execute(htmlDoc, wb, acc)); } // In which dorf is the building. Maybe not needed. if (!acc.Wb.CurrentUrl.Contains($"/dorf{((task.BuildingId ?? default) < 19 ? 1 : 2)}.php")) { //Switch village! BotTask updateDorfTask = (task.BuildingId ?? default) < 19 ? (BotTask) new UpdateDorf1() : (BotTask) new UpdateDorf2(); updateDorfTask.vill = this.vill; updateDorfTask.ExecuteAt = DateTime.MinValue.AddHours(2); TaskExecutor.AddTask(acc, updateDorfTask); this.NextExecute = updateDorfTask.ExecuteAt.AddMinutes(1); return(TaskRes.Executed); } // Check if there are already too many buildings currently constructed BuildingHelper.RemoveFinishedCB(vill); var maxBuild = 1; if (acc.AccInfo.PlusAccount) { maxBuild++; } if (acc.AccInfo.Tribe == TribeEnum.Romans) { maxBuild++; } if (vill.Build.CurrentlyBuilding.Count >= maxBuild) { //Execute next upgrade task after currently building this.NextExecute = vill.Build.CurrentlyBuilding.First().Duration.AddSeconds(3); TaskExecutor.ReorderTaskList(acc); return(TaskRes.Executed); } var url = $"{acc.AccInfo.ServerUrl}/build.php?id={urlId}"; // Fast building for TTWars, only if we have enough resources //if (acc.AccInfo.ServerUrl.Contains("ttwars") && !url.Contains("category") && false) // disabling this //{ // var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == this.task.BuildingId); // var lvl = building.Level; // if (building.UnderConstruction) lvl++; // var storedRes = ResourcesHelper.ResourcesToArray(vill.Res.Stored.Resources); // var neededRes = BuildingsCost.GetBuildingCost(this.task.Building, lvl + 1); // if (ResourcesHelper.EnoughRes(storedRes, neededRes)) // { // //url += "&fastUP=1"; // return TaskRes.Executed; // } //} //append correct tab switch (this.task.Building) { case BuildingEnum.RallyPoint: url += "&tt=0"; break; case BuildingEnum.Marketplace: url += "&t=0"; break; } await acc.Wb.Navigate(url); this.PostTaskCheck.Add(ConfigNextExecute); this.NextExecute = DateTime.Now.AddMinutes(2); var contractBuilding = htmlDoc.GetElementbyId($"contract_building{(int)task.Building}"); var upgradeBuildingContract = htmlDoc.GetElementbyId("build"); if (contractBuilding != null) //Construct a new building { var resWrapper = contractBuilding.Descendants().FirstOrDefault(x => x.HasClass("resourceWrapper")); var res = ResourceParser.GetResourceCost(resWrapper); var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, res); if (nextExecute < DateTime.Now.AddMilliseconds(1)) // we have enough res, go construct that building boii { var button = contractBuilding.Descendants("button").FirstOrDefault(x => x.HasClass("new")); //TODO: if button null: check for prerequisites. Maybe a prerequisit is currently building... if (button == null) { this.NextExecute = vill.Build.CurrentlyBuilding.LastOrDefault()?.Duration; this.PostTaskCheck.Remove(ConfigNextExecute); return(TaskRes.Executed); } //check if button is null! wb.ExecuteScript($"document.getElementById('{button.Id}').click()"); this.task.ConstructNew = false; return(TaskRes.Executed); } //not enough resources, wait until resources get produced/transited from main village this.NextExecute = nextExecute; this.PostTaskCheck.Remove(ConfigNextExecute); return(TaskRes.Executed); } else if (upgradeBuildingContract != null) // Upgrade building { (var buildingEnum, var lvl) = InfrastructureParser.UpgradeBuildingGetInfo(upgradeBuildingContract); if (buildingEnum == BuildingEnum.Site || lvl == -1) { this.ErrorMessage = $"Can't upgrade building {this.task.Building} in village {this.vill.Name}. Will be removed from the queue."; vill.Build.Tasks.Remove(this.task); return(TaskRes.Executed); } // If there is already a different building in this spot, find a new id to construct it. if (buildingEnum != task.Building) { if (!BuildingHelper.FindBuildingId(vill, task)) { vill.Build.Tasks.Remove(this.task); } return(TaskRes.Retry); } // Basic task already on/above desired level, don't upgrade further var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == this.task.BuildingId); if (building.UnderConstruction) { lvl++; } if (lvl >= task.Level) { this.ErrorMessage = $"{this.task.Building} is on level {lvl}, above desired {task.Level}. Removing it from queue."; vill.Build.Tasks.Remove(this.task); RemoveCompletedTasks(this.vill, acc); return(TaskRes.Executed); } var container = htmlDoc.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("upgradeButtonsContainer")); var buttons = container?.Descendants("button"); if (buttons == null) { this.ErrorMessage = "No 'upgrade' button found!"; return(TaskRes.Executed); } HtmlNode upgradeButton = buttons.FirstOrDefault(x => x.HasClass("build")); //We have enough resources, click on build if (upgradeButton != null) { var buildDuration = InfrastructureParser.GetBuildDuration(container, acc.AccInfo.ServerVersion); if (IsTaskCompleted(vill, acc, this.task)) { this.ErrorMessage = $"Building {this.task.Building} in village {this.vill.Name} is already done. Will be removed from the queue."; vill.Build.Tasks.Remove(this.task); return(TaskRes.Executed); } //TODO move this CheckSettlers(acc, vill, lvl, DateTime.Now.Add(buildDuration)); Console.WriteLine($"Village {vill.Name} will upgrade {task.Building}"); wb.ExecuteScript($"document.getElementById('{upgradeButton.Id}').click()"); return(TaskRes.Executed); } else { HtmlNode error = container.Descendants("span").FirstOrDefault(x => x.HasClass("none")); //Not enough resources var contract = htmlDoc.GetElementbyId("contract"); var resWrapper = contract.Descendants().FirstOrDefault(x => x.HasClass("resourceWrapper")); var res = ResourceParser.GetResourceCost(resWrapper); this.PostTaskCheck.Remove(ConfigNextExecute); this.NextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, res); return(TaskRes.Executed); } } else { throw new Exception("No construct or upgrade contract was found!"); } }