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); }
private static int[] ScanTalents(string name) { int[] talents = { -1, -1, -1 }; int specialOffset = 0; // Check if character has a movement talent like // Mona or Ayaka if (name.Contains("Mona") || name.Contains("Ayaka")) { specialOffset = 1; } var xRef = 1280.0; var yRef = 720.0; if (Navigation.GetAspectRatio() == new Size(8, 5)) { yRef = 800.0; } Rectangle region = new RECT( Left: (int)(160 / xRef * Navigation.GetWidth()), Top: (int)(116 / yRef * Navigation.GetHeight()), Right: (int)(225 / xRef * Navigation.GetWidth()), Bottom: (int)(141 / yRef * Navigation.GetHeight())); for (int i = 0; i < 3; i++) { // Change y-offset for talent clicking int yOffset = (int)(110 / yRef * Navigation.GetHeight()) + (i + ((i == 2) ? specialOffset : 0)) * (int)(60 / yRef * Navigation.GetHeight()); Navigation.SetCursorPos(Navigation.GetPosition().Left + (int)(1130 / xRef * Navigation.GetWidth()), Navigation.GetPosition().Top + yOffset); Navigation.Click(); Navigation.Speed speed = i == 0 ? Navigation.Speed.Normal : Navigation.Speed.Fast; Navigation.SystemRandomWait(speed); while (talents[i] < 1 || talents[i] > 15) { Bitmap talentLevel = Navigation.CaptureRegion(region); talentLevel = Scraper.ResizeImage(talentLevel, talentLevel.Width * 2, talentLevel.Height * 2); Bitmap n = Scraper.ConvertToGrayscale(talentLevel); Scraper.SetContrast(60, ref n); Scraper.SetInvert(ref n); string text = Scraper.AnalyzeText(n).Trim(); text = Regex.Replace(text, @"\D", string.Empty); if (int.TryParse(text, out int level)) { if (level >= 1 && level <= 15) { talents[i] = level; UserInterface.SetCharacter_Talent(talentLevel, text, i); } } n.Dispose(); talentLevel.Dispose(); } } Navigation.sim.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.ESCAPE); return(talents); }
private static void ScanNameAndElement(ref string name, ref string element) { int attempts = 0; int maxAttempts = 75; Rectangle region = new RECT( Left: (int)(85 / 1280.0 * Navigation.GetWidth()), Top: (int)(10 / 720.0 * Navigation.GetHeight()), Right: (int)(305 / 1280.0 * Navigation.GetWidth()), Bottom: (int)(55 / 720.0 * Navigation.GetHeight())); do { Navigation.SystemRandomWait(Navigation.Speed.Fast); using (Bitmap bm = Navigation.CaptureRegion(region)) { Bitmap n = Scraper.ConvertToGrayscale(bm); Scraper.SetThreshold(110, ref n); Scraper.SetInvert(ref n); n = Scraper.ResizeImage(n, n.Width * 2, n.Height * 2); string block = Scraper.AnalyzeText(n, Tesseract.PageSegMode.Auto).ToLower().Trim(); string line = Scraper.AnalyzeText(n, Tesseract.PageSegMode.SingleLine).ToLower().Trim(); // Characters with wrapped names will not have a slash string nameAndElement = line.Contains("/") ? line : block; if (nameAndElement.Contains("/")) { var split = nameAndElement.Split('/'); // Search for element and character name in block // Long name characters might look like // <Element> <First Name> // / <Last Name> element = !split[0].Contains(" ") ? Scraper.FindElementByName(split[0].Trim()) : Scraper.FindElementByName(split[0].Split(' ')[0].Trim()); // Find character based on string after / // Long name characters might search by their last name only but it'll still work. name = Scraper.FindClosestCharacterName(Regex.Replace(split[1], @"[\W]", string.Empty)); if (name == "Traveler") { foreach (var item in from item in Scraper.Characters where item.Value["GOOD"].ToString() == "Traveler" select item) { name = item.Key; } } } n.Dispose(); if (!string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(element)) { UserInterface.SetCharacter_NameAndElement(bm, name, element); return; } } attempts++; Navigation.SystemRandomWait(Navigation.Speed.Normal); } while ((string.IsNullOrWhiteSpace(name) || string.IsNullOrEmpty(element)) && (attempts < maxAttempts)); name = null; element = null; }