/// <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(Account acc)
        {
            var wb = acc.Wb.Driver;

            // If we have Plus account, just check that.
            if (acc.AccInfo.PlusAccount)
            {
                await VersionHelper.Navigate(acc, "/dorf3.php?s=5&su=2", "/village/statistics/troops?su=2");

                OverviewParser.UpdateTroopsLevels(acc.Wb.Html, 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(acc.Wb.Html);
                TroopsHelper.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);
        }
Exemple #2
0
        // Copied from UpdateTroops BotTask
        public async Task UpdateTroopsResearchedAndLevels(Account acc)
        {
            if (acc.AccInfo.PlusAccount)
            {
                // From overview we get all researched troops and their levels
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf3.php?s=5&su=2");

                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/village/statistics/troops?su=2");

                    break;
                }
                OverviewParser.UpdateTroopsLevels(acc.Wb.Html, ref acc);
                // We have updated all villages at the same time. No need to continue.
                acc.Tasks.RemoveAll(x => x.GetType() == typeof(UpdateTroops));
                return;
            }

            var smithy = Vill.Build.Buildings.FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Smithy);

            if (smithy != null)
            {
                // If smithy exists, we get all researched troops and their levels
                await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={smithy.Id}");

                Vill.Troops.Levels = TroopsParser.GetTroopLevels(acc.Wb.Html);
                TroopsHelper.UpdateResearchedTroops(Vill);
                return;
            }
        }
Exemple #3
0
        public bool TroopsCountRecieved(Account acc, int[] troopsAtHome)
        {
            // Attack with all offensive troops
            for (int i = 0; i < 10; i++)
            {
                var troop = TroopsHelper.TroopFromInt(acc, i);
                if (!TroopsData.IsTroopOffensive(troop))
                {
                    continue;
                }
                base.TroopsMovement.Troops[i] = troopsAtHome[i];
            }
            // Hero
            if (troopsAtHome.Length == 11 && troopsAtHome[10] == 1)
            {
                base.TroopsMovement.Troops[10] = 1;
            }

            // Check if we have enough offensive troops to send
            var upkeep = TroopsHelper.GetTroopsUpkeep(acc, base.TroopsMovement.Troops);

            if (upkeep < this.Vill.FarmingNonGold.MinTroops)
            {
                var log = $"Village {Vill.Name} does not have enough offensive troops to attack the oasis!";
                log += $"Required {this.Vill.FarmingNonGold.MinTroops}, but only {upkeep} (crop consumption) ";
                log += "of off was in the village. Bot won't send the attack.";
                acc.Wb.Log(log);
                return(false);
            }
            return(true);
        }
Exemple #4
0
        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.Marketplace);

            if (building == null)
            {
                //update dorg, 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={building.Id}&t=5");

            //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   = ResourcesHelper.ResourcesToArray(vill.Res.Stored.Resources);
            var targetVillStoredRes = ResourcesHelper.ResourcesToArray(TargetVill.Res.Stored.Resources);

            // 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.EnoughRes(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);
        }
        private void UpdateWorkshop(Account acc, Village vill, CellCollection cells, int column)
        {
            var text = cells[column].Text;
            var troop = (Classificator.TroopsEnum)Enum.Parse(typeof(Classificator.TroopsEnum), text.Replace(" ", ""));
            if (troop == vill.Settings.WorkshopTrain) return; //no difference

            vill.Settings.WorkshopTrain = troop;
            TroopsHelper.ReStartResearchAndImprovement(acc, vill);
        }
