예제 #1
0
        //If Troop == null, just update the troop levels
        public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc)
        {
            var academy = vill.Build.Buildings.FirstOrDefault(x => x.Type == Classificator.BuildingEnum.Academy);

            if (academy == null)
            {
                return(TaskRes.Executed);
            }
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={academy.Id}");

            var troop = vill.Troops.ToResearch.FirstOrDefault();

            if (troop == TroopsEnum.None)
            {
                return(TaskRes.Executed);                          //We have researched all troops that were on the list
            }
            var troopNode = htmlDoc.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop));

            if (troopNode == null)
            {
                this.ErrorMessage = $"Researching {troop} was not possible! Bot assumes you already have it researched";
                vill.Troops.Researched.Add(troop);
                return(TaskRes.Retry);
            }
            while (!troopNode.HasClass("research"))
            {
                troopNode = troopNode.ParentNode;
            }

            var button = troopNode.Descendants("button").FirstOrDefault(x => x.HasClass("green"));

            if (button == null)
            {
                RepeatTask(vill, troop, DateTime.Now);
            }
            (TimeSpan dur, Resources cost) = TroopsParser.AcademyResearchCost(htmlDoc, troop);

            var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, cost);

            if (nextExecute < DateTime.Now.AddMilliseconds(1)) //We have enough resources, click Research button
            {
                wb.ExecuteScript($"document.getElementById('{button.Id}').click()");
                var executeNext = DateTime.Now.Add(dur).AddMilliseconds(10 * AccountHelper.Delay());
                TaskExecutor.AddTask(acc,
                                     new ImproveTroop()
                {
                    vill = this.vill, ExecuteAt = DateTime.Now.Add(dur)
                }
                                     );
                RepeatTask(vill, troop, executeNext);

                return(TaskRes.Executed);
            }
            else //Retry same task after resources get produced/transited
            {
                this.NextExecute = nextExecute;
                return(TaskRes.Executed);
            }
        }
예제 #2
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.Residence || x.Type == Classificator.BuildingEnum.Palace || x.Type == Classificator.BuildingEnum.CommandCenter);

            if (building == null)
            {
                //update dorg, no buildingId found?
                TaskExecutor.AddTask(acc, new UpdateDorf2()
                {
                    ExecuteAt = DateTime.Now, vill = vill
                });
                Console.WriteLine($"There is no Residence/Palace/CommandCenter in this village!");
                return(TaskRes.Executed);
            }
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?s=1&id={building.Id}");

            var cost = htmlDoc.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("resourceWrapper"));

            if (cost == null)
            {
                this.ErrorMessage = "Could not train settlers. Will retry in 5min";
                this.NextExecute  = DateTime.Now.AddMinutes(5); //retry in 5min
                return(TaskRes.Executed);
            }

            var resources   = ResourceParser.GetResourceCost(cost);
            var enoughResAt = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, resources);

            if (enoughResAt <= DateTime.Now.AddMilliseconds(1)) //we have enough res, create new settler!
            {
                wb.ExecuteScript($"document.getElementsByName('t10')[0].value='1'");
                await Task.Delay(AccountHelper.Delay());

                wb.ExecuteScript($"document.getElementById('s1').click()"); //Train settler
                vill.Troops.Settlers++;
                if (vill.Troops.Settlers < 3)
                {
                    //In 1 minute, do the same task (to get total of 3 settlers)
                    this.NextExecute = DateTime.Now.AddSeconds(1);
                }
                else
                {
                    if (acc.NewVillages.AutoSettleNewVillages)
                    {
                        //parse in training table
                        this.PostTaskCheck.Add(NewVillage);
                    }
                }
                return(TaskRes.Executed);
            }
            else
            {
                //Not enough res, wait for production/transit res
                this.NextExecute = enoughResAt.AddSeconds(60 * AccountHelper.Delay());
                return(TaskRes.Executed);
            }
        }
