public async Task OnInit() { Leagues = null; Leagues = await poeTradeClient.Fetch <League>(); var newLeagues = false; using var algorithm = SHA256.Create(); var leaguesHash = Encoding.UTF8.GetString( algorithm.ComputeHash( Encoding.UTF8.GetBytes( JsonSerializer.Serialize(Leagues.Select(x => x.Id).ToList()) ) ) ); if (leaguesHash != settings.LeaguesHash) { settings.LeaguesHash = leaguesHash; settings.Save(); newLeagues = true; } if (string.IsNullOrEmpty(settings.LeagueId) || !Leagues.Any(x => x.Id == settings.LeagueId)) { settings.LeagueId = Leagues.FirstOrDefault().Id; settings.Save(); newLeagues = true; } if (newLeagues && OnNewLeagues != null) { OnNewLeagues.Invoke(); } }
private static async Task FetchAndSaveData <T>(IPoeTradeClient client) { var data = await client.Fetch <T>(); File.WriteAllText(Path.Join( "..", "..", "..", "..", "Sidekick.TestInfrastructure", "TestData", $"{typeof(T).Name}.json"), JsonSerializer.Serialize(data, client.Options)); }
public async Task OnInit() { var categories = await poeApiClient.Fetch <StaticItemCategory>(); ImageUrls = new Dictionary <string, string>(); Ids = new Dictionary <string, string>(); foreach (var category in categories) { foreach (var entry in category.Entries) { ImageUrls.Add(entry.Id, entry.Image); if (!Ids.ContainsKey(entry.Text)) { Ids.Add(entry.Text, entry.Id); } } } }
public async Task <List <League> > Handle(GetLeaguesQuery request, CancellationToken cancellationToken) { if (request.UseCache) { var cacheLeagues = await leagueRepository.FindAll(); if (cacheLeagues.Count != 0) { return(cacheLeagues); } } var result = await poeTradeClient.Fetch <League>("data/leagues"); await leagueRepository.SaveAll(result.Result); return(result.Result); }
public async Task Initialize() { var result = await cacheRepository.GetOrSet( "Sidekick.Infrastructure.PoeApi.Items.Static.ItemStaticDataProvider.Initialize", () => poeTradeClient.Fetch <StaticItemCategory>("data/static")); ImageUrls = new Dictionary <string, string>(); Ids = new Dictionary <string, string>(); foreach (var category in result.Result) { foreach (var entry in category.Entries) { ImageUrls.Add(entry.Id, entry.Image); if (!Ids.ContainsKey(entry.Text)) { Ids.Add(entry.Text, entry.Id); } } } }
public async Task OnInit() { var categories = await cacheService.GetOrCreate("StatDataService.OnInit", () => poeApiClient.Fetch <StatDataCategory>()); PseudoPatterns = new List <StatData>(); ExplicitPatterns = new List <StatData>(); ImplicitPatterns = new List <StatData>(); EnchantPatterns = new List <StatData>(); CraftedPatterns = new List <StatData>(); VeiledPatterns = new List <StatData>(); FracturedPatterns = new List <StatData>(); NewLinePattern = new Regex("(?:\\\\)*[\\r\\n]+"); IncreasedPattern = new Regex(languageProvider.Language.ModifierIncreased); var hashPattern = new Regex("\\\\#"); var parenthesesPattern = new Regex("((?:\\\\\\ )*\\\\\\([^\\(\\)]*\\\\\\))"); 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 <StatData> 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) { entry.Category = category.Label; 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 { foreach (var option in entry.Option.Options) { if (NewLinePattern.IsMatch(option.Text)) { var lines = NewLinePattern.Split(option.Text).ToList(); var options = lines.ConvertAll(x => x = hashPattern.Replace(pattern, Regex.Escape(x))); option.Pattern = new Regex($"(?:^|\\n){string.Join("\\n", options)}{suffix}"); option.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 { option.Pattern = new Regex($"(?:^|\\n){hashPattern.Replace(pattern, Regex.Escape(option.Text))}{suffix}", RegexOptions.None); } } pattern = hashPattern.Replace(pattern, "(.*)"); } if (IncreasedPattern.IsMatch(pattern)) { var negativePattern = IncreasedPattern.Replace(pattern, languageProvider.Language.ModifierReduced); entry.NegativePattern = new Regex($"(?:^|\\n){negativePattern}{suffix}", RegexOptions.None); } entry.Pattern = new Regex($"(?:^|\\n){pattern}{suffix}", RegexOptions.None); patterns.Add(entry); } } }
public async Task Initialize() { if (Definitions != null && Definitions.Count > 0) { return; } try { logger.LogInformation($"Pseudo stat service initialization started."); var result = await cacheRepository.GetOrSet( "Sidekick.Infrastructure.PoeApi.Items.Pseudo.PseudoModifierProvider.Initialize", () => poeTradeClient.Fetch <ApiCategory>("data/stats", useDefaultLanguage: true)); logger.LogInformation($"{result.Result.Count} attributes fetched."); var groups = InitGroups(result.Result); foreach (var category in result.Result) { var first = category.Entries.FirstOrDefault(); if (first == null || first.Id.Split('.').First() == "pseudo") { continue; } foreach (var entry in category.Entries) { foreach (var group in groups) { if (group.Exception != null && group.Exception.IsMatch(entry.Text)) { continue; } foreach (var pattern in group.Patterns) { if (pattern.Pattern.IsMatch(entry.Text)) { pattern.Matches.Add(new PseudoPatternMatch(entry.Id, entry.Type, entry.Text)); } } } } } foreach (var group in groups) { var definition = new PseudoDefinition(group.Id, group.Text); foreach (var pattern in group.Patterns) { PseudoDefinitionModifier modifier = null; foreach (var match in pattern.Matches.OrderBy(x => x.Type).ThenBy(x => x.Text.Length)) { if (modifier != null) { if (modifier.Type != match.Type) { modifier = null; } else if (!match.Text.StartsWith(modifier.Text)) { modifier = null; } } if (modifier == null) { modifier = new PseudoDefinitionModifier(match.Type, match.Text, pattern.Multiplier); } modifier.Ids.Add(match.Id); if (!definition.Modifiers.Contains(modifier)) { definition.Modifiers.Add(modifier); } } } Definitions.Add(definition); } } catch (Exception) { logger.LogInformation($"Could not initialize pseudo service."); throw; } }
public async Task OnInit() { var categories = await poeApiClient.Fetch <StatDataCategory>(); PseudoPatterns = new List <StatData>(); ExplicitPatterns = new List <StatData>(); ImplicitPatterns = new List <StatData>(); EnchantPatterns = new List <StatData>(); CraftedPatterns = new List <StatData>(); VeiledPatterns = new List <StatData>(); NewLinePattern = new Regex("(?:\\\\)*[\\r\\n]+"); var hashPattern = new Regex("\\\\#"); var parenthesesPattern = new Regex("((?:\\\\\\ )*\\\\\\([^\\(\\)]*\\\\\\))"); 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 <StatData> patterns; switch (first.Id.Split('.').First()) { default: continue; case "pseudo": suffix = "\\ *\\n+"; patterns = PseudoPatterns; break; case "delve": case "monster": case "explicit": suffix = "\\ *\\n+"; patterns = ExplicitPatterns; break; case "implicit": suffix = "\\ *\\(implicit\\)"; patterns = ImplicitPatterns; break; case "enchant": suffix = "\\ *\\(enchant\\)"; patterns = EnchantPatterns; break; case "crafted": suffix = "\\ *\\(crafted\\)"; patterns = CraftedPatterns; break; case "veiled": suffix = "\\ *\\(veiled\\)"; patterns = VeiledPatterns; break; } foreach (var entry in category.Entries) { entry.Category = category.Label; pattern = Regex.Escape(entry.Text); pattern = parenthesesPattern.Replace(pattern, "(?:$1)?"); pattern = hashPattern.Replace(pattern, "([-+\\d,\\.]+)"); pattern = NewLinePattern.Replace(pattern, "\\n"); entry.Pattern = new Regex($"\\n+{pattern}{suffix}"); patterns.Add(entry); } } }
public async Task Initialize() { await statTranslationProvider.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 <ModifierPatternMetadata>(); ExplicitPatterns = new List <ModifierPatternMetadata>(); ImplicitPatterns = new List <ModifierPatternMetadata>(); EnchantPatterns = new List <ModifierPatternMetadata>(); CraftedPatterns = new List <ModifierPatternMetadata>(); VeiledPatterns = new List <ModifierPatternMetadata>(); FracturedPatterns = new List <ModifierPatternMetadata>(); foreach (var category in categories) { if (!category.Entries.Any()) { continue; } // The notes in parentheses are never translated by the game. // We should be fine hardcoding them this way. List <ModifierPatternMetadata> patterns; var categoryLabel = category.Entries[0].Id.Split('.').First(); switch (categoryLabel) { default: continue; case "pseudo": patterns = PseudoPatterns; break; case "delve": case "monster": case "explicit": patterns = ExplicitPatterns; break; case "implicit": patterns = ImplicitPatterns; break; case "enchant": patterns = EnchantPatterns; break; case "crafted": patterns = CraftedPatterns; break; case "veiled": patterns = VeiledPatterns; break; case "fractured": patterns = FracturedPatterns; break; } foreach (var entry in category.Entries) { var modifier = new ModifierPatternMetadata() { Category = categoryLabel, Id = entry.Id, IsOption = entry.Option?.Options?.Any() ?? false, }; if (modifier.IsOption) { for (var i = 0; i < entry.Option.Options.Count; i++) { modifier.Patterns.Add(new ModifierPattern() { Text = ComputeOptionText(entry.Text, entry.Option.Options[i].Text), LineCount = NewLinePattern.Matches(entry.Text).Count + NewLinePattern.Matches(entry.Option.Options[i].Text).Count + 1, Value = i + 1, Pattern = ComputePattern(categoryLabel, entry.Text, entry.Option.Options[i].Text), }); } } else { var stats = statTranslationProvider.GetAlternateModifiers(entry.Text); if (stats != null) { foreach (var stat in stats) { modifier.Patterns.Add(new ModifierPattern() { Text = stat.Text, LineCount = NewLinePattern.Matches(stat.Text).Count + 1, Pattern = ComputePattern(categoryLabel, stat.Text), Negative = stat.Negative, Value = stat.Value, }); } } else { modifier.Patterns.Add(new ModifierPattern() { Text = entry.Text, LineCount = NewLinePattern.Matches(entry.Text).Count + 1, Pattern = ComputePattern(categoryLabel, entry.Text), }); } } patterns.Add(modifier); } } }
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); } } }