Esempio n. 1
0
        /// <summary>
        /// Finds BotTask that refreshes the village (dorf1) and re-schedules it a random time between
        /// user specified. If time argument is specified, next village refresh will be executed as specified.
        /// </summary>
        public static void SetNextRefresh(Account acc, Village vill, DateTime?time = null)
        {
            // In case user sets refresh to 0/1 min
            if (vill.Settings.RefreshMin < 2)
            {
                vill.Settings.RefreshMin = 30;
            }
            if (vill.Settings.RefreshMax < 2)
            {
                vill.Settings.RefreshMin = 60;
            }

            var ran = new Random();

            if (time == null)
            {
                time = DateTime.Now.AddMinutes(ran.Next(vill.Settings.RefreshMin, vill.Settings.RefreshMax));
            }

            var task = acc.Tasks.FirstOrDefault(x => x.Vill == vill && x.GetType() == typeof(UpdateDorf1));

            if (task == null)
            {
                TaskExecutor.AddTask(acc, new UpdateDorf1
                {
                    Vill      = vill,
                    ExecuteAt = time ?? default,
                    Priority  = Tasks.BotTask.TaskPriority.Low
                });
Esempio n. 2
0
        public static void ReStartBuilding(Account acc, Village vill)
        {
            RemoveCompletedTasks(vill, acc);
            //remove ongoing building task for this village
            acc.Tasks.RemoveAll(x =>
                                x.vill == vill &&
                                x.GetType() == typeof(UpgradeBuilding)
                                );

            if (vill.Build.Tasks.Count == 0)
            {
                return;                              //No build tasks
            }
            var nextExecution = DateTime.Now.AddSeconds(5);
            var lastCB        = vill.Build.CurrentlyBuilding.LastOrDefault();

            var maxBuildings = 1;

            if (acc.AccInfo.PlusAccount)
            {
                maxBuildings++;
            }
            if (lastCB != null && lastCB.Duration > nextExecution && vill.Build.CurrentlyBuilding.Count >= maxBuildings)
            {
                nextExecution = lastCB.Duration;
            }

            var building = new UpgradeBuilding()
            {
                vill      = vill,
                ExecuteAt = nextExecution,
            };

            TaskExecutor.AddTask(acc, building);
        }
Esempio n. 3
0
        public static void ReStartBuilding(Account acc, Village vill)
        {
            RemoveCompletedTasks(vill, acc);
            //remove ongoing building task for this village
            acc.Tasks.RemoveAll(x =>
                                x.Vill == vill &&
                                x.GetType() == typeof(UpgradeBuilding)
                                );

            if (vill.Build.Tasks.Count == 0)
            {
                return;                              //No build tasks
            }
            var(_, nextExecution) = UpgradeBuildingHelper.NextBuildingTask(acc, vill);

            TaskExecutor.AddTask(acc, new UpgradeBuilding()
            {
                Vill      = vill,
                ExecuteAt = nextExecution,
            });
        }
Esempio n. 4
0
        /// <summary>
        /// Called PageLoaded (after navigating to a specific url) or from
        /// Task timer, if there is no url/bot is already on the url
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="task">Task to be executed</param>
        /// <returns></returns>
        public static async Task Execute(Account acc, BotTask task)
        {
            // Before every execution, wait a random delay
            if (acc.AccInfo.ServerVersion == Classificator.ServerVersionEnum.T4_5)
            {
                await Task.Delay(AccountHelper.Delay());
            }

            if (acc.Wb?.CurrentUrl == null && task.GetType() != typeof(CheckProxy))
            {
                await acc.Wb.Navigate($"{acc.AccInfo.ServerUrl}/dorf1.php");
            }

            if (task.Vill == null)
            {
                task.Vill = acc.Villages.FirstOrDefault(x => x.Active);
            }

            try
            {
                acc.Wb.Log($"Executing task {task.GetName()}" + (task.Vill == null ? "" : $" in village {task.Vill.Name}"));

                switch (await task.Execute(acc))
                {
                case TaskRes.Retry:
                    task.RetryCounter++;
                    if (task.NextExecute == null)
                    {
                        task.NextExecute = DateTime.Now.AddMinutes(3);
                    }
                    break;

                default:
                    task.RetryCounter = 0;
                    if (task.NextTask != null)
                    {
                        task.NextTask.ExecuteAt = DateTime.MinValue.AddHours(5);
                        task.NextTask.Stage     = TaskStage.Start;
                        TaskExecutor.AddTask(acc, task.NextTask);
                        task.NextTask = null;
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                if (acc.Wb != null)
                {
                    acc.Wb.Log($"Error executing task {task.GetName()}! Vill {task.Vill?.Name}", e);
                }
                task.RetryCounter++;
                if (task.NextExecute == null)
                {
                    task.NextExecute = DateTime.Now.AddMinutes(3);
                }
            }

            //We want to re-execute the same task later
            if (task.NextExecute != null && task.RetryCounter < 3)
            {
                task.ExecuteAt   = task.NextExecute ?? default;
                task.NextExecute = null;
                ReorderTaskList(acc);
                task.Stage = TaskStage.Start;
                return;
            }
            // Remove the task from the task list
            acc.Tasks.Remove(task);
        }
Esempio n. 5
0
 /// <summary>
 /// Will (re)start troop training for all buildings (barracks,stable,gs...)
 /// </summary>
 /// <param name="acc">Account</param>
 /// <param name="vill">Village to start troops training</param>
 public static void ReStartTroopTraining(Account acc, Village vill)
 {
     //remove training tasks
     acc.Tasks?.RemoveAll(x =>
                          x.Vill == vill &&
                          x.GetType() == typeof(TrainTroops)
                          );
     //start training tasks
     if (vill.Settings.BarracksTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.BarracksTrain))
     {
         var barracksTrain = DateTime.Now;
         if (vill.Troops.CurrentlyTraining.Barracks.Count > 0)
         {
             barracksTrain = vill.Troops.CurrentlyTraining.Barracks.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance);
         }
         TaskExecutor.AddTask(acc, new TrainTroops()
         {
             ExecuteAt = barracksTrain,
             Great     = false,
             Vill      = vill,
             Troop     = vill.Settings.BarracksTrain
         });
         if (vill.Settings.GreatBarracksTrain)
         {
             var gbTrain = DateTime.Now;
             if (vill.Troops.CurrentlyTraining.GB.Count > 0)
             {
                 gbTrain = vill.Troops.CurrentlyTraining.GB.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance);
             }
             TaskExecutor.AddTask(acc, new TrainTroops()
             {
                 ExecuteAt = gbTrain,
                 Great     = true,
                 Vill      = vill,
                 Troop     = vill.Settings.BarracksTrain
             });
         }
     }
     //stable
     if (vill.Settings.StableTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.StableTrain))
     {
         var stableTrain = DateTime.Now;
         if (vill.Troops.CurrentlyTraining.Stable.Count > 0)
         {
             stableTrain = vill.Troops.CurrentlyTraining.Stable.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance);
         }
         TaskExecutor.AddTask(acc, new TrainTroops()
         {
             ExecuteAt = stableTrain,
             Great     = false,
             Vill      = vill,
             Troop     = vill.Settings.StableTrain
         });
         if (vill.Settings.GreatStableTrain)
         {
             var gsTrain = DateTime.Now;
             if (vill.Troops.CurrentlyTraining.GS.Count > 0)
             {
                 gsTrain = vill.Troops.CurrentlyTraining.GS.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance);
             }
             TaskExecutor.AddTask(acc, new TrainTroops()
             {
                 ExecuteAt = gsTrain,
                 Great     = true,
                 Vill      = vill,
                 Troop     = vill.Settings.StableTrain
             });
         }
     }
     //workshop
     if (vill.Settings.WorkshopTrain != TroopsEnum.None && !vill.Troops.ToResearch.Any(x => x == vill.Settings.WorkshopTrain))
     {
         var wsTrain = DateTime.Now;
         if (vill.Troops.CurrentlyTraining.Workshop.Count > 0)
         {
             wsTrain = vill.Troops.CurrentlyTraining.Workshop.Last().FinishTraining.AddHours(-acc.Settings.FillInAdvance);
         }
         TaskExecutor.AddTask(acc, new TrainTroops()
         {
             ExecuteAt = wsTrain,
             Vill      = vill,
             Troop     = vill.Settings.WorkshopTrain
         });
     }
 }
