public Modifiers ParseMods(string text) { text = NewLinePattern.Replace(text, "\n"); var mods = new Modifiers(); // Make sure the text ends with an empty line for our regexes to work correctly if (!text.EndsWith("\n")) { text += "\n"; } FillMods(mods.Explicit, ExplicitPatterns, text); FillMods(mods.Implicit, ImplicitPatterns, text); FillMods(mods.Enchant, EnchantPatterns, text); FillMods(mods.Crafted, CraftedPatterns, text); //FillMods(mods.Veiled, VeiledPatterns, text); FillMods(mods.Fractured, FracturedPatterns, text); FillPseudo(mods.Pseudo, mods.Explicit); FillPseudo(mods.Pseudo, mods.Implicit); FillPseudo(mods.Pseudo, mods.Enchant); FillPseudo(mods.Pseudo, mods.Crafted); mods.Pseudo.ForEach(x => { x.Text = ParseHashPattern.Replace(x.Text, ((int)x.Values[0]).ToString(), 1); }); return(mods); }
public ItemModifiers Parse(ParsingItem parsingItem) { var text = NewLinePattern.Replace(parsingItem.Text, "\n"); var mods = new ItemModifiers(); // Make sure the text ends with an empty line for our regexes to work correctly if (!text.EndsWith("\n")) { text += "\n"; } ParseMods(mods.Explicit, ExplicitPatterns, text); ParseMods(mods.Implicit, ImplicitPatterns, text); ParseMods(mods.Enchant, EnchantPatterns, text); ParseMods(mods.Crafted, CraftedPatterns, text); //FillMods(mods.Veiled, VeiledPatterns, text); ParseMods(mods.Fractured, FracturedPatterns, text); mods.Pseudo = pseudoModifierProvider.Parse(mods); return(mods); }
public async Task Initialize() { var result = await cacheRepository.GetOrSet( "Sidekick.Infrastructure.PoeApi.Items.Modifiers.ModifierProvider.Initialize", () => poeTradeClient.Fetch <ApiCategory>("data/stats")); var categories = result.Result; PseudoPatterns = new List <ModifierPattern>(); ExplicitPatterns = new List <ModifierPattern>(); ImplicitPatterns = new List <ModifierPattern>(); EnchantPatterns = new List <ModifierPattern>(); CraftedPatterns = new List <ModifierPattern>(); VeiledPatterns = new List <ModifierPattern>(); FracturedPatterns = new List <ModifierPattern>(); IncreasedPattern = new Regex(gameLanguageProvider.Language.ModifierIncreased); var hashPattern = new Regex("\\\\#"); var parenthesesPattern = new Regex("((?:\\\\\\ )*\\\\\\([^\\(\\)]*\\\\\\))"); var additionalProjectileEscaped = Regex.Escape(gameLanguageProvider.Language.AdditionalProjectile); var additionalProjectiles = hashPattern.Replace(Regex.Escape(gameLanguageProvider.Language.AdditionalProjectiles), "([-+\\d,\\.]+)"); // We need to ignore the case here, there are some mistakes in the data of the game. AdditionalProjectilePattern = new Regex(gameLanguageProvider.Language.AdditionalProjectile, RegexOptions.IgnoreCase); foreach (var category in categories) { var first = category.Entries.FirstOrDefault(); if (first == null) { continue; } // The notes in parentheses are never translated by the game. // We should be fine hardcoding them this way. string suffix, pattern; List <ModifierPattern> patterns; switch (first.Id.Split('.').First()) { default: continue; case "pseudo": suffix = "(?:\\n|(?<!(?:\\n.*){2,})$)"; patterns = PseudoPatterns; break; case "delve": case "monster": case "explicit": suffix = "(?:\\n|(?<!(?:\\n.*){2,})$)"; patterns = ExplicitPatterns; break; case "implicit": suffix = "(?:\\ \\(implicit\\)\\n|(?<!(?:\\n.*){2,})$)"; patterns = ImplicitPatterns; break; case "enchant": suffix = "(?:\\ \\(enchant\\)\\n|(?<!(?:\\n.*){2,})$)"; patterns = EnchantPatterns; break; case "crafted": suffix = "(?:\\ \\(crafted\\)\\n|(?<!(?:\\n.*){2,})$)"; patterns = CraftedPatterns; break; case "veiled": suffix = "(?:\\ \\(veiled\\)\\n|(?<!(?:\\n.*){2,})$)"; patterns = VeiledPatterns; break; case "fractured": suffix = "(?:\\ \\(fractured\\)\\n|(?<!(?:\\n.*){2,})$)"; patterns = FracturedPatterns; break; } foreach (var entry in category.Entries) { var modifier = new ModifierPattern() { Metadata = new ModifierMetadata() { Category = category.Label, Id = entry.Id, Text = entry.Text, Type = entry.Type, }, }; pattern = Regex.Escape(entry.Text); pattern = parenthesesPattern.Replace(pattern, "(?:$1)?"); pattern = NewLinePattern.Replace(pattern, "\\n"); if (entry.Option == null || entry.Option.Options == null || entry.Option.Options.Count == 0) { pattern = hashPattern.Replace(pattern, "([-+\\d,\\.]+)"); } else { modifier.Options = new List <ModifierOptionParse>(); foreach (var entryOption in entry.Option.Options) { var modifierOption = new ModifierOptionParse() { Text = entryOption.Text, }; if (NewLinePattern.IsMatch(entryOption.Text)) { var lines = NewLinePattern.Split(entryOption.Text).ToList(); var options = lines.ConvertAll(x => hashPattern.Replace(pattern, Regex.Escape(x))); modifierOption.Pattern = new Regex($"(?:^|\\n){string.Join("\\n", options)}{suffix}"); modifierOption.Text = string.Join("\n", lines.Select((x, i) => new { Text = x, Index = i }) .ToList() .ConvertAll(x => { if (x.Index == 0) { return(x.Text); } return(entry.Text.Replace("#", x.Text)); })); } else { modifierOption.Pattern = new Regex($"(?:^|\\n){hashPattern.Replace(pattern, Regex.Escape(entryOption.Text))}{suffix}", RegexOptions.None); } } pattern = hashPattern.Replace(pattern, "(.*)"); } if (IncreasedPattern.IsMatch(pattern)) { var negativePattern = IncreasedPattern.Replace(pattern, gameLanguageProvider.Language.ModifierReduced); modifier.NegativePattern = new Regex($"(?:^|\\n){negativePattern}{suffix}", RegexOptions.None); } if (AdditionalProjectilePattern.IsMatch(entry.Text)) { var additionalProjectilePattern = pattern.Replace(additionalProjectileEscaped, additionalProjectiles, System.StringComparison.OrdinalIgnoreCase); modifier.AdditionalProjectilePattern = new Regex($"(?:^|\\n){additionalProjectilePattern}{suffix}", RegexOptions.IgnoreCase); } modifier.Pattern = new Regex($"(?:^|\\n){pattern}{suffix}", RegexOptions.None); patterns.Add(modifier); } } }