Exemple #6
0
        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);
        }
        /// <summary>
        /// PostTask. Repeats sending resources and training troops. Needs to fill up training above X hours.
        /// </summary>
        /// <param name="htmlDoc">html of the page</param>
        /// <param name="acc">Account</param>
        public void RepeatTrainingCycle(HtmlDocument htmlDoc, Account acc)
        {
            var trainingEnds = TroopsHelper.GetTrainingTimeForBuilding(building, vill);

            // If sendRes is activated and there are some resources left to send
            if (vill.Settings.SendRes && MarketHelper.GetResToMainVillage(this.vill).Sum() > 0)
            {
                // Check If all troops are filled in this vill before sending resources back to main village
                if (TroopsHelper.EverythingFilled(acc, vill))
                {
                    TaskExecutor.AddTask(acc, new SendResToMain()
                    {
                        vill = this.vill, ExecuteAt = DateTime.MinValue.AddHours(1)
                    });
                }
            }
            if (vill.Settings.GetRes)
            {
                var nextCycle = trainingEnds.AddHours(-acc.Settings.FillInAdvance);
                if (nextCycle < DateTime.Now)
                {
                    // Send resources asap.
                    nextCycle = DateTime.MinValue.AddHours(3);
                }
                else
                {
                    TaskExecutor.AddTask(acc, new UpdateDorf1()
                    {
                        ExecuteAt = nextCycle,
                        vill      = this.vill
                    });
                }

                TaskExecutor.AddTask(acc, new SendResFillTroops()
                {
                    ExecuteAt  = nextCycle.AddMilliseconds(1),
                    vill       = AccountHelper.GetMainVillage(acc),
                    TargetVill = this.vill,
                    TrainTask  = this
                });
                this.NextExecute = nextCycle.AddMinutes(30); //will get overwritten in sendResFillTroops
                TaskExecutor.ReorderTaskList(acc);
            }
            else
            {
                var later = DateTime.Now.AddMinutes(1);
                // Don't training again sooner than after 10min
                if (later > trainingEnds)
                {
                    trainingEnds = later;
                }

                this.NextExecute = trainingEnds;
            }
        }
        private void UpdateGS(Account acc, Village vill, CellCollection cells, int column)
        {
            bool enabled = cells[column].Checked;
            if (vill.Settings.GreatStableTrain == enabled) return; //no difference

            vill.Settings.GreatStableTrain = enabled;
            if (enabled)
            {
                if (!TroopsHelper.EverythingFilled(acc, vill)) TroopsHelper.ReStartTroopTraining(acc, vill);
            }
        }
Exemple #9
0
        public void NewVillage(HtmlDocument htmlDoc, Account acc)
        {
            //TODO: parse when the 3rd settler will be trained.
            var training = TroopsHelper.TrainingDuration(htmlDoc);

            TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers()
            {
                ExecuteAt = training.AddSeconds(3),
                vill      = this.vill,
                Priority  = TaskPriority.Medium
            });
        }
Exemple #10
0
        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);
        }
        //TODO add my troops in other villages, with village coords  etc
        //TODO: troops count, troops researched, market stuff

        public void Init(Account acc)
        {
            //TroopsInVillage = new List<TroopsRaw>();
            //MyTroops = new List<TroopsRaw>();
            CurrentlyTraining = new CurrentlyTraining();
            CurrentlyTraining.Init();
            Researched = new List <Classificator.TroopsEnum>();
            Researched.Add(TroopsHelper.TribeFirstTroop(acc.AccInfo.Tribe));

            Levels     = new List <TroopLevel>();
            ToResearch = new List <Classificator.TroopsEnum>();
            ToImprove  = new List <Classificator.TroopsEnum>();
        }
        //Save button
        private void button1_Click(object sender, EventArgs e)
        {
            var acc = GetSelectedAcc();
            //change vill names list
            var changeVillNames = new List <(int, string)>();

            for (int i = 0; i < tableModelMain.Rows.Count; i++)
            {
                var cells  = tableModelMain.Rows[i].Cells;
                int column = 0;
                //Village id
                var id   = Int32.Parse(cells[column].Text);
                var vill = acc.Villages.First(x => x.Id == id);

                //check if name is different. if it is, change the name
                var name = cells[++column].Text;
                if (name != vill.Name)
                {
                    changeVillNames.Add((id, name));
                }
                column++;
                UpdateBarracks(acc, vill, cells, column);
                column++;
                UpdateGB(acc, vill, cells, column);
                column++;
                UpdateStable(acc, vill, cells, column);
                column++;
                UpdateGS(acc, vill, cells, column);
                column++;
                UpdateWorkshop(acc, vill, cells, column);
                column++;
                vill.Settings.AutoImprove = cells[column].Checked;

                // Reset training
                if (!TroopsHelper.EverythingFilled(acc, vill) && acc.Tasks != null)
                {
                    TroopsHelper.ReStartTroopTraining(acc, vill);
                }
            }
            //Change name of village/s
            if (0 < changeVillNames.Count && acc.Tasks != null)
            {
                TaskExecutor.AddTaskIfNotExists(acc,
                                                new ChangeVillageName()
                {
                    ExecuteAt  = DateTime.Now,
                    ChangeList = changeVillNames
                });
            }
        }
        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);
        }
        //You would probably have to take into account ally training bonus, artifacts, helmets, horse fountain...
        public static TimeSpan GetTrainingTime(Account acc, Village vill, Classificator.TroopsEnum troop, bool great)
        {
            var buildingType = TroopsHelper.GetTroopBuilding(troop, great);
            var building     = vill.Build.Buildings.FirstOrDefault(x => x.Type == buildingType);
            var troopId      = (int)troop;

            if (troopId > 40)
            {
                troopId -= 20;               //since we don't have values for nature/natars
            }
            var baseTime     = TrainTime[troopId];
            var sec          = Math.Pow(0.9, building.Level - 1) * baseTime;
            var millis       = sec % 1;
            var baseTimespan = new TimeSpan(0, 0, 0, (int)sec, (int)millis * 1000);

            return(new TimeSpan(baseTimespan.Ticks / acc.AccInfo.ServerSpeed));
        }
 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();
 }
        private void SendSettlersTask(Account acc)
        {
            var training = TroopsHelper.TrainingDuration(acc.Wb.Html);

            if (training < DateTime.Now)
            {
                training = DateTime.Now;
            }
            training = training.AddSeconds(5);

            acc.Wb.Log($"Bot will (try to) send settlers in {TimeHelper.InSeconds(training)} sec");

            TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers()
            {
                ExecuteAt = training,
                Vill      = this.Vill
            });
        }
        private void SendSettlersTask(Account acc)
        {
            var training = TroopsHelper.TrainingDuration(acc.Wb.Html);

            if (training < DateTime.Now)
            {
                training = DateTime.Now;
            }
            training = training.AddSeconds(5);

            acc.Wb.Log($"Bot will (try to) send settlers in {TimeHelper.InSeconds(training)} sec");

            TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers()
            {
                ExecuteAt = training,
                Vill      = this.Vill,
                // For high speed servers, you want to train settlers asap
                Priority = 1000 < acc.AccInfo.ServerSpeed ? TaskPriority.High : TaskPriority.Medium,
            });
        }
