public override async Task <string> GetSkillOrder(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetChampionURL(championId, position), soft: true)); var skillOrder = doc.DocumentNode.Descendants().Where(o => o.HasClass("skill-order")).Last(); char[] skills = new char[18]; foreach (var skill in skillOrder.Descendants().Where(o => o.HasClass("skill-selections"))) { int i = 0; foreach (var item in skill.Descendants("div")) { if (item.HasClass("selected")) { skills[i] = item.Descendants("span").First().InnerText[0]; } i++; } } return(new string(skills)); }
public override async Task <Position[]> GetPossibleRoles(int championId) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetChampionURL(championId), soft: true)); var n = doc.DocumentNode.SelectNodes("//ul//a[contains(@href, 'champion')]//h3"); var ret = new List <Position>(); foreach (var item in n) { string positionName = item.InnerText; foreach (var pos in PositionToName) { if (pos.Value.Equals(positionName.Trim())) { ret.Add(pos.Key); break; } } } return(ret.ToArray()); }
public override async Task <ItemSet> GetItemSet(int championId, Position position) { if (position == Position.Fill) { position = (await GetPossibleRoles(championId))[0]; } string champ = (await Riot.GetChampion(championId)).Key; var json = await WebCache.String($"http://lolflavor.com/champions/{champ}/Recommended/{champ}_{PositionToName[position]}_scrape.json", soft : true); if (json == null) { return(null); } var lolItemSet = JsonConvert.DeserializeObject <LolItemSetsItemSet> (json); return(new ItemSet { Champion = championId, Position = position, Name = Name + ": " + position, Blocks = lolItemSet.blocks.Select(o => new ItemSet.SetBlock { Name = o.type, Items = o.items.Select(i => int.Parse(i.id)).ToArray() }).ToArray() }); }
public override async Task <Position[]> GetPossibleRoles(int championId) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetRoleUrl(championId, Position.Fill), soft: true)); var n = doc.DocumentNode.SelectNodes("//a[contains(@class, 'lanefilter')]"); var ret = new List <Position>(); foreach (var item in n) { string img = item.ChildNodes["img"].GetAttributeValue("src", ""); foreach (var pos in PositionToName) { if (img.Contains(pos.Value.ToLower())) { ret.Add(pos.Key); break; } } } return(ret.ToArray()); }
public override async Task <Champion[]> GetCountersFor(int championId, Position position, int maxCount = 5) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(await GetChampionURL(championId), soft: true)); return(await doc.DocumentNode .QuerySelectorAll(".row._yq1p7n._cu8r22._gzehfc") .ElementAt(1) .QuerySelectorAll("img") .Select(o => { var imgUrl = o.GetAttributeValue("src", ""); if (string.IsNullOrEmpty(imgUrl)) { return null; } var champKey = Path.GetFileNameWithoutExtension(new Uri(imgUrl).Segments.ArrayLast()); return Riot.GetChampionAsync(champKey); }) .Where(o => o != null) .Take(maxCount) .ToArray() .AwaitAll()); }
public override async Task <Champion[]> GetCountersFor(int championId, Position position, int maxCount = 5) { var json = JObject.Parse(await WebCache.String($"https://stats2.u.gg/lol/{UGGApiVersion}/matchups/{await GetLolUGGVersion()}/ranked_solo_5x5/{championId}/{UGGOverviewVersion}.json")); var ret = await Task.WhenAll(json["1"]["1"][IdToPosition.Invert()[position].ToString()][0] .Take(maxCount) .Select(o => Riot.GetChampionAsync(o[0].Value <int>())).ToArray()); return(ret); }
private async Task <string> GetLolUGGVersion() { if (_LolUGGVersion == null) { var url = $"https://u.gg/json/new_ugg_versions/{UGGDataVersion}.json"; var json = JObject.Parse(await WebCache.String(url)); _LolUGGVersion = (json.Children().First().Next as JProperty).Name; } return(_LolUGGVersion); }
protected async Task <JObject> GetChampionData(int championId) { if (!ChampionData.TryGetValue(championId, out var data)) { string url = $"https://stats2.u.gg/lol/{UGGApiVersion}/overview/{await GetLolUGGVersion()}/ranked_solo_5x5/{championId}/{UGGOverviewVersion}.json"; var json = JObject.Parse(await WebCache.String(url, soft: true)); ChampionData[championId] = data = (JObject)json[OverviewWorld.ToString()][OverviewPlatPlus.ToString()]; } return(data); }
public override async Task <RunePage> GetRunePage(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetChampionURL(championId, position), soft: true)); var pathIcons = doc.DocumentNode.SelectNodes("//img[contains(@class, 'PathButton__Icon')]").Take(2); var pathStyles = pathIcons.Select(GetPathStyleId).ToArray(); var perkIcons = doc.DocumentNode.SelectNodes("//div[contains(@class, 'LeftSide')]//img[contains(@class, 'PerkButton__Icon')]").Take(9); var perkIds = perkIcons.Select(GetPerkId).ToArray(); return(FillStatsIfNone(new RunePage(perkIds, pathStyles[0], pathStyles[1], championId, position))); }
public override async Task <Position[]> GetPossibleRoles(int championId) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(await GetChampionURL(championId), soft: true)); return(doc.DocumentNode .QuerySelectorAll("a._yeu4ck") .Select(o => { var linkHref = o.GetAttributeValue("href", "").Split('/').ArrayLast(); return PositionNames.Single(i => i.Value == linkHref).Key; }) .ToArray()); }
public async Task Load(IProgress <float> progress) { if (!File.Exists("guesser_data.json")) { var ugg = new UGGProvider(); var version = await Riot.GetLatestVersionAsync(); var data = JObject.Parse(await WebCache.String($"http://ddragon.leagueoflegends.com/cdn/{version}/data/en_US/champion.json")); var champions = data["data"].ToObject <Dictionary <string, TeamChampion> >(); var ev = new AsyncCountdownEvent(8); int champCount = 0; int totalChamps = champions.Count; foreach (var champs in Partitioner.Create(champions.Values).GetPartitions(8)) { new Thread(async() => { while (champs.MoveNext()) { var champ = champs.Current; var roles = (await ugg.GetDeepRoles(champ.ID)).ToArray(); Console.WriteLine($"{champ.Name}: {string.Join(", ", roles)}"); ChampionPositions[champ.ID] = roles; progress?.Report((float)champCount / totalChamps); } ev.Signal(); }).Start(); } await ev.WaitAsync(); ugg = null; GC.Collect(); File.WriteAllText("guesser_data.json", JsonConvert.SerializeObject(ChampionPositions)); } else { ChampionPositions = JsonConvert.DeserializeObject <Dictionary <int, PositionData[]> >(File.ReadAllText("guesser_data.json")); } }
public override async Task <Champion[]> GetCountersFor(int championId, Position position, int maxCount = 5) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetRoleUrl(championId, position), soft: false)); var rows = doc.DocumentNode.QuerySelectorAll(".champion-stats-header-matchup__table--strong > tbody > tr"); var ids = rows.Select(o => o.GetAttributeValue("data-champion-id", 0)); var champs = new List <Champion>(); foreach (var item in ids.Take(maxCount)) { champs.Add(await Riot.GetChampionAsync(item)); } return(champs.ToArray()); }
public override async Task <ItemSet> GetItemSet(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetChampionURL(championId, position), soft: true)); var buildWrappers = doc.DocumentNode.Descendants().Where(o => o.HasClass("build-wrapper")).Reverse(); var blocks = new List <ItemSet.SetBlock>(); foreach (var wrapper in buildWrappers) { string title = wrapper.PreviousSibling.PreviousSibling.InnerText; var items = new List <int>(); string[] stats = wrapper.Descendants() .Where(o => o.Name == "strong" && o.ParentNode.HasClass("build-text")) .Select(o => o.InnerText) .ToArray(); foreach (var item in wrapper.Descendants().Where(o => o.Name == "img")) { items.Add(ParseItem(item)); } blocks.Add(new ItemSet.SetBlock { Items = items.ToArray(), Name = $"{title} ({stats[0]} win rate | {stats[1]} games)" }); } return(new ItemSet { Champion = championId, Position = position, Blocks = blocks.ToArray(), Name = this.Name + ": " + position }); int ParseItem(HtmlNode aNode) { return(int.Parse(aNode.GetAttributeValue("data-id", ""))); } }
private async Task <string> GetLolUGGVersion() { if (_LolUGGVersion == null) { var page = await WebCache.String("https://u.gg", soft : true); var scriptUrl = Regex.Match(page, @"src=""(.*/main\..*?\.js)").Groups[1].Value; var scriptText = await WebCache.String(scriptUrl, soft : true); var versionsJson = Regex.Match(scriptText, @"(?<=\=)\[\{value:""\d+_\d+.*?]").Value; var versions = JArray.Parse(versionsJson); _LolUGGVersion = versions[0]["value"].ToObject <string>(); } return(_LolUGGVersion); }
public override async Task <RunePage> GetRunePage(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(await GetRoleUrl(championId, position), soft: true)); var pages = doc.DocumentNode.Descendants().Where(o => o.HasClass("perk-page")).Take(2); int[][] pageRows = pages.SelectMany(o => o.Descendants().Select(ParseRow)).Select(o => o.ToArray()).Where(o => o.Length > 0).ToArray(); var perks = pageRows.Where((_, i) => i != 0 && i != 5).SelectMany(o => o).ToList(); var fragments = doc.DocumentNode.Descendants().Where(o => o.HasClass("fragment__row")).Take(3); perks.AddRange(fragments.Select(o => { var src = o.Descendants().Single(i => i.HasClass("tip") && i.HasClass("active")).GetAttributeValue("src", ""); return(int.Parse(Regex.Match(src, @"(?<=perkShard\/).*?(?=\.png)").Value)); })); return(new RunePage(perks.ToArray(), pageRows[0][0], pageRows[5][0], championId, position)); }
public override async Task <string> GetSkillOrder(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(await GetRoleUrl(championId, position), soft: true)); char[] tips = doc.DocumentNode.Descendants("li") .Where(o => o.HasClass("champion-stats__list__item") && o.HasClass("tip")) .Take(3) .Select(o => o.Descendants("span").First().InnerText[0]) .ToArray(); char[] slong = doc.DocumentNode.Descendants("table") .First(o => o.HasClass("champion-skill-build__table")) .Descendants("tr").Last() .Descendants() .Where(o => o.Name.Equals("td", StringComparison.OrdinalIgnoreCase)) .Select(o => o.HasClass("tip") ? o.Descendants("span").First().InnerText.TrimStart()[0] : o.InnerText.TrimStart()[0]) .ToArray(); return($"({string.Join (">", tips)}) {new string (slong)}"); }
public override async Task <Position[]> GetPossibleRoles(int championId) { string champ = (await Riot.GetChampion(championId)).Key; var ret = new SynchronizedCollection <Position> (); await Task.WhenAll(PositionToName.Select(async item => { if (item.Key == Position.Fill) { return; } var data = await WebCache.String($"http://lolflavor.com/champions/{champ}/Recommended/{champ}_{item.Value}_scrape.json", soft: true); if (data != null) { ret.Add(item.Key); } })); return(ret.ToArray()); }
public override async Task <RunePage> GetRunePage(int championId, Position position) { var doc = new HtmlDocument(); doc.LoadHtml(await WebCache.String(GetRoleUrl(championId, position), soft: true)); var runeClasses = doc.DocumentNode.SelectNodes("//div[@class='runeclassicon']"); if (runeClasses.Count != 2) { throw new FormatException("More than 2 rune trees found."); } var runes = doc.DocumentNode.SelectNodes("//div[contains(@class, 'tip')]"); if (runes.Count != 6) { throw new FormatException("Couldn't find all runes."); } var page = new RunePage { ChampionID = championId, Position = position, PrimaryTree = GetRuneClass(runeClasses[0]), SecondaryTree = GetRuneClass(runeClasses[1]), RuneIDs = runes.Select(o => int.Parse(o.GetAttributeValue("data-id", "0"))).ToArray() }; page.PrimaryTree = Swap(page.PrimaryTree, 8300, 8400); page.SecondaryTree = Swap(page.SecondaryTree, 8300, 8400); return(page); int GetRuneClass(HtmlNode node) => int.Parse(Regex.Match(node.ChildNodes[0].GetAttributeValue("src", ""), @"(?<=\/)\d+(?=\.)").Value); int Swap(int v, int a, int b) => v == a ? b : v == b ? a : v; }