Ejemplo n.º 1
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            // First navigate to dorf2 and then to the main building, to make sure the currently demolish list is refreshed
            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.MainBuilding, update: true))
            {
                return(TaskRes.Executed);
            }

            if (Vill.Build.DemolishTasks.Count == 0)
            {
                return(TaskRes.Executed);                                     //No more demolish tasks
            }
            var id = BuildingToDemolish(Vill, acc.Wb.Html);

            if (id == null)
            {
                return(TaskRes.Executed);            //No more demolish tasks
            }
            await DriverHelper.WriteById(acc, "demolish", id);

            await DriverHelper.ClickById(acc, "btn_demolish");

            this.NextExecute = TimeHelper.RanDelay(acc, await NextDemolishTime(acc));

            return(TaskRes.Executed);
        }
Ejemplo n.º 2
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/alliance/bonuses");

            for (int i = 0; i < 4; i++)
            {
                var radioId = Ids[i];
                var radio   = acc.Wb.Html.GetElementbyId(radioId);

                // If the bonus is max / already being upgraded
                if (radio.GetAttributeValue("disabled", "") == "disabled")
                {
                    continue;
                }

                await DriverHelper.ClickById(acc, radioId);
            }

            var donateArr = ResToDonate.ToArray();

            for (int i = 0; i < 4; i++)
            {
                await DriverHelper.WriteById(acc, $"donate{(i + 1)}", donateArr[i]);
            }

            await DriverHelper.ClickById(acc, "donate_green");

            return(TaskRes.Executed);
        }
Ejemplo n.º 3
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var script = $"document.getElementById('mentorTaskList').querySelector('[data-questid=\"{this.QuestToClaim.Id}\"]').click();";
            await DriverHelper.ExecuteScript(acc, script);

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

            string buttonId = "";

            switch (acc.AccInfo.ServerVersion)
            {
            case Classificator.ServerVersionEnum.T4_5:
                buttonId = acc.Wb.Html.DocumentNode.Descendants("button").FirstOrDefault(x => x.GetAttributeValue("questid", "") == this.QuestToClaim.Id).Id;
                break;

            case Classificator.ServerVersionEnum.T4_4:
                buttonId = acc.Wb.Html.DocumentNode.Descendants("button").FirstOrDefault(x => x.HasClass("questButtonNext"))?.Id;
                break;
            }

            await DriverHelper.ClickById(acc, buttonId);

            await TaskExecutor.PageLoaded(acc); // Optional

            return(TaskRes.Executed);
        }
Ejemplo n.º 4
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            VersionHelper.Navigate(acc, "/options.php", "/options");

            if (ContextualHelp != null)
            {
                await DriverHelper.CheckById(acc, "v13", ContextualHelp ?? true);
            }

            if (TroopsPerPage != null)
            {
                await DriverHelper.WriteById(acc, "troopMovementsPerPage", TroopsPerPage ?? 10);
            }


            var acceptButton = acc.Wb.Html.DocumentNode
                               .Descendants("div")
                               .First(x => x.HasClass("submitButtonContainer"))
                               .Descendants("button")
                               .First();

            await DriverHelper.ClickById(acc, acceptButton.Id);

            return(TaskRes.Executed);
        }
Ejemplo n.º 5
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var wb = acc.Wb.Driver;

            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.MainBuilding))
            {
                return(TaskRes.Executed);
            }

            if (Vill.Build.DemolishTasks.Count == 0)
            {
                return(TaskRes.Executed);                                     //No more demolish tasks
            }
            var id = BuildingToDemolish(Vill, acc.Wb.Html);

            if (id == null)
            {
                return(TaskRes.Executed);            //No more demolish tasks
            }
            await DriverHelper.WriteById(acc, "demolish", id);

            await DriverHelper.ClickById(acc, "btn_demolish");

            this.NextExecute = NextDemolishTime(acc);

            return(TaskRes.Executed);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Building isn't constructed yet - construct it
        /// </summary>
        /// <param name="acc">Account</param>
        /// <returns>TaskResult</returnss>
        private async Task <TaskRes> Construct(Account acc, HtmlNode node)
        {
            var button = node.Descendants("button").FirstOrDefault(x => x.HasClass("new"));

            // Check for prerequisites
            if (button == null)
            {
                // Add prerequisite buildings in order to construct this building.
                AddBuildingPrerequisites(acc, Vill, Task.Building, false);

                // Next execute after the last building finishes
                this.NextExecute = Vill.Build.CurrentlyBuilding.LastOrDefault()?.Duration;

                acc.Wb.Log($"Wanted to construct {this.Task.Building} but prerequired buildings are missing");
                return(TaskRes.Executed);
            }

            await DriverHelper.ClickById(acc, button.Id);

            this.Task.ConstructNew = false;

            CheckIfTaskFinished(1);

            acc.Wb.Log($"Started construction of {this.Task.Building} in {this.Vill?.Name}");

            await PostTaskCheckDorf(acc);

            return(TaskRes.Executed);
        }
