/// <summary>
        /// Search an element on FFXIVCrafting
        /// </summary>
        private void SearchThread()
        {
            string        elemToSearch = VPThreading.GetText(_searchTextBox);
            int           minLevel     = (int)VPThreading.GetValue(_minLevelNumericUpDown);
            int           maxLevel     = (int)VPThreading.GetValue(_maxLevelNumericUpDown);
            List <string> jobs         = new List <string>();

            lock (_locker)
            {
                jobs = _jobFilter;
            }
            Service_Misc.LogText(_logTextBox, "Alright, let's look for " + elemToSearch);
            List <FFXIVSearchItem> listResults = GarlandTool.Search(elemToSearch, _logTextBox, FFXIVItem.TypeItem.Crafted, jobs, minLevel, maxLevel);

            //Storing in options
            MiqoCraftOptions options = new MiqoCraftOptions();

            options.Load(OptionLocation.UserOption);
            options.LastSearchResult = listResults;
            options.Save();

            if (listResults.Count > 0)
            {
                Service_Misc.LogText(_logTextBox, "All done ! Found " + listResults.Count + " items!");
            }
            else
            {
                Service_Misc.LogText(_logTextBox, "All done ! But I couldn't find your item...");
            }

            DisplayItemList(listResults);
        }
        private void UpdateResultPicturesThread()
        {
            List <ListViewItem> iItems = VPThreading.GetItems(_resultListView);

            Service_Misc.LogText(_logTextBox, "Updating Item Pictures...");
            foreach (ListViewItem listViewItem in iItems)
            {
                try
                {
                    FFXIVSearchItem item = VPThreading.GetTag(listViewItem) as FFXIVSearchItem;
                    if (!_prerequisiteImageList.Images.ContainsKey(item.ID))
                    {
                        System.Net.WebRequest  request    = System.Net.WebRequest.Create(item.UrlImage);
                        System.Net.WebResponse resp       = request.GetResponse();
                        System.IO.Stream       respStream = resp.GetResponseStream();
                        Bitmap bmp = new Bitmap(respStream);
                        respStream.Dispose();

                        VPThreading.AddImage(_resultListView, _prerequisiteImageList, item.ID, bmp);
                    }
                    VPThreading.SetImageKey(listViewItem, item.ID);
                }
                catch (Exception)
                {
                }
            }
        }
        private void DisplayItemList(List <FFXIVSearchItem> iItems)
        {
            VPThreading.ClearItems(_resultListView);
            _lastDisplayedItems = iItems;

            Service_Misc.LogText(_logTextBox, "Updating list...");
            foreach (FFXIVSearchItem item in iItems)
            {
                if (null == item)
                {
                    continue;
                }

                ListViewItem listViewItem = new ListViewItem();
                listViewItem.Tag  = item;
                listViewItem.Text = item.Quantity + "x " + item.Name;
                listViewItem.SubItems.Add(item.Class + " lvl" + item.Level);
                listViewItem.ToolTipText = item.Class + " lvl" + item.Level;

                VPThreading.AddItem(_resultListView, listViewItem);
            }
            VPThreading.SetText(_nbResultItemLabel, iItems.Count + " Items found");

            UpdateResultPictures();
        }