Exemple #18
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            // Troops task
            TroopsHelper.ReStartTroopTraining(acc, Vill);
            await Task.Delay(AccountHelper.Delay());

            TroopsHelper.ReStartResearchAndImprovement(acc, Vill);
            await Task.Delay(AccountHelper.Delay());

            // Building task
            BuildingHelper.ReStartBuilding(acc, Vill);
            await Task.Delay(AccountHelper.Delay());

            BuildingHelper.ReStartDemolishing(acc, Vill);
            await Task.Delay(AccountHelper.Delay());

            // Celebration task
            AccountHelper.ReStartCelebration(acc, Vill);
            return(TaskRes.Executed);
        }
Exemple #19
0
        public bool TroopsCountRecieved(Account acc, int[] troopsAtHome)
        {
            int upkeepSent = 0;

            for (int i = 0; i < 10; i++)
            {
                var troop = TroopsHelper.TroopFromInt(acc, i);
                if (!TroopsData.IsTroopDefensive(troop) || troopsAtHome[i] == 0)
                {
                    continue;
                }

                var upkeep     = TroopSpeed.GetTroopUpkeep(troop);
                int sendAmount = troopsAtHome[i];

                int  toSend   = this.DeffAmount.Amount / upkeep;
                bool finished = false;
                if (toSend - upkeepSent < sendAmount)
                {
                    // If we have enough troops, no other tasks need to be executed
                    this.NextTask = null;
                    finished      = true;
                    sendAmount    = toSend;
                }

                base.TroopsMovement.Troops[i] = sendAmount;

                upkeepSent += sendAmount * upkeep;

                if (finished)
                {
                    break;
                }
            }

            this.DeffAmount.Amount -= upkeepSent;
            acc.Wb.Log($"Bot will send {upkeepSent} deff (in upkeep) from {this.Vill.Name} to {this.TargetVillage}. Still needed {this.DeffAmount.Amount} deff");

            return(true);
        }
Exemple #20
0
        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());
            }
        }
        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());
        }
Exemple #22
0
        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);
        }
Exemple #23
0
        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)
        {
            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);
        }
        private async void NewTick()
        {
            // Dirty hack. TODO fix the code, so building/troops filling tasks won't fail by themselves
            restartTasksCounter++;
            if (restartTasksCounter > 7200)
            {
                restartTasksCounter = 0;
                foreach (var vill in acc.Villages)
                {
                    if (!TroopsHelper.EverythingFilled(acc, vill))
                    {
                        TroopsHelper.ReStartTroopTraining(acc, vill);
                    }
                    BuildingHelper.ReStartBuilding(acc, vill);
                }
            }

            if (acc.Tasks.Count == 0)
            {
                return;                       //No tasks
            }
            // Another task is already in progress. wait
            var taskInProgress = acc.Tasks.FirstOrDefault(x => x.Stage != TaskStage.Start);

            if (taskInProgress != null)
            {
                if (taskInProgress.DurationCounter++ > 30) //after 20sec try to re-execute the task
                {
                    Console.WriteLine($"Task {taskInProgress} timed out. Restarting it..");
                    taskInProgress.DurationCounter = 15;
                    taskInProgress.Stage           = TaskStage.Start; //re-navigate & execute
                                                                      //We have tried re-executing the task 3 times already, something is clearly wrong. Just delete the task.
                    if (++taskInProgress.RetryCounter > 3)
                    {
                        acc.Tasks.Remove(taskInProgress);
                    }
                }
                return;
            }

            var tasks = acc.Tasks.Where(x => x.ExecuteAt <= DateTime.Now).ToList();

            if (tasks.Count == 0)
            {
                return;                   // No tasks yet
            }
            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();
            }

            //Console.WriteLine($"---Tasks: {acc.Tasks.Count}, first one {firstTask.GetType()}");


            if (firstTask.Stage != TaskStage.Start)
            {
                return;
            }
            //If correct village is selected, otherwise change village
            if (firstTask.vill != null)
            {
                var active = acc.Villages.FirstOrDefault(x => x.Active);
                if (active != null) //error handling
                {
                    if (firstTask.vill != active && firstTask.GetType() != typeof(SwitchVillage))
                    {
                        //wrong village selected, reselect village
                        TaskExecutor.AddTask(acc, new SwitchVillage()
                        {
                            vill = firstTask.vill, Priority = TaskPriority.High
                        });
                        return;
                    }
                }
            }

            firstTask.Stage = TaskStage.Executing;
            _ = TaskExecutor.Execute(acc, firstTask);
        }
 public static bool IsTroopOffensive(Account acc, int i) =>
 IsTroopOffensive(TroopsHelper.TroopFromInt(acc, i));