Ejemplo n.º 7
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var palace = Vill.Build.Buildings.FirstOrDefault(x => x.Type == Helpers.Classificator.BuildingEnum.Palace);

            if (palace == null)
            {
                // TODO: Check for residence, if it exists demolish it and build palace
                acc.Wb.Log("Palace was not found in the village!");
                return(TaskRes.Executed);
            }

            // Go into palace
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={palace.Id}");

            switch (acc.AccInfo.ServerVersion)
            {
            case Helpers.Classificator.ServerVersionEnum.T4_4:
                await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?id={palace.Id}&change_capital");

                await DriverHelper.WriteByName(acc, "pw", acc.Access.GetCurrentAccess().Password);

                await DriverHelper.ClickById(acc, "btn_ok");

                break;

            case Helpers.Classificator.ServerVersionEnum.T4_5:
                throw new System.Exception("Setting capital isn't supported in T4.5 yet!");
            }
            return(TaskRes.Executed);
        }
Ejemplo n.º 8
0
        //If Troop == null, just update the troop levels
        public override async Task <TaskRes> Execute(Account acc)
        {
            await base.Execute(acc); // Navigate to dorf2

            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Academy))
            {
                return(TaskRes.Executed);
            }

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

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

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

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

            if (button == null)
            {
                RepeatTask(Vill, troop, DateTime.Now);
            }
            (TimeSpan dur, Resources cost) = TroopsParser.AcademyResearchCost(acc.Wb.Html, troop);

            // Check if we have enough resources to research the troop
            if (!ResourcesHelper.IsEnoughRes(Vill, cost.ToArray()))
            {
                ResourcesHelper.NotEnoughRes(acc, Vill, cost, this);
                return(TaskRes.Executed);
            }

            await DriverHelper.ClickById(acc, button.Id);

            var executeNext = DateTime.Now.Add(dur).AddMilliseconds(10 * AccountHelper.Delay());

            if (Vill.Settings.AutoImprove)
            {
                TaskExecutor.AddTask(acc, new ImproveTroop()
                {
                    Vill = this.Vill, ExecuteAt = DateTime.Now.Add(dur)
                });
            }

            RepeatTask(Vill, troop, executeNext);

            return(TaskRes.Executed);
        }
Ejemplo n.º 9
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/options");

            await DriverHelper.ClickById(acc, "v13");

            var acceptButton = acc.Wb.Html.DocumentNode
                               .Descendants("div")
                               .First(x => x.HasClass("submitButtonContainer"))
                               .Descendants("button")
                               .First();

            await DriverHelper.ClickById(acc, acceptButton.Id);

            return(TaskRes.Executed);
        }
