Пример #1
0
        static void Main(string[] args)
        {
            // Create query parameters
            // TODO: pass these in on command line, or in a settings file?
            RiotQuerySettings querySettings = new RiotQuerySettings(Queue.RankedSolo5x5);

            // Parse api key from args
            if (args.Length == 0)
                return;

            // Check if no-download mode is requested
            // NOTE: will only disable player/match queries
            if (args.Contains("-nodownload"))
            {
                querySettings.NoDownload = true;
                args = args.Where(arg => arg != "-nodownload").ToArray();
            }

            string apiKey = args[0];

            // Check if rates were included in the args
            RiotApi api = null;
            if (args.Length >= 3)
            {
                int rateper10s, rateper10m;
                if (int.TryParse(args[1], out rateper10s) && int.TryParse(args[2], out rateper10m))
                {
                    // Create a production API
                    api = RiotApi.GetInstance(apiKey, rateper10s, rateper10m);
                }
            }

            if (api == null)
            {
                // No rates, create a non-production API
                api = RiotApi.GetInstance(apiKey);
            }

            // Get static API and initialize static data
            StaticRiotApi staticApi = StaticRiotApi.GetInstance(apiKey);
            StaticDataStore.Initialize(staticApi);

            // Create pipeline
            //ChampionWinCounter winCounter = new ChampionWinCounter();
            ItemPurchaseRecorder purchaseRecorder = new ItemPurchaseRecorder();
            MatchPipeline pipeline = new MatchPipeline(api, querySettings, purchaseRecorder);
            pipeline.Process();

            // Get stats
            var championPurchaseStats =
                purchaseRecorder.ChampionPurchaseTrackers.ToDictionary(
                    kvp => kvp.Value.ChampionId,
                    kvp => kvp.Value.GetStats());

            // Generate item sets
            Dictionary<PurchaseSetKey, ItemSet> itemSets = ItemSetGenerator.generateAll(championPurchaseStats);

            // Write all sets to disk
            string itemSetRoot = "itemsets";
            string webDataRoot = "web";

            string webItemSetRoot = Path.Combine(webDataRoot, itemSetRoot);

            // Create web directory if it doesn't exist
            if (!Directory.Exists(webDataRoot))
                Directory.CreateDirectory(webDataRoot);

            // Clear old item sets
            if (Directory.Exists(webItemSetRoot))
                Directory.Delete(webItemSetRoot, true);

            Directory.CreateDirectory(webItemSetRoot);

            // Filter out sets we don't consider valid
            long minMatchCount = Math.Min(
                SetBuilderSettings.FilterMatchMinCount,
                (long)((double)pipeline.MatchCount * SetBuilderSettings.FilterMatchMinPercentage));

            var filteredSets = itemSets.Where(kvp =>
            {
                // Filter out item sets without a minimum percentage of matches
                if (kvp.Value.MatchCount < minMatchCount)
                    return false;

                // While smiteless-jungle might be viable, from the data this looks more like a
                // situation where the champion in question was roaming a lot, so the lane was
                // misidentified as jungle. We'll just exclude these for now.
                if (SetBuilderSettings.FilterExcludeNoSmiteJungle &&
                    kvp.Value.SetKey.Lane == Lane.Jungle && !kvp.Value.SetKey.HasSmite)
                    return false;

                // All other sets are fine
                return true;
            });

            // Group sets
            var groupedSets = filteredSets.GroupBy(kvp => kvp.Key.ChampionId);

            // Combine sets
            var smiteSpell = StaticDataStore.SummonerSpells.SummonerSpells["SummonerSmite"];

            var combinedSets = groupedSets.Select(g =>
            {
                // If there aren't two sets, or the two sets both do or don't have smite
                if (g.Count() != 2 ||
                    !(g.Any(set => set.Key.HasSmite) && g.Any(set => set.Key.HasSmite)))
                    return new { Key = g.Key, Sets = g.ToList(), HasOtherLane = false, OtherLane = Lane.Bot };

                var seta = g.ElementAt(0);
                var setb = g.ElementAt(1);

                var smiteset = seta.Key.HasSmite ? seta : setb;
                var nosmiteset = seta.Key.HasSmite ? setb : seta;

                // Mark set blocks as smite required or not required
                smiteset.Value.blocks.ForEach(block => block.showIfSummonerSpell = smiteSpell.Key);
                nosmiteset.Value.blocks.ForEach(block => block.hideIfSummonerSpell = smiteSpell.Key);

                // Combine into smite set
                smiteset.Value.MatchCount = Math.Max(smiteset.Value.MatchCount, nosmiteset.Value.MatchCount);
                smiteset.Value.blocks.AddRange(nosmiteset.Value.blocks);

                // Return combined block
                return new { Key = g.Key, Sets = Enumerable.Repeat(smiteset, 1).ToList(), HasOtherLane = true, OtherLane = nosmiteset.Key.Lane };
            }).ToList();

            // Generate names for item sets
            var setsWithNames = combinedSets.SelectMany(g =>
            {
                var champion = StaticDataStore.Champions.GetChampionById(g.Key);

                // Ensure the champion directory exists
                string webpath = Path.Combine(itemSetRoot, champion.Key, "Recommended");
                string path = Path.Combine(webDataRoot, webpath);
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                // Find differentiating fields
                bool diffHasSmite = g.Sets.Any(kvp => kvp.Key.HasSmite != g.Sets.First().Key.HasSmite);
                bool diffLane = g.Sets.Any(kvp => kvp.Key.Lane != g.Sets.First().Key.Lane);

                // Create name for each based on differentiating fields
                return g.Sets.Select(setkvp =>
                {
                    string filename = "ProBuilds_" + champion.Key;
                    string title = "";

                    // Always handle combined sets specially
                    if (g.Sets.Count == 1 && g.HasOtherLane == true)
                    {
                        title += g.OtherLane.ToString() + " / " + g.Sets.First().Key.Lane.ToString();
                        filename += "_" + g.OtherLane.ToString() + "_" + g.Sets.First().Key.Lane.ToString();
                    }
                    else
                    {
                        // We always write out jungle
                        // We always write out the lane if it has smite (to differentiate it from jungle)
                        if (g.Sets.Count == 1 ||
                            diffLane ||
                            (setkvp.Key.Lane == Lane.Jungle && !setkvp.Value.blocks.Any(block => block.showIfSummonerSpell != "")) ||
                            setkvp.Key.HasSmite)
                        {
                            title += setkvp.Key.Lane.ToString();
                            filename += "_" + setkvp.Key.Lane.ToString();
                        }

                        if (diffHasSmite)
                        {
                            // Add smite information to title if jungling without smite, or taking smite without jungling
                            if ((setkvp.Key.HasSmite && setkvp.Key.Lane != Lane.Jungle) ||
                                (!setkvp.Key.HasSmite && setkvp.Key.Lane == Lane.Jungle))
                            {
                                title += setkvp.Key.HasSmite ? " with Smite" : " without Smite";
                            }

                            filename += setkvp.Key.HasSmite ? "_Smite" : "_NoSmite";
                        }
                    }

                    // Set the title
                    setkvp.Value.title = title;

                    filename += ".json";

                    return new
                    {
                        Name = filename,
                        WebPath = webpath,
                        FilePath = path,
                        Key = setkvp.Key,
                        Set = setkvp.Value
                    };
                });
            }).ToList();

            // Write item sets
            var setfiles = setsWithNames.AsParallel().WithDegreeOfParallelism(4).Select(set =>
            {
                string filename = set.Name;
                string file = Path.Combine(set.FilePath, filename);
                string setJson = JsonConvert.SerializeObject(set.Set);
                File.WriteAllText(file, setJson);

                return new { Key = set.Key, File = Path.Combine(set.WebPath, filename).Replace('\\', '/'), Title = set.Set.title };
            }).GroupBy(set => set.Key.ChampionId).ToDictionary(
                g => StaticDataStore.Champions.Keys[g.Key],
                g => g.ToList());

            // Write static data
            string championsfile = Path.Combine(webDataRoot, "champions.json");
            string itemsfile = Path.Combine(webDataRoot, "items.json");
            string summonerspellsfile = Path.Combine(webDataRoot, "summonerspells.json");

            string championsjson = JsonConvert.SerializeObject(StaticDataStore.Champions);
            string itemsjson = JsonConvert.SerializeObject(StaticDataStore.Items);
            string summonerspellsjson = JsonConvert.SerializeObject(StaticDataStore.SummonerSpells);

            File.WriteAllText(championsfile, championsjson);
            File.WriteAllText(itemsfile, itemsjson);
            File.WriteAllText(summonerspellsfile, summonerspellsjson);

            // Write item set manifest
            var manifest = new { root = itemSetRoot + Path.DirectorySeparatorChar, sets = setfiles };

            string manifestfile = Path.Combine(webDataRoot, "setmanifest.json");
            string manifestjson = JsonConvert.SerializeObject(manifest);

            File.WriteAllText(manifestfile, manifestjson);

            // Zip all item sets
            string zipSource = webItemSetRoot;
            string zipOutputFilename =  Path.Combine(webDataRoot, "allprosets.zip");
            if (File.Exists(zipOutputFilename))
                File.Delete(zipOutputFilename);

            ZipFile.CreateFromDirectory(zipSource, zipOutputFilename);

            // Serialize all purchase stats
            //string json = JsonConvert.SerializeObject(championPurchaseStats);

            // Complete
            Console.WriteLine();
            Console.WriteLine("Complete, press any key to exit");
            Console.ReadKey();
        }
