private static int ScanMora()
        {
            var region = new Rectangle(
                x: (int)(125 / 1280.0 * Navigation.GetWidth()),
                y: (int)(665 / 720.0 * Navigation.GetHeight()),
                width: (int)(300 / 1280.0 * Navigation.GetWidth()),
                height: (int)(30 / 720.0 * Navigation.GetHeight()));

            if (Navigation.GetAspectRatio() == new Size(8, 5))
            {
                region.Y = (int)(740 / 800.0 * Navigation.GetHeight());
            }

            using (var screenshot = Navigation.CaptureRegion(region))
            {
                string mora = ParseMoraFromScreenshot(screenshot);

                if (int.TryParse(mora, out int count))
                {
                    UserInterface.ResetCharacterDisplay();
                    UserInterface.SetMora(screenshot, count);
                }
                else
                {
                    UserInterface.SetNavigation_Image(screenshot);
                    UserInterface.AddError("Unable to parse mora count");
                    screenshot.Save("./logging/materials/mora.png");
                }
                return(count);
            }
        }
示例#2
0
 public static void UnexpectedError(string error)
 {
     if (scannerThread.IsAlive)
     {
         UserInterface.AddError(error);
     }
 }
示例#3
0
 public static void AssignTravelerName(string traveler)
 {
     if (!string.IsNullOrEmpty(traveler))
     {
         AddTravelerToCharacterList(traveler);
         Logger.Debug("Parsed traveler name {traveler}", traveler);
     }
     else
     {
         UserInterface.AddError("Could not parse Traveler's username");
     }
 }
        public static string ScanMainCharacterName()
        {
            var xReference = 1280.0;
            var yReference = 720.0;

            if (Navigation.GetAspectRatio() == new Size(8, 5))
            {
                yReference = 800.0;
            }

            RECT region = new RECT(
                Left:   (int)(185 / xReference * Navigation.GetWidth()),
                Top:    (int)(26 / yReference * Navigation.GetHeight()),
                Right:  (int)(460 / xReference * Navigation.GetWidth()),
                Bottom: (int)(60 / yReference * Navigation.GetHeight()));

            Bitmap nameBitmap = Navigation.CaptureRegion(region);

            //Image Operations
            Scraper.SetGamma(0.2, 0.2, 0.2, ref nameBitmap);
            Scraper.SetInvert(ref nameBitmap);
            Bitmap n = Scraper.ConvertToGrayscale(nameBitmap);

            UserInterface.SetNavigation_Image(nameBitmap);

            string text = Scraper.AnalyzeText(n).Trim();

            if (text != "")
            {
                // Only keep a-Z and 0-9
                text = Regex.Replace(text, @"[\W_]", string.Empty).ToLower();

                // Only keep text up until first space
                text = Regex.Replace(text, @"\s+\w*", string.Empty);

                UserInterface.SetMainCharacterName(text);
            }
            else
            {
                UserInterface.AddError(text);
            }
            n.Dispose();
            nameBitmap.Dispose();
            return(text);
        }