Ejemplo n.º 10
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var wb = acc.Wb.Driver;

            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace))
            {
                return(TaskRes.Executed);
            }

            var npcMerchant = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("npcMerchant"));
            var npcButton   = npcMerchant.Descendants("button").FirstOrDefault(x => x.HasClass("gold"));

            // Exchange resources button
            await DriverHelper.ClickById(acc, npcButton.Id);

            var resSum    = Parser.RemoveNonNumeric(acc.Wb.Html.GetElementbyId("remain").InnerText);
            var targetRes = MarketHelper.NpcTargetResources(Vill, resSum);

            if (!Vill.Market.Npc.NpcIfOverflow && MarketHelper.NpcWillOverflow(Vill, targetRes))
            {
                return(TaskRes.Executed);
            }
            for (int i = 0; i < 4; i++)
            {
                //await acc.Wb.Driver.FindElementById($"m2[{i}]").Write(targetRes[i]);
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    await DriverHelper.ExecuteScript(acc, $"document.getElementById('m2[{i}]').value='{targetRes[i]}'");

                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    await DriverHelper.ExecuteScript(acc, $"document.getElementsByName('desired{i}')[0].value='{targetRes[i]}'");

                    break;
                }
            }

            var submit     = acc.Wb.Html.GetElementbyId("submitText");
            var distribute = submit.Descendants("button").FirstOrDefault();

            await DriverHelper.ExecuteScript(acc, $"document.getElementById('{distribute.Id}').click()");

            wb.ExecuteScript($"document.getElementById('npc_market_button').click()"); //Exchange resources button
            return(TaskRes.Executed);
        }
Ejemplo n.º 11
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var wb = acc.Wb.Driver;

            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=99&id=39");

            // Show "Add raid" popup
            await DriverHelper.ExecuteScript(acc, $"Travian.Game.RaidList.addSlot({this.FarmListId},'','','rallyPoint');");

            // Input coordinates
            await DriverHelper.WriteCoordinates(acc, Farm.Coords);

            // Input troops
            for (int i = 0; i < Farm.Troops.Length; i++)
            {
                if (Farm.Troops[i] == 0)
                {
                    continue;
                }
                await DriverHelper.WriteById(acc, $"t{i + 1}", Farm.Troops[i]);
            }

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

            // Click "save"
            switch (acc.AccInfo.ServerVersion)
            {
            case Classificator.ServerVersionEnum.T4_4:
                wb.ExecuteScript("Travian.Game.RaidList.saveSlot(getSelectedListId(), $('edit_form').toQueryString().parseQueryString(), true);");
                break;

            case Classificator.ServerVersionEnum.T4_5:
                await DriverHelper.ClickById(acc, "save");

                break;
            }

            return(TaskRes.Executed);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Tries to watch an Ad for +25% faster upgrade
        /// </summary>
        /// <param name="acc">Account</param>
        /// <returns>Whether bot watched the ad</returns>
        private async Task <bool> TryFastUpgrade(Account acc)
        {
            if (!await DriverHelper.ClickByClassName(acc, "videoFeatureButton green", false))
            {
                return(false);
            }

            // Accept ads
            if (await DriverHelper.ClickByName(acc, "adSalesVideoInfoScreen", false))
            {
                await DriverHelper.ExecuteScript(acc, "jQuery(window).trigger('showVideoWindowAfterInfoScreen')");
            }

            // Has to be a legit "click"
            acc.Wb.Driver.FindElementById("videoFeature").Click();

            var timeout = DateTime.Now.AddSeconds(100);

            do
            {
                await System.Threading.Tasks.Task.Delay(1000);

                if (timeout < DateTime.Now)
                {
                    return(false);
                }
            }while (acc.Wb.Driver.Url.Contains("build.php"));

            // Don't show again
            acc.Wb.UpdateHtml();
            if (acc.Wb.Html.GetElementbyId("dontShowThisAgain") != null)
            {
                await DriverHelper.ClickById(acc, "dontShowThisAgain");

                await DriverHelper.ClickByClassName(acc, "dialogButtonOk ok");
            }
            return(true);
        }
Ejemplo n.º 13
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            if (Vill == null)
            {
                Vill = acc.Villages.First(x => x.Active);
            }

            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Smithy))
            {
                return(TaskRes.Executed);
            }

            var levels = TroopsParser.GetTroopLevels(acc.Wb.Html);

            if (levels == null)
            {
                acc.Wb.Log("There was an error at getting Smithy troop levels");
                return(TaskRes.Executed);
            }
            Vill.Troops.Levels = levels;
            TroopsHelper.UpdateResearchedTroops(Vill);

            var currentlyImproving = TroopsParser.GetImprovingTroops(acc.Wb.Html);
            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 (maxImproving <= currentlyImproving.Count())
            {
                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);

            // Check if we have enough resources to improve the troop
            if (!ResourcesHelper.IsEnoughRes(Vill, cost.UpgradeCost.ToArray()))
            {
                ResourcesHelper.NotEnoughRes(acc, Vill, cost.UpgradeCost, this);
                return(TaskRes.Executed);
            }

            //Click on the button
            var troopNode = acc.Wb.Html.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)
            {
                acc.Wb.Log($"Could not find Upgrade button to improve {troop}");
                this.NextExecute = DateTime.Now.AddMinutes(1);
                return(TaskRes.Retry);
            }

            await DriverHelper.ClickById(acc, button.Id);

            // 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);
        }
