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());
        }
예제 #3
0
        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()
            });
        }
예제 #4
0
        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());
        }
예제 #5
0
        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());
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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)));
        }
예제 #10
0
        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());
        }
예제 #11
0
        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"));
            }
        }
예제 #12
0
        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", "")));
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
        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));
        }
예제 #16
0
        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)}");
        }
예제 #17
0
        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());
        }
예제 #18
0
        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;
        }