public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/spieler.php?uid=1"); var vills = htmlDoc.GetElementbyId("villages").Descendants("tr"); int addedFarms = 0; foreach (var vill in vills) { var name = vill.ChildNodes.First(x => x.HasClass("name")).InnerText; var pop = (int)Parser.RemoveNonNumeric(vill.Descendants().First(x => x.HasClass("inhabitants")).InnerHtml); if (pop > MinPop && pop < MaxPop) { var href = vill.Descendants("a").First(x => x.GetAttributeValue("href", "").StartsWith("karte.php?x=")).GetAttributeValue("href", "").Split('?')[1]; var xy = href.Split('&'); Coordinates coords = new Coordinates { x = (int)Parser.RemoveNonNumeric(xy[0].Split('=')[1]), y = (int)Parser.RemoveNonNumeric(xy[1].Split('=')[1]) }; var task = new AddFarm() { Coordinates = coords, ExecuteAt = DateTime.Now.AddMilliseconds(addedFarms), FarmListId = this.FL.Id, Troops = new List <TroopsRaw>() { new TroopsRaw() { Type = 1, Number = 10 } } //just add 10 of 1st troops }; TaskExecutor.AddTask(acc, task); addedFarms++; if (FL.NumOfFarms + addedFarms >= 100) { break; //no more slots FL slots! } } } return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=2&id=39"); var wavesReady = new List <WaveReadyModel>(); // Get request time for getting more accurate attacks Ping ping = new Ping(); PingReply reply = ping.Send(IoHelperCore.UrlRemoveHttp(acc.AccInfo.ServerUrl)); var reqTripMs = (int)(reply.RoundtripTime / 2); Random rnd = new Random(); // Prepare the waves for (int i = 0; i < SendWaveModels.Count; i++) { Console.WriteLine(DateTime.Now + "Send wave 1"); await Task.Delay(rnd.Next(800, 1000)); var htmlDoc1 = await HttpHelper.SendGetReq(acc, "/build.php?tt=2&id=39"); var build = htmlDoc1.GetElementbyId("build"); var ajaxToken = await HttpHelper.GetAjaxToken(wb); var values = new Dictionary <string, string> { { "dname", "" }, // Name of the village, empty. Bot uses coordinates { "x", SendWaveModels[i].Coordinates.x.ToString() }, { "y", SendWaveModels[i].Coordinates.y.ToString() }, { "c", ((int)SendWaveModels[i].MovementType).ToString() }, // 2 = reinformance, 3 = attack, 4 = raid { "s1", "ok" }, { "ajaxToken", ajaxToken } }; foreach (var hidden in hiddenFields) { var value = build.Descendants("input").FirstOrDefault(x => x.GetAttributeValue("name", "") == hidden).GetAttributeValue("value", ""); values.Add(hidden, value); } // Get available troops int[] troopsAtHome = TroopsMovementParser.GetTroopsInRallyPoint(htmlDoc1); // Send all off dirty hack if (SendWaveModels[i].AllOff) { for (int j = 0; j < 10; j++) { var troop = TroopsHelper.TroopFromInt(acc, j); if (TroopsHelper.IsTroopOffensive(troop) || TroopsHelper.IsTroopRam(troop)) { SendWaveModels[i].Troops[j] = troopsAtHome[j]; troopsAtHome[j] = 0; } } } // Send fake attack dirty hack if (SendWaveModels[i].FakeAttack) { for (int j = 0; j < 10; j++) { if (troopsAtHome[j] > 19) { SendWaveModels[i].Troops[j] = 19; troopsAtHome[j] -= 19; break; } } } for (int j = 0; j < SendWaveModels[i].Troops.Length; j++) { values.Add($"t{j + 1}", SendWaveModels[i].Troops[j].ToString()); } var content = new FormUrlEncodedContent(values); await Task.Delay(rnd.Next(800, 1000)); var ret = await HttpHelper.SendPostReq(acc, content, "/build.php?tt=2&id=39"); var htmlDoc2 = new HtmlAgilityPack.HtmlDocument(); htmlDoc2.LoadHtml(ret); // Get time it takes for troops to the target, for later usage var timespan = TroopsMovementParser.GetTimeOfMovement(htmlDoc2); lastArriveAt = TroopsMovementParser.GetArrivalTime(htmlDoc2); if (timeDifference == TimeSpan.Zero) { var serverTime = TimeParser.GetServerTime(htmlDoc2); timeDifference = DateTime.Now - serverTime; // Negate seconds and milliseconds in time difference. var negateMillis = timeDifference.Milliseconds; negateMillis += timeDifference.Seconds * 1000; timeDifference = timeDifference.Subtract(new TimeSpan(0, 0, 0, 0, negateMillis)); var executeTime = CorrectExecuteTime(timespan); if (DateTime.Now.AddMinutes(1) < executeTime) { // Restart this task at the correct time this.NextExecute = executeTime; return(TaskRes.Executed); } } //var ajaxToken = await HttpHelper.GetAjaxToken(wb); var values2 = new Dictionary <string, string> { { "s1", "ok" }, }; // Copy all hidden names and values var build2 = htmlDoc2.GetElementbyId("build"); var hiddens2 = build2.Descendants("input").Where(x => x.GetAttributeValue("type", "") == "hidden"); foreach (var hidden2 in hiddens2) { var val = hidden2.GetAttributeValue("value", ""); var name = hidden2.GetAttributeValue("name", ""); values2.Add(name, val); } // Add catapult targets values2.TryGetValue("t8", out string cataCount); if (int.Parse(cataCount) > 0) { values2.Add("ctar1", "99"); // 99 = Random, 1 = woodcuter, 2 = claypit.. values2.Add("ctar2", "99"); // 99 = Random } wavesReady.Add(new WaveReadyModel { Content = new FormUrlEncodedContent(values2), MovementTime = timespan }); this.DurationCounter = 0; Console.WriteLine(DateTime.Now + "Send wave 2"); } var waitMs = 1000 - DateTime.Now.Millisecond - reqTripMs; if (waitMs < 0) { waitMs += 1000; } var wait = new TimeSpan(0, 0, 0, 0, waitMs); // Calculate how much you need to wait so waves will arrive at correct time! var targetArrival = SendWaveModels.FirstOrDefault(x => x.Arrival != DateTime.MinValue).Arrival; TimeSpan waitForTarget = (targetArrival - lastArriveAt); if (waitForTarget > TimeSpan.Zero) { var waitForTargetSec = waitForTarget.Seconds + (waitForTarget.Minutes * 60) - 1; // -1 to compensate var waitForTargetTimeSpan = new TimeSpan(0, 0, waitForTargetSec); wait = wait.Add(waitForTargetTimeSpan); this.DurationCounter = -(int)(wait.TotalSeconds * 2); } await Task.Delay(wait); // Send the waves for (int i = 0; i < wavesReady.Count; i++) { // Wait +- 10% selected delay var delay = SendWaveModels[i].DelayMs; var delay10Percent = (int)delay / 10; await Task.Delay(rnd.Next(delay - delay10Percent, delay + delay10Percent)); _ = HttpHelper.SendPostReq(acc, wavesReady[i].Content, "/build.php?tt=2&id=39"); this.DurationCounter = 0; } await Task.Delay(AccountHelper.Delay() * 2); acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?gid=16&tt=1&filter=2&subfilters=4"); //Todo: check waves? return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf1.php"); Random rnd = new Random(); int sec = rnd.Next(725, 740); TaskExecutor.AddTask(acc, new TTWarsGetAnimals() { ExecuteAt = DateTime.Now.AddSeconds(sec), vill = AccountHelper.GetMainVillage(acc) }); //Open payment wizard on tab Plus features (where you can buy stuff with gold) wb.ExecuteScript("window.fireEvent('startPaymentWizard', {data:{activeTab: 'paymentFeatures'}});"); await Task.Delay(AccountHelper.Delay()); wb.ExecuteScript("$$('.paymentWizardMenu').addClass('hide');$$('.buyGoldInfoStep').removeClass('active');$$('.buyGoldInfoStep#3').addClass('active');$$('.paymentWizardMenu#buyResources').removeClass('hide');"); //Excgabge resources button await Task.Delay(AccountHelper.Delay() * 2); htmlDoc.LoadHtml(wb.PageSource); var buy = htmlDoc.DocumentNode.SelectNodes("//*[text()[contains(., '3000')]]")[0]; while (buy.Name != "button") { buy = buy.ParentNode; } var buyId = buy.GetAttributeValue("id", ""); wb.ExecuteScript($"document.getElementById('{buyId}').click()"); //Clicking on buy button DOES NOT trigger a page reloag. We have to do it manually. return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { string str = "?"; if (acc.Wb.CurrentUrl.Contains("?")) { str = "&"; } var url = $"{acc.Wb.CurrentUrl}{str}newdid={this.vill.Id}"; await acc.Wb.Navigate(url); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf2.php"); Random rnd = new Random(); int sec = rnd.Next(370, 380); TaskExecutor.AddTask(acc, new TTWarsGetRes() { ExecuteAt = DateTime.Now.AddSeconds(sec), vill = AccountHelper.GetMainVillage(acc) }); TaskExecutor.AddTask(acc, new TrainExchangeRes() { ExecuteAt = DateTime.Now.AddSeconds(sec + 5), troop = acc.Villages[0].Troops.TroopToTrain ?? Classificator.TroopsEnum.Hero, vill = vill }); TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = DateTime.Now.AddSeconds(sec + 9), Troop = acc.Villages[0].Troops.TroopToTrain ?? Classificator.TroopsEnum.Hero, vill = vill, HighSpeedServer = true }); wb.ExecuteScript("window.fireEvent('startPaymentWizard', {data:{activeTab: 'paymentFeatures'}});"); await Task.Delay(AccountHelper.Delay() * 2); wb.ExecuteScript("$$('.paymentWizardMenu').addClass('hide');$$('.buyGoldInfoStep').removeClass('active');$$('.buyGoldInfoStep#2').addClass('active');$$('.paymentWizardMenu#buyResources').removeClass('hide');"); //Excgabge resources button await Task.Delay(AccountHelper.Delay() * 2); htmlDoc.LoadHtml(wb.PageSource); //gold prosButton buyResources6 //gold prosButton buyAnimal5 var buy = htmlDoc.DocumentNode.Descendants("button").FirstOrDefault(x => x.HasClass("buyResources6")); if (buy == null) { this.ErrorMessage = "Can't find the button with class buyResources6. Are you sure you are on vip/unl TTWars server?"; return(TaskRes.Executed); } var buyId = buy.GetAttributeValue("id", ""); wb.ExecuteScript($"document.getElementById('{buyId}').click()"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=99&id=39"); wb.ExecuteScript($"Travian.Game.RaidList.addSlot({this.FarmListId},'','','rallyPoint');"); //show "Add raid" popup await Task.Delay(AccountHelper.Delay()); //select coordinates wb.ExecuteScript($"document.getElementById('xCoordInput').value='{Coordinates.x}'"); wb.ExecuteScript($"document.getElementById('yCoordInput').value='{Coordinates.y}'"); await Task.Delay(AccountHelper.Delay()); //add number of troops to the input boxes foreach (var troop in Troops) { int troopNum = (int)troop.Type % 10; wb.ExecuteScript($"document.getElementsByName('{"t" + troopNum}')[0].value='{troop.Number}'"); } await Task.Delay(AccountHelper.Delay()); //click "save" wb.ExecuteScript("Travian.Game.RaidList.saveSlot(getSelectedListId(), $('edit_form').toQueryString().parseQueryString(), true);"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?gid=16&tt=1&filter=1&subfilters=1"); //(var attackWithHero, var count)= TroopsMovementParser.FullAttackWithHero(htmlDoc); //if (attackWithHero) //{ // IoHelper.AlertUser(vill.Name + " is under attack!"); //} //if(count > 0) //{ // this.NextExecute = DateTime.Now.AddMinutes(1); //} return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { var leftBar = htmlDoc.GetElementbyId("sidebarBeforeContent"); var button = leftBar.Descendants("button").FirstOrDefault(x => x.HasClass("gold")); if (button == null) { return(TaskRes.Executed); } var buttonid = button.GetAttributeValue("id", ""); acc.Wb.Driver.ExecuteScript($"document.getElementById('{buttonid}').click()"); //boost production return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { var market = vill.Build.Buildings.FirstOrDefault(x => x.Type == TravBotSharp.Files.Helpers.Classificator.BuildingEnum.Marketplace); if (market == null) { return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?t=0&id={market.Id}"); var npcMerchant = htmlDoc.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("npcMerchant")); var npcButton = npcMerchant.Descendants("button").FirstOrDefault(x => x.HasClass("gold")); wb.ExecuteScript($"document.getElementById('{npcButton.GetAttributeValue("id", "")}').click()"); //Excgabge resources button await Task.Delay(AccountHelper.Delay() * 2); htmlDoc.LoadHtml(wb.PageSource); var resSum = Parser.RemoveNonNumeric(htmlDoc.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++) { wb.ExecuteScript($"document.getElementById('m2[{i}]').value='{targetRes[i]}'"); await Task.Delay(100); } var submit = htmlDoc.GetElementbyId("submitText"); var distribute = submit.Descendants("button").FirstOrDefault(); wb.ExecuteScript($"document.getElementById('{distribute.Id}').click()"); //Distribute resources button await Task.Delay(AccountHelper.Delay()); wb.ExecuteScript($"document.getElementById('npc_market_button').click()"); //Exchange resources button 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!"); } }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/karte.php"); var mainVill = AccountHelper.GetMainVillage(acc); var ajaxToken = await HttpHelper.GetAjaxToken(wb); var values = new Dictionary <string, string> { { "cmd", "mapPositionData" }, { "data[x]", mainVill.Coordinates.x.ToString() }, { "data[y]", mainVill.Coordinates.y.ToString() }, { "data[zoomLevel]", "3" }, { "ajaxToken", ajaxToken }, }; var content = new FormUrlEncodedContent(values); var resString = await HttpHelper.SendPostReq(acc, content, "/ajax.php?cmd=mapPositionData"); var root = JsonConvert.DeserializeObject <MapPositionData.Root>(resString); if (!root.response.error) { var closesCoords = new Coordinates(); var closest = 1000.0; foreach (var tile in root.response.data.tiles) { if (tile.c == null || !tile.c.StartsWith("{k.vt}")) { continue; } // Check if village type meets criteria if (acc.NewVillages.Types.Count != 0) { var num = (int)Parser.RemoveNonNumeric(tile.c.Split('f')[1]); var type = (Classificator.VillTypeEnum)(++num); if (!acc.NewVillages.Types.Any(x => x == type)) { continue; } } Coordinates coords = new Coordinates() { x = Int32.Parse(tile.x), y = Int32.Parse(tile.y), }; var distance = MapHelper.CalculateDistance(acc, mainVill.Coordinates, coords); if (closest > distance) { closest = distance; closesCoords = coords; } } //acc.Settings.new acc.NewVillages.Locations.Add(new Models.VillageModels.NewVillage() { coordinates = closesCoords, Name = NewVillageHelper.GenerateName(acc), }); } return(TaskRes.Executed); }
//TODO Add options for catapult/scout targets inside SendTroops2! public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=2&id=39"); //add number of troops to the input boxes for (int i = 0; i < TroopsMovement.Troops.Length; i++) { if (TroopsMovement.Troops[i] == 0) { continue; } wb.ExecuteScript($"document.getElementsByName('t{i + 1 }')[0].value='{TroopsMovement.Troops[i]}'"); await Task.Delay(222); } //select coordinates wb.ExecuteScript($"document.getElementById('xCoordInput').value='{TroopsMovement.Coordinates.x}'"); wb.ExecuteScript($"document.getElementById('yCoordInput').value='{TroopsMovement.Coordinates.y}'"); await Task.Delay(AccountHelper.Delay()); //Select type of troop sending string script = "var radio = document.getElementsByClassName(\"radio\");for(var i = 0; i < radio.length; i++){"; script += $"if(radio[i].value == \"{(int)TroopsMovement.MovementType}\") radio[i].checked = \"checked\"}}"; wb.ExecuteScript(script); await Task.Delay(2 *AccountHelper.Delay()); //Click on "Send" button wb.ExecuteScript($"document.getElementById('btn_ok').click()"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/hero.php"); acc.Hero.HeroInfo = HeroParser.GetHeroInfo(htmlDoc); var points = acc.Hero.HeroInfo.AvaliblePoints; for (int i = 0; i < 4; i++) { var amount = acc.Hero.Settings.Upgrades[i]; if (amount == 0) { continue; } var id = HeroHelper.AttributeDomId(i); var script = $"var attribute = document.getElementById('{id}');"; script += "var upPoint = attribute.getElementsByClassName('pointsValueSetter')[1];"; script += "upPoint.getElementsByTagName('a')[0].click();"; for (int j = 0; j < amount; j++) { // Execute the script (set point) to add 1 point wb.ExecuteScript(script); } await Task.Delay(AccountHelper.Delay()); } await Task.Delay(AccountHelper.Delay()); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { if (vill == null) { vill = AccountHelper.GetMainVillage(acc); } Classificator.BuildingEnum building = (Great == false) ? TroopsHelper.GetTroopBuilding(troop, false) : TroopsHelper.GetTroopBuilding(troop, true); var buildId = vill.Build.Buildings.FirstOrDefault(x => x.Type == building); if (buildId == null) { //update dorf, no buildingId found? TaskExecutor.AddTask(acc, new UpdateDorf2() { ExecuteAt = DateTime.Now }); Console.WriteLine($"There is no {building} in this village!"); return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={buildId.Id}"); var troopNode = htmlDoc.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop)); while (!troopNode.HasClass("details")) { troopNode = troopNode.ParentNode; } //finding the correct "Exchange resources" button var exchangeResButton = troopNode.Descendants("button").FirstOrDefault(x => x.HasClass("gold")); wb.ExecuteScript($"document.getElementById('{exchangeResButton.GetAttributeValue("id", "")}').click()"); //Exchange resources button await Task.Delay(AccountHelper.Delay()); htmlDoc.LoadHtml(wb.PageSource); await Task.Delay(AccountHelper.Delay()); var distribute = htmlDoc.DocumentNode.SelectNodes("//*[text()[contains(., 'Distribute remaining resources.')]]")[0]; while (distribute.Name != "button") { distribute = distribute.ParentNode; } string distributeid = distribute.GetAttributeValue("id", ""); wb.ExecuteScript($"document.getElementById('{distributeid}').click()"); //Distribute resources button await Task.Delay(AccountHelper.Delay()); wb.ExecuteScript($"document.getElementById('npc_market_button').click()"); //Exchange resources button return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { TaskExecutor.AddTaskIfNotExists(acc, new TransitToMainAcc { coords = this.coords, delay = this.delay, ExecuteAt = DateTime.Now.AddSeconds(delay), vill = this.vill }); //Resources res = new Resources() { Wood = 50000000, Clay = 50000000, Iron = 50000000, Crop = 50000000 }; TaskExecutor.AddTask(acc, new SendResources() { ExecuteAt = DateTime.Now, Coordinates = coords, vill = this.vill }); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { building = TroopsHelper.GetTroopBuilding(Troop, Great); var buildId = vill.Build.Buildings.FirstOrDefault(x => x.Type == building); if (buildId == null) { //update dorf, no buildingId found? TaskExecutor.AddTask(acc, new UpdateDorf2() { ExecuteAt = DateTime.Now, vill = vill }); Console.WriteLine($"There is no {building} in this village!"); return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={buildId.Id}"); //after finishing task, update currently training this.PostTaskCheck.Add(UpdateCurrentlyTraining); if (!HighSpeedServer) { this.PostTaskCheck.Add(RepeatTrainingCycle); } if (this.UpdateOnly || this.Troop == TroopsEnum.None) { return(TaskRes.Executed); } (TimeSpan dur, Resources cost) = TroopsParser.GetTrainCost(htmlDoc, this.Troop); var troopNode = htmlDoc.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)Troop)); while (!troopNode.HasClass("details")) { troopNode = troopNode.ParentNode; } var inputName = troopNode.Descendants("input").FirstOrDefault().GetAttributeValue("name", ""); var maxNum = Parser.RemoveNonNumeric(troopNode.ChildNodes.FirstOrDefault(x => x.Name == "a").InnerText); if (!HighSpeedServer) { var trainNum = TroopsHelper.TroopsToFill(acc, vill, this.Troop, this.Great); // Don't train too many troops, just fill up the training building if (maxNum > trainNum) { maxNum = trainNum; } } if (maxNum < 0) { // We have already enough troops in training. return(TaskRes.Executed); } wb.ExecuteScript($"document.getElementsByName('{inputName}')[0].value='{maxNum}'"); await Task.Delay(100); wb.ExecuteScript("document.getElementsByName('s1')[0].click()"); //Train button return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { //remove all same tasks TaskExecutor.RemoveSameTasksForVillage(acc, vill, this.GetType(), this); var url = $"{acc.AccInfo.ServerUrl}/dorf1.php"; await acc.Wb.Navigate(url); return(TaskRes.Executed); }
//If Troop == null, just update the troop levels public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { var academy = vill.Build.Buildings.FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Academy); if (academy == null) { return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={academy.Id}"); 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 = htmlDoc.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop)); if (troopNode == null) { this.ErrorMessage = $"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(htmlDoc, troop); var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, cost); if (nextExecute < DateTime.Now.AddMilliseconds(1)) //We have enough resources, click Research button { wb.ExecuteScript($"document.getElementById('{button.Id}').click()"); var executeNext = DateTime.Now.Add(dur).AddMilliseconds(10 * AccountHelper.Delay()); TaskExecutor.AddTask(acc, new ImproveTroop() { vill = this.vill, ExecuteAt = DateTime.Now.Add(dur) } ); RepeatTask(vill, troop, executeNext); return(TaskRes.Executed); } else //Retry same task after resources get produced/transited { this.NextExecute = nextExecute; return(TaskRes.Executed); } }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { if (vill == null) { vill = acc.Villages.First(x => x.Active); } var smithy = vill.Build.Buildings.FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Smithy); if (smithy == null) { return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={smithy.Id}"); var levels = TroopsParser.GetTroopLevels(htmlDoc); if (levels == null) { this.ErrorMessage = "There was an error at getting Smithy troop levels"; return(TaskRes.Executed); } vill.Troops.Levels = levels; UpdateResearchedTroops(vill); var currentlyImproving = TroopsParser.GetImprovingTroops(htmlDoc); 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 (currentlyImproving.Count() >= maxImproving) { 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); var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, cost.UpgradeCost); if (nextExecute < DateTime.Now.AddMilliseconds(1)) //We have enough resources, click Improve button { //Click on the button var troopNode = htmlDoc.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) { this.ErrorMessage = $"Could not find Upgrade button to improve {troop}"; this.NextExecute = DateTime.Now.AddMinutes(1); return(TaskRes.Retry); } wb.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); } else //Retry same task after resources get produced/transited { this.NextExecute = nextExecute; return(TaskRes.Executed); } }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2&z=1"); var yStr = htmlDoc.GetElementbyId("yCoordInput").GetAttributeValue("value", ""); var y = (int)Parser.RemoveNonNumeric(yStr); acc.AccInfo.MapSize = Math.Abs(y); return(TaskRes.Executed); }
/// <summary> /// When new village is found by the bot, it should firstly check barracks, then stable and then workshop, /// to see which troops are researched /// </summary> public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { // If we have Plus account, just check that. if (acc.AccInfo.PlusAccount) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf3.php?s=5&su=2"); OverviewParser.UpdateTroopsLevels(htmlDoc, ref acc); // We have updated all villages at the same time. No need to continue. acc.Tasks.RemoveAll(x => x.GetType() == typeof(UpdateTroops)); return(TaskRes.Executed); } var smithy = vill.Build.Buildings.FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Smithy); if (smithy != null) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={smithy.Id}"); vill.Troops.Levels = TroopsParser.GetTroopLevels(htmlDoc); UpdateResearchedTroops(vill); return(TaskRes.Executed); } for (int i = 0; i < 3; i++) { //var building = GetBuilding(i); //await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={building.Id}"); // TODO: parse content } return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { Random rnd = new Random(); int totalSec = 0; foreach (var fl in acc.Farming.FL) { // Check interval of the farmlist if (fl.Interval > 1) { if (fl.IntervalCounter <= fl.Interval) { fl.IntervalCounter++; continue; } fl.IntervalCounter = 0; } if (fl.Enabled) { //TODO: do some logic with counters, so not all FLs get sent with same period TaskExecutor.AddTask(acc, new SendFarmlist() { ExecuteAt = DateTime.Now.AddSeconds(totalSec), FL = fl }); totalSec += rnd.Next(acc.Farming.MinInterval, acc.Farming.MaxInterval); } } TaskExecutor.AddTask(acc, new SendFLs() { ExecuteAt = DateTime.Now.AddSeconds(totalSec) }); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { //Sitters cannot extend protection on TTWARS! var extendButton = htmlDoc.DocumentNode.Descendants("button").FirstOrDefault(x => x.GetAttributeValue("value", "") == "Extend"); if (extendButton == null) { this.ErrorMessage = "Can not extend protection! Are you a sitter?"; return(TaskRes.Executed); } //class dialogButtonOk //type submit http://prntscr.com/ryunwj return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.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 (building == null) { //update dorg, no buildingId found? TaskExecutor.AddTask(acc, new UpdateDorf2() { ExecuteAt = DateTime.Now, vill = vill }); Console.WriteLine($"There is no Residence/Palace/CommandCenter in this village!"); return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?s=1&id={building.Id}"); var cost = htmlDoc.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("resourceWrapper")); if (cost == null) { this.ErrorMessage = "Could not train settlers. Will retry in 5min"; this.NextExecute = DateTime.Now.AddMinutes(5); //retry in 5min return(TaskRes.Executed); } var resources = ResourceParser.GetResourceCost(cost); var enoughResAt = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, resources); if (enoughResAt <= DateTime.Now.AddMilliseconds(1)) //we have enough res, create new settler! { wb.ExecuteScript($"document.getElementsByName('t10')[0].value='1'"); await Task.Delay(AccountHelper.Delay()); wb.ExecuteScript($"document.getElementById('s1').click()"); //Train settler vill.Troops.Settlers++; if (vill.Troops.Settlers < 3) { //In 1 minute, do the same task (to get total of 3 settlers) this.NextExecute = DateTime.Now.AddSeconds(1); } else { if (acc.NewVillages.AutoSettleNewVillages) { //parse in training table this.PostTaskCheck.Add(NewVillage); } } return(TaskRes.Executed); } else { //Not enough res, wait for production/transit res this.NextExecute = enoughResAt.AddSeconds(60 * AccountHelper.Delay()); return(TaskRes.Executed); } }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate("https://api.ipify.org/"); var ip = htmlDoc.DocumentNode.InnerText; var currentProxy = acc.Access.GetCurrentAccess().Proxy; if (!string.IsNullOrEmpty(currentProxy) && ip.Trim() != currentProxy.Trim()) { // Proxy error! Utils.log.Information($"Failed proxy {currentProxy} for account {acc.AccInfo.Nickname}! Trying to get new proxy."); if (acc.Access.AllAccess.Count > 1) { // Try another access. acc.Wb.Close(); await Task.Delay(AccountHelper.Delay()); acc.Wb.InitSelenium(acc); return(TaskRes.Executed); } } return(TaskRes.Executed); }
//TODO: add option for scouting type / catapult target(s) public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await Task.Delay(AccountHelper.Delay()); wb.ExecuteScript($"document.getElementById('btn_ok').click()"); //Click send return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=99&id=39"); //TODO: if there is no rally point, switch to different village!] var flNode = htmlDoc.GetElementbyId("list" + this.FL.Id); if (flNode == null) { TaskExecutor.AddTask(acc, new SwitchVillage() { vill = AccountHelper.GetMainVillage(acc), ExecuteAt = DateTime.MinValue.AddMinutes(10), Priority = TaskPriority.High }); this.NextExecute = DateTime.Now.AddSeconds(5); return(TaskRes.Executed); } if (acc.Farming.TrainTroopsAfterFL) { TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = DateTime.Now.AddSeconds(2), Troop = acc.Villages[0].Troops.TroopToTrain ?? Classificator.TroopsEnum.Hero, vill = this.vill, HighSpeedServer = true }); } wb.ExecuteScript($"Travian.Game.RaidList.toggleList({this.FL.Id});"); //Toggle the FL (show it) await Task.Delay(AccountHelper.Delay() * 2); htmlDoc.LoadHtml(wb.PageSource); await Task.Delay(AccountHelper.Delay()); // Update flNode! flNode = htmlDoc.GetElementbyId("list" + this.FL.Id); foreach (var farm in flNode.Descendants("tr").Where(x => x.HasClass("slotRow"))) { //iReport2 = yellow swords, iReport3 = red swords, iReport1 = successful raid var img = farm.ChildNodes.FirstOrDefault(x => x.HasClass("lastRaid"))?.Descendants("img"); //there has to be an image (we already have a report) and wrong raid style to not check this farmlist: if (img.Count() != 0 && ( //no image -> no recent attack (img.FirstOrDefault(x => x.HasClass("iReport3")) != null && this.FL.RaidStyle != RaidStyle.RaidLost) || //raid was lost and we don't have RaidLost raidstyle (img.FirstOrDefault(x => x.HasClass("iReport2")) != null && (this.FL.RaidStyle == RaidStyle.RaidSuccessful)) //some casualities, but we only attack on successful )) { continue; } var checkbox = farm.Descendants("input").FirstOrDefault(x => x.HasClass("markSlot")); var str = $"document.getElementById('{checkbox.Id}').checked=true"; wb.ExecuteScript(str); //Check the checkbox } await Task.Delay(AccountHelper.Delay() * 2); wb.ExecuteScript($"document.getElementById('{flNode.Id}').childNodes[1].submit()"); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf1.php?ok"); await Task.Delay(AccountHelper.Delay()); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=2&id=39"); int[] troopsAtHome = TroopsMovementParser.GetTroopsInRallyPoint(htmlDoc); for (int i = 0; i < 10; i++) { var troop = TroopsHelper.TroopFromInt(acc, i); if (TroopsHelper.IsTroopDefensive(troop)) { var upkeep = TroopSpeed.GetTroopUpkeep(troop); int sendAmount = troopsAtHome[i]; if (this.DeffAmount.DeffCount != null) { if (sendAmount * upkeep > this.DeffAmount.DeffCount) { // We have sent all needed deff sendAmount = (this.DeffAmount.DeffCount ?? 0) / upkeep; // Remove all other (linked) SendDeff bot tasks var list = new List <SendDeff> { this.NextDeffTask }; while (list.Last() != null) { list.Add(list.Last().NextDeffTask); } foreach (var task in list) { if (task == null) { continue; } acc.Tasks.Remove(task); } } else { this.DeffAmount.DeffCount -= sendAmount * upkeep; } } wb.ExecuteScript($"document.getElementsByName('t{i + 1 }')[0].value='{sendAmount}'"); } } //select coordinates wb.ExecuteScript($"document.getElementById('xCoordInput').value='{TargetVillage.x}'"); wb.ExecuteScript($"document.getElementById('yCoordInput').value='{TargetVillage.y}'"); await Task.Delay(AccountHelper.Delay()); //Select reinforcement string script = "var radio = document.getElementsByClassName(\"radio\");for(var i = 0; i < radio.length; i++){"; script += $"if(radio[i].value == '2') radio[i].checked = \"checked\"}}"; wb.ExecuteScript(script); await Task.Delay(2 *AccountHelper.Delay()); wb.ExecuteScript($"document.getElementById('btn_ok').click()"); await Task.Delay(2 *AccountHelper.Delay()); // Confirm wb.ExecuteScript($"document.getElementById('btn_ok').click()"); //Click send return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc) { acc.Wb.Close(); // Wait some time between the proxy switching. Random rnd = new Random(); var seconds = rnd.Next(30, 600); // TODO: make this configurable (wait time between switches) //TODO: also check for high priority tasks (attacking/deffending). If there is one, don't wait so long! this.DurationCounter = -2 * seconds; await Task.Delay(seconds * 1000); acc.Wb.InitSelenium(acc); return(TaskRes.Executed); }