Beispiel #1
0
        /// <summary>
        /// Building is already constructed, upgrade it
        /// </summary>
        /// <param name="acc">Account</param>
        /// <returns>TaskResult</returns>
        private async Task <TaskRes> Upgrade(Account acc, HtmlNode node)
        {
            (var buildingEnum, var lvl) = InfrastructureParser.UpgradeBuildingGetInfo(node);

            if (buildingEnum == BuildingEnum.Site || lvl == -1)
            {
                acc.Wb.Log($"Can't upgrade building {this.Task.Building} in village {this.Vill.Name}. Will be removed from the queue.");
                RemoveCurrentTask();
                return(TaskRes.Executed);
            }

            // If there is already a different building in this spot, find a new id to construct it.
            if (buildingEnum != Task.Building)
            {
                acc.Wb.Log($"We wanted to upgrade {Task.Building}, but there's already {buildingEnum} on this id ({Task.BuildingId}).");
                if (!BuildingHelper.FindBuildingId(Vill, this.Task))
                {
                    acc.Wb.Log($"Found another Id to build {Task.Building}, new id: {Task.BuildingId}");
                    return(TaskRes.Retry);
                }
                acc.Wb.Log($"Failed to find another Id to build {Task.Building}! No space in village. Building task will be removed");
                RemoveCurrentTask();
                return(TaskRes.Executed);
            }

            // Basic task already on/above desired level, don't upgrade further
            var building = Vill.Build.Buildings.FirstOrDefault(x => x.Id == this.Task.BuildingId);

            lvl = building.Level;
            if (building.UnderConstruction)
            {
                lvl++;
            }
            if (Task.Level <= lvl)
            {
                acc.Wb.Log($"{this.Task.Building} is on level {lvl}, on/above desired {Task.Level}. Removing it from queue.");
                RemoveCurrentTask();
                RemoveCompletedTasks(this.Vill, acc);
                return(TaskRes.Executed);
            }

            var container = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("upgradeButtonsContainer"));
            var buttons   = container?.Descendants("button");

            if (buttons == null)
            {
                acc.Wb.Log($"We wanted to upgrade {Task.Building}, but no 'upgrade' button was found! Url={acc.Wb.CurrentUrl}");
                return(TaskRes.Retry);
            }

            var errorMessage = acc.Wb.Html.GetElementbyId("build")
                               .Descendants("div")
                               .FirstOrDefault(x => x.HasClass("upgradeBuilding"))?
                               .Descendants("div")?
                               .FirstOrDefault(x => x.HasClass("errorMessage"));
            HtmlNode upgradeButton = buttons.FirstOrDefault(x => x.HasClass("build"));

            if (upgradeButton == null)
            {
                acc.Wb.Log($"We wanted to upgrade {Task.Building}, but no 'upgrade' button was found!");
                return(TaskRes.Retry);
            }

            // Not enough resources?
            if (acc.AccInfo.ServerVersion == ServerVersionEnum.T4_5 && errorMessage != null)
            {
                acc.Wb.Log($"We wanted to upgrade {Task.Building}, but there was an error message:\n{errorMessage.InnerText}");
                return(TaskRes.Retry);
            }

            var buildDuration = InfrastructureParser.GetBuildDuration(container, acc.AccInfo.ServerVersion);

            if (IsTaskCompleted(Vill, acc, this.Task))
            {
                acc.Wb.Log($"Building {this.Task.Building} in village {this.Vill.Name} is already on desired level. Will be removed from the queue.");
                RemoveCurrentTask();
                return(TaskRes.Executed);
            }

            if (acc.AccInfo.ServerVersion == ServerVersionEnum.T4_4 ||
                buildDuration.TotalMinutes <= acc.Settings.WatchAdAbove ||
                !await TryFastUpgrade(acc))                          // +25% speed upgrade
            {
                await DriverHelper.ClickById(acc, upgradeButton.Id); // Normal upgrade
            }

            lvl++;
            CheckIfTaskFinished(lvl);

            acc.Wb.Log($"Started upgrading {this.Task.Building} to level {lvl} in {this.Vill?.Name}");
            await PostTaskCheckDorf(acc);

            return(TaskRes.Executed);
        }
Beispiel #2
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!");
            }
        }