Esempio n. 6
0
        /// <summary>
        /// Will send resources from main village to the target village
        /// </summary>
        /// <param name="vill">(target) Village to get the resources</param>
        /// <returns>Returns DateTime when approximately will resources get transited to target village </returns>
        public static DateTime TransitResourcesFromMain(Account acc, Village vill)
        {
            // Transit resources for this village is disabled.
            if (!vill.Market.Settings.Configuration.Enabled)
            {
                return(DateTime.MaxValue);
            }

            // There already is a sendResources BotTask for this village
            var transitTask = (SendResources)acc.Tasks.FirstOrDefault(x =>
                                                                      x.GetType() == typeof(SendResources) &&
                                                                      ((SendResources)x).Coordinates == vill.Coordinates
                                                                      );

            //vill.Market.Settings.Configuration.
            if (transitTask != null)
            {
                return(transitTask.Configuration.TransitArrival);
            }
            //Less than 5min ago we already sent resources. Just to catch bugs.
            //if(vill.Market.)

            // Merchants are on their way
            if (vill.Market.Settings.Configuration.TransitArrival > DateTime.Now)
            {
                return(vill.Market.Settings.Configuration.TransitArrival);
            }

            //send resources
            var sendRes    = new Resources();
            var conf       = vill.Market.Settings.Configuration;
            var currentRes = vill.Res.Stored.Resources;
            var cap        = vill.Res.Capacity;

            var woodNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Wood / 100.0);

            sendRes.Wood = (woodNeeded > conf.FillLimit.Wood ? conf.FillLimit.Wood : woodNeeded) - currentRes.Wood;
            sendRes.Wood = (sendRes.Wood < 0 ? 0 : sendRes.Wood);

            var clayNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Clay / 100.0);

            sendRes.Clay = (clayNeeded > conf.FillLimit.Clay ? conf.FillLimit.Clay : clayNeeded) - currentRes.Clay;
            sendRes.Clay = (sendRes.Clay < 0 ? 0 : sendRes.Clay);

            var ironNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Iron / 100.0);

            sendRes.Iron = (ironNeeded > conf.FillLimit.Iron ? conf.FillLimit.Iron : ironNeeded) - currentRes.Iron;
            sendRes.Iron = (sendRes.Iron < 0 ? 0 : sendRes.Iron);

            var cropNeeded = (long)(cap.GranaryCapacity * conf.TargetLimit.Crop / 100.0);

            sendRes.Crop = (cropNeeded > conf.FillLimit.Crop ? conf.FillLimit.Crop : cropNeeded) - currentRes.Crop;
            sendRes.Crop = (sendRes.Crop < 0 ? 0 : sendRes.Crop);

            if (ResourcesHelper.IsZeroResources(sendRes)) //we have enough res :)
            {
                return(DateTime.MinValue);
            }

            // Send resources to a village only once per 5 minutes
            TimeSpan transitAfter = vill.Market.LastTransit.AddMinutes(5) - DateTime.Now;

            if (transitAfter < TimeSpan.Zero)
            {
                transitAfter = TimeSpan.Zero;
            }

            var sendResTask = new SendResources
            {
                Configuration = conf,
                Coordinates   = vill.Coordinates,
                ExecuteAt     = DateTime.Now + transitAfter,
                Vill          = AccountHelper.GetMainVillage(acc),
                Resources     = sendRes
            };


            TaskExecutor.AddTask(acc, sendResTask);

            //AddMinutes(1) since bot has to wait for the SendResources task and then
            //go to the marketplace and send resources
            //TransitArrival will get updated to more specific time

            return(DateTime.Now.Add(transitAfter + CalculateTransitTimeMainVillage(acc, vill)).AddMinutes(1));
        }