Ejemplo n.º 14
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            // Check if the account has enough culture points
            if (acc.AccInfo.CulturePoints.MaxVillages <= acc.AccInfo.CulturePoints.VillageCount)
            {
                // TODO: this shouldn't be here?
                acc.Wb.Log("Don't have enough culture points");
                this.Vill.Expansion.ExpansionAvailable = true;
                return(TaskRes.Executed);
            }

            if (acc.NewVillages.Locations.Count == 0)
            {
                if (acc.NewVillages.AutoFindVillages) // Find new village to settle
                {
                    TaskExecutor.AddTaskIfNotExists(acc, new FindVillageToSettle()
                    {
                        Vill      = AccountHelper.GetMainVillage(acc),
                        ExecuteAt = DateTime.MinValue.AddHours(10),
                        Priority  = TaskPriority.High
                    });
                    this.NextExecute = DateTime.MinValue.AddHours(11);
                }

                return(TaskRes.Executed);
            }

            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/karte.php");

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

            var newVillage = acc.NewVillages.Locations.FirstOrDefault();

            //acc.NewVillage.NewVillages.Remove(coords); //remove it after settling and changing the vill name??
            string kid = MapHelper.KidFromCoordinates(newVillage.Coordinates, acc).ToString();

            string url = $"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2";

            switch (acc.AccInfo.ServerVersion)
            {
            case Classificator.ServerVersionEnum.T4_4:
                // https://low4.ttwars.com/build.php?id=39&tt=2&kid=7274&a=6
                url += $"&kid={kid}&a=6";
                break;

            case Classificator.ServerVersionEnum.T4_5:
                // https://tx3.travian.com/build.php?id=39&tt=2&mapid=123&s=1&gid=16
                url += $"&mapid={kid}&s=1&gid=16";
                break;
            }
            await acc.Wb.Navigate(url);

            // Check if we have enough resource
            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);
            }

            if (!await DriverHelper.ClickById(acc, "btn_ok"))
            {
                return(TaskRes.Retry);
            }

            newVillage.SettlersSent = true;
            this.Vill.Expansion.ExpansionAvailable = false;

            return(TaskRes.Executed);
        }