Exemple #4
0
        public void TestiNight()
        {
            JToken token = JObject.Parse(Service_Misc.RemoveIllegalCharacters(File.ReadAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\Searchlog.log"))));

            string rawText = File.ReadAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\GeneralDataBase.log"));

            File.WriteAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\GeneralDataBase_raw.log"), rawText);
            string correctedText = Service_Misc.RemoveIllegalCharacters(File.ReadAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\GeneralDataBase.log")));

            File.WriteAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\GeneralDataBase_corrected.log"), correctedText);
            JToken token2 = JObject.Parse(Service_Misc.RemoveIllegalCharacters(File.ReadAllText(Path.Combine(Service_Misc.GetExecutionPath(), @"References\iNight_Bug\GeneralDataBase.log"))));
        }
        public MainUserControlV2()
        {
            InitializeComponent();
            Service_Misc.LogText(_logTextBox, "Hey There ! I am MiqoCrafter, nice to met you.");
            Service_Misc.LogText(_logTextBox, "What can I do for you today ?");

            //Loading last search result
            MiqoCraftOptions options = new MiqoCraftOptions();

            options.Load(OptionLocation.UserOption);
            DisplayItemList(options.LastSearchResult);

            UpdateBDDStatusFromOptions();
        }
Exemple #6
0
        public void TestTitaniumLanceWithDuplicates()
        {
            VPOptions.OptionsForUnitTest = null;
            _dumpSuffix = "_withduplicates";
            MiqoCraftOptions customOptions = new MiqoCraftOptions();

            string        solution_dir = Service_Misc.GetExecutionPath();
            DirectoryInfo refDirectory = new DirectoryInfo(Path.Combine(solution_dir, "References"));

            customOptions.MiqoPresetPath = Path.Combine(refDirectory.FullName, @"Options\Set1");

            VPOptions.OptionsForUnitTest = customOptions;

            TestFullScenarioImpl("Titanium Lance", FFXIVItem.TypeItem.Crafted);
        }
        private void _quantityNumericUpDown_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                ListView.SelectedListViewItemCollection iItems = _resultListView.SelectedItems;

                Service_Misc.LogText(_logTextBox, "Updating Item Pictures...");
                foreach (ListViewItem listViewItem in iItems)
                {
                    try
                    {
                        FFXIVSearchItem item = VPThreading.GetTag(listViewItem) as FFXIVSearchItem;
                        //if (null != item) item.Quantity = (int)VPThreading.GetValue(_quantityNumericUpDown);
                        DisplayItemList(_lastDisplayedItems);
                    }
                    catch
                    {
                    }
                }
            }
        }
        private void MiqoGridFinder_Load(object sender, EventArgs e)
        {
            DirectoryInfo exeDirectory           = new DirectoryInfo(Service_Misc.GetExecutionPath());
            DirectoryInfo newGridDirectory       = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "NewGrids"));
            DirectoryInfo newGridBitmapDirectory = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "NewGridsBitmap"));

            if (!newGridDirectory.Exists)
            {
                newGridDirectory.Create();
            }
            if (!newGridBitmapDirectory.Exists)
            {
                newGridBitmapDirectory.Create();
            }
            foreach (FileInfo file in newGridDirectory.GetFiles())
            {
                file.Delete();
            }
            foreach (FileInfo file in newGridBitmapDirectory.GetFiles())
            {
                file.Delete();
            }
        }