示例#5
0
        internal void WriteToJSON(string outputDirectory, string oldDataFilePath = "")
        {
            // Creates directory if doesn't exist
            Directory.CreateDirectory(outputDirectory);

            // Create file with timestamp in name
            string fileName = "\\genshinData_GOOD_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm") + ".json";

            fileName = fileName.Replace('/', '_');
            string outputFile = outputDirectory + fileName;

            // Write file
            WriteToJson(outputFile);


            if (!File.Exists(outputFile))             // did not make file
            {
                UserInterface.AddError($"Failed to output at : {outputDirectory}");
            }
        }
        private static int ScanExperience()
        {
            int experience = 0;

            int      xOffset          = 1117;
            int      yOffset          = 151;
            Bitmap   bm               = new Bitmap(90, 10);
            Graphics g                = Graphics.FromImage(bm);
            int      screenLocation_X = Navigation.GetPosition().Left + xOffset;
            int      screenLocation_Y = Navigation.GetPosition().Top + yOffset;

            g.CopyFromScreen(screenLocation_X, screenLocation_Y, 0, 0, bm.Size);

            //Image Operations
            bm = Scraper.ResizeImage(bm, bm.Width * 6, bm.Height * 6);
            //Scraper.ConvertToGrayscale(ref bm);
            //Scraper.SetInvert(ref bm);
            Scraper.SetContrast(30.0, ref bm);

            string text = Scraper.AnalyzeText(bm);

            text = text.Trim();
            text = Regex.Replace(text, @"(?![0-9\s/]).", string.Empty);

            if (Regex.IsMatch(text, "/"))
            {
                string[] temp = text.Split('/');
                experience = Convert.ToInt32(temp[0]);
            }
            else
            {
                Debug.Print("Error: Found " + experience + " instead of experience");
                UserInterface.AddError("Found " + experience + " instead of experience");
            }

            return(experience);
        }
        public void GatherData()
        {
            // Initize Image Processors
            for (int i = 0; i < maxProcessors; i++)
            {
                Thread processor = new Thread(ImageProcessorWorker)
                {
                    IsBackground = true
                };
                processor.Start();
                ImageProcessors.Add(processor);
            }
            Logger.Debug("Added {ImageProcessors.Count} workers", ImageProcessors.Count);

            Scraper.RestartEngines();

            // Scan Main character Name
            string mainCharacterName = CharacterScraper.ScanMainCharacterName();

            Scraper.AssignTravelerName(mainCharacterName);

            if (Properties.Settings.Default.ScanWeapons)
            {
                Logger.Info("Scanning weapons...");
                // Get Weapons
                Navigation.InventoryScreen();
                Navigation.SelectWeaponInventory();
                try
                {
                    WeaponScraper.ScanWeapons();
                }
                catch (FormatException ex) { UserInterface.AddError(ex.Message); }
                catch (ThreadAbortException) { }
                catch (Exception ex)
                {
                    UserInterface.AddError(ex.Message + "\n" + ex.StackTrace);
                }
                Navigation.MainMenuScreen();
                Logger.Info("Done scanning weapons");
            }

            if (Properties.Settings.Default.ScanArtifacts)
            {
                Logger.Info("Scanning artifacts...");

                // Get Artifacts
                Navigation.InventoryScreen();
                Navigation.SelectArtifactInventory();
                try
                {
                    ArtifactScraper.ScanArtifacts();
                }
                catch (FormatException ex) { UserInterface.AddError(ex.Message); }
                catch (ThreadAbortException) { }
                catch (Exception ex)
                {
                    UserInterface.AddError(ex.Message + "\n" + ex.StackTrace);
                }
                Navigation.MainMenuScreen();
                Logger.Info("Done scanning artifacts");
            }

            workerQueue.Enqueue(new OCRImageCollection(null, "END", 0));

            if (Properties.Settings.Default.ScanCharacters)
            {
                Logger.Info("Scanning characters...");
                // Get characters
                Navigation.CharacterScreen();
                var c = new List <Character>();
                try
                {
                    CharacterScraper.ScanCharacters(ref c);
                }
                catch (ThreadAbortException) { }
                catch (Exception ex)
                {
                    UserInterface.AddError(ex.Message + "\n" + ex.StackTrace);
                }
                Characters = c;
                Navigation.MainMenuScreen();
                Logger.Info("Done scanning characters");
            }

            // Wait for Image Processors to finish
            AwaitProcessors();

            if (Properties.Settings.Default.ScanCharacters)
            {
                // Assign Artifacts to Characters
                if (Properties.Settings.Default.ScanArtifacts)
                {
                    AssignArtifacts();
                }
                if (Properties.Settings.Default.ScanWeapons)
                {
                    AssignWeapons();
                }
            }

            // Scan Character Development Items
            if (Properties.Settings.Default.ScanCharDevItems)
            {
                Logger.Info("Scanning character development materials...");
                // Get Materials
                Navigation.InventoryScreen();
                Navigation.SelectCharacterDevelopmentInventory();
                HashSet <Material> devItems = new HashSet <Material>();
                try
                {
                    MaterialScraper.Scan_Materials(InventorySection.CharacterDevelopmentItems, ref Materials);
                }
                catch (FormatException ex) { UserInterface.AddError(ex.Message); }
                catch (ThreadAbortException) { }
                catch (Exception ex)
                {
                    UserInterface.AddError(ex.Message + "\n" + ex.StackTrace);
                }
                Navigation.MainMenuScreen();
                Logger.Info("Done scanning character development materials");
            }

            // Scan Materials
            if (Properties.Settings.Default.ScanMaterials)
            {
                Logger.Info("Scanning materials...");
                // Get Materials
                Navigation.InventoryScreen();
                Navigation.SelectMaterialInventory();
                HashSet <Material> materials = new HashSet <Material>();
                try
                {
                    MaterialScraper.Scan_Materials(InventorySection.Materials, ref Materials);
                }
                catch (FormatException ex) { UserInterface.AddError(ex.Message); }
                catch (ThreadAbortException) { }
                catch (Exception ex)
                {
                    UserInterface.AddError(ex.Message + "\n" + ex.StackTrace);
                }
                Navigation.MainMenuScreen();
                Logger.Info("Done scanning materials");
            }

            Inventory.AddMaterials(ref Materials);
        }
        public void ImageProcessorWorker()
        {
            Logger.Debug("Thread #{0} priority: {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Priority);
            while (true)
            {
                if (b_threadCancel)
                {
                    workerQueue.Clear();
                    break;
                }

                if (workerQueue.TryDequeue(out OCRImageCollection imageCollection))
                {
                    switch (imageCollection.Type)
                    {
                    case "weapon":
                        if (WeaponScraper.IsEnhancementMaterial(imageCollection.Bitmaps.First()))
                        {
                            Logger.Debug("Enhancement Material found for weapon #{weaponID}", imageCollection.Id);
                            WeaponScraper.StopScanning = true;
                            break;
                        }

                        UserInterface.SetGearPictureBox(imageCollection.Bitmaps.Last());

                        // Scan as weapon
                        Weapon weapon = WeaponScraper.CatalogueFromBitmapsAsync(imageCollection.Bitmaps, imageCollection.Id).Result;
                        UserInterface.SetGear(imageCollection.Bitmaps.Last(), weapon);


                        if (weapon.IsValid())
                        {
                            if (weapon.Rarity >= (int)Properties.Settings.Default.MinimumWeaponRarity)
                            {
                                UserInterface.IncrementWeaponCount();
                                Inventory.Add(weapon);
                                if (!string.IsNullOrWhiteSpace(weapon.EquippedCharacter))
                                {
                                    equippedWeapons.Add(weapon);
                                }
                            }
                        }
                        else
                        {
                            string weaponPath = $"./logging/weapons/weapon{weapon.Id}/";
                            Directory.CreateDirectory(weaponPath);
                            UserInterface.AddError($"Unable to validate information for weapon ID#{weapon.Id}");
                            string error = "";
                            if (!weapon.HasValidWeaponName())
                            {
                                try
                                {
                                    error += "Invalid weapon name\n";
                                    Directory.CreateDirectory(weaponPath + "name");
                                    imageCollection.Bitmaps[0].Save(weaponPath + "name/name.png");
                                }
                                catch { }
                            }
                            if (!weapon.HasValidRarity())
                            {
                                try
                                {
                                    error += "Invalid weapon rarity\n";
                                    Directory.CreateDirectory(weaponPath + "rarity");
                                    imageCollection.Bitmaps[0].Save(weaponPath + "rarity/rarity.png");
                                }
                                catch { }
                            }
                            if (!weapon.HasValidLevel())
                            {
                                try
                                {
                                    error += "Invalid weapon level\n";
                                    Directory.CreateDirectory(weaponPath + "level");
                                    imageCollection.Bitmaps[1].Save(weaponPath + "level/level.png");
                                } catch { }
                            }
                            if (!weapon.HasValidRefinementLevel())
                            {
                                try
                                {
                                    error += "Invalid refinement level\n";
                                    Directory.CreateDirectory(weaponPath + "refinement");
                                    imageCollection.Bitmaps[2].Save(weaponPath + "refinement/refinement.png");
                                } catch { }
                            }
                            if (!weapon.HasValidEquippedCharacter())
                            {
                                try
                                {
                                    error += "Inavlid equipped character\n";
                                    Directory.CreateDirectory(weaponPath + "equipped");
                                    imageCollection.Bitmaps[4].Save(weaponPath + "equipped/equipped.png");
                                }
                                catch { }
                            }
                            UserInterface.AddError(error + weapon.ToString());
                            imageCollection.Bitmaps.Last().Save(weaponPath + "card.png");
                            using (var writer = File.CreateText(weaponPath + "log.txt"))
                            {
                                writer.WriteLine($"Version: {Regex.Replace(Assembly.GetExecutingAssembly().GetName().Version.ToString(), @"[.0]*$", string.Empty)}");
                                writer.WriteLine($"Resolution: {Navigation.GetWidth()}x{Navigation.GetHeight()}");
                                writer.WriteLine("Settings:");
                                writer.WriteLine($"\tDelay: {Properties.Settings.Default.ScannerDelay}");
                                writer.WriteLine($"\tMinimum Rarity: {Properties.Settings.Default.MinimumArtifactRarity}");
                                writer.WriteLine($"Error log:\n\t{error.Replace("\n", "\n\t")}");
                            }
                        }

                        // Dispose of everything
                        imageCollection.Bitmaps.ForEach(b => b.Dispose());
                        break;

                    case "artifact":
                        if (ArtifactScraper.IsEnhancementMaterial(imageCollection.Bitmaps.Last()))
                        {
                            Logger.Debug("Enhancement Material found for artifact #{artifactID}", imageCollection.Id);
                            ArtifactScraper.StopScanning = true;
                            break;
                        }

                        UserInterface.SetGearPictureBox(imageCollection.Bitmaps.Last());
                        // Scan as artifact
                        Artifact artifact = ArtifactScraper.CatalogueFromBitmapsAsync(imageCollection.Bitmaps, imageCollection.Id).Result;
                        UserInterface.SetGear(imageCollection.Bitmaps.Last(), artifact);
                        if (artifact.IsValid())
                        {
                            if (artifact.Rarity >= (int)Properties.Settings.Default.MinimumArtifactRarity)
                            {
                                UserInterface.IncrementArtifactCount();
                                Inventory.Add(artifact);
                                if (!string.IsNullOrWhiteSpace(artifact.EquippedCharacter))
                                {
                                    equippedArtifacts.Add(artifact);
                                }
                            }
                        }
                        else
                        {
                            string artifactPath = $"./logging/artifacts/artifact{artifact.Id}/";

                            Directory.CreateDirectory(artifactPath);

                            UserInterface.AddError($"Unable to validate information for artifact ID#{artifact.Id}");
                            string error = "";
                            if (!artifact.HasValidSlot())
                            {
                                try
                                {
                                    error += "Invalid artifact gear slot\n";
                                    Directory.CreateDirectory(artifactPath + "slot");
                                    imageCollection.Bitmaps[1].Save(artifactPath + "slot/slot.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidSetName())
                            {
                                try
                                {
                                    error += "Invalid artifact set name\n";
                                    Directory.CreateDirectory(artifactPath + "set");
                                    imageCollection.Bitmaps[4].Save(artifactPath + "set/set.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidRarity())
                            {
                                try
                                {
                                    error += "Invalid artifact rarity\n";
                                    Directory.CreateDirectory(artifactPath + "rarity");
                                    imageCollection.Bitmaps[0].Save(artifactPath + "rarity/rarity.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidLevel())
                            {
                                try
                                {
                                    error += "Invalid artifact level\n";
                                    Directory.CreateDirectory(artifactPath + "level");
                                    imageCollection.Bitmaps[3].Save(artifactPath + "level/level.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidMainStat())
                            {
                                try
                                {
                                    error += "Invalid artifact main stat\n";
                                    Directory.CreateDirectory(artifactPath + "mainstat");
                                    imageCollection.Bitmaps[2].Save(artifactPath + "mainstat/mainstat.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidSubStats())
                            {
                                try
                                {
                                    error += "Invalid artifact sub stats\n";
                                    Directory.CreateDirectory(artifactPath + "substats");
                                    imageCollection.Bitmaps[4].Save(artifactPath + "substats/substats.png");
                                }
                                catch { }
                            }
                            if (!artifact.HasValidEquippedCharacter())
                            {
                                try
                                {
                                    error += "Invalid equipped character\n";
                                    Directory.CreateDirectory(artifactPath + "equipped");
                                    imageCollection.Bitmaps[5].Save(artifactPath + "equipped/equipped.png");
                                }
                                catch { }
                            }
                            UserInterface.AddError(error + artifact.ToString());

                            imageCollection.Bitmaps.Last().Save($"./logging/artifacts/artifact{artifact.Id}/card.png");
                            using (var writer = File.CreateText(artifactPath + "log.txt"))
                            {
                                writer.WriteLine($"Version: {Regex.Replace(Assembly.GetExecutingAssembly().GetName().Version.ToString(), @"[.0]*$", string.Empty)}");
                                writer.WriteLine($"Resolution: {Navigation.GetWidth()}x{Navigation.GetHeight()}");
                                writer.WriteLine("Settings:");
                                writer.WriteLine($"\tDelay: {Properties.Settings.Default.ScannerDelay}");
                                writer.WriteLine($"\tMinimum Rarity: {Properties.Settings.Default.MinimumArtifactRarity}");
                                writer.WriteLine($"Error Log:\n\t{error.Replace("\n", "\n\t")}");
                            }
                        }

                        // Dispose of everything
                        imageCollection.Bitmaps.ForEach(b => b.Dispose());
                        break;

                    case "END":
                        b_threadCancel = true;
                        break;

                    default:
                        MainForm.UnexpectedError("Unknown Image type for Image Processor");
                        break;
                    }
                }
                else
                {
                    // Wait for more images to process
                    Thread.Sleep(250);
                }
            }
            Logger.Debug("Thread {threadId} exit", Thread.CurrentThread.ManagedThreadId);
        }
        private static bool ScanCharacter(out Character character)
        {
            character = new Character();
            Navigation.SelectCharacterAttributes();
            string name    = null;
            string element = null;

            // Scan the Name and element of Character. Attempt 75 times max.
            ScanNameAndElement(ref name, ref element);

            if (string.IsNullOrWhiteSpace(name))
            {
                if (string.IsNullOrWhiteSpace(name))
                {
                    UserInterface.AddError("Could not determine character's name");
                }
                if (string.IsNullOrWhiteSpace(element))
                {
                    UserInterface.AddError("Could not determine character's element");
                }
                return(false);
            }

            // Check if character was first scanned
            if (name != firstCharacterName)
            {
                if (string.IsNullOrWhiteSpace(firstCharacterName))
                {
                    firstCharacterName = name;
                }

                bool ascended = false;
                // Scan Level and ascension
                int level = ScanLevel(ref ascended);
                if (level == -1)
                {
                    UserInterface.AddError($"Could not determine {name}'s level");
                    return(false);
                }

                // Scan Experience
                //experience = ScanExperience();
                Navigation.SystemRandomWait(Navigation.Speed.Normal);

                // Scan Constellation
                Navigation.SelectCharacterConstellation();
                int constellation = ScanConstellations();
                Navigation.SystemRandomWait(Navigation.Speed.Normal);

                // Scan Talents
                Navigation.SelectCharacterTalents();
                int[] talents = ScanTalents(name);
                Navigation.SystemRandomWait(Navigation.Speed.Normal);

                // Scale down talents due to constellations
                if (constellation >= 3)
                {
                    if (Scraper.Characters.ContainsKey(name.ToLower()))
                    {
                        // get talent if character
                        if (constellation >= 5)
                        {
                            talents[1] -= 3;
                            talents[2] -= 3;
                        }
                        else if ((string)Scraper.Characters[name.ToLower()]["ConstellationOrder"][0] == "skill")
                        {
                            talents[1] -= 3;
                        }
                        else
                        {
                            talents[2] -= 3;
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }

                var weaponType = Scraper.Characters[name.ToLower()]["WeaponType"].ToObject <int>();

                int experience = 0;
                character = new Character(name, element, level, ascended, experience, constellation, talents, (WeaponType)weaponType);
                return(true);
            }
            Logger.Info("Repeat character {0} detected. Finishing character scan...", name);
            return(false);
        }
示例#10
0
        private void StartButton_Clicked(object sender, EventArgs e)
        {
            GC.Collect();

            UserInterface.ResetAll();

            UserInterface.SetProgramStatus("Scanning");
            Logger.Info("Starting scan");

            if (Directory.Exists(OutputPath_TextBox.Text) || Directory.CreateDirectory(OutputPath_TextBox.Text).Exists)
            {
                if (running)
                {
                    Logger.Debug("Already running");
                    return;
                }
                running = true;

                HotkeyManager.Current.AddOrReplace("Stop", Keys.Enter, Hotkey_Pressed);
                Logger.Info("Hotkey registered");
                var settings = Properties.Settings.Default;
                var options  = $"\n\tWeapons:\t\t\t {settings.ScanWeapons}\n" +
                               $"\tArtifacts:\t\t\t {settings.ScanArtifacts}\n" +
                               $"\tCharacters:\t\t\t {settings.ScanCharacters}\n" +
                               $"\tDev Items:\t\t\t {settings.ScanCharDevItems}\n" +
                               $"\tMaterials:\t\t\t {settings.ScanMaterials}\n" +
                               $"\tMin Weapon Rarity:\t {settings.MinimumWeaponRarity}\n" +
                               $"\tMin Artifact Rarity: {settings.MinimumArtifactRarity}\n" +
                               $"\tDelay:\t\t\t\t {settings.ScannerDelay}";

                scannerThread = new Thread(() =>
                {
                    try
                    {
                        // Get Screen Location and Size
                        Navigation.Initialize();

                        List <Size> sizes = new List <Size>
                        {
                            new Size(16, 9),
                            new Size(8, 5),
                        };

                        if (!sizes.Contains(Navigation.GetAspectRatio()))
                        {
                            throw new NotImplementedException($"{Navigation.GetSize().Width}x{Navigation.GetSize().Height} is an unsupported resolution.");
                        }

                        if (Navigation.GetSize() != Navigation.CaptureWindow().Size)
                        {
                            throw new FormatException("Window size and screenshot size mismatch. Please make sure the game is not in a fullscreen mode.");
                        }

                        data = new InventoryKamera();

                        // Add navigation delay
                        Navigation.SetDelay(ScannerDelayValue(Delay));

                        Logger.Info("Scan settings: {0}", options);

                        // The Data object of json object
                        data.GatherData();

                        // Covert to GOOD
                        GOOD good = new GOOD(data);
                        Logger.Info("Data converted to GOOD");

                        // Make Json File
                        good.WriteToJSON(OutputPath_TextBox.Text);
                        Logger.Info("Exported data");

                        UserInterface.SetProgramStatus("Finished");
                    }
                    catch (ThreadAbortException)
                    {
                        // Workers can get stuck if the thread is aborted or an exception is raised
                        if (!(data is null))
                        {
                            data.StopImageProcessorWorkers();
                        }
                        UserInterface.SetProgramStatus("Scan stopped");
                    }
                    catch (NotImplementedException ex)
                    {
                        UserInterface.AddError(ex.Message);
                    }
                    catch (Exception ex)
                    {
                        // Workers can get stuck if the thread is aborted or an exception is raised
                        if (!(data is null))
                        {
                            data.StopImageProcessorWorkers();
                        }
                        UserInterface.AddError(ex.ToString());
                        UserInterface.SetProgramStatus("Scan aborted", ok: false);
                    }
                    finally
                    {
                        ResetUI();
                        running = false;
                        Logger.Info("Scanner stopped");
                    }
                })
                {
                    IsBackground = true
                };
                scannerThread.Start();
            }
            else
            {
                if (string.IsNullOrWhiteSpace(OutputPath_TextBox.Text))
                {
                    UserInterface.AddError("Please set an output directory");
                }
                else
                {
                    UserInterface.AddError($"{OutputPath_TextBox.Text} is not a valid directory");
                }
            }
        }
        public static void Scan_Materials(InventorySection section, ref HashSet <Material> materials)
        {
            if (!materials.Contains(new Material("Mora", 0)))
            {
                materials.Add(new Material("Mora", ScanMora()));
            }

            int scrollCount = 0;

            Material material         = new Material(null, 0);
            Material previousMaterial = new Material(null, -1);

            List <Rectangle> rectangles;
            int page = 0;

            // Keep scanning while not repeating any items names
            while (true)
            {
                int rows, cols;
                // Find all items on the screen
                (rectangles, cols, rows) = GetPageOfItems(section, page);

                // Remove last row. Sometimes the bottom of a page of items is caught which results
                // in a faded quantity that can't be parsed. Removing slightly increases the number of pages that
                // need to be scrolled but it's fine.
                var r = rectangles.Take(rectangles.Count() - cols).ToList();

                foreach (var rectangle in r)
                {
                    // Select Material
                    Navigation.SetCursorPos(Navigation.GetPosition().Left + rectangle.Center().X, Navigation.GetPosition().Top + rectangle.Center().Y);
                    Navigation.Click();
                    Navigation.SystemRandomWait(Navigation.Speed.SelectNextInventoryItem);

                    material.name  = ScanMaterialName(section, out Bitmap nameplate);
                    material.count = 0;

                    // Check if new material has been found
                    if (materials.Contains(material))
                    {
                        goto LastPage;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(material.name))
                        {
                            // Scan Material Number
                            material.count = ScanMaterialCount(rectangle, out Bitmap quantity);
                            if (material.count == 0)
                            {
                                UserInterface.AddError($"Failed to parse quantity for {material.name}");
                                quantity.Save($"./logging/materials/{material.name}_Quantity.png");
                            }
                            materials.Add(material);
                            UserInterface.ResetCharacterDisplay();
                            UserInterface.SetMaterial(nameplate, quantity, material.name, material.count);

                            previousMaterial.name = material.name;
                        }
                    }
                    nameplate.Dispose();
                    Navigation.Wait(150);
                }

                Navigation.SetCursorPos(Navigation.GetPosition().Left + r.Last().Center().X, Navigation.GetPosition().Top + r.Last().Center().Y);
                Navigation.Click();
                Navigation.Wait(150);
                // Scroll to next page
                for (int i = 0; i < rows - 1; i++)
                {
                    scrollCount++;

                    // scroll down
                    for (int k = 0; k < 10; k++)
                    {
                        Navigation.sim.Mouse.VerticalScroll(-1);
                        // skip a scroll
                        if ((k == 7) && ((scrollCount % 3) == 0))
                        {
                            k++;
                            if (scrollCount % 9 == 0)
                            {
                                if (scrollCount == 18)
                                {
                                    scrollCount = 0;
                                }
                                else
                                {
                                    Navigation.sim.Mouse.VerticalScroll(-1);
                                }
                            }
                        }
                        Navigation.SystemRandomWait(Navigation.Speed.InventoryScroll);
                    }
                }
                Navigation.SystemRandomWait(Navigation.Speed.Normal);
                ++page;
            }

LastPage:
            // scroll down as much as possible
            for (int i = 0; i < 20; i++)
            {
                Navigation.sim.Mouse.VerticalScroll(-1);
                Navigation.SystemRandomWait(Navigation.Speed.InventoryScroll);
            }

            Navigation.Wait(500);

            (rectangles, _, _) = GetPageOfItems(section, page);
            bool passby = true;

            for (int i = rectangles.Count - 1; i >= 0; i--)             // Click through but backwards to short-circuit after new materials
            {
                // Select Material
                Rectangle rectangle = rectangles[i];
                Navigation.SetCursorPos(Navigation.GetPosition().Left + rectangle.Center().X, Navigation.GetPosition().Top + rectangle.Center().Y);
                Navigation.Click();
                Navigation.SystemRandomWait(Navigation.Speed.SelectNextInventoryItem);

                material.name  = ScanMaterialName(section, out Bitmap nameplate);
                material.count = 0;

                if (materials.Contains(material) && passby)
                {
                    continue;
                }

                if (!materials.Contains(material))
                {
                    if (!string.IsNullOrEmpty(material.name))
                    {
                        // Scan Material Number
                        material.count = ScanMaterialCount(rectangle, out Bitmap quantity);
                        if (material.count == 0)
                        {
                            UserInterface.AddError($"Failed to parse quantity for {material.name}");
                            quantity.Save($"./logging/materials/{material.name}_Quantity.png");
                        }
                        materials.Add(material);
                        UserInterface.ResetCharacterDisplay();
                        UserInterface.SetMaterial(nameplate, quantity, material.name, material.count);
                        passby = false;                         // New material found so break on next old material
                        quantity.Dispose();
                    }
                }
                else
                {
                    nameplate.Dispose();
                    break;
                }
                Navigation.Wait(150);
            }
        }
示例#12
0
        public static void QueueScan(int id)
        {
            int width  = Navigation.GetWidth();
            int height = Navigation.GetHeight();

            // Separate to all pieces of artifact and add to pics
            List <Bitmap> artifactImages = new List <Bitmap>();

            Bitmap card;
            RECT   reference;
            Bitmap name, gearSlot, mainStat, subStats, level, equipped, locked;

            if (Navigation.GetAspectRatio() == new Size(16, 9))
            {
                reference = new RECT(new Rectangle(872, 80, 327, 560));

                int left   = (int)Math.Round(reference.Left / 1280.0 * width, MidpointRounding.AwayFromZero);
                int top    = (int)Math.Round(reference.Top / 720.0 * height, MidpointRounding.AwayFromZero);
                int right  = (int)Math.Round(reference.Right / 1280.0 * width, MidpointRounding.AwayFromZero);
                int bottom = (int)Math.Round(reference.Bottom / 720.0 * height, MidpointRounding.AwayFromZero);

                card = Navigation.CaptureRegion(new RECT(left, top, right, bottom));

                equipped = card.Clone(new RECT(
                                          Left: (int)(50.0 / reference.Width * card.Width),
                                          Top: (int)(522.0 / reference.Height * card.Height),
                                          Right: card.Width,
                                          Bottom: card.Height), card.PixelFormat);
            }
            else             // if (Navigation.GetAspectRatio() == new Size(8, 5))
            {
                reference = new RECT(new Rectangle(872, 80, 327, 640));

                int left   = (int)Math.Round(reference.Left / 1280.0 * width, MidpointRounding.AwayFromZero);
                int top    = (int)Math.Round(reference.Top / 800.0 * height, MidpointRounding.AwayFromZero);
                int right  = (int)Math.Round(reference.Right / 1280.0 * width, MidpointRounding.AwayFromZero);
                int bottom = (int)Math.Round(reference.Bottom / 800.0 * height, MidpointRounding.AwayFromZero);

                card = Navigation.CaptureRegion(new RECT(left, top, right, bottom));

                equipped = card.Clone(new RECT(
                                          Left: (int)(50.0 / reference.Width * card.Width),
                                          Top: (int)(602.0 / reference.Height * card.Height),
                                          Right: card.Width,
                                          Bottom: card.Height), card.PixelFormat);
            }

            gearSlot = card.Clone(new RECT(
                                      Left: (int)(3.0 / reference.Width * card.Width),
                                      Top: (int)(46.0 / reference.Height * card.Height),
                                      Right: (int)(((reference.Width / 2.0) + 20) / reference.Width * card.Width),
                                      Bottom: (int)(66.0 / reference.Height * card.Height)), card.PixelFormat);

            mainStat = card.Clone(new RECT(
                                      Left: 0,
                                      Top: (int)(100.0 / reference.Height * card.Height),
                                      Right: (int)(((reference.Width / 2.0) + 20) / reference.Width * card.Width),
                                      Bottom: (int)(120.0 / reference.Height * card.Height)), card.PixelFormat);

            level = card.Clone(new RECT(
                                   Left: (int)(18.0 / reference.Width * card.Width),
                                   Top: (int)(203.0 / reference.Height * card.Height),
                                   Right: (int)(61.0 / reference.Width * card.Width),
                                   Bottom: (int)(228.0 / reference.Height * card.Height)), card.PixelFormat);

            subStats = card.Clone(new RECT(
                                      Left: 0,
                                      Top: (int)(235.0 / reference.Height * card.Height),
                                      Right: card.Width,
                                      Bottom: (int)(370.0 / reference.Height * card.Height)), card.PixelFormat);

            locked = card.Clone(new RECT(
                                    Left: (int)(284.0 / reference.Width * card.Width),
                                    Top: (int)(201.0 / reference.Height * card.Height),
                                    Right: (int)(312.0 / reference.Width * card.Width),
                                    Bottom: (int)(228.0 / reference.Height * card.Height)), card.PixelFormat);

            name = card.Clone(new RECT(
                                  Left: 0,
                                  Top: 0,
                                  Right: card.Width,
                                  Bottom: (int)(38.0 / reference.Height * card.Height)), card.PixelFormat);


            // Add all to artifact Images
            artifactImages.Add(name);             // 0
            artifactImages.Add(gearSlot);
            artifactImages.Add(mainStat);
            artifactImages.Add(level);
            artifactImages.Add(subStats);
            artifactImages.Add(equipped);             // 5
            artifactImages.Add(locked);
            artifactImages.Add(card);

            try
            {
                int rarity = GetRarity(name);
                if (rarity < Properties.Settings.Default.MinimumArtifactRarity)
                {
                    artifactImages.ForEach(i => i.Dispose());
                    StopScanning = true;
                }
                else                 // Send images to Worker Queue
                {
                    InventoryKamera.workerQueue.Enqueue(new OCRImageCollection(artifactImages, "artifact", id));
                }
            }
            catch (Exception ex)
            {
                UserInterface.AddError($"Unexpected error getting the rarity for artifact ID#{id}");
                UserInterface.AddError(ex.ToString());
                name.Save($"./logging/artifacts/artifact{id}.png");
            }
        }
        public static void QueueScan(int id)
        {
            int width  = Navigation.GetWidth();
            int height = Navigation.GetHeight();

            // Separate to all pieces of card
            List <Bitmap> weaponImages = new List <Bitmap>();

            Bitmap card;
            RECT   reference;
            Bitmap name, level, refinement, equipped, locked;

            if (Navigation.GetAspectRatio() == new Size(16, 9))
            {
                // Grab image of entire card on Right
                reference = new RECT(new Rectangle(872, 80, 327, 560));                 // In 1280x720

                int left   = (int)Math.Round(reference.Left / 1280.0 * width, MidpointRounding.AwayFromZero);
                int top    = (int)Math.Round(reference.Top / 720.0 * height, MidpointRounding.AwayFromZero);
                int right  = (int)Math.Round(reference.Right / 1280.0 * width, MidpointRounding.AwayFromZero);
                int bottom = (int)Math.Round(reference.Bottom / 720.0 * height, MidpointRounding.AwayFromZero);

                card = Navigation.CaptureRegion(new RECT(left, top, right, bottom));

                // Equipped Character
                equipped = card.Clone(new RECT(
                                          Left: (int)(52.0 / reference.Width * card.Width),
                                          Top: (int)(522.0 / reference.Height * card.Height),
                                          Right: card.Width,
                                          Bottom: card.Height), card.PixelFormat);
            }
            else             // if (Navigation.GetAspectRatio() == new Size(8, 5))
            {
                // Grab image of entire card on Right
                reference = new Rectangle(872, 80, 328, 640);                 // In 1280x800

                int left   = (int)Math.Round(reference.Left / 1280.0 * width, MidpointRounding.AwayFromZero);
                int top    = (int)Math.Round(reference.Top / 800.0 * height, MidpointRounding.AwayFromZero);
                int right  = (int)Math.Round(reference.Right / 1280.0 * width, MidpointRounding.AwayFromZero);
                int bottom = (int)Math.Round(reference.Bottom / 800.0 * height, MidpointRounding.AwayFromZero);

                RECT itemCard = new RECT(left, top, right, bottom);

                card = Navigation.CaptureRegion(itemCard);

                // Equipped Character
                equipped = card.Clone(new RECT(
                                          Left: (int)(52.0 / reference.Width * card.Width),
                                          Top: (int)(602.0 / reference.Height * card.Height),
                                          Right: card.Width,
                                          Bottom: card.Height), card.PixelFormat);
            }

            // Name
            name = card.Clone(new RECT(
                                  Left: 0,
                                  Top: 0,
                                  Right: card.Width,
                                  Bottom: (int)(38.0 / reference.Height * card.Height)), card.PixelFormat);

            // Level
            level = card.Clone(new RECT(
                                   Left: (int)(19.0 / reference.Width * card.Width),
                                   Top: (int)(206.0 / reference.Height * card.Height),
                                   Right: (int)(107.0 / reference.Width * card.Width),
                                   Bottom: (int)(225.0 / reference.Height * card.Height)), card.PixelFormat);

            // Refinement
            refinement = card.Clone(new RECT(
                                        Left: (int)(20.0 / reference.Width * card.Width),
                                        Top: (int)(235.0 / reference.Height * card.Height),
                                        Right: (int)(40.0 / reference.Width * card.Width),
                                        Bottom: (int)(254.0 / reference.Height * card.Height)), card.PixelFormat);

            locked = card.Clone(new RECT(
                                    Left: (int)(284.0 / reference.Width * card.Width),
                                    Top: (int)(201.0 / reference.Height * card.Height),
                                    Right: (int)(312.0 / reference.Width * card.Width),
                                    Bottom: (int)(228.0 / reference.Height * card.Height)), card.PixelFormat);;

            // Assign to List
            weaponImages.Add(name);             //0
            weaponImages.Add(level);
            weaponImages.Add(refinement);
            weaponImages.Add(locked);
            weaponImages.Add(equipped);
            weaponImages.Add(card);             //5

            try
            {
                int rarity = GetRarity(name);
                if (rarity < Properties.Settings.Default.MinimumWeaponRarity)
                {
                    weaponImages.ForEach(i => i.Dispose());
                    StopScanning = true;
                    return;
                }
                else                 // Send images to worker queue
                {
                    InventoryKamera.workerQueue.Enqueue(new OCRImageCollection(weaponImages, "weapon", id));
                }
            }
            catch (Exception ex)
            {
                UserInterface.AddError($"Unexpected error getting the rarity for weapon ID#{id}");
                UserInterface.AddError(ex.ToString());
                name.Save($"./logging/weapons/weapon{id}.png");
            }
        }