Ejemplo n.º 15
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var url = $"{acc.AccInfo.ServerUrl}/build.php?id=39&tt=2";

            if (SetCoordsInUrl)
            {
                url += "&z=" + MapHelper.KidFromCoordinates(TroopsMovement.TargetCoordinates, acc);
            }

            await acc.Wb.Navigate(url);

            var proceed = TroopsCallback?.Invoke(acc, TroopsMovementParser.GetTroopsInRallyPoint(acc.Wb.Html));

            if (!(proceed ?? true))
            {
                return(TaskRes.Retry);
            }

            // No troops selected to be sent from this village
            if (this.TroopsMovement.Troops.Sum() == 0)
            {
                return(TaskRes.Executed);
            }

            // Add number of troops to the input boxes
            for (int i = 0; i < TroopsMovement.Troops.Length; i++)
            {
                if (TroopsMovement.Troops[i] == 0)
                {
                    continue;
                }
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    await DriverHelper.WriteByName(acc, $"t{i + 1}", TroopsMovement.Troops[i]);

                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    await DriverHelper.WriteByName(acc, $"troops[0][t{i + 1}]", TroopsMovement.Troops[i]);

                    break;
                }
            }

            // Select coordinates, if we haven't set them in the url already
            if (!SetCoordsInUrl)
            {
                await DriverHelper.WriteCoordinates(acc, TroopsMovement.TargetCoordinates);
            }

            //Select type of troop sending
            string script = $"Array.from(document.getElementsByName('c')).find(x=>x.value=={(int)TroopsMovement.MovementType}).checked=true;";
            await DriverHelper.ExecuteScript(acc, script);

            //Click on "Send" button
            await DriverHelper.ClickById(acc, "btn_ok");

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

            // Select catapult targets
            if (this.TroopsMovement.Target1 != Classificator.BuildingEnum.Site)
            {
                await DriverHelper.SelectIndexByName(acc, "ctar1", (int)this.TroopsMovement.Target1);
            }
            if (this.TroopsMovement.Target2 != Classificator.BuildingEnum.Site)
            {
                await DriverHelper.SelectIndexByName(acc, "ctar2", (int)this.TroopsMovement.Target2);
            }

            // Scout type
            if (this.TroopsMovement.ScoutType != ScoutEnum.None)
            {
                string scout = $"Array.from(document.getElementsByName('spy')).find(x=>x.value=={(int)TroopsMovement.ScoutType}).checked=true;";
                await DriverHelper.ExecuteScript(acc, scout);
            }

            // Parse movement duration of the troops
            this.Arrival = TroopsMovementParser.GetMovementDuration(acc.Wb.Html);

            //Click on "Send" button
            await DriverHelper.ClickById(acc, "btn_ok");

            acc.Wb.Log($"Bot sent troops from village {Vill.Name} to {this.TroopsMovement.TargetCoordinates}");

            return(TaskRes.Executed);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Tries to watch an Ad for +25% faster upgrade
        /// </summary>
        /// <param name="acc">Account</param>
        /// <returns>Whether bot watched the ad</returns>
        private async Task <bool> TryFastUpgrade(Account acc)
        {
            if (!await DriverHelper.ClickByClassName(acc, "videoFeatureButton green", false))
            {
                return(false);
            }
            await System.Threading.Tasks.Task.Delay(AccountHelper.Delay());

            // Confirm
            acc.Wb.UpdateHtml();
            if (acc.Wb.Html.DocumentNode.SelectSingleNode("//input[@name='adSalesVideoInfoScreen']") != null)
            {
                await DriverHelper.ClickByName(acc, "adSalesVideoInfoScreen");

                await System.Threading.Tasks.Task.Delay(AccountHelper.Delay());

                await DriverHelper.ExecuteScript(acc, "jQuery(window).trigger('showVideoWindowAfterInfoScreen')");

                await System.Threading.Tasks.Task.Delay(AccountHelper.Delay());
            }

            // Has to be a legit "click"
            acc.Wb.Driver.FindElementById("videoFeature").Click();

            // wait for finish watching ads
            var timeout = DateTime.Now.AddSeconds(100);

            do
            {
                await System.Threading.Tasks.Task.Delay(3000);

                //skip ads from Travian Games
                //they use ifarme to emebed ads video to their game
                acc.Wb.UpdateHtml();
                if (acc.Wb.Html.GetElementbyId("videoArea") != null)
                {
                    acc.Wb.Driver.SwitchTo().Frame(acc.Wb.Driver.FindElementById("videoArea"));
                    // trick to skip
                    await DriverHelper.ExecuteScript(acc, "var video = document.getElementsByTagName('video')[0];video.currentTime = video.duration - 1;", false, false);

                    //back to first page
                    acc.Wb.Driver.SwitchTo().DefaultContent();
                }
                if (timeout < DateTime.Now)
                {
                    return(false);
                }
            }while (acc.Wb.Driver.Url.Contains("build.php"));

            // Don't show again
            acc.Wb.UpdateHtml();
            if (acc.Wb.Html.GetElementbyId("dontShowThisAgain") != null)
            {
                await DriverHelper.ClickById(acc, "dontShowThisAgain");

                await System.Threading.Tasks.Task.Delay(AccountHelper.Delay());

                await DriverHelper.ClickByClassName(acc, "dialogButtonOk ok");
            }

            return(true);
        }