Exemple #9
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            VPApplication.ApplicationName = "MiqoCrafter";

            //Clean cache

            string logName = Path.Combine(Service_Misc.GetExecutionPath(), "GeneralDataBase.log");

            if (File.Exists(logName))
            {
                try
                {
                    File.Delete(logName);
                }
                catch
                {
                }
            }

            Application.Run(new MainForm());
        }
        public void TestCacheGrids()
        {
            DirectoryInfo cacheGridDirectory = new DirectoryInfo(Path.Combine(Service_Misc.GetExecutionPath(), "CacheGrid"));

            if (!cacheGridDirectory.Exists)
            {
                throw new Exception("Cache grid directory does not exist !");
            }

            foreach (FileInfo file in cacheGridDirectory.GetFiles())
            {
                string gridText = File.ReadAllText(file.FullName);

                if (gridText.IndexOf("grid.") != 0)
                {
                    throw new Exception("Grid text file does not start with grid. : " + file.FullName);
                }

                string gridHeader = gridText.Split('{')[0];

                string gridContent = gridText.Replace(gridHeader, "").Trim();

                string gridDescription = file.Name;

                try
                {
                    JToken gridMainToken = JObject.Parse(gridContent);

                    gridDescription = gridMainToken["description"].Value <string>();

                    string gridTeleportDescription = gridDescription.Split('[')[1].Split(']')[0];
                    if (!gridTeleportDescription.Contains("@"))
                    {
                        throw new Exception("Grid description " + gridDescription + " doesn not include teleport name : " + file.FullName);
                    }

                    string gridArea      = gridTeleportDescription.Split('@')[0].Trim();
                    string gridAetheryte = gridTeleportDescription.Split('@')[1].Trim();

                    List <string> listAreas     = new List <string>();
                    List <string> listTeleports = new List <string>();

                    //La Noscea
                    listAreas.Add("Limsa Lominsa Lower Decks"); listTeleports.Add("Limsa Lominsa Lower Decks");
                    listAreas.Add("Middle La Noscea"); listTeleports.Add("Summerford Farms");
                    listAreas.Add("Lower La Noscea"); listTeleports.Add("Moraby Drydocks");
                    listAreas.Add("Eastern La Noscea"); listTeleports.Add("Costa del Sol");
                    listAreas.Add("Eastern La Noscea"); listTeleports.Add("Wineport");
                    listAreas.Add("Western La Noscea"); listTeleports.Add("Swiftperch");
                    listAreas.Add("Western La Noscea"); listTeleports.Add("Aleport");
                    listAreas.Add("Upper La Noscea"); listTeleports.Add("Camp Bronze Lake");
                    listAreas.Add("Outer La Noscea"); listTeleports.Add("Camp Overlook");
                    listAreas.Add("Wolves' Den Pier"); listTeleports.Add("Wolves' Den Pier");

                    //The Black Shroud
                    listAreas.Add("New Gridania"); listTeleports.Add("New Gridania");
                    listAreas.Add("Central Shroud"); listTeleports.Add("Bentbranch Meadows");
                    listAreas.Add("East Shroud"); listTeleports.Add("The Hawthorne Hut");
                    listAreas.Add("South Shroud"); listTeleports.Add("Quarrymill");
                    listAreas.Add("South Shroud"); listTeleports.Add("Camp Tranquil");
                    listAreas.Add("North Shroud"); listTeleports.Add("Fallgourd Float");

                    //Thanalan
                    listAreas.Add("Ul'dah - Steps of Nald"); listTeleports.Add("Ul'dah - Steps of Nald");
                    listAreas.Add("Western Thanalan"); listTeleports.Add("Horizon");
                    listAreas.Add("Central Thanalan"); listTeleports.Add("Black Brush Station");
                    listAreas.Add("Eastern Thanalan"); listTeleports.Add("Camp Drybone");
                    listAreas.Add("Southern Thanalan"); listTeleports.Add("Little Ala Mhigo");
                    listAreas.Add("Southern Thanalan"); listTeleports.Add("Forgotten Springs");
                    listAreas.Add("Northern Thanalan"); listTeleports.Add("Camp Bluefog");
                    listAreas.Add("Northern Thanalan"); listTeleports.Add("Ceruleum Processing Plant");
                    listAreas.Add("The Gold Saucer"); listTeleports.Add("The Gold Saucer");

                    //Coerthas
                    listAreas.Add("Foundation"); listTeleports.Add("Foundation");
                    listAreas.Add("Coerthas Central Highlands"); listTeleports.Add("Camp Dragonhead");
                    listAreas.Add("Coerthas Western Highlands"); listTeleports.Add("Falcon's Nest");

                    //Abalathia'sSpine
                    listAreas.Add("The Sea of Clouds"); listTeleports.Add("Camp Cloudtop");
                    listAreas.Add("The Sea of Clouds"); listTeleports.Add("Ok' Zundu");
                    listAreas.Add("Azys Lla"); listTeleports.Add("Helix");

                    //Dravania
                    listAreas.Add("Idyllshire"); listTeleports.Add("Idyllshire");
                    listAreas.Add("The Dravanian Forelands"); listTeleports.Add("Tailfeather");
                    listAreas.Add("The Dravanian Forelands"); listTeleports.Add("Anyx Trine");
                    listAreas.Add("The Churning Mists"); listTeleports.Add("Moghome");
                    listAreas.Add("The Churning Mists"); listTeleports.Add("Zenith");

                    //Gyr Abania
                    listAreas.Add("Rhalgr's Reach"); listTeleports.Add("Rhalgr's Reach");
                    listAreas.Add("The Fringes"); listTeleports.Add("Castrum Oriens");
                    listAreas.Add("The Fringes"); listTeleports.Add("The Peering Stones");
                    listAreas.Add("The Peaks"); listTeleports.Add("Ala Gannha");
                    listAreas.Add("The Peaks"); listTeleports.Add("Ala Ghiri");
                    listAreas.Add("The Lochs"); listTeleports.Add("Porta Praetoria");
                    listAreas.Add("The Lochs"); listTeleports.Add("The Ala Mhigan Quarter");

                    //Hingashi
                    listAreas.Add("Kugane"); listTeleports.Add("Kugane");

                    //Othard
                    listAreas.Add("The Ruby Sea"); listTeleports.Add("Tamamizu");
                    listAreas.Add("The Ruby Sea"); listTeleports.Add("Onokoro");
                    listAreas.Add("Yanxia"); listTeleports.Add("Namai");
                    listAreas.Add("Yanxia"); listTeleports.Add("The House of the Fierce");
                    listAreas.Add("The Azim Steppe"); listTeleports.Add("Reunion");
                    listAreas.Add("The Azim Steppe"); listTeleports.Add("The Dawn Throne");
                    listAreas.Add("The Azim Steppe"); listTeleports.Add("Dhoro Iloh");
                    listAreas.Add("The Doman Enclave"); listTeleports.Add("The Doman Enclave");

                    //Ilsabard
                    listAreas.Add("Radz-at-Han"); listTeleports.Add("Radz-at-Han");
                    listAreas.Add("Thavnair"); listTeleports.Add("Yedlihmad");
                    listAreas.Add("Thavnair"); listTeleports.Add("The Great Work");
                    listAreas.Add("Thavnair"); listTeleports.Add("Palaka's Stand");
                    listAreas.Add("Garlemald"); listTeleports.Add("Camp Broken Glass");
                    listAreas.Add("Garlemald"); listTeleports.Add("Tertium");

                    //Norvrandt
                    listAreas.Add("The Crystarium"); listTeleports.Add("The Crystarium");
                    listAreas.Add("Eulmore"); listTeleports.Add("Eulmore");
                    listAreas.Add("Lakeland"); listTeleports.Add("Fort Jobb");
                    listAreas.Add("Lakeland"); listTeleports.Add("The Ostall Imperative");
                    listAreas.Add("Kholusia"); listTeleports.Add("Stilltide");
                    listAreas.Add("Kholusia"); listTeleports.Add("Wright");
                    listAreas.Add("Kholusia"); listTeleports.Add("Tomra");
                    listAreas.Add("Amh Araeng"); listTeleports.Add("Mord Souq");
                    listAreas.Add("Amh Araeng"); listTeleports.Add("The Inn at Journey's Head");
                    listAreas.Add("Amh Araeng"); listTeleports.Add("Twine");
                    listAreas.Add("Il Mheg"); listTeleports.Add("Lydha Lran");
                    listAreas.Add("Il Mheg"); listTeleports.Add("Pla Enni");
                    listAreas.Add("Il Mheg"); listTeleports.Add("Wolekdorf");
                    listAreas.Add("The Rak'tika Greatwood"); listTeleports.Add("Slitherbough");
                    listAreas.Add("The Rak'tika Greatwood"); listTeleports.Add("Fanow");
                    listAreas.Add("The Tempest"); listTeleports.Add("The Ondo Cups");
                    listAreas.Add("The Tempest"); listTeleports.Add("The Macarenses Angle");

                    //Mor Dhona
                    listAreas.Add("Mor Dhona"); listTeleports.Add("Revenant's Toll");

                    //The Northern Empty
                    listAreas.Add("Old Sharlayan"); listTeleports.Add("Old Sharlayan");
                    listAreas.Add("Labyrinthos"); listTeleports.Add("The Archeion");
                    listAreas.Add("Labyrinthos"); listTeleports.Add("Sharlayan Hamlet");
                    listAreas.Add("Labyrinthos"); listTeleports.Add("Aporia");

                    //The Sea of Stars
                    listAreas.Add("Mare Lamentorum"); listTeleports.Add("Sinus Lacrimarum");
                    listAreas.Add("Mare Lamentorum"); listTeleports.Add("Bestways Burrow");
                    listAreas.Add("Ultima Thule"); listTeleports.Add("Reah Tahra");
                    listAreas.Add("Ultima Thule"); listTeleports.Add("Abode of the Ea");
                    listAreas.Add("Ultima Thule"); listTeleports.Add("Base Omicron");

                    //The World Unsundered
                    listAreas.Add("Elpis"); listTeleports.Add("Anagnorisis");
                    listAreas.Add("Elpis"); listTeleports.Add("The Twelve Wonders");
                    listAreas.Add("Elpis"); listTeleports.Add("Poieten Oikos");

                    int indexTeleport = listTeleports.IndexOf(gridAetheryte);
                    if (indexTeleport < 0)
                    {
                        throw new Exception("Aetheryte unknown : " + gridAetheryte + ": " + file.FullName);
                    }

                    if (listAreas[indexTeleport].ToLower().Replace("the ", "").Trim() != gridArea.ToLower().Trim() &&
                        listAreas[indexTeleport] != gridArea &&
                        listAreas[indexTeleport].ToLower().Trim() != gridArea.ToLower().Trim())
                    {
                        throw new Exception("Incorrect Area : \"" + gridArea + "\" Expected : \"" + listAreas[indexTeleport] + "\" - File : " + file.FullName);
                    }
                }
                catch (Exception exc)
                {
                    throw new Exception("Grid description " + gridDescription + " has generated a CD : " + file.FullName + Environment.NewLine + exc.Message);
                }
            }
        }
        private void UpdateGridBDDThread()
        {
            List <string> _gatherableItemNames = new List <string>();
            List <string> _gridOKItemNames     = new List <string>();

            Service_Misc.LogText(_logTextBox, "Updating database...");

            MiqoCraftCore.MiqoCraftCore.DownloadGrids();

            try
            {
                List <MiqoItemPage> result            = new List <MiqoItemPage>();
                CookieCollection    logMiqobotCookies = Miqobot.LogInForum();

                CookieCollection             oCookies = new CookieCollection();
                HttpStatusCode               oCode    = HttpStatusCode.NotFound;
                HtmlAgilityPack.HtmlDocument answer   = Service_Misc.GetWebPageFromRequest("GET https://miqobot.com/forum/forums/topic/index-gathering-grids/ HTTP/1.1|Host: miqobot.com|Connection: keep-alive|Cache-Control: max-age=0|Upgrade-Insecure-Requests: 1|User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36|Sec-Fetch-Mode: navigate|Sec-Fetch-User: ?1|Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3|Sec-Fetch-Site: same-origin|Referer: https://miqobot.com/forum/forums/forum/grids-and-presets/|Accept-Encoding: gzip, deflate, br|Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7|Cookie: wordpress_test_cookie=WP+Cookie+check; _ga=GA1.2.1771485810.1566089776||",
                                                                                           logMiqobotCookies, ref oCookies, ref oCode);
                if (null == answer)
                {
                    Service_Misc.LogText(_logTextBox, "Failed to update database. No answer from miqobot forum.");
                    return;
                }

                HtmlAgilityPack.HtmlNode firstAnswerNode = Service_Misc.GetFirstChildNode(answer.DocumentNode, "div", "topic-tag-gathering");

                List <HtmlAgilityPack.HtmlNode> listItemNodes = firstAnswerNode.Descendants("li").ToList();

                DirectoryInfo exeDirectory   = new DirectoryInfo(Service_Misc.GetExecutionPath());
                DirectoryInfo cacheDirectory = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "CacheGrid"));
                if (!cacheDirectory.Exists)
                {
                    Service_Misc.LogText(_logTextBox, "Failed to compute database status, CacheGrid directory does not exist.");
                    return;
                }

                foreach (HtmlAgilityPack.HtmlNode node in listItemNodes)
                {
                    if (null == node)
                    {
                        continue;
                    }

                    string nodeInnerTextLower = node.InnerText.ToLower();
                    if (nodeInnerTextLower.Contains("Mining Your Own Business".ToLower()))
                    {
                        break;
                    }
                    if (nodeInnerTextLower.Contains("lv."))
                    {
                        //Found node !
                        string level    = nodeInnerTextLower.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                        string itemName = nodeInnerTextLower.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries)[1].Trim().Replace("(hidden)", "").Trim();

                        _gatherableItemNames.Add(itemName);
                        if (File.Exists(Path.Combine(cacheDirectory.FullName, itemName + " Grid.txt")))
                        {
                            _gridOKItemNames.Add(itemName);
                        }
                    }
                }

                lock (_locker)
                {
                    MiqoCraftOptions options = new MiqoCraftOptions();
                    options.Load(OptionLocation.GlobalOption);
                    options.ListGatherableItems = _gatherableItemNames;
                    options.ListGridOKItems     = _gridOKItemNames;
                    options.Save();
                }

                UpdateBDDStatusFromOptions();

                {
                    Service_Misc.LogText(_logTextBox, "Database updated !");
                    return;
                }
            }
            catch
            {
                Service_Misc.LogText(_logTextBox, "Failed to compute database status, CacheGrid directory does not exist.");
                return;
            }
        }