Esempio n. 7
0
        /// <summary>
        /// Method will create EquipHero BotTasks that will use resources needed
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="vill">Village to use resources in</param>
        /// <param name="neededRes">Needed resources</param>
        /// <param name="heroRes">Hero resources</param
        /// <param name="task">Potential BuildingTask that requires the resources</param>
        private static HeroEquip UseHeroResources(Account acc, Village vill, ref long[] neededRes, long[] heroRes, BuildingTask task = null)
        {
            var useRes = new List <(Classificator.HeroItemEnum, int)>();

            for (int i = 0; i < 4; i++)
            {
                if (neededRes[i] == 0 || heroRes[i] == 0)
                {
                    continue;
                }

                long resToBeUsed = RoundUpTo100(neededRes[i]);
                if (heroRes[i] < resToBeUsed)
                {
                    resToBeUsed = heroRes[i];
                }
                neededRes[i] -= resToBeUsed;

                HeroItemEnum item = HeroItemEnum.Others_Wood_0;
                switch (i)
                {
                case 0:
                    item = HeroItemEnum.Others_Wood_0;
                    break;

                case 1:
                    item = HeroItemEnum.Others_Clay_0;
                    break;

                case 2:
                    item = HeroItemEnum.Others_Iron_0;
                    break;

                case 3:
                    item = HeroItemEnum.Others_Crop_0;
                    break;
                }
                useRes.Add((item, (int)resToBeUsed));
            }

            var heroEquip = new HeroEquip()
            {
                Items     = useRes,
                ExecuteAt = DateTime.Now.AddHours(-2), // -2 since sendRes is -1
                Vill      = vill
            };

            TaskExecutor.AddTask(acc, heroEquip);

            // A BuildTask needed the resources. If it was auto-build res fields task, make a new
            // general building task - so resources actually get used for intended building upgrade
            if (task != null && task.TaskType == Classificator.BuildingType.AutoUpgradeResFields)
            {
                var building = vill.Build.Buildings.FirstOrDefault(x => x.Id == task.BuildingId);
                var lvl      = building.Level;
                if (building.UnderConstruction)
                {
                    lvl++;
                }
                BuildingHelper.AddBuildingTask(acc, vill, new BuildingTask()
                {
                    TaskType   = Classificator.BuildingType.General,
                    Building   = task.Building,
                    BuildingId = task.BuildingId,
                    Level      = ++lvl
                }, false);
            }

            return(heroEquip);
        }