Ejemplo n.º 18
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            var wb = acc.Wb.Driver;

            if (!await VillageHelper.EnterBuilding(acc, Vill, Classificator.BuildingEnum.Marketplace, "&t=0"))
            {
                return(TaskRes.Executed);
            }

            var npcMerchant = acc.Wb.Html.DocumentNode.Descendants("div").FirstOrDefault(x => x.HasClass("npcMerchant"));
            var npcButton   = npcMerchant.Descendants("button").FirstOrDefault(x => x.HasClass("gold"));

            // Exchange resources button
            await DriverHelper.ClickById(acc, npcButton.Id);

            //wait npc form show
            var timeout = DateTime.Now.AddSeconds(100);

            HtmlNode remainRes = null;

            do
            {
                await Task.Delay(1000);

                remainRes = acc.Wb.Html.GetElementbyId("remain");

                if (timeout < DateTime.Now)
                {
                    acc.Wb.Log($"NPC in village {Vill.Name} is time out. Retry after 3 mins");
                    this.NextExecute = DateTime.Now.AddMinutes(3);
                    return(TaskRes.Executed);
                }
            }while (remainRes == null);

            var resSum    = Parser.RemoveNonNumeric(remainRes.InnerText);
            var targetRes = MarketHelper.NpcTargetResources(Vill, resSum);

            if (!Vill.Market.Npc.NpcIfOverflow && MarketHelper.NpcWillOverflow(Vill, targetRes))
            {
                acc.Wb.Log($"NPC in village {Vill.Name} will be overflow. Stop NPC");
                return(TaskRes.Executed);
            }
            for (int i = 0; i < 4; i++)
            {
                //await acc.Wb.Driver.FindElementById($"m2[{i}]").Write(targetRes[i]);
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    await DriverHelper.ExecuteScript(acc, $"document.getElementById('m2[{i}]').value='{targetRes[i]}'");

                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    await DriverHelper.ExecuteScript(acc, $"document.getElementsByName('desired{i}')[0].value='{targetRes[i]}'");

                    break;
                }
            }

            var submit     = acc.Wb.Html.GetElementbyId("submitText");
            var distribute = submit.Descendants("button").FirstOrDefault();

            await DriverHelper.ClickById(acc, distribute.Id);

            await DriverHelper.ClickById(acc, "npc_market_button");

            return(TaskRes.Executed);
        }