Exemple #12
0
        public void TestFullScenarioImpl(string iItemName, FFXIVItem.TypeItem iExpectedType, int iNbExpectedItems = 1, int iPosItemInList = 0, string iRealName = "", bool iIgnoreCatalyst = false, int iQuantity = 1, bool iCollectable = false, int iNbPerSlot = 1, string iCustomTeleport = "")
        {
            InitTestEnvironment();

            string elemToSearch          = iItemName;
            int    nbExpectedSearchItems = iNbExpectedItems;
            int    nbItemInList          = iPosItemInList;
            string itemFullName          = iRealName;

            if (itemFullName.Length <= 0)
            {
                itemFullName = iItemName;
            }
            FFXIVItem.TypeItem expectedType = iExpectedType;

            List <FFXIVSearchItem> listResults = GarlandTool.Search(elemToSearch, null);

            if (listResults.Count != nbExpectedSearchItems)
            {
                throw new Exception("Erreur de recherche de " + elemToSearch + ": " + listResults.Count + " items found while " + nbExpectedSearchItems + " expected.");
            }

            FFXIVItem item = listResults[nbItemInList];

            if (item.Name != itemFullName)
            {
                throw new Exception("Item name is not the expected one: " + item.Name + ", expected : " + itemFullName);
            }

            FFXIVItem itemToCraft = GarlandTool.RecBuildCraftingTree(null, item.ID);

            if (itemToCraft.Type != expectedType)
            {
                throw new Exception("Item type is not the expected one: " + itemToCraft.Type + ", expected : " + expectedType);
            }

            string        solution_dir = Service_Misc.GetExecutionPath();
            DirectoryInfo refDirectory = new DirectoryInfo(Path.Combine(solution_dir, "References"));

            if (!refDirectory.Exists)
            {
                throw new Exception("Reference directory " + refDirectory.FullName + " does not exist");
            }

            MiqoCraftCore.MiqoCraftCore.MiqobotScenarioOption options = new MiqoCraftCore.MiqoCraftCore.MiqobotScenarioOption();
            options.GatheringRotation = "HQ +10%";
            options.CraftPreset       = "recommended";
            options.NQHQPreset        = "balanced";
            options.CustomTeleport    = iCustomTeleport;
            options.Quantity          = iQuantity;
            options.NbPerNode         = iNbPerSlot;
            options.Collectable       = iCollectable;
            options.IgnoreCatalysts   = iIgnoreCatalyst;

            string fullScenario = "";
            string res          = MiqoCraftCore.MiqoCraftCore.GenerateScenario(itemToCraft, options, null, out fullScenario);

            FileInfo refFile = new FileInfo(Path.Combine(refDirectory.FullName, itemFullName + _dumpSuffix + ".txt"));

            string pathResult = refFile.FullName.Replace(".txt", "_runresult.txt");

            File.WriteAllText(pathResult, res);
            if (_updateDumps)
            {
                File.WriteAllText(refFile.FullName, res);
            }
            string fullScenarioResult = File.ReadAllText(pathResult);

            FileInfo refScenarioFile = new FileInfo(Path.Combine(refDirectory.FullName, itemFullName + _dumpSuffix + " Scenario.txt"));

            pathResult = refScenarioFile.FullName.Replace(".txt", "_runresult.txt");
            File.WriteAllText(pathResult, fullScenario);
            if (_updateDumps)
            {
                File.WriteAllText(refScenarioFile.FullName, fullScenario);
            }

            if (!refFile.Exists)
            {
                throw new Exception("Reference file " + refFile.FullName + " does not exist");
            }
            string fullScenarioReference = File.ReadAllText(refFile.FullName);

            //Testing miqobot scenario
            if (fullScenarioResult.Trim() != fullScenarioReference.Trim())
            {
                throw new Exception("Resulting scenario does not match.; See " + refFile.FullName);
            }

            //Testing plain text scenario
            fullScenarioResult = File.ReadAllText(pathResult);

            if (!refScenarioFile.Exists)
            {
                throw new Exception("Reference file " + refScenarioFile.FullName + " does not exist");
            }
            string fullScenarioTextReference = File.ReadAllText(refScenarioFile.FullName);

            if (fullScenarioResult.Trim() != fullScenarioTextReference.Trim())
            {
                throw new Exception("Resulting scenario text does not match.; See " + refScenarioFile.FullName);
            }
        }
        private void AnalyzeGridThread()
        {
            VPThreading.ClearItems(_gridListView);

            DirectoryInfo exeDirectory     = new DirectoryInfo(Service_Misc.GetExecutionPath());
            DirectoryInfo cacheDirectory   = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "CacheGrid"));
            DirectoryInfo analyzeDirectory = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "DownloadedGrids"));

            if (!analyzeDirectory.Exists)
            {
                DownloadMissingItemGrids();
            }
            if (!analyzeDirectory.Exists)
            {
                return;
            }
            Dictionary <string, double> dictionaryClosestAetherytes = new Dictionary <string, double>();

            FileInfo[] files = analyzeDirectory.GetFiles();
            int        index = 0;

            foreach (FileInfo file in files)
            {
                index++;
                double percentage = (double)index / (double)files.Count() * 100.0;

                VPThreading.SetText(_progressLabel, "Analyzing Grids..." + percentage + "%");
                if (null == file)
                {
                    continue;
                }
                try
                {
                    string itemName = file.Name.Split(new string[] { " Grid---" }, StringSplitOptions.None)[0];

                    //Looking into cache directory
                    string   gridItemName  = itemName + " Grid";
                    FileInfo cacheGridFile = new FileInfo(Path.Combine(cacheDirectory.FullName, gridItemName + ".txt"));
                    if (cacheGridFile.Exists)
                    {
                        VPThreading.SetText(_progressLabel, "Item already has a grid.");
                        continue;
                    }

                    FFXIVItemGridF gridF = new FFXIVItemGridF();
                    gridF.ItemName = itemName;
                    gridF.GridFile = new FileInfo(file.FullName);
                    gridF.Analyze(ListAetherytes, ListGatheringNodes, ref dictionaryClosestAetherytes);
                    ListGridF.Add(gridF);

                    if (gridF.IsValid)
                    {
                        gridF.SaveAsGrids();
                    }

                    ListViewItem item = new ListViewItem();
                    item.Text = file.Name;
                    item.SubItems.Add(gridF.Status);
                    item.Tag = gridF;
                    VPThreading.AddItem(_gridListView, item);
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc.Message);
                }
            }
        }
        private void DownloadFromURL(string iURL, string iItemName = "", CookieCollection iCookies = null)
        {
            VPThreading.SetText(_progressLabel, "Downloading grid from given URL...");
            if (null == iCookies)
            {
                iCookies = Miqobot.LogInForum();
            }
            List <string>      listGridRawContent = Miqobot.GetAllGridsRawContentFromForum(iURL, iCookies);
            List <MiqobotGrid> listGrids          = new List <MiqobotGrid>();

            MiqoGridFinderOptions options = new MiqoGridFinderOptions();

            options.Load(VPL.Application.Data.OptionLocation.GlobalOption);
            List <FFXIVSearchItem> listAllGatheredItems = options.ListAllGatheredItems;

            if (listAllGatheredItems.Count <= 0)
            {
                VPThreading.SetText(_progressLabel, "Downloading all item names...");
                listAllGatheredItems = GarlandTool.Search("", null, FFXIVItem.TypeItem.Gathered);
            }
            options.ListAllGatheredItems = listAllGatheredItems;
            options.Save();


            VPThreading.SetText(_progressLabel, "Reading grids...");
            foreach (string rawContent in listGridRawContent)
            {
                listGrids.AddRange(Miqobot.GetAllGridsFromContent(rawContent));
            }

            DirectoryInfo exeDirectory     = new DirectoryInfo(Service_Misc.GetExecutionPath());
            DirectoryInfo cacheDirectory   = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "CacheGrid"));
            DirectoryInfo analyzeDirectory = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "DownloadedGrids"));

            if (!analyzeDirectory.Exists)
            {
                analyzeDirectory.Create();
            }
            if (!cacheDirectory.Exists)
            {
                VPThreading.SetText(_progressLabel, "Failed to compute database status, CacheGrid directory does not exist.");
                return;
            }

            VPThreading.SetText(_progressLabel, "Matching grid to item list...");
            int gridIndex = 1;

            foreach (MiqobotGrid grid in listGrids)
            {
                List <string> listCorrespondingItemNames = new List <string>();
                foreach (FFXIVSearchItem item in listAllGatheredItems)
                {
                    if (null == grid.Description)
                    {
                        continue;
                    }
                    if (grid.Description.ToLower().Contains(item.Name.ToLower()))
                    {
                        listCorrespondingItemNames.Add(item.Name);
                    }
                    if (grid.Header.ToLower().Contains(item.Name.ToLower()))
                    {
                        listCorrespondingItemNames.Add(item.Name);
                    }
                }

                if (listCorrespondingItemNames.Count <= 0 && iItemName != "")
                {
                    listCorrespondingItemNames.Add(iItemName);
                }
                List <string> listFilteredCorrespondingItemNames = new List <string>();
                foreach (string itemName in listCorrespondingItemNames)
                {
                    bool hasBigger = false;
                    foreach (string itemName2 in listCorrespondingItemNames)
                    {
                        if (itemName2 != itemName && itemName2.Contains(itemName))
                        {
                            hasBigger = true;
                            break;
                        }
                    }
                    if (!hasBigger)
                    {
                        listFilteredCorrespondingItemNames.Add(itemName);
                    }
                }
                foreach (string itemName in listFilteredCorrespondingItemNames)
                {
                    //Check if grid exist
                    string gridItemName = itemName + " Grid";

                    //Looking into cache directory
                    FileInfo cacheGridFile = new FileInfo(Path.Combine(cacheDirectory.FullName, gridItemName + ".txt"));
                    if (cacheGridFile.Exists)
                    {
                        continue;
                    }

                    //Saving grid
                    string pathGrid = Path.Combine(analyzeDirectory.FullName, gridItemName + "---" + gridIndex + ".txt");
                    if (File.Exists(pathGrid))
                    {
                        File.Delete(pathGrid);
                    }

                    File.WriteAllText(pathGrid, "grid." + grid.Header + Environment.NewLine + grid.Content);
                    gridIndex++;
                }
            }
        }
        private void DownloadMissingItemGrids()
        {
            List <MiqoItemPage> result            = new List <MiqoItemPage>();
            CookieCollection    logMiqobotCookies = Miqobot.LogInForum();

            CookieCollection oCookies = new CookieCollection();
            HttpStatusCode   oCode    = HttpStatusCode.NotFound;

            HtmlAgilityPack.HtmlDocument answer = Service_Misc.GetWebPageFromRequest("GET https://miqobot.com/forum/forums/topic/index-gathering-grids/ HTTP/1.1|Host: miqobot.com|Connection: keep-alive|Cache-Control: max-age=0|Upgrade-Insecure-Requests: 1|User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36|Sec-Fetch-Mode: navigate|Sec-Fetch-User: ?1|Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3|Sec-Fetch-Site: same-origin|Referer: https://miqobot.com/forum/forums/forum/grids-and-presets/|Accept-Encoding: gzip, deflate, br|Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7|Cookie: wordpress_test_cookie=WP+Cookie+check; _ga=GA1.2.1771485810.1566089776||",
                                                                                     logMiqobotCookies, ref oCookies, ref oCode);
            if (null == answer)
            {
                VPThreading.SetText(_progressLabel, "Failed to update database. No answer from miqobot forum.");
                return;
            }

            HtmlAgilityPack.HtmlNode firstAnswerNode = Service_Misc.GetFirstChildNode(answer.DocumentNode, "div", "topic-tag-gathering");

            List <HtmlAgilityPack.HtmlNode> listItemNodes = firstAnswerNode.Descendants("li").ToList();

            DirectoryInfo exeDirectory     = new DirectoryInfo(Service_Misc.GetExecutionPath());
            DirectoryInfo cacheDirectory   = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "CacheGrid"));
            DirectoryInfo analyzeDirectory = new DirectoryInfo(Path.Combine(exeDirectory.FullName, "DownloadedGrids"));

            if (!analyzeDirectory.Exists)
            {
                analyzeDirectory.Create();
            }
            if (!cacheDirectory.Exists)
            {
                VPThreading.SetText(_progressLabel, "Failed to compute database status, CacheGrid directory does not exist.");
                return;
            }
            int indexProg = 0;

            foreach (HtmlAgilityPack.HtmlNode node in listItemNodes)
            {
                indexProg++;

                VPThreading.SetProgress(_progressBar, indexProg * 100 / listItemNodes.Count);
                if (null == node)
                {
                    continue;
                }

                string nodeInnerTextLower = node.InnerText.ToLower();
                if (nodeInnerTextLower.Contains("Mining Your Own Business".ToLower()))
                {
                    break;
                }
                if (nodeInnerTextLower.Contains("lv."))
                {
                    //Found node !
                    string level    = nodeInnerTextLower.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                    string itemName = nodeInnerTextLower.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries)[1].Trim().Replace("(hidden)", "").Trim();

                    //Check if grid exist
                    string gridItemName = itemName + " Grid";

                    //Looking into cache directory
                    FileInfo cacheGridFile = new FileInfo(Path.Combine(cacheDirectory.FullName, gridItemName + ".txt"));
                    if (cacheGridFile.Exists)
                    {
                        VPThreading.SetText(_progressLabel, "Item already has a grid.");
                        continue;
                    }
                    VPThreading.SetText(_progressLabel, "Trying to find a new grid : " + itemName);

                    //Looking for all links
                    List <MiqoItemPage> listLinks = Miqobot.GetURLItem(itemName, logMiqobotCookies, answer);
                    foreach (MiqoItemPage page in listLinks)
                    {
                        //List<string> ListGrids = Miqobot.GetAllGridsFromForum(itemName, logMiqobotCookies, page);
                        //if (null == ListGrids) continue;

                        //foreach(string grid in ListGrids)
                        //{
                        //    try
                        //    {
                        //        string pathGrid = Path.Combine(analyzeDirectory.FullName, gridItemName + "---" + gridIndex + ".txt");
                        //        if (File.Exists(pathGrid)) File.Delete(pathGrid);

                        //        File.WriteAllText(pathGrid, grid);
                        //        gridIndex++;
                        //    }
                        //    catch
                        //    {

                        //    }
                        //}
                        DownloadFromURL(page.URL, itemName, logMiqobotCookies);
                    }
                }
            }
            VPThreading.SetProgress(_progressBar, 100);
            VPThreading.SetText(_progressLabel, "Done!");
        }