ARAM balance data from aramonly.com
This commit is contained in:
@@ -24,46 +24,9 @@ public partial class ChampionViewModel(ChampionData data) : ObservableObject
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(data.Name);
|
||||
foreach (KeyValuePair<string, double> kv in data.AramBalance)
|
||||
if (data.AramBalance.HasValue)
|
||||
{
|
||||
switch (kv.Key)
|
||||
{
|
||||
case "dmg_dealt":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Dmg Dealt: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "dmg_taken":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Dmg Taken: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "healing":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Healing: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "energyregen_mod":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Energy Regen: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "tenacity":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Tenacity: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "shielding":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Shielding: {0:+#0%;-#0%}", kv.Value - 1);
|
||||
break;
|
||||
case "ability_haste":
|
||||
sb.AppendFormat("Ability Haste: {0}", kv.Value);
|
||||
break;
|
||||
case "total_as":
|
||||
if (kv.Value == 1) { continue; }
|
||||
sb.AppendFormat("Total AS: {0}", kv.Value);
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("{0}: {1}", kv.Key, kv.Value);
|
||||
break;
|
||||
}
|
||||
sb.AppendLine();
|
||||
data.AramBalance.Value.ToDisplayString(sb);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -175,13 +175,13 @@ public partial class MainViewModel : ObservableObject, IDisposable
|
||||
foreach (int championId in championIds)
|
||||
{
|
||||
ChampionData? championData = await _client.GetChampionByIdAsync(championId);
|
||||
if (championData is null)
|
||||
if (championData is null || championData.Name is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string imagePath = await ResourceService.GetChampionIconPathAsync(championId);
|
||||
ChampionViewModel vm = new(championData with { AramBalance = _aramBalanceService.GetAramStats(championData.Id) })
|
||||
ChampionViewModel vm = new(championData with { AramBalance = _aramBalanceService.GetAramChampion(championData.Name) })
|
||||
{
|
||||
IsNeededForChallenge = _needChampionIds.Contains(championData.Id),
|
||||
ImagePath = imagePath,
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
using System.Text.Json;
|
||||
using CliWrap;
|
||||
using CliWrap.Buffered;
|
||||
using MoonSharp.Interpreter;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace LeagueAPI.ARAM;
|
||||
|
||||
public record class WikiChampion(int Id, WikiChampionStats Stats);
|
||||
public record class WikiChampionStats(Dictionary<string, double> Aram);
|
||||
|
||||
public class ARAMBalanceLookup : Dictionary<int, Dictionary<string, double>> { }
|
||||
public class ARAMBalanceLookup : Dictionary<string, AramChampion> { }
|
||||
|
||||
public class ARAMBalanceService
|
||||
{
|
||||
private static readonly string URL = "https://wiki.leagueoflegends.com/en-us/rest.php/v1/page/Module:ChampionData%2Fdata";
|
||||
private static readonly string ARAMONLY_URL = "https://www.aramonly.com/page-data/aram-changes/page-data.json";
|
||||
|
||||
private ARAMBalanceLookup _champions = [];
|
||||
|
||||
static ARAMBalanceService()
|
||||
{
|
||||
UserData.RegisterType<WikiChampion>();
|
||||
UserData.RegisterType<WikiChampionStats>();
|
||||
}
|
||||
|
||||
public async Task EnsureIsLoadedAsync()
|
||||
{
|
||||
if (_champions is not { Count: > 0 })
|
||||
@@ -39,71 +29,139 @@ public class ARAMBalanceService
|
||||
return;
|
||||
}
|
||||
|
||||
Command curl = Cli.Wrap("curl")
|
||||
.WithArguments(URL);
|
||||
BufferedCommandResult result = await curl.ExecuteBufferedAsync();
|
||||
await FetchFromAramonly();
|
||||
}
|
||||
|
||||
string json = result.StandardOutput;
|
||||
JsonDocument jsonDocument = JsonDocument.Parse(json);
|
||||
string lua = jsonDocument.RootElement.GetProperty("source").GetString() ?? string.Empty;
|
||||
private async Task<bool> FetchFromAramonly()
|
||||
{
|
||||
using HttpClient _client = new();
|
||||
using HttpResponseMessage response = await _client.GetAsync(ARAMONLY_URL);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DynValue champs = Script.RunString(lua);
|
||||
if (champs.Type == DataType.Table)
|
||||
string json = await response.Content.ReadAsStringAsync();
|
||||
AramonlyComResponse? result = JsonSerializer.Deserialize<AramonlyComResponse?>(json);
|
||||
AramChampion?[] nodes = result?.Result?.Data?.AllAramModifiersJson?.Nodes ?? [];
|
||||
if (nodes is not { Length: > 0 })
|
||||
{
|
||||
Dictionary<string, WikiChampion> nameDictionary = [];
|
||||
foreach (TablePair kv in champs.Table.Pairs)
|
||||
return false;
|
||||
}
|
||||
_champions = [];
|
||||
foreach (AramChampion? node in nodes)
|
||||
{
|
||||
if (kv.Key.Type is not DataType.String || kv.Value.Type is not DataType.Table)
|
||||
if (node is null || !node.HasValue || !node.Value.Champion.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string key = kv.Key.String;
|
||||
Table championTable = kv.Value.Table;
|
||||
DynValue idValue = championTable.Get("id");
|
||||
DynValue statsValue = championTable.Get("stats");
|
||||
|
||||
Dictionary<string, double> aramStats = [];
|
||||
|
||||
if (statsValue.Type is DataType.Table)
|
||||
string name = node.Value.Champion.Value.Name ?? string.Empty;
|
||||
if (name == string.Empty)
|
||||
{
|
||||
DynValue aramValue = statsValue.Table.Get("aram");
|
||||
|
||||
if (aramValue.Type is DataType.Table)
|
||||
{
|
||||
foreach (TablePair aramKv in aramValue.Table.Pairs)
|
||||
{
|
||||
if (aramKv.Key.Type is DataType.String && aramKv.Value.Type is DataType.Number)
|
||||
{
|
||||
aramStats[aramKv.Key.String] = aramKv.Value.Number;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
_champions.Add(name, node.Value);
|
||||
}
|
||||
|
||||
WikiChampion champ = new(idValue.Type is DataType.Number ? (int)idValue.Number : -1, new(aramStats));
|
||||
nameDictionary.Add(key, champ);
|
||||
}
|
||||
|
||||
_champions = [];
|
||||
|
||||
foreach (KeyValuePair<string, WikiChampion> kv in nameDictionary)
|
||||
{
|
||||
if (!_champions.TryGetValue(kv.Value.Id, out Dictionary<string, double>? value))
|
||||
{
|
||||
_champions[kv.Value.Id] = new(kv.Value.Stats.Aram);
|
||||
}
|
||||
else
|
||||
{
|
||||
kv.Value.Stats.Aram.ToList().ForEach(kv => value.Add(kv.Key, kv.Value));
|
||||
}
|
||||
}
|
||||
ResourceService.SetARAMBalanceLookup(_champions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Dictionary<string, double> GetAramStats(int championId)
|
||||
public AramChampion? GetAramChampion(string championName)
|
||||
{
|
||||
EnsureIsLoadedAsync().Wait();
|
||||
return _champions.TryGetValue(championId, out Dictionary<string, double>? stats) ? stats : [];
|
||||
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
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using LeagueAPI.ARAM;
|
||||
|
||||
namespace LeagueAPI.Models.DDragon.Champions;
|
||||
|
||||
@@ -41,5 +42,5 @@ public record ChampionData
|
||||
public ChampionDataStats? Stats { get; init; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Dictionary<string, double> AramBalance { get; set; } = [];
|
||||
public AramChampion? AramBalance { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user