예제 #3
0
        public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc)
        {
            if (vill == null)
            {
                vill = acc.Villages.First(x => x.Active);
            }

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

            if (smithy == null)
            {
                return(TaskRes.Executed);
            }
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={smithy.Id}");

            var levels = TroopsParser.GetTroopLevels(htmlDoc);

            if (levels == null)
            {
                this.ErrorMessage = "There was an error at getting Smithy troop levels";
                return(TaskRes.Executed);
            }
            vill.Troops.Levels = levels;
            UpdateResearchedTroops(vill);

            var currentlyImproving = TroopsParser.GetImprovingTroops(htmlDoc);
            var troop = TroopToImprove(vill, currentlyImproving);

            if (troop == Classificator.TroopsEnum.None)
            {
                return(TaskRes.Executed);
            }

            //If we have plus account we can improve 2 troops at the same time
            int maxImproving = acc.AccInfo.PlusAccount ? 2 : 1;

            if (currentlyImproving.Count() >= maxImproving)
            {
                this.NextExecute = DateTime.Now.Add(currentlyImproving.Last().Time);
                return(TaskRes.Executed);
            }
            //call NextImprove() after enough res OR when this improvement finishes.

            var cost = vill.Troops.Levels.FirstOrDefault(x => x.Troop == troop);

            var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, cost.UpgradeCost);

            if (nextExecute < DateTime.Now.AddMilliseconds(1)) //We have enough resources, click Improve button
            {
                //Click on the button
                var troopNode = htmlDoc.DocumentNode.Descendants("img").FirstOrDefault(x => x.HasClass("u" + (int)troop));
                while (!troopNode.HasClass("research"))
                {
                    troopNode = troopNode.ParentNode;
                }

                var button = troopNode.Descendants("button").FirstOrDefault(x => x.HasClass("green"));
                if (button == null)
                {
                    this.ErrorMessage = $"Could not find Upgrade button to improve {troop}";
                    this.NextExecute  = DateTime.Now.AddMinutes(1);
                    return(TaskRes.Retry);
                }


                wb.ExecuteScript($"document.getElementById('{button.Id}').click()");
                // If we have plus account and there is currently no other troop to improve, go ahead and improve the unit again
                this.NextExecute = (currentlyImproving.Count() == 0 && maxImproving == 2) ?
                                   DateTime.MinValue :
                                   DateTime.Now.Add(cost.TimeCost).AddMilliseconds(5 * AccountHelper.Delay());
                return(TaskRes.Executed);
            }
            else //Retry same task after resources get produced/transited
            {
                this.NextExecute = nextExecute;
                return(TaskRes.Executed);
            }
        }
