public override async Task <TaskRes> Execute(Account acc) { // First navigate to dorf2 and then to the main building, to make sure the currently demolish list is refreshed if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.MainBuilding, update: true)) { return(TaskRes.Executed); } if (Vill.Build.DemolishTasks.Count == 0) { return(TaskRes.Executed); //No more demolish tasks } var id = BuildingToDemolish(Vill, acc.Wb.Html); if (id == null) { return(TaskRes.Executed); //No more demolish tasks } await DriverHelper.WriteById(acc, "demolish", id); await DriverHelper.ClickById(acc, "btn_demolish"); this.NextExecute = TimeHelper.RanDelay(acc, await NextDemolishTime(acc)); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/alliance/bonuses"); for (int i = 0; i < 4; i++) { var radioId = Ids[i]; var radio = acc.Wb.Html.GetElementbyId(radioId); // If the bonus is max / already being upgraded if (radio.GetAttributeValue("disabled", "") == "disabled") { continue; } await DriverHelper.ClickById(acc, radioId); } var donateArr = ResToDonate.ToArray(); for (int i = 0; i < 4; i++) { await DriverHelper.WriteById(acc, $"donate{(i + 1)}", donateArr[i]); } await DriverHelper.ClickById(acc, "donate_green"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var script = $"document.getElementById('mentorTaskList').querySelector('[data-questid=\"{this.QuestToClaim.Id}\"]').click();"; await DriverHelper.ExecuteScript(acc, script); await Task.Delay(AccountHelper.Delay() * 2); string buttonId = ""; switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_5: buttonId = acc.Wb.Html.DocumentNode.Descendants("button").FirstOrDefault(x => x.GetAttributeValue("questid", "") == this.QuestToClaim.Id).Id; break; case Classificator.ServerVersionEnum.T4_4: buttonId = acc.Wb.Html.DocumentNode.Descendants("button").FirstOrDefault(x => x.HasClass("questButtonNext"))?.Id; break; } await DriverHelper.ClickById(acc, buttonId); await TaskExecutor.PageLoaded(acc); // Optional return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { VersionHelper.Navigate(acc, "/options.php", "/options"); if (ContextualHelp != null) { await DriverHelper.CheckById(acc, "v13", ContextualHelp ?? true); } if (TroopsPerPage != null) { await DriverHelper.WriteById(acc, "troopMovementsPerPage", TroopsPerPage ?? 10); } var acceptButton = acc.Wb.Html.DocumentNode .Descendants("div") .First(x => x.HasClass("submitButtonContainer")) .Descendants("button") .First(); await DriverHelper.ClickById(acc, acceptButton.Id); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var wb = acc.Wb.Driver; if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.MainBuilding)) { return(TaskRes.Executed); } if (Vill.Build.DemolishTasks.Count == 0) { return(TaskRes.Executed); //No more demolish tasks } var id = BuildingToDemolish(Vill, acc.Wb.Html); if (id == null) { return(TaskRes.Executed); //No more demolish tasks } await DriverHelper.WriteById(acc, "demolish", id); await DriverHelper.ClickById(acc, "btn_demolish"); this.NextExecute = NextDemolishTime(acc); return(TaskRes.Executed); }
/// <summary> /// Building isn't constructed yet - construct it /// </summary> /// <param name="acc">Account</param> /// <returns>TaskResult</returnss> private async Task <TaskRes> Construct(Account acc, HtmlNode node) { var button = node.Descendants("button").FirstOrDefault(x => x.HasClass("new")); // Check for prerequisites if (button == null) { // Add prerequisite buildings in order to construct this building. AddBuildingPrerequisites(acc, Vill, Task.Building, false); // Next execute after the last building finishes this.NextExecute = Vill.Build.CurrentlyBuilding.LastOrDefault()?.Duration; acc.Wb.Log($"Wanted to construct {this.Task.Building} but prerequired buildings are missing"); return(TaskRes.Executed); } await DriverHelper.ClickById(acc, button.Id); this.Task.ConstructNew = false; CheckIfTaskFinished(1); acc.Wb.Log($"Started construction of {this.Task.Building} in {this.Vill?.Name}"); await PostTaskCheckDorf(acc); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var palace = Vill.Build.Buildings.FirstOrDefault(x => x.Type == Helpers.Classificator.BuildingEnum.Palace); if (palace == null) { // TODO: Check for residence, if it exists demolish it and build palace acc.Wb.Log("Palace was not found in the village!"); return(TaskRes.Executed); } // Go into palace await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={palace.Id}"); switch (acc.AccInfo.ServerVersion) { case Helpers.Classificator.ServerVersionEnum.T4_4: await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={palace.Id}&change_capital"); await DriverHelper.WriteByName(acc, "pw", acc.Access.GetCurrentAccess().Password); await DriverHelper.ClickById(acc, "btn_ok"); break; case Helpers.Classificator.ServerVersionEnum.T4_5: throw new System.Exception("Setting capital isn't supported in T4.5 yet!"); } return(TaskRes.Executed); }
//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 acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/options"); await DriverHelper.ClickById(acc, "v13"); var acceptButton = acc.Wb.Html.DocumentNode .Descendants("div") .First(x => x.HasClass("submitButtonContainer")) .Descendants("button") .First(); await DriverHelper.ClickById(acc, acceptButton.Id); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var wb = acc.Wb.Driver; if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace)) { return(TaskRes.Executed); } var npcMerchant = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("npcMerchant")); var npcButton = npcMerchant.Descendants("button").FirstOrDefault(x => x.HasClass("gold")); // Exchange resources button await DriverHelper.ClickById(acc, npcButton.Id); var resSum = Parser.RemoveNonNumeric(acc.Wb.Html.GetElementbyId("remain").InnerText); var targetRes = MarketHelper.NpcTargetResources(Vill, resSum); if (!Vill.Market.Npc.NpcIfOverflow && MarketHelper.NpcWillOverflow(Vill, targetRes)) { return(TaskRes.Executed); } for (int i = 0; i < 4; i++) { //await acc.Wb.Driver.FindElementById($"m2[{i}]").Write(targetRes[i]); switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: await DriverHelper.ExecuteScript(acc, $"document.getElementById('m2[{i}]').value='{targetRes[i]}'"); break; case Classificator.ServerVersionEnum.T4_5: await DriverHelper.ExecuteScript(acc, $"document.getElementsByName('desired{i}')[0].value='{targetRes[i]}'"); break; } } var submit = acc.Wb.Html.GetElementbyId("submitText"); var distribute = submit.Descendants("button").FirstOrDefault(); await DriverHelper.ExecuteScript(acc, $"document.getElementById('{distribute.Id}').click()"); wb.ExecuteScript($"document.getElementById('npc_market_button').click()"); //Exchange resources button return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { var wb = acc.Wb.Driver; await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=99&id=39"); // Show "Add raid" popup await DriverHelper.ExecuteScript(acc, $"Travian.Game.RaidList.addSlot({this.FarmListId},'','','rallyPoint');"); // Input coordinates await DriverHelper.WriteCoordinates(acc, Farm.Coords); // Input troops for (int i = 0; i < Farm.Troops.Length; i++) { if (Farm.Troops[i] == 0) { continue; } await DriverHelper.WriteById(acc, $"t{i + 1}", Farm.Troops[i]); } await Task.Delay(AccountHelper.Delay()); // Click "save" switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: wb.ExecuteScript("Travian.Game.RaidList.saveSlot(getSelectedListId(), $('edit_form').toQueryString().parseQueryString(), true);"); break; case Classificator.ServerVersionEnum.T4_5: await DriverHelper.ClickById(acc, "save"); break; } return(TaskRes.Executed); }
/// <summary> /// Tries to watch an Ad for +25% faster upgrade /// </summary> /// <param name="acc">Account</param> /// <returns>Whether bot watched the ad</returns> private async Task <bool> TryFastUpgrade(Account acc) { if (!await DriverHelper.ClickByClassName(acc, "videoFeatureButton green", false)) { return(false); } // Accept ads if (await DriverHelper.ClickByName(acc, "adSalesVideoInfoScreen", false)) { await DriverHelper.ExecuteScript(acc, "jQuery(window).trigger('showVideoWindowAfterInfoScreen')"); } // Has to be a legit "click" acc.Wb.Driver.FindElementById("videoFeature").Click(); var timeout = DateTime.Now.AddSeconds(100); do { await System.Threading.Tasks.Task.Delay(1000); if (timeout < DateTime.Now) { return(false); } }while (acc.Wb.Driver.Url.Contains("build.php")); // Don't show again acc.Wb.UpdateHtml(); if (acc.Wb.Html.GetElementbyId("dontShowThisAgain") != null) { await DriverHelper.ClickById(acc, "dontShowThisAgain"); await DriverHelper.ClickByClassName(acc, "dialogButtonOk ok"); } return(true); }
public override async Task <TaskRes> Execute(Account acc) { 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); } await DriverHelper.ClickById(acc, button.Id); // 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); }
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 url = $"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2"; if (SetCoordsInUrl) { url += "&z=" + MapHelper.KidFromCoordinates(TroopsMovement.TargetCoordinates, acc); } await acc.Wb.Navigate(url); var proceed = TroopsCallback?.Invoke(acc, TroopsMovementParser.GetTroopsInRallyPoint(acc.Wb.Html)); if (!(proceed ?? true)) { return(TaskRes.Retry); } // No troops selected to be sent from this village if (this.TroopsMovement.Troops.Sum() == 0) { return(TaskRes.Executed); } // Add number of troops to the input boxes for (int i = 0; i < TroopsMovement.Troops.Length; i++) { if (TroopsMovement.Troops[i] == 0) { continue; } switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: await DriverHelper.WriteByName(acc, $"t{i + 1}", TroopsMovement.Troops[i]); break; case Classificator.ServerVersionEnum.T4_5: await DriverHelper.WriteByName(acc, $"troops[0][t{i + 1}]", TroopsMovement.Troops[i]); break; } } // Select coordinates, if we haven't set them in the url already if (!SetCoordsInUrl) { await DriverHelper.WriteCoordinates(acc, TroopsMovement.TargetCoordinates); } //Select type of troop sending string script = $"Array.from(document.getElementsByName('c')).find(x=>x.value=={(int)TroopsMovement.MovementType}).checked=true;"; await DriverHelper.ExecuteScript(acc, script); //Click on "Send" button await DriverHelper.ClickById(acc, "btn_ok"); await Task.Delay(AccountHelper.Delay()); // Select catapult targets if (this.TroopsMovement.Target1 != Classificator.BuildingEnum.Site) { await DriverHelper.SelectIndexByName(acc, "ctar1", (int)this.TroopsMovement.Target1); } if (this.TroopsMovement.Target2 != Classificator.BuildingEnum.Site) { await DriverHelper.SelectIndexByName(acc, "ctar2", (int)this.TroopsMovement.Target2); } // Scout type if (this.TroopsMovement.ScoutType != ScoutEnum.None) { string scout = $"Array.from(document.getElementsByName('spy')).find(x=>x.value=={(int)TroopsMovement.ScoutType}).checked=true;"; await DriverHelper.ExecuteScript(acc, scout); } // Parse movement duration of the troops this.Arrival = TroopsMovementParser.GetMovementDuration(acc.Wb.Html); //Click on "Send" button await DriverHelper.ClickById(acc, "btn_ok"); acc.Wb.Log($"Bot sent troops from village {Vill.Name} to {this.TroopsMovement.TargetCoordinates}"); 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); }
/// <summary> /// Tries to watch an Ad for +25% faster upgrade /// </summary> /// <param name="acc">Account</param> /// <returns>Whether bot watched the ad</returns> private async Task <bool> TryFastUpgrade(Account acc) { if (!await DriverHelper.ClickByClassName(acc, "videoFeatureButton green", false)) { return(false); } await System.Threading.Tasks.Task.Delay(AccountHelper.Delay()); // Confirm acc.Wb.UpdateHtml(); if (acc.Wb.Html.DocumentNode.SelectSingleNode("//input[@name='adSalesVideoInfoScreen']") != null) { await DriverHelper.ClickByName(acc, "adSalesVideoInfoScreen"); await System.Threading.Tasks.Task.Delay(AccountHelper.Delay()); await DriverHelper.ExecuteScript(acc, "jQuery(window).trigger('showVideoWindowAfterInfoScreen')"); await System.Threading.Tasks.Task.Delay(AccountHelper.Delay()); } // Has to be a legit "click" acc.Wb.Driver.FindElementById("videoFeature").Click(); // wait for finish watching ads var timeout = DateTime.Now.AddSeconds(100); do { await System.Threading.Tasks.Task.Delay(3000); //skip ads from Travian Games //they use ifarme to emebed ads video to their game acc.Wb.UpdateHtml(); if (acc.Wb.Html.GetElementbyId("videoArea") != null) { acc.Wb.Driver.SwitchTo().Frame(acc.Wb.Driver.FindElementById("videoArea")); // trick to skip await DriverHelper.ExecuteScript(acc, "var video = document.getElementsByTagName('video')[0];video.currentTime = video.duration - 1;", false, false); //back to first page acc.Wb.Driver.SwitchTo().DefaultContent(); } if (timeout < DateTime.Now) { return(false); } }while (acc.Wb.Driver.Url.Contains("build.php")); // Don't show again acc.Wb.UpdateHtml(); if (acc.Wb.Html.GetElementbyId("dontShowThisAgain") != null) { await DriverHelper.ClickById(acc, "dontShowThisAgain"); await System.Threading.Tasks.Task.Delay(AccountHelper.Delay()); await DriverHelper.ClickByClassName(acc, "dialogButtonOk ok"); } return(true); }
public override async Task <TaskRes> Execute(Account acc) { var wb = acc.Wb.Driver; if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace, "&t=0")) { return(TaskRes.Executed); } var npcMerchant = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("npcMerchant")); var npcButton = npcMerchant.Descendants("button").FirstOrDefault(x => x.HasClass("gold")); // Exchange resources button await DriverHelper.ClickById(acc, npcButton.Id); //wait npc form show var timeout = DateTime.Now.AddSeconds(100); HtmlNode remainRes = null; do { await Task.Delay(1000); remainRes = acc.Wb.Html.GetElementbyId("remain"); if (timeout < DateTime.Now) { acc.Wb.Log($"NPC in village {Vill.Name} is time out. Retry after 3 mins"); this.NextExecute = DateTime.Now.AddMinutes(3); return(TaskRes.Executed); } }while (remainRes == null); var resSum = Parser.RemoveNonNumeric(remainRes.InnerText); var targetRes = MarketHelper.NpcTargetResources(Vill, resSum); if (!Vill.Market.Npc.NpcIfOverflow && MarketHelper.NpcWillOverflow(Vill, targetRes)) { acc.Wb.Log($"NPC in village {Vill.Name} will be overflow. Stop NPC"); return(TaskRes.Executed); } for (int i = 0; i < 4; i++) { //await acc.Wb.Driver.FindElementById($"m2[{i}]").Write(targetRes[i]); switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: await DriverHelper.ExecuteScript(acc, $"document.getElementById('m2[{i}]').value='{targetRes[i]}'"); break; case Classificator.ServerVersionEnum.T4_5: await DriverHelper.ExecuteScript(acc, $"document.getElementsByName('desired{i}')[0].value='{targetRes[i]}'"); break; } } var submit = acc.Wb.Html.GetElementbyId("submitText"); var distribute = submit.Descendants("button").FirstOrDefault(); await DriverHelper.ClickById(acc, distribute.Id); await DriverHelper.ClickById(acc, "npc_market_button"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=2&id=39"); TroopsCallback?.Invoke(acc, TroopsMovementParser.GetTroopsInRallyPoint(acc.Wb.Html)); // No troops selected to be sent from this village if (this.TroopsMovement.Troops.Sum() == 0) { return(TaskRes.Executed); } // Add number of troops to the input boxes for (int i = 0; i < TroopsMovement.Troops.Length; i++) { if (TroopsMovement.Troops[i] == 0) { continue; } switch (acc.AccInfo.ServerVersion) { case Classificator.ServerVersionEnum.T4_4: await DriverHelper.WriteByName(acc, $"t{i + 1}", TroopsMovement.Troops[i]); break; case Classificator.ServerVersionEnum.T4_5: await DriverHelper.WriteByName(acc, $"troops[0][t{i + 1}]", TroopsMovement.Troops[i]); break; } } // Select coordinates await DriverHelper.WriteCoordinates(acc, TroopsMovement.TargetCoordinates); //Select type of troop sending string script = $"Array.from(document.getElementsByName('c')).find(x=>x.value=={(int)TroopsMovement.MovementType}).checked=true;"; await DriverHelper.ExecuteScript(acc, script); //Click on "Send" button await DriverHelper.ClickById(acc, "btn_ok"); await Task.Delay(AccountHelper.Delay()); // Select catapult targets if (this.TroopsMovement.Target1 != Classificator.BuildingEnum.Site) { await DriverHelper.SelectIndexByName(acc, "ctar1", (int)this.TroopsMovement.Target1); } if (this.TroopsMovement.Target2 != Classificator.BuildingEnum.Site) { await DriverHelper.SelectIndexByName(acc, "ctar2", (int)this.TroopsMovement.Target2); } // Scout type if (this.TroopsMovement.ScoutType != ScoutEnum.None) { string scout = $"Array.from(document.getElementsByName('spy')).find(x=>x.value=={(int)TroopsMovement.ScoutType}).checked=true;"; await DriverHelper.ExecuteScript(acc, scout); } //Click on "Send" button await DriverHelper.ClickById(acc, "btn_ok"); return(TaskRes.Executed); }
/// <summary> /// Used by BotTasks to insert resources/coordinates into the page. /// </summary> /// <param name="acc">Account</param> /// <param name="resources">Target resources</param> /// <param name="coordinates">Target coordinates</param> /// <returns>Time it will take for transit to complete</returns> public static async Task <TimeSpan> MarketSendResource(Account acc, long[] resources, Village targetVillage, BotTask botTask) { var times = 1; if (acc.AccInfo.GoldClub ?? false) { times = 3; } else if (acc.AccInfo.PlusAccount) { times = 2; } // No resources to send if (resources.Sum() == 0) { return(TimeSpan.Zero); } var sendRes = resources.Select(x => x / times).ToArray(); //round the resources that we want to send, so it looks less like a bot (var merchantsCapacity, var merchantsNum) = MarketHelper.ParseMerchantsInfo(acc.Wb.Html); // We don't have any merchants. if (merchantsNum == 0) { //Parse currently ongoing transits var transits = MarketParser.ParseTransits(acc.Wb.Html); var activeVill = acc.Villages.FirstOrDefault(x => x.Active); // Could also just pass that in params var nextTry = SoonestAvailableMerchants(acc, activeVill, targetVillage, transits); if (nextTry != DateTime.MaxValue) { nextTry = nextTry.AddSeconds(5); } botTask.NextExecute = nextTry; // Just return something, will get overwritten anyways. return(new TimeSpan((int)(nextTry - DateTime.Now).TotalHours + 1, 0, 0)); } var maxRes = merchantsCapacity * times; var allRes = resources.Sum(); if (allRes > maxRes) { // We don't have enough merchants to transit all the resources. Divide all resources by some divider. var resDivider = (float)allRes / maxRes; float[] resFloat = sendRes.Select(x => x / resDivider).ToArray(); sendRes = resFloat.Select(x => (long)Math.Floor(x)).ToArray(); } var wb = acc.Wb.Driver; for (int i = 0; i < 4; i++) { // To avoid exception devide by zero if (50 <= sendRes[i]) { //round the number to about -1%, for rounder numbers var digits = Math.Ceiling(Math.Log10(sendRes[i])); var remainder = sendRes[i] % (long)Math.Pow(10, digits - 2); sendRes[i] -= remainder; await DriverHelper.WriteById(acc, "r" + (i + 1), sendRes[i]); } await Task.Delay(AccountHelper.Delay() / 5); } // Input coordinates await DriverHelper.WriteCoordinates(acc, targetVillage.Coordinates); //Select x2/x3 if (times != 1) { wb.ExecuteScript($"document.getElementById('x2').value='{times}'"); await Task.Delay(AccountHelper.Delay() / 5); } await DriverHelper.ClickById(acc, "enabledButton"); var durNode = acc.Wb.Html.GetElementbyId("target_validate"); if (durNode == null && acc.Wb.Html.GetElementbyId("prepareError") != null) { // Error "Abuse! You have not enough resources." is displayed. } //get duration of transit var dur = durNode.Descendants("td").ToList()[3].InnerText.Replace("\t", "").Replace("\n", ""); // Will NOT trigger a page reload! Thus we should await some time before continuing. await DriverHelper.ClickById(acc, "enabledButton"); targetVillage.Market.LastTransit = DateTime.Now; var duration = TimeParser.ParseDuration(dur); return(TimeSpan.FromTicks(duration.Ticks * (times * 2 - 1))); }