Ejemplo n.º 19
0
        public override async Task <TaskRes> Execute(Account acc)
        {
            await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/build.php?tt=2&id=39");

            TroopsCallback?.Invoke(acc, TroopsMovementParser.GetTroopsInRallyPoint(acc.Wb.Html));

            // No troops selected to be sent from this village
            if (this.TroopsMovement.Troops.Sum() == 0)
            {
                return(TaskRes.Executed);
            }

            // Add number of troops to the input boxes
            for (int i = 0; i < TroopsMovement.Troops.Length; i++)
            {
                if (TroopsMovement.Troops[i] == 0)
                {
                    continue;
                }
                switch (acc.AccInfo.ServerVersion)
                {
                case Classificator.ServerVersionEnum.T4_4:
                    await DriverHelper.WriteByName(acc, $"t{i + 1}", TroopsMovement.Troops[i]);

                    break;

                case Classificator.ServerVersionEnum.T4_5:
                    await DriverHelper.WriteByName(acc, $"troops[0][t{i + 1}]", TroopsMovement.Troops[i]);

                    break;
                }
            }

            // Select coordinates
            await DriverHelper.WriteCoordinates(acc, TroopsMovement.TargetCoordinates);

            //Select type of troop sending
            string script = $"Array.from(document.getElementsByName('c')).find(x=>x.value=={(int)TroopsMovement.MovementType}).checked=true;";
            await DriverHelper.ExecuteScript(acc, script);

            //Click on "Send" button
            await DriverHelper.ClickById(acc, "btn_ok");

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

            // Select catapult targets
            if (this.TroopsMovement.Target1 != Classificator.BuildingEnum.Site)
            {
                await DriverHelper.SelectIndexByName(acc, "ctar1", (int)this.TroopsMovement.Target1);
            }
            if (this.TroopsMovement.Target2 != Classificator.BuildingEnum.Site)
            {
                await DriverHelper.SelectIndexByName(acc, "ctar2", (int)this.TroopsMovement.Target2);
            }

            // Scout type
            if (this.TroopsMovement.ScoutType != ScoutEnum.None)
            {
                string scout = $"Array.from(document.getElementsByName('spy')).find(x=>x.value=={(int)TroopsMovement.ScoutType}).checked=true;";
                await DriverHelper.ExecuteScript(acc, scout);
            }

            //Click on "Send" button
            await DriverHelper.ClickById(acc, "btn_ok");

            return(TaskRes.Executed);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Used by BotTasks to insert resources/coordinates into the page.
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="resources">Target resources</param>
        /// <param name="coordinates">Target coordinates</param>
        /// <returns>Time it will take for transit to complete</returns>
        public static async Task <TimeSpan> MarketSendResource(Account acc, long[] resources, Village targetVillage, BotTask botTask)
        {
            var times = 1;

            if (acc.AccInfo.GoldClub ?? false)
            {
                times = 3;
            }
            else if (acc.AccInfo.PlusAccount)
            {
                times = 2;
            }

            // No resources to send
            if (resources.Sum() == 0)
            {
                return(TimeSpan.Zero);
            }

            var sendRes = resources.Select(x => x / times).ToArray();

            //round the resources that we want to send, so it looks less like a bot

            (var merchantsCapacity, var merchantsNum) = MarketHelper.ParseMerchantsInfo(acc.Wb.Html);
            // We don't have any merchants.
            if (merchantsNum == 0)
            {
                //Parse currently ongoing transits
                var transits   = MarketParser.ParseTransits(acc.Wb.Html);
                var activeVill = acc.Villages.FirstOrDefault(x => x.Active); // Could also just pass that in params

                var nextTry = SoonestAvailableMerchants(acc, activeVill, targetVillage, transits);
                if (nextTry != DateTime.MaxValue)
                {
                    nextTry = nextTry.AddSeconds(5);
                }

                botTask.NextExecute = nextTry;
                // Just return something, will get overwritten anyways.
                return(new TimeSpan((int)(nextTry - DateTime.Now).TotalHours + 1, 0, 0));
            }

            var maxRes = merchantsCapacity * times;
            var allRes = resources.Sum();

            if (allRes > maxRes)
            {
                // We don't have enough merchants to transit all the resources. Divide all resources by some divider.
                var     resDivider = (float)allRes / maxRes;
                float[] resFloat   = sendRes.Select(x => x / resDivider).ToArray();
                sendRes = resFloat.Select(x => (long)Math.Floor(x)).ToArray();
            }

            var wb = acc.Wb.Driver;

            for (int i = 0; i < 4; i++)
            {
                // To avoid exception devide by zero
                if (50 <= sendRes[i])
                {
                    //round the number to about -1%, for rounder numbers
                    var digits    = Math.Ceiling(Math.Log10(sendRes[i]));
                    var remainder = sendRes[i] % (long)Math.Pow(10, digits - 2);
                    sendRes[i] -= remainder;
                    await DriverHelper.WriteById(acc, "r" + (i + 1), sendRes[i]);
                }
                await Task.Delay(AccountHelper.Delay() / 5);
            }

            // Input coordinates
            await DriverHelper.WriteCoordinates(acc, targetVillage.Coordinates);

            //Select x2/x3
            if (times != 1)
            {
                wb.ExecuteScript($"document.getElementById('x2').value='{times}'");
                await Task.Delay(AccountHelper.Delay() / 5);
            }
            await DriverHelper.ClickById(acc, "enabledButton");

            var durNode = acc.Wb.Html.GetElementbyId("target_validate");

            if (durNode == null && acc.Wb.Html.GetElementbyId("prepareError") != null)
            {
                // Error "Abuse! You have not enough resources." is displayed.
            }
            //get duration of transit
            var dur = durNode.Descendants("td").ToList()[3].InnerText.Replace("\t", "").Replace("\n", "");

            // Will NOT trigger a page reload! Thus we should await some time before continuing.
            await DriverHelper.ClickById(acc, "enabledButton");

            targetVillage.Market.LastTransit = DateTime.Now;

            var duration = TimeParser.ParseDuration(dur);

            return(TimeSpan.FromTicks(duration.Ticks * (times * 2 - 1)));
        }