예제 #4
0
        public override async Task <TaskRes> Execute(HtmlDocument htmlDoc, ChromeDriver wb, Files.Models.AccModels.Account acc)
        {
            if (this.task == null)
            {
                ConfigNextExecute(acc.Wb.Html, acc);
                this.NextExecute = DateTime.Now.AddMinutes(2);
                if (this.task == null)
                {
                    // There is no building task left. Remove the BotTask
                    acc.Tasks.Remove(this);
                    return(TaskRes.Executed);
                }
            }

            // Check if the task is complete
            var urlId = BuildingHelper.GetUrlForBuilding(vill, task);

            if (urlId == null)
            {
                //no space for this building
                vill.Build.Tasks.Remove(this.task);
                this.task = null;
                return(await Execute(htmlDoc, wb, acc));
            }

            // In which dorf is the building. Maybe not needed.
            if (!acc.Wb.CurrentUrl.Contains($"/dorf{((task.BuildingId ?? default) < 19 ? 1 : 2)}.php"))
            {
                //Switch village!
                BotTask updateDorfTask = (task.BuildingId ?? default) < 19 ?
                                         (BotTask) new UpdateDorf1() :
                                         (BotTask) new UpdateDorf2();

                updateDorfTask.vill      = this.vill;
                updateDorfTask.ExecuteAt = DateTime.MinValue.AddHours(2);

                TaskExecutor.AddTask(acc, updateDorfTask);
                this.NextExecute = updateDorfTask.ExecuteAt.AddMinutes(1);
                return(TaskRes.Executed);
            }

            // Check if there are already too many buildings currently constructed
            BuildingHelper.RemoveFinishedCB(vill);
            var maxBuild = 1;

            if (acc.AccInfo.PlusAccount)
            {
                maxBuild++;
            }
            if (acc.AccInfo.Tribe == TribeEnum.Romans)
            {
                maxBuild++;
            }
            if (vill.Build.CurrentlyBuilding.Count >= maxBuild)
            {
                //Execute next upgrade task after currently building
                this.NextExecute = vill.Build.CurrentlyBuilding.First().Duration.AddSeconds(3);
                TaskExecutor.ReorderTaskList(acc);
                return(TaskRes.Executed);
            }


            var url = $"{acc.AccInfo.ServerUrl}/build.php?id={urlId}";

            // Fast building for TTWars, only if we have enough resources
            //if (acc.AccInfo.ServerUrl.Contains("ttwars") && !url.Contains("category") && false) // disabling this
            //{
            //    var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == this.task.BuildingId);
            //    var lvl = building.Level;
            //    if (building.UnderConstruction) lvl++;

            //    var storedRes = ResourcesHelper.ResourcesToArray(vill.Res.Stored.Resources);
            //    var neededRes = BuildingsCost.GetBuildingCost(this.task.Building, lvl + 1);
            //    if (ResourcesHelper.EnoughRes(storedRes, neededRes))
            //    {
            //        //url += "&fastUP=1";
            //        return TaskRes.Executed;
            //    }
            //}

            //append correct tab
            switch (this.task.Building)
            {
            case BuildingEnum.RallyPoint:
                url += "&tt=0";
                break;

            case BuildingEnum.Marketplace:
                url += "&t=0";
                break;
            }
            await acc.Wb.Navigate(url);

            this.PostTaskCheck.Add(ConfigNextExecute);
            this.NextExecute = DateTime.Now.AddMinutes(2);

            var contractBuilding        = htmlDoc.GetElementbyId($"contract_building{(int)task.Building}");
            var upgradeBuildingContract = htmlDoc.GetElementbyId("build");

            if (contractBuilding != null) //Construct a new building
            {
                var resWrapper = contractBuilding.Descendants().FirstOrDefault(x => x.HasClass("resourceWrapper"));
                var res        = ResourceParser.GetResourceCost(resWrapper);

                var nextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, res);

                if (nextExecute < DateTime.Now.AddMilliseconds(1)) // we have enough res, go construct that building boii
                {
                    var button = contractBuilding.Descendants("button").FirstOrDefault(x => x.HasClass("new"));
                    //TODO: if button null: check for prerequisites. Maybe a prerequisit is currently building...
                    if (button == null)
                    {
                        this.NextExecute = vill.Build.CurrentlyBuilding.LastOrDefault()?.Duration;
                        this.PostTaskCheck.Remove(ConfigNextExecute);
                        return(TaskRes.Executed);
                    }
                    //check if button is null!
                    wb.ExecuteScript($"document.getElementById('{button.Id}').click()");
                    this.task.ConstructNew = false;

                    return(TaskRes.Executed);
                }
                //not enough resources, wait until resources get produced/transited from main village
                this.NextExecute = nextExecute;
                this.PostTaskCheck.Remove(ConfigNextExecute);
                return(TaskRes.Executed);
            }
            else if (upgradeBuildingContract != null) // Upgrade building
            {
                (var buildingEnum, var lvl) = InfrastructureParser.UpgradeBuildingGetInfo(upgradeBuildingContract);

                if (buildingEnum == BuildingEnum.Site || lvl == -1)
                {
                    this.ErrorMessage = $"Can't upgrade building {this.task.Building} in village {this.vill.Name}. Will be removed from the queue.";
                    vill.Build.Tasks.Remove(this.task);
                    return(TaskRes.Executed);
                }

                // If there is already a different building in this spot, find a new id to construct it.
                if (buildingEnum != task.Building)
                {
                    if (!BuildingHelper.FindBuildingId(vill, task))
                    {
                        vill.Build.Tasks.Remove(this.task);
                    }
                    return(TaskRes.Retry);
                }

                // Basic task already on/above desired level, don't upgrade further
                var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == this.task.BuildingId);
                if (building.UnderConstruction)
                {
                    lvl++;
                }
                if (lvl >= task.Level)
                {
                    this.ErrorMessage = $"{this.task.Building} is on level {lvl}, above desired {task.Level}. Removing it from queue.";
                    vill.Build.Tasks.Remove(this.task);
                    RemoveCompletedTasks(this.vill, acc);
                    return(TaskRes.Executed);
                }

                var container = htmlDoc.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("upgradeButtonsContainer"));
                var buttons   = container?.Descendants("button");
                if (buttons == null)
                {
                    this.ErrorMessage = "No 'upgrade' button found!";
                    return(TaskRes.Executed);
                }
                HtmlNode upgradeButton = buttons.FirstOrDefault(x => x.HasClass("build"));
                //We have enough resources, click on build
                if (upgradeButton != null)
                {
                    var buildDuration = InfrastructureParser.GetBuildDuration(container, acc.AccInfo.ServerVersion);

                    if (IsTaskCompleted(vill, acc, this.task))
                    {
                        this.ErrorMessage = $"Building {this.task.Building} in village {this.vill.Name} is already done. Will be removed from the queue.";
                        vill.Build.Tasks.Remove(this.task);
                        return(TaskRes.Executed);
                    }
                    //TODO move this
                    CheckSettlers(acc, vill, lvl, DateTime.Now.Add(buildDuration));

                    Console.WriteLine($"Village {vill.Name} will upgrade {task.Building}");
                    wb.ExecuteScript($"document.getElementById('{upgradeButton.Id}').click()");
                    return(TaskRes.Executed);
                }
                else
                {
                    HtmlNode error = container.Descendants("span").FirstOrDefault(x => x.HasClass("none"));
                    //Not enough resources
                    var contract   = htmlDoc.GetElementbyId("contract");
                    var resWrapper = contract.Descendants().FirstOrDefault(x => x.HasClass("resourceWrapper"));
                    var res        = ResourceParser.GetResourceCost(resWrapper);
                    this.PostTaskCheck.Remove(ConfigNextExecute);
                    this.NextExecute = ResourcesHelper.EnoughResourcesOrTransit(acc, vill, res);
                    return(TaskRes.Executed);
                }
            }
            else
            {
                throw new Exception("No construct or upgrade contract was found!");
            }
        }