using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace LeagueAPI.ARAM; public class ARAMBalanceLookup : Dictionary { } public class ARAMBalanceService { private static readonly string ARAMONLY_URL = "https://www.aramonly.com/page-data/aram-changes/page-data.json"; private ARAMBalanceLookup _champions = []; public async Task EnsureIsLoadedAsync() { if (_champions is not { Count: > 0 }) { await ReloadAsync(); } } public async Task ReloadAsync(bool force = false) { ARAMBalanceLookup? champions = ResourceService.GetARAMBalanceLookup(); if (!force && champions is { Count: > 0 }) { _champions = champions; return; } await FetchFromAramonly(); } private async Task FetchFromAramonly() { using HttpClient _client = new(); using HttpResponseMessage response = await _client.GetAsync(ARAMONLY_URL); if (!response.IsSuccessStatusCode) { return false; } string json = await response.Content.ReadAsStringAsync(); AramonlyComResponse? result = JsonSerializer.Deserialize(json); AramChampion?[] nodes = result?.Result?.Data?.AllAramModifiersJson?.Nodes ?? []; if (nodes is not { Length: > 0 }) { return false; } _champions = []; foreach (AramChampion? node in nodes) { if (node is null || !node.HasValue || !node.Value.Champion.HasValue) { continue; } string name = node.Value.Champion.Value.Name ?? string.Empty; if (name == string.Empty) { continue; } _champions.Add(name, node.Value); } ResourceService.SetARAMBalanceLookup(_champions); return true; } public AramChampion? GetAramChampion(string championName) { EnsureIsLoadedAsync().Wait(); return _champions.TryGetValue(championName, out AramChampion aramChampion) ? aramChampion : null; } } public record struct AramonlyComResponse([property: JsonPropertyName("result")] AramonlyComResult? Result); public record struct AramonlyComResult([property: JsonPropertyName("data")] AramonlyComData? Data); public record struct AramonlyComData( [property: JsonPropertyName("allAramModifiersJson")] AramonlyComModifiersJson? AllAramModifiersJson, [property: JsonPropertyName("patchVersionJson")] PatchVersionJson? PatchVersionJson ); public record struct AramonlyComModifiersJson([property: JsonPropertyName("nodes")] AramChampion?[]? Nodes); public record struct AramChampion( [property: JsonPropertyName("timestamp")] DateTime? Timestamp, [property: JsonPropertyName("champion")] Champion? Champion, [property: JsonPropertyName("aramDamageDealt")] double? AramDamageDealt, [property: JsonPropertyName("aramDamageTaken")] double? AramDamageTaken, [property: JsonPropertyName("aramHealing")] double? AramHealing, [property: JsonPropertyName("aramShielding")] double? AramShielding, [property: JsonPropertyName("aramTenacity")] double? AramTenacity, [property: JsonPropertyName("aramAbilityHaste")] int? AramAbilityHaste, [property: JsonPropertyName("aramAttackSpeed")] double? AramAttackSpeed, [property: JsonPropertyName("aramEnergyRegen")] double? AramEnergyRegen ) { public readonly void ToDisplayString(StringBuilder sb) { // Damage Dealt if (AramDamageDealt is not null and not 0 and not 1) { double value = (double)AramDamageDealt; sb.AppendLine($"Dmg Dealt: {value - 1:+#0%;-#0%}"); } // Damage Taken if (AramDamageTaken is not null and not 0 and not 1) { double value = (double)AramDamageTaken; sb.AppendLine($"Dmg Taken: {value - 1:+#0%;-#0%}"); } // Healing if (AramHealing is not null and not 0 and not 1) { double value = (double)AramHealing; sb.AppendLine($"Healing: {value - 1:+#0%;-#0%}"); } // Shielding if (AramShielding is not null and not 0 and not 1) { double value = (double)AramShielding; sb.AppendLine($"Shielding: {value - 1:+#0%;-#0%}"); } // Tenacity if (AramTenacity is not null and not 0 and not 1) { double value = (double)AramTenacity; sb.AppendLine($"Tenacity: {value - 1:+#0%;-#0%}"); } // Ability Haste (Raw value) if (AramAbilityHaste is not null and not 0 and not 1) { double value = (double)AramAbilityHaste; sb.AppendLine($"Ability Haste: {value}"); } // Total AS (Raw value) if (AramAttackSpeed is not null and not 0 and not 1) { double value = (double)AramAttackSpeed; sb.AppendLine($"Total AS: {value}"); } // Energy Regen (Percentage) if (AramEnergyRegen is not null and not 0 and not 1) { double value = (double)AramEnergyRegen; sb.AppendLine($"Energy Regen: {value - 1:+#0%;-#0%}"); } } } public record struct Champion( [property: JsonPropertyName("name")] string? Name, [property: JsonPropertyName("sanitizedName")] string? SanitizedName ); public record struct PatchVersionJson( [property: JsonPropertyName("patchVersion")] string? PatchVersion );