Files
LeagueARAMTracker/LeagueAPI/ARAM/ARAMBalanceService.cs
2026-03-13 01:22:28 +01:00

110 lines
3.7 KiB
C#

using System.Text.Json;
using CliWrap;
using CliWrap.Buffered;
using MoonSharp.Interpreter;
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 ARAMBalanceService
{
private static readonly string URL = "https://wiki.leagueoflegends.com/en-us/rest.php/v1/page/Module:ChampionData%2Fdata";
private ARAMBalanceLookup _champions = [];
static ARAMBalanceService()
{
UserData.RegisterType<WikiChampion>();
UserData.RegisterType<WikiChampionStats>();
}
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;
}
Command curl = Cli.Wrap("curl")
.WithArguments(URL);
BufferedCommandResult result = await curl.ExecuteBufferedAsync();
string json = result.StandardOutput;
JsonDocument jsonDocument = JsonDocument.Parse(json);
string lua = jsonDocument.RootElement.GetProperty("source").GetString() ?? string.Empty;
DynValue champs = Script.RunString(lua);
if (champs.Type == DataType.Table)
{
Dictionary<string, WikiChampion> nameDictionary = [];
foreach (TablePair kv in champs.Table.Pairs)
{
if (kv.Key.Type is not DataType.String || kv.Value.Type is not DataType.Table)
{
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)
{
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;
}
}
}
}
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);
}
}
public Dictionary<string, double> GetAramStats(int championId)
{
EnsureIsLoadedAsync().Wait();
return _champions.TryGetValue(championId, out Dictionary<string, double>? stats) ? stats : [];
}
}