Esempio n. 8
0
        public static void StartAccountTasks(Account acc)
        {
            // Get the server info (on first running the account)
            if (acc.AccInfo.ServerSpeed == 0 || acc.AccInfo.MapSize == 0)
            {
                TaskExecutor.AddTaskIfNotExists(acc, new GetServerInfo()
                {
                    ExecuteAt = DateTime.MinValue.AddHours(2)
                });
            }

            if (acc.AccInfo.Tribe == null)
            {
                TaskExecutor.AddTaskIfNotExists(acc, new GetTribe()
                {
                    ExecuteAt = DateTime.MinValue.AddHours(3)
                });
            }

            //FL
            if (acc.Farming.Enabled)
            {
                TaskExecutor.AddTaskIfNotExists(acc, new SendFLs()
                {
                    ExecuteAt = DateTime.Now
                });
            }

            // Bot sleep
            TaskExecutor.AddTaskIfNotExists(acc, new Sleep()
            {
                ExecuteAt = DateTime.Now + TimeHelper.GetWorkTime(acc),
                AutoSleep = true
            });

            // Access change
            var nextAccessChange = TimeHelper.GetNextProxyChange(acc);

            if (nextAccessChange != TimeSpan.MaxValue)
            {
                TaskExecutor.AddTaskIfNotExists(acc, new ChangeAccess()
                {
                    ExecuteAt = DateTime.Now + nextAccessChange
                });
            }
            //research / improve / train troops
            foreach (var vill in acc.Villages)
            {
                //if (vill.Troops.Researched.Count == 0) TaskExecutor.AddTask(acc, new UpdateTroops() { ExecuteAt = DateTime.Now, vill = vill });
                TroopsHelper.ReStartResearchAndImprovement(acc, vill);
                TroopsHelper.ReStartTroopTraining(acc, vill);
                BuildingHelper.ReStartBuilding(acc, vill);
                BuildingHelper.ReStartDemolishing(acc, vill);
                MarketHelper.ReStartSendingToMain(acc, vill);
                ReStartCelebration(acc, vill);
                VillageHelper.SetNextRefresh(acc, vill);
                if (vill.FarmingNonGold.OasisFarmingEnabled)
                {
                    TaskExecutor.AddTaskIfNotExistInVillage(acc, vill, new AttackOasis()
                    {
                        Vill = vill
                    });
                }

                // Remove in later updates!
                if (vill.Settings.RefreshMin == 0)
                {
                    vill.Settings.RefreshMin = 30;
                }
                if (vill.Settings.RefreshMax == 0)
                {
                    vill.Settings.RefreshMax = 60;
                }
            }
            // Remove in later updates!
            if (acc.Hero.Settings.MinUpdate == 0)
            {
                acc.Hero.Settings.MinUpdate = 40;
            }
            if (acc.Hero.Settings.MaxUpdate == 0)
            {
                acc.Hero.Settings.MaxUpdate = 80;
            }

            // Hero update info
            if (acc.Hero.Settings.AutoRefreshInfo)
            {
                Random ran = new Random();
                TaskExecutor.AddTask(acc, new HeroUpdateInfo()
                {
                    ExecuteAt = DateTime.Now.AddMinutes(ran.Next(40, 80)),
                    Priority  = Tasks.BotTask.TaskPriority.Low
                });
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Will be called before each task to update resources/msg?,villages,quests,hero health, adventures num, gold/silver
        /// </summary>
        /// <param name="acc">Account</param>
        /// <returns>True if successful, false if error</returns>
        private static bool PreTaskRefresh(Account acc)
        {
            var html = acc.Wb.Html;

            try
            {
                //check & update dorf1/dorf2
                if (!UpdateAccountObject.UpdateVillages(html, acc))
                {
                    return(false);                                                //Web browser not initiali
                }
                var activeVill = acc.Villages.FirstOrDefault(x => x.Active);
                //update dorf1/dorf2
                if (acc.Wb.CurrentUrl.Contains("dorf1"))
                {
                    UpdateDorf1Info(acc);
                }
                else if (acc.Wb.CurrentUrl.Contains("dorf2"))
                {
                    UpdateDorf2Info(acc);
                }


                acc.AccInfo.CulturePoints = RightBarParser.GetCulurePoints(html, acc.AccInfo.ServerVersion);

                var villExpansionReady = acc.Villages.FirstOrDefault(x => x.Expansion.ExpensionAvailable);
                if (acc.AccInfo.CulturePoints.MaxVillages > acc.AccInfo.CulturePoints.VillageCount &&
                    villExpansionReady != null)
                {
                    villExpansionReady.Expansion.ExpensionAvailable = false;
                    TaskExecutor.AddTaskIfNotExists(acc, new SendSettlers()
                    {
                        ExecuteAt = DateTime.Now, vill = villExpansionReady
                    });
                }

                acc.AccInfo.Tribe = LeftBarParser.GetAccountTribe(acc, html);
                acc.Quests        = RightBarParser.GetQuests(html);
                var goldSilver = RightBarParser.GetGoldAndSilver(html, acc.AccInfo.ServerVersion);
                acc.AccInfo.Gold        = goldSilver[0];
                acc.AccInfo.Silver      = goldSilver[1];
                acc.AccInfo.PlusAccount = RightBarParser.HasPlusAccount(html, acc.AccInfo.ServerVersion);
                //Check reports/msg count
                if (MsgParser.UnreadMessages(html, acc.AccInfo.ServerVersion) > 0 &&
                    !acc.Wb.CurrentUrl.Contains("messages.php") &&
                    !IsTaskOnQueue(acc, typeof(ReadMessage)))
                {
                    TaskExecutor.AddTask(acc, new ReadMessage()
                    {
                        ExecuteAt = DateTime.Now.AddMilliseconds(AccountHelper.Delay() * 30)
                    });
                }

                //update loyalty of village


                activeVill.Res.FreeCrop = RightBarParser.GetFreeCrop(html);
                activeVill.Res.Capacity = ResourceParser.GetResourceCapacity(html, acc.AccInfo.ServerVersion);
                activeVill.Res.Stored   = ResourceParser.GetResources(html);

                float ratio = (float)activeVill.Res.Stored.Resources.Crop / activeVill.Res.Capacity.GranaryCapacity;
                if (ratio >= 0.99 &&
                    acc.AccInfo.Gold >= 3 &&
                    activeVill.Market.Npc.Enabled &&
                    (activeVill.Market.Npc.NpcIfOverflow || !MarketHelper.NpcWillOverflow(activeVill)))
                {  //npc crop!
                    TaskExecutor.AddTaskIfNotExistInVillage(acc, activeVill, new NPC()
                    {
                        ExecuteAt = DateTime.MinValue,
                        vill      = activeVill
                    });
                }
                if (acc.Settings.AutoActivateProductionBoost && CheckProductionBoost(acc))
                {
                    TaskExecutor.AddTask(acc, new TTWarsPlusAndBoost()
                    {
                        ExecuteAt = DateTime.Now.AddSeconds(1)
                    });
                }

                acc.Hero.AdventureNum    = HeroParser.GetAdventureNum(html, acc.AccInfo.ServerVersion);
                acc.Hero.Status          = HeroParser.HeroStatus(html, acc.AccInfo.ServerVersion);
                acc.Hero.HeroInfo.Health = HeroParser.GetHeroHealth(html, acc.AccInfo.ServerVersion);

                bool heroReady = (acc.Hero.HeroInfo.Health > acc.Hero.Settings.MinHealth &&
                                  acc.Hero.Settings.AutoSendToAdventure &&
                                  acc.Hero.Status == Hero.StatusEnum.Home &&
                                  acc.Hero.NextHeroSend < DateTime.Now);
                // Update adventures
                if (heroReady &&
                    (acc.Hero.AdventureNum != acc.Hero.Adventures.Count() || HeroHelper.AdventureInRange(acc))) //update adventures
                {
                    AddTaskIfNotExists(acc, new StartAdventure()
                    {
                        ExecuteAt = DateTime.Now.AddSeconds(10)
                    });
                }
                if (acc.Hero.AdventureNum == 0 && acc.Hero.Settings.BuyAdventures) //for UNL servers, buy adventures
                {
                    AddTaskIfNotExists(acc, new TTWarsBuyAdventure()
                    {
                        ExecuteAt = DateTime.Now.AddSeconds(5)
                    });
                }
                if (acc.Hero.Status == Hero.StatusEnum.Dead && acc.Hero.Settings.AutoReviveHero) //if hero is dead, revive him
                {
                    AddTaskIfNotExists(acc, new ReviveHero()
                    {
                        ExecuteAt = DateTime.Now.AddSeconds(5), vill = AccountHelper.GetHeroReviveVillage(acc)
                    });
                }
                if (HeroParser.LeveledUp(html) && acc.Hero.Settings.AutoSetPoints)
                {
                    AddTaskIfNotExists(acc, new HeroSetPoints()
                    {
                        ExecuteAt = DateTime.Now
                    });
                }
                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error in PreTask " + e.Message + "\n\nStack Trace: " + e.StackTrace + "\n-----------------------");
                return(false);
            }
        }