Exemple #27
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var wb = acc.Wb.Driver;
            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++)
            {
                await Task.Delay(rnd.Next(800, 1000));

                var htmlDoc1 = HttpHelper.SendGetReq(acc, "/build.php?tt=2&id=39");

                var build = htmlDoc1.GetElementbyId("build");


                var req = new RestRequest
                {
                    Resource = "/build.php?tt=2&id=39",
                    Method   = Method.POST,
                };

                req.AddParameter("dname", "");
                req.AddParameter("x", SendWaveModels[i].Coordinates.x.ToString());
                req.AddParameter("y", SendWaveModels[i].Coordinates.y.ToString());
                req.AddParameter("c", ((int)SendWaveModels[i].MovementType).ToString());
                req.AddParameter("s1", "ok");

                foreach (var hidden in hiddenFields)
                {
                    var value = build.Descendants("input").FirstOrDefault(x => x.GetAttributeValue("name", "") == hidden);
                    if (value == null)
                    {
                        continue;
                    }
                    req.AddParameter(hidden, value.GetAttributeValue("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++)
                {
                    switch (acc.AccInfo.ServerVersion)
                    {
                    case Classificator.ServerVersionEnum.T4_4:
                        req.AddParameter($"t{j + 1}", TroopCount(SendWaveModels[i].Troops[j]));
                        break;

                    case Classificator.ServerVersionEnum.T4_5:
                        req.AddParameter($"troops[0][t{j + 1}]", TroopCount(SendWaveModels[i].Troops[j]));
                        break;
                    }
                }
                await Task.Delay(rnd.Next(800, 1000));

                var ret = HttpHelper.SendPostReq(acc, req);

                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(2) < executeTime)
                    {
                        // Restart this task at the correct time
                        this.NextExecute = executeTime;
                        return(TaskRes.Executed);
                    }
                }

                //var ajaxToken = await HttpHelper.GetAjaxToken(wb);
                var req2 = new RestRequest
                {
                    Resource = "/build.php?tt=2&id=39",
                    Method   = Method.POST,
                };

                req2.AddParameter("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", "");
                    req2.AddParameter(name, val);
                }

                // Add catapult targets
                string cataCount = "0";
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    cataCount = req2.Parameters.FirstOrDefault(x => x.Name == "t8").Value.ToString();
                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    cataCount = req2.Parameters.FirstOrDefault(x => x.Name == "troops[0][t8]").Value.ToString();
                    // If T4.5, we need to get value "a" as well - From Confirm button
                    var    button = htmlDoc2.GetElementbyId("btn_ok");
                    string a      = button.GetAttributeValue("value", "");
                    req2.AddParameter("a", a);
                    break;
                }

                if (int.Parse(cataCount) > 0)
                {
                    req2.AddParameter("ctar1", "99"); // 99 = Random, 1 = woodcuter, 2 = claypit..
                    req2.AddParameter("ctar2", "99"); // 99 = Random
                }

                wavesReady.Add(new WaveReadyModel
                {
                    Request      = req2,
                    MovementTime = timespan
                });
            }

            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 arrive at the 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);
            }
            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].Request);
            }
            acc.Wb.Log($"Successfully sent {wavesReady.Count} waves!");

            await Task.Delay(AccountHelper.Delay() * 2);

            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?gid=16&tt=1&filter=2&subfilters=4");

            //Todo: check waves?
            return(TaskRes.Executed);
        }
Exemple #28
0
        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(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);
        }
Exemple #30
0
        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);
        }