Пример #2
0
        static void Main(string[] args)
        {
            // Create query parameters
            // TODO: pass these in on command line, or in a settings file?
            RiotQuerySettings querySettings = new RiotQuerySettings(Queue.RankedSolo5x5);

            // Parse api key from args
            if (args.Length == 0)
            {
                return;
            }

            // Check if no-download mode is requested
            // NOTE: will only disable player/match queries
            if (args.Contains("-nodownload"))
            {
                querySettings.NoDownload = true;
                args = args.Where(arg => arg != "-nodownload").ToArray();
            }

            string apiKey = args[0];

            // Check if rates were included in the args
            RiotApi api = null;

            if (args.Length >= 3)
            {
                int rateper10s, rateper10m;
                if (int.TryParse(args[1], out rateper10s) && int.TryParse(args[2], out rateper10m))
                {
                    // Create a production API
                    api = RiotApi.GetInstance(apiKey, rateper10s, rateper10m);
                }
            }

            if (api == null)
            {
                // No rates, create a non-production API
                api = RiotApi.GetInstance(apiKey);
            }

            // Get static API and initialize static data
            StaticRiotApi staticApi = StaticRiotApi.GetInstance(apiKey);

            StaticDataStore.Initialize(staticApi);

            // Create pipeline
            //ChampionWinCounter winCounter = new ChampionWinCounter();
            ItemPurchaseRecorder purchaseRecorder = new ItemPurchaseRecorder();
            MatchPipeline        pipeline         = new MatchPipeline(api, querySettings, purchaseRecorder);

            pipeline.Process();

            // Get stats
            var championPurchaseStats =
                purchaseRecorder.ChampionPurchaseTrackers.ToDictionary(
                    kvp => kvp.Value.ChampionId,
                    kvp => kvp.Value.GetStats());

            // Generate item sets
            Dictionary <PurchaseSetKey, ItemSet> itemSets = ItemSetGenerator.generateAll(championPurchaseStats);

            // Write all sets to disk
            string itemSetRoot = "itemsets";
            string webDataRoot = "web";

            string webItemSetRoot = Path.Combine(webDataRoot, itemSetRoot);

            // Create web directory if it doesn't exist
            if (!Directory.Exists(webDataRoot))
            {
                Directory.CreateDirectory(webDataRoot);
            }

            // Clear old item sets
            if (Directory.Exists(webItemSetRoot))
            {
                Directory.Delete(webItemSetRoot, true);
            }

            Directory.CreateDirectory(webItemSetRoot);

            // Filter out sets we don't consider valid
            long minMatchCount = Math.Min(
                SetBuilderSettings.FilterMatchMinCount,
                (long)((double)pipeline.MatchCount * SetBuilderSettings.FilterMatchMinPercentage));

            var filteredSets = itemSets.Where(kvp =>
            {
                // Filter out item sets without a minimum percentage of matches
                if (kvp.Value.MatchCount < minMatchCount)
                {
                    return(false);
                }

                // While smiteless-jungle might be viable, from the data this looks more like a
                // situation where the champion in question was roaming a lot, so the lane was
                // misidentified as jungle. We'll just exclude these for now.
                if (SetBuilderSettings.FilterExcludeNoSmiteJungle &&
                    kvp.Value.SetKey.Lane == Lane.Jungle && !kvp.Value.SetKey.HasSmite)
                {
                    return(false);
                }

                // All other sets are fine
                return(true);
            });

            // Group sets
            var groupedSets = filteredSets.GroupBy(kvp => kvp.Key.ChampionId);

            // Combine sets
            var smiteSpell = StaticDataStore.SummonerSpells.SummonerSpells["SummonerSmite"];

            var combinedSets = groupedSets.Select(g =>
            {
                // If there aren't two sets, or the two sets both do or don't have smite
                if (g.Count() != 2 ||
                    !(g.Any(set => set.Key.HasSmite) && g.Any(set => set.Key.HasSmite)))
                {
                    return new { Key = g.Key, Sets = g.ToList(), HasOtherLane = false, OtherLane = Lane.Bot }
                }
                ;

                var seta = g.ElementAt(0);
                var setb = g.ElementAt(1);

                var smiteset   = seta.Key.HasSmite ? seta : setb;
                var nosmiteset = seta.Key.HasSmite ? setb : seta;

                // Mark set blocks as smite required or not required
                smiteset.Value.blocks.ForEach(block => block.showIfSummonerSpell   = smiteSpell.Key);
                nosmiteset.Value.blocks.ForEach(block => block.hideIfSummonerSpell = smiteSpell.Key);

                // Combine into smite set
                smiteset.Value.MatchCount = Math.Max(smiteset.Value.MatchCount, nosmiteset.Value.MatchCount);
                smiteset.Value.blocks.AddRange(nosmiteset.Value.blocks);

                // Return combined block
                return(new { Key = g.Key, Sets = Enumerable.Repeat(smiteset, 1).ToList(), HasOtherLane = true, OtherLane = nosmiteset.Key.Lane });
            }).ToList();

            // Generate names for item sets
            var setsWithNames = combinedSets.SelectMany(g =>
            {
                var champion = StaticDataStore.Champions.GetChampionById(g.Key);

                // Ensure the champion directory exists
                string webpath = Path.Combine(itemSetRoot, champion.Key, "Recommended");
                string path    = Path.Combine(webDataRoot, webpath);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                // Find differentiating fields
                bool diffHasSmite = g.Sets.Any(kvp => kvp.Key.HasSmite != g.Sets.First().Key.HasSmite);
                bool diffLane     = g.Sets.Any(kvp => kvp.Key.Lane != g.Sets.First().Key.Lane);

                // Create name for each based on differentiating fields
                return(g.Sets.Select(setkvp =>
                {
                    string filename = "ProBuilds_" + champion.Key;
                    string title = "";

                    // Always handle combined sets specially
                    if (g.Sets.Count == 1 && g.HasOtherLane == true)
                    {
                        title += g.OtherLane.ToString() + " / " + g.Sets.First().Key.Lane.ToString();
                        filename += "_" + g.OtherLane.ToString() + "_" + g.Sets.First().Key.Lane.ToString();
                    }
                    else
                    {
                        // We always write out jungle
                        // We always write out the lane if it has smite (to differentiate it from jungle)
                        if (g.Sets.Count == 1 ||
                            diffLane ||
                            (setkvp.Key.Lane == Lane.Jungle && !setkvp.Value.blocks.Any(block => block.showIfSummonerSpell != "")) ||
                            setkvp.Key.HasSmite)
                        {
                            title += setkvp.Key.Lane.ToString();
                            filename += "_" + setkvp.Key.Lane.ToString();
                        }

                        if (diffHasSmite)
                        {
                            // Add smite information to title if jungling without smite, or taking smite without jungling
                            if ((setkvp.Key.HasSmite && setkvp.Key.Lane != Lane.Jungle) ||
                                (!setkvp.Key.HasSmite && setkvp.Key.Lane == Lane.Jungle))
                            {
                                title += setkvp.Key.HasSmite ? " with Smite" : " without Smite";
                            }

                            filename += setkvp.Key.HasSmite ? "_Smite" : "_NoSmite";
                        }
                    }

                    // Set the title
                    setkvp.Value.title = title;

                    filename += ".json";

                    return new
                    {
                        Name = filename,
                        WebPath = webpath,
                        FilePath = path,
                        Key = setkvp.Key,
                        Set = setkvp.Value
                    };
                }));
            }).ToList();

            // Write item sets
            var setfiles = setsWithNames.AsParallel().WithDegreeOfParallelism(4).Select(set =>
            {
                string filename = set.Name;
                string file     = Path.Combine(set.FilePath, filename);
                string setJson  = JsonConvert.SerializeObject(set.Set);
                File.WriteAllText(file, setJson);

                return(new { Key = set.Key, File = Path.Combine(set.WebPath, filename).Replace('\\', '/'), Title = set.Set.title });
            }).GroupBy(set => set.Key.ChampionId).ToDictionary(
                g => StaticDataStore.Champions.Keys[g.Key],
                g => g.ToList());


            // Write static data
            string championsfile      = Path.Combine(webDataRoot, "champions.json");
            string itemsfile          = Path.Combine(webDataRoot, "items.json");
            string summonerspellsfile = Path.Combine(webDataRoot, "summonerspells.json");

            string championsjson      = JsonConvert.SerializeObject(StaticDataStore.Champions);
            string itemsjson          = JsonConvert.SerializeObject(StaticDataStore.Items);
            string summonerspellsjson = JsonConvert.SerializeObject(StaticDataStore.SummonerSpells);

            File.WriteAllText(championsfile, championsjson);
            File.WriteAllText(itemsfile, itemsjson);
            File.WriteAllText(summonerspellsfile, summonerspellsjson);

            // Write item set manifest
            var manifest = new { root = itemSetRoot + Path.DirectorySeparatorChar, sets = setfiles };

            string manifestfile = Path.Combine(webDataRoot, "setmanifest.json");
            string manifestjson = JsonConvert.SerializeObject(manifest);

            File.WriteAllText(manifestfile, manifestjson);

            // Zip all item sets
            string zipSource         = webItemSetRoot;
            string zipOutputFilename = Path.Combine(webDataRoot, "allprosets.zip");

            if (File.Exists(zipOutputFilename))
            {
                File.Delete(zipOutputFilename);
            }

            ZipFile.CreateFromDirectory(zipSource, zipOutputFilename);

            // Serialize all purchase stats
            //string json = JsonConvert.SerializeObject(championPurchaseStats);

            // Complete
            Console.WriteLine();
            Console.WriteLine("Complete, press any key to exit");
            Console.ReadKey();
        }