private void UpdateUc(bool updateVillList = true) { var acc = GetSelectedAcc(); if (villSelected < 0 || acc.Villages.Count <= villSelected) { villSelected = acc.Villages.Count - 1; } if (updateVillList) { VillagesListView.Items.Clear(); for (int i = 0; i < acc.Villages.Count; i++) // Update villages list { var item = new ListViewItem(); item.SubItems[0].Text = acc.Villages[i].Name; item.SubItems[0].ForeColor = Color.FromName(villSelected == i ? "DodgerBlue" : "Black"); item.SubItems.Add(acc.Villages[i].Coordinates.x + "/" + acc.Villages[i].Coordinates.y); //coords item.SubItems.Add(VillageHelper.VillageType(acc.Villages[i])); //type (resource) item.SubItems.Add(VillageHelper.ResourceIndicator(acc.Villages[i])); //resources count VillagesListView.Items.Add(item); } } // Don't update village view if there is no village selected! if (GetSelectedVillage() == null) { return; } Ucs.ElementAtOrDefault(villageTabController.SelectedIndex)?.UpdateUc(); }
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) { 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); }
private void UpdateBuildTasks(Village vill) { buildListView.Items.Clear(); for (int i = 0; i < vill.Build.Tasks.Count; i++) { var task = vill.Build.Tasks[i]; var item = new ListViewItem(); //building if (task.TaskType == BuildingType.AutoUpgradeResFields) { item.SubItems[0].Text = AutoBuildResFieldsStr(task); } else { item.SubItems[0].Text = VillageHelper.BuildingTypeToString(task.Building); } item.ForeColor = Color.FromName(oldSelected == i ? "DodgerBlue" : "Black"); item.SubItems.Add(task.Level.ToString()); //lvl item.SubItems.Add(task.BuildingId.ToString()); //buildingId //var upgradeTask = acc.Tasks?.FirstOrDefault(x => // x.GetType() == typeof(UpgradeBuilding) // && ((UpgradeBuilding)x).Task == task // ); //item.SubItems.Add(upgradeTask == null ? "" : upgradeTask.ExecuteAt.ToString()); //execute at buildListView.Items.Add(item); } }
public void UpdateTroopTab() { var acc = getSelectedAcc(); var vill = getSelectedVillage(acc); if (acc.AccInfo.Tribe != null) { if (vill.Troops.TroopToTrain != null) { labelTroopsToTrain.Text = $"Selected: {VillageHelper.EnumStrToString(vill.Troops.TroopToTrain.ToString() ?? "")}"; } else { labelTroopsToTrain.Text = "Selected:"; } comboBoxTroopsToTrain.Items.Clear(); int troopsEnum = ((int)acc.AccInfo.Tribe - 1) * 10; for (var i = troopsEnum + 1; i < troopsEnum + 11; i++) { Classificator.TroopsEnum troop = (Classificator.TroopsEnum)i; comboBoxTroopsToTrain.Items.Add(VillageHelper.EnumStrToString(troop.ToString())); } if (comboBoxTroopsToTrain.Items.Count > 0) { comboBoxTroopsToTrain.SelectedIndex = 0; } } else { labelTroopsToTrain.Text = "Selected:"; comboBoxTroopsToTrain.Items.Clear(); } }
} //once / twice / 3 times public override async Task <TaskRes> Execute(Account acc) { if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace, "&t=5")) { return(TaskRes.Executed); } if (this.Resources == null) { this.Resources = Vill.Res.Stored.Resources; } // Check if we have enough resources in main village var resToSend = MarketHelper.SendResCapToStorage(acc, this.Resources); var targetVillage = acc.Villages.FirstOrDefault(x => x.Coordinates == this.Coordinates); var duration = await MarketHelper.MarketSendResource(acc, resToSend, targetVillage, this); var targetVill = acc.Villages.FirstOrDefault(x => x.Coordinates == Coordinates); targetVill.Market.Settings.Configuration.TransitArrival = DateTime.Now.Add(duration); if (this.Configuration != null && duration != null) { this.Configuration.TransitArrival = DateTime.Now.Add(duration); } // When you send resources there actually isn't a page load 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); }
private void RefreshBuildingsList(Village vill) { //update buildings list view buildingsList.Items.Clear(); //19, 38); for (int i = 0; i <= 39; i++) { var building = vill.Build.Buildings[i]; var item = new ListViewItem(); var id = building.Id; item.SubItems[0].Text = id.ToString();//id string buildingName = VillageHelper.BuildingTypeToString(building.Type); //if there is a task for upgrading/construction the building on this site string upgradeLvl = ""; var upgradeBuilding = vill.Build.Tasks.LastOrDefault(x => x.BuildingId == id); if (upgradeBuilding != null) { upgradeLvl = " -> " + upgradeBuilding.Level; if (buildingName == "Site") { buildingName = VillageHelper.BuildingTypeToString(upgradeBuilding.Building); } } item.SubItems.Add(buildingName); //building item.SubItems.Add(building.Level.ToString() + upgradeLvl); //level //set color switch (building.Type) { case BuildingEnum.Woodcutter: item.ForeColor = Color.LightGreen; break; case BuildingEnum.ClayPit: item.ForeColor = Color.Orange; break; case BuildingEnum.IronMine: item.ForeColor = Color.Gray; break; case BuildingEnum.Cropland: item.ForeColor = Color.Yellow; break; case BuildingEnum.Site: item.ForeColor = (buildingName == "Site" ? Color.White : Color.LightBlue); break; default: item.ForeColor = Color.GreenYellow; break; } buildingsList.Items.Add(item); } }
public void UpdateUc() { Account acc = GetSelectedAcc(); var vill = GetSelectedVillage(); if (vill == null) { return; } RefreshBuildingsList(vill); //Building Tasks ListView UpdateBuildTasks(vill); foreach (var task in vill.Build.DemolishTasks) { var item = new ListViewItem(); //building item.SubItems[0].Text = "Demolish " + VillageHelper.BuildingTypeToString(vill.Build.Buildings.FirstOrDefault(x => x.Id == task.BuildingId).Type); item.SubItems.Add(task.Level.ToString()); //lvl item.SubItems.Add(task.BuildingId.ToString()); //buildingId buildListView.Items.Add(item); } //Currently building ListView currentlyBuildinglistView.Items.Clear(); foreach (var building in vill.Build.CurrentlyBuilding) { var item = new ListViewItem(); item.SubItems[0].Text = building.Building.ToString(); item.SubItems.Add(building.Level.ToString()); //lvl item.SubItems.Add(building.Duration == DateTime.MinValue ? "/" : building.Duration.ToString()); //execute at currentlyBuildinglistView.Items.Add(item); } autoBuildResType.SelectedIndex = 0; autoBuildResStrat.SelectedIndex = 0; autoBuildResLevel.Value = 10; AutoBuildBonusBuildings.Checked = vill.Build.AutoBuildResourceBonusBuildings; buildTypeComboBox.Enabled = false; buildRadioButton.Checked = true; instaUpgradeUpDown.Enabled = vill.Build.InstaBuild; instaUpgradeUpDown.Value = vill.Build.InstaBuildHours; var prereqComboList = BuildingHelper.SetPrereqCombo(acc, vill); prereqCombo.Items.Clear(); prereqComboList.ForEach(x => prereqCombo.Items.Add(x)); if (0 < prereqComboList.Count) { prereqCombo.SelectedIndex = 0; } }
private void button10_Click(object sender, EventArgs e) //select troop to train { var acc = getSelectedAcc(); var vill = getSelectedVillage(); int troopsEnum = ((int)acc.AccInfo.Tribe - 1) * 10; var troopSelected = troopsEnum + comboBoxTroopsToTrain.SelectedIndex + 1; vill.Troops.TroopToTrain = (Classificator.TroopsEnum)troopSelected; labelTroopsToTrain.Text = $"Selected: {VillageHelper.EnumStrToString(vill.Troops.TroopToTrain.ToString() ?? "")}"; }
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); }
public override async Task <TaskRes> Execute(Account acc) { // Tribe => id="questmasterButton", class name vid_{tribeId} // If no questmasterButton, check tribe after updating villages => rally point/barracks base.MinWait = 500; base.MaxWait = 3000; await base.Execute(acc); var questMaster = acc.Wb.Html.GetElementbyId("questmasterButton"); if (questMaster != null) { var vid = questMaster.GetClasses().FirstOrDefault(x => x.StartsWith("vid")); var tribeId = Parser.RemoveNonNumeric(vid); SetTribe(acc, (Classificator.TribeEnum)tribeId); return(TaskRes.Executed); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf2.php"); await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id=39"); List <int> idsChecked = new List <int>(acc.Villages.Count); // If no rally point, navigate somewhere else while (acc.Wb.Html.GetElementbyId("contract") == null) { idsChecked.Add(this.Vill.Id); var nextId = NextVillCheck(acc, idsChecked); if (nextId == 0) { throw new System.Exception("Can't get account tribe! Please build rally point!"); } await VillageHelper.SwitchVillage(acc, nextId); } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2"); var unitImg = acc.Wb.Html.DocumentNode.Descendants("img").First(x => x.HasClass("unit")); var unitInt = Parser.RemoveNonNumeric(unitImg.GetClasses().First(x => x != "unit")); int tribeInt = (int)(unitInt / 10); // ++ since the first element in Classificator.TribeEnum is Any, second is Romans. tribeInt++; SetTribe(acc, (Classificator.TribeEnum)tribeInt); return(TaskRes.Executed); }
private async void NewTick() { try { if (acc.Tasks.Count == 0) { return; //No tasks } // Another task is already in progress. wait if (acc.Tasks.Any(x => x.Stage != TaskStage.Start)) { return; } var tasks = acc.Tasks.Where(x => x.ExecuteAt <= DateTime.Now).ToList(); if (tasks.Count == 0) { NoTasks(acc); return; } BotTask firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.High); if (firstTask == null) { firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.Medium); } if (firstTask == null) { firstTask = tasks.FirstOrDefault(); } firstTask.Stage = TaskStage.Executing; //If correct village is selected, otherwise change village if (firstTask.Vill != null) { var active = acc.Villages.FirstOrDefault(x => x.Active); if (active != null && active != firstTask.Vill) { await VillageHelper.SwitchVillage(acc, firstTask.Vill.Id); } } await TaskExecutor.Execute(acc, firstTask); } catch (Exception e) { acc?.Wb?.Log($"Error in TaskTimer! {e.Message}\n{e.StackTrace}"); } }
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); }
private void UpdateVillageTab(bool updateVillList = true) { if (accounts.Count == 0) { return; } var acc = GetSelectedAcc(); if (updateVillList) { VillagesListView.Items.Clear(); foreach (var vill in acc.Villages) //update villages list { var item = new ListViewItem(); item.SubItems[0].Text = vill.Name; item.SubItems.Add(vill.Coordinates.x + "/" + vill.Coordinates.y); //coords item.SubItems.Add(VillageHelper.VillageType(vill)); //type (resource) item.SubItems.Add(VillageHelper.ResourceIndicator(vill)); //resources count VillagesListView.Items.Add(item); } } if (acc.Villages.Count <= 0) { return; } switch (villageTabController.SelectedIndex) { case 0: // Build buildUc1.UpdateBuildTab(); break; case 1: // Market marketUc1.UpdateMarketTab(); break; case 2: // Troops troopsUc1.UpdateTroopTab(); break; case 3: // Attack tab attackUc1.UpdateTab(); break; default: break; } }
public override async Task <TaskRes> Execute(Account acc) { var wb = acc.Wb.Driver; if (Vill == null) { Vill = AccountHelper.GetMainVillage(acc); } await base.Execute(acc); var building = TroopsHelper.GetTroopBuilding(troop, Great); if (!await VillageHelper.EnterBuilding(acc, Vill, building)) { return(TaskRes.Executed); } var troopNode = acc.Wb.Html.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")); string script = $"document.getElementById('{exchangeResButton.GetAttributeValue("id", "")}').click()"; await DriverHelper.ExecuteScript(acc, script); var distribute = acc.Wb.Html.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); }
private string[] GetPossibleTroops(Classificator.BuildingEnum building) { List<string> ret = new List<string>(); ret.Add("None"); var acc = getSelectedAcc(); if (acc.Villages.Count == 0) return ret.ToArray(); //Acc has now been initialised int troopsEnum = ((int)acc.AccInfo.Tribe - 1) * 10; for (var i = troopsEnum + 1; i < troopsEnum + 11; i++) { Classificator.TroopsEnum troop = (Classificator.TroopsEnum)i; if (TroopsHelper.GetTroopBuilding(troop, false) == building) { ret.Add(VillageHelper.EnumStrToString(troop.ToString())); } } return ret.ToArray(); }
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> /// Checks demolish time. /// </summary> /// <param name="acc">account</param> public async Task <DateTime> NextDemolishTime(Account acc) { // Is this needed? if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.MainBuilding)) { return(DateTime.Now); } var table = acc.Wb.Html.GetElementbyId("demolish"); if (table == null) //No building is being demolished { return(DateTime.Now); } //Re-execute the demolish building task var time = DateTime.Now.Add(TimeParser.ParseTimer(table)); return(time.AddSeconds(2)); }
private string[] GetPossibleTroops(Classificator.BuildingEnum building) { List <string> ret = new List <string>(); ret.Add("None"); var acc = GetSelectedAcc(); if (acc.Villages.Count == 0) { return(ret.ToArray()); //Acc has now been initialised } var tribes = new List <Classificator.TribeEnum>(5); if (NYS.Checked) { tribes.Add(Classificator.TribeEnum.Egyptians); tribes.Add(Classificator.TribeEnum.Gauls); tribes.Add(Classificator.TribeEnum.Huns); tribes.Add(Classificator.TribeEnum.Romans); tribes.Add(Classificator.TribeEnum.Teutons); } else { tribes.Add(acc.AccInfo.Tribe ?? Classificator.TribeEnum.Any); } foreach (var tribe in tribes) { int troopsEnum = ((int)tribe - 1) * 10; for (var i = troopsEnum + 1; i < troopsEnum + 11; i++) { Classificator.TroopsEnum troop = (Classificator.TroopsEnum)i; if (TroopsHelper.GetTroopBuilding(troop, false) == building) { ret.Add(VillageHelper.EnumStrToString(troop.ToString())); } } } return(ret.ToArray()); }
public async Task UpdateTroopsTraining(Account acc) { foreach (var trainingBuilding in trainingBuildings) { if (!await VillageHelper.EnterBuilding(acc, Vill, trainingBuilding)) { continue; } // Mark troops that user can train in building as researched TroopsHelper.UpdateTroopsResearched(Vill, acc.Wb.Html); var ct = TroopsParser.GetTroopsCurrentlyTraining(acc.Wb.Html); switch (trainingBuilding) { case Classificator.BuildingEnum.Barracks: Vill.Troops.CurrentlyTraining.Barracks = ct; break; case Classificator.BuildingEnum.Stable: Vill.Troops.CurrentlyTraining.Stable = ct; break; case Classificator.BuildingEnum.GreatBarracks: Vill.Troops.CurrentlyTraining.GB = ct; break; case Classificator.BuildingEnum.GreatStable: Vill.Troops.CurrentlyTraining.GS = ct; break; case Classificator.BuildingEnum.Workshop: Vill.Troops.CurrentlyTraining.Workshop = ct; break; } await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf2.php"); await Task.Delay(AccountHelper.Delay()); } }
public override async Task <TaskRes> Execute(Account acc) { if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace, "&t=5")) { return(TaskRes.Executed); } if (this.Vill.Settings.Type == VillType.Support && this.Vill.Settings.SendRes) { // Repeat this task var ran = new Random(); this.NextExecute = DateTime.Now.AddMinutes(ran.Next(30, 60)); } var mainVill = AccountHelper.GetMainVillage(acc); var res = MarketHelper.GetResToMainVillage(Vill); var ret = await MarketHelper.MarketSendResource(acc, res, mainVill, this); return(TaskRes.Executed); }
public override async Task <TaskRes> Execute(Account acc) { TaskExecutor.RemoveSameTasksForVillage(acc, Vill, typeof(UpdateDorf1), this); TaskExecutor.RemoveSameTasksForVillage(acc, Vill, typeof(UpdateDorf2), this); await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf1.php"); // Update dorf1 await Task.Delay(AccountHelper.Delay()); await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf2.php"); // Update dorf2 // On new village import the building tasks if (ImportTasks && !string.IsNullOrEmpty(acc.NewVillages.BuildingTasksLocationNewVillage)) { IoHelperCore.AddBuildTasksFromFile(acc, Vill, acc.NewVillages.BuildingTasksLocationNewVillage); } await UpdateTroopsResearchedAndLevels(acc); await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf2.php"); await Task.Delay(AccountHelper.Delay()); await UpdateTroopsTraining(acc); var firstTroop = TroopsHelper.TribeFirstTroop(acc.AccInfo.Tribe); Vill.Troops.TroopToTrain = firstTroop; Vill.Troops.Researched.Add(firstTroop); if (await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.TownHall)) { // Village has town hall, parse celebration duration Vill.Expansion.CelebrationEnd = TimeParser.GetCelebrationTime(acc.Wb.Html); } return(TaskRes.Executed); }
private async void NewTick() { if (acc.Tasks.Count == 0) { return; //No tasks } // Another task is already in progress. wait if (acc.Tasks.IsTaskExcuting()) { return; } var tasks = acc.Tasks.GetTasksReady(); if (tasks.Count == 0) { NoTasks(acc); return; } BotTask firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.High); if (firstTask == null) { firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.Medium); } if (firstTask == null) { firstTask = tasks.FirstOrDefault(); } firstTask.Stage = TaskStage.Executing; //If correct village is selected, otherwise change village if (firstTask.Vill != null) { var active = acc.Villages.FirstOrDefault(x => x.Active); if (active != null && active != firstTask.Vill) { try { await VillageHelper.SwitchVillage(acc, firstTask.Vill.Id); } catch (WebDriverException e) when(e.Message.Contains("chrome not reachable") || e.Message.Contains("no such window:")) { acc.Logger.Warning($"Chrome has problem. Try reopen Chrome"); acc.Tasks.Add(new ReopenDriver() { ExecuteAt = DateTime.MinValue, Priority = TaskPriority.High, ReopenAt = DateTime.MinValue }); firstTask.Stage = TaskStage.Start; return; } } } await TaskExecutor.Execute(acc, firstTask); }
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) { 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 wb = acc.Wb.Driver; await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=99&id=39"); var flNode = GetFlNode(acc.Wb.Html, acc.AccInfo.ServerVersion); // If there is no rally point, switch to different village if (flNode == null) { var mainVill = AccountHelper.GetMainVillage(acc); if (mainVill == this.Vill) { return(TaskRes.Executed); // No gold account? } await VillageHelper.SwitchVillage(acc, mainVill.Id); flNode = GetFlNode(acc.Wb.Html, acc.AccInfo.ServerVersion); if (flNode == null) { return(TaskRes.Retry); } } if (acc.Farming.TrainTroopsAfterFL) // For TTWars servers { TaskExecutor.AddTask(acc, new TrainTroops() { ExecuteAt = DateTime.Now.AddSeconds(2), Troop = Vill.Troops.TroopToTrain ?? Classificator.TroopsEnum.Hero, Vill = this.Vill, HighSpeedServer = true }); } // If FL is collapsed, expand it if (acc.AccInfo.ServerVersion == ServerVersionEnum.T4_4 || flNode.Descendants("div").Any(x => x.HasClass("expandCollapse") && x.HasClass("collapsed"))) { await DriverHelper.ExecuteScript(acc, $"Travian.Game.RaidList.toggleList({this.FL.Id});"); // Update flNode! flNode = GetFlNode(acc.Wb.Html, acc.AccInfo.ServerVersion); } 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")); await DriverHelper.CheckById(acc, checkbox.Id, true, update : false); } await Task.Delay(AccountHelper.Delay() * 2); switch (acc.AccInfo.ServerVersion) { case ServerVersionEnum.T4_4: var sendFlScript = $"document.getElementById('{flNode.Id}').childNodes[1].submit()"; wb.ExecuteScript(sendFlScript); break; case ServerVersionEnum.T4_5: var startRaid = flNode.Descendants("button").FirstOrDefault(x => x.HasClass("startButton")); acc.Wb.Driver.FindElementById(startRaid.Id).Click(); break; } acc.Wb.Log($"FarmList '{this.FL.Name}' was sent"); return(TaskRes.Executed); }
public void UpdateBuildTab() { Account acc = getSelectedAcc(); var vill = getSelectedVillage(); if (vill == null) { return; } RefreshBuildingsList(vill); //Building Tasks ListView buildListView.Items.Clear(); foreach (var task in vill.Build.Tasks) { var item = new ListViewItem(); //building if (task.TaskType == BuildingHelper.BuildingType.AutoUpgradeResFields) { item.SubItems[0].Text = "Auto-upgrade Res Fields"; } else { item.SubItems[0].Text = VillageHelper.BuildingTypeToString(task.Building); } item.SubItems.Add(task.Level.ToString()); //lvl item.SubItems.Add(task.BuildingId.ToString()); //buildingId item.SubItems.Add("TODO when will it be executed"); //execute at buildListView.Items.Add(item); } foreach (var task in vill.Build.DemolishTasks) { var item = new ListViewItem(); //building item.SubItems[0].Text = "Demolish " + VillageHelper.BuildingTypeToString(vill.Build.Buildings.FirstOrDefault(x => x.Id == task.BuildingId).Type); item.SubItems.Add(task.Level.ToString()); //lvl item.SubItems.Add(task.BuildingId.ToString()); //buildingId buildListView.Items.Add(item); } //Currently building ListView currentlyBuildinglistView.Items.Clear(); foreach (var building in vill.Build.CurrentlyBuilding) { var item = new ListViewItem(); item.SubItems[0].Text = building.Building.ToString(); item.SubItems.Add(building.Level.ToString()); //lvl item.SubItems.Add(building.Duration == DateTime.MinValue ? "/" : building.Duration.ToString()); //execute at currentlyBuildinglistView.Items.Add(item); } autoBuildResType.SelectedIndex = 0; autoBuildResStrat.SelectedIndex = 0; autoBuildResLevel.Value = 10; AutoBuildBonusBuildings.Checked = vill.Build.AutoBuildResourceBonusBuildings; buildTypeComboBox.Enabled = false; buildRadioButton.Checked = true; }
public override async Task <TaskRes> Execute(Account acc) { building = TroopsHelper.GetTroopBuilding(Troop, Great); // Switch hero helmet. If hero will be switched, this TrainTroops task // will be executed right after the hero helmet switch if (HeroHelper.SwitchHelmet(acc, this.Vill, building, this)) { return(TaskRes.Executed); } await base.Execute(acc); if (!await VillageHelper.EnterBuilding(acc, Vill, building)) { return(TaskRes.Executed); } if (this.UpdateOnly || this.Troop == TroopsEnum.None) { return(TaskRes.Executed); } (TimeSpan dur, Resources cost) = TroopsParser.GetTrainCost(acc.Wb.Html, this.Troop); var troopNode = acc.Wb.Html.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)Troop)); if (troopNode == null) { acc.Wb.Log($"Bot tried to train {Troop} in {Vill.Name}, but couldn't find it in {building}! Are you sure you have {Troop} researched?"); return(TaskRes.Executed); } while (!troopNode.HasClass("details")) { troopNode = troopNode.ParentNode; } var inputName = troopNode.Descendants("input").FirstOrDefault().GetAttributeValue("name", ""); long maxNum = 0; switch (acc.AccInfo.ServerVersion) { case ServerVersionEnum.T4_4: maxNum = Parser.RemoveNonNumeric( troopNode.ChildNodes .FirstOrDefault(x => x.Name == "a")?.InnerText ?? "0" ); break; case ServerVersionEnum.T4_5: maxNum = Parser.RemoveNonNumeric( troopNode.ChildNodes .First(x => x.HasClass("cta")) .ChildNodes .First(x => x.Name == "a") .InnerText); break; } 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); } acc.Wb.Driver.ExecuteScript($"document.getElementsByName('{inputName}')[0].value='{maxNum}'"); await Task.Delay(100); await DriverHelper.ExecuteScript(acc, "document.getElementsByName('s1')[0].click()"); UpdateCurrentlyTraining(acc.Wb.Html, acc); if (!HighSpeedServer) { RepeatTrainingCycle(acc.Wb.Html, acc); } 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, "&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); }