Example #1
0
        public override void Execute()
        {
            var displayPlays = new List <UserPlayInfo>();

            var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);

            Console.WriteLine("Getting user data...");
            dynamic userData = getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={Ruleset}")[0];

            Console.WriteLine("Getting user top scores...");

            foreach (var play in getJsonFromApi($"get_user_best?k={Key}&u={ProfileName}&m={Ruleset}&limit=100"))
            {
                string beatmapID = play.beatmap_id;

                string cachePath = Path.Combine("cache", $"{beatmapID}.osu");

                if (!File.Exists(cachePath))
                {
                    Console.WriteLine($"Downloading {beatmapID}.osu...");
                    new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").Perform();
                }

                Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)play.enabled_mods).ToArray();

                var working = new ProcessorWorkingBeatmap(cachePath, (int)play.beatmap_id);

                var score = new ProcessorScoreDecoder(working).Parse(new ScoreInfo
                {
                    Ruleset    = ruleset.RulesetInfo,
                    MaxCombo   = play.maxcombo,
                    Mods       = mods,
                    Statistics = new Dictionary <HitResult, int>
                    {
                        { HitResult.Perfect, (int)play.countgeki },
                        { HitResult.Great, (int)play.count300 },
                        { HitResult.Good, (int)play.count100 },
                        { HitResult.Ok, (int)play.countkatu },
                        { HitResult.Meh, (int)play.count50 },
                        { HitResult.Miss, (int)play.countmiss }
                    }
                });

                var thisPlay = new UserPlayInfo
                {
                    Beatmap = working.BeatmapInfo,
                    LocalPP = ruleset.CreatePerformanceCalculator(working, score.ScoreInfo).Calculate(),
                    LivePP  = play.pp,
                    Mods    = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}") : "None"
                };

                displayPlays.Add(thisPlay);
            }

            var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
            var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

            int    index        = 0;
            double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);
            double totalLivePP  = userData.pp_raw;

            index = 0;
            double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

            //todo: implement properly. this is pretty damn wrong.
            var playcountBonusPP = (totalLivePP - nonBonusLivePP);

            totalLocalPP += playcountBonusPP;
            double totalDiffPP = totalLocalPP - totalLivePP;

            OutputDocument(new Document(
                               new Span($"User:     {userData.username}"), "\n",
                               new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                               new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                               new Grid
            {
                Columns  = { GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto },
                Children =
                {
                    new Cell("beatmap"),
                    new Cell("live pp"),
                    new Cell("local pp"),
                    new Cell("pp change"),
                    new Cell("position change"),
                    localOrdered.Select(item => new[]
                    {
                        new Cell($"{item.Beatmap.OnlineBeatmapID} - {item.Beatmap}"),
                        new Cell($"{item.LivePP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{item.LocalPP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{item.LocalPP - item.LivePP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                        {
                            Align = Align.Center
                        },
                    })
                }
            }
                               ));
        }
Example #2
0
        public override void Execute()
        {
            var displayPlays = new List <UserPlayInfo>();

            var ruleset        = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);
            var rulesetApiName = LegacyHelper.GetRulesetShortNameFromId(Ruleset ?? 0);

            Console.WriteLine("Getting user data...");
            dynamic userData = GetJsonFromApi($"users/{ProfileName}/{rulesetApiName}");

            Console.WriteLine("Getting user top scores...");

            foreach (var play in GetJsonFromApi($"users/{userData.id}/scores/best?mode={rulesetApiName}&limit=100"))
            {
                var working = ProcessorWorkingBeatmap.FromFileOrId((string)play.beatmap.id);

                var   modsAcronyms = ((JArray)play.mods).Select(x => x.ToString()).ToArray();
                Mod[] mods         = ruleset.CreateAllMods().Where(m => modsAcronyms.Contains(m.Acronym)).ToArray();

                var scoreInfo = new ScoreInfo(working.BeatmapInfo, ruleset.RulesetInfo)
                {
                    TotalScore = play.score,
                    MaxCombo   = play.max_combo,
                    Mods       = mods,
                    Statistics = new Dictionary <HitResult, int>()
                };

                scoreInfo.SetCount300((int)play.statistics.count_300);
                scoreInfo.SetCountGeki((int)play.statistics.count_geki);
                scoreInfo.SetCount100((int)play.statistics.count_100);
                scoreInfo.SetCountKatu((int)play.statistics.count_katu);
                scoreInfo.SetCount50((int)play.statistics.count_50);
                scoreInfo.SetCountMiss((int)play.statistics.count_miss);

                var score = new ProcessorScoreDecoder(working).Parse(scoreInfo);

                var difficultyCalculator  = ruleset.CreateDifficultyCalculator(working);
                var difficultyAttributes  = difficultyCalculator.Calculate(LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(ruleset, scoreInfo.Mods).ToArray());
                var performanceCalculator = ruleset.CreatePerformanceCalculator();

                var ppAttributes = performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes);
                var thisPlay     = new UserPlayInfo
                {
                    Beatmap   = working.BeatmapInfo,
                    LocalPP   = ppAttributes?.Total ?? 0,
                    LivePP    = play.pp,
                    Mods      = scoreInfo.Mods.Select(m => m.Acronym).ToArray(),
                    MissCount = play.statistics.count_miss,
                    Accuracy  = scoreInfo.Accuracy * 100,
                    Combo     = play.max_combo,
                    MaxCombo  = difficultyAttributes.MaxCombo
                };

                displayPlays.Add(thisPlay);
            }

            var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
            var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

            int    index        = 0;
            double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);
            double totalLivePP  = userData.statistics.pp;

            index = 0;
            double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

            //todo: implement properly. this is pretty damn wrong.
            var playcountBonusPP = (totalLivePP - nonBonusLivePP);

            totalLocalPP += playcountBonusPP;
            double totalDiffPP = totalLocalPP - totalLivePP;

            if (OutputJson)
            {
                var json = JsonConvert.SerializeObject(new
                {
                    Username    = userData.username,
                    LivePp      = totalLivePP,
                    LocalPp     = totalLocalPP,
                    PlaycountPp = playcountBonusPP,
                    Scores      = localOrdered.Select(item => new
                    {
                        BeatmapId   = item.Beatmap.OnlineID,
                        BeatmapName = item.Beatmap.ToString(),
                        item.Combo,
                        item.Accuracy,
                        item.MissCount,
                        item.Mods,
                        LivePp         = item.LivePP,
                        LocalPp        = item.LocalPP,
                        PositionChange = liveOrdered.IndexOf(item) - localOrdered.IndexOf(item)
                    })
                });

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                OutputDocument(new Document(
                                   new Span($"User:     {userData.username}"), "\n",
                                   new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                                   new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                                   new Grid
                {
                    Columns =
                    {
                        GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto
                    },
                    Children =
                    {
                        new Cell("#"),
                        new Cell("beatmap"),
                        new Cell("max combo"),
                        new Cell("accuracy"),
                        new Cell("misses"),
                        new Cell("mods"),
                        new Cell("live pp"),
                        new Cell("local pp"),
                        new Cell("pp change"),
                        new Cell("position change"),
                        localOrdered.Select(item => new[]
                        {
                            new Cell($"{localOrdered.IndexOf(item) + 1}"),
                            new Cell($"{item.Beatmap.OnlineID} - {item.Beatmap}"),
                            new Cell($"{item.Combo}/{item.MaxCombo}x")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{Math.Round(item.Accuracy, 2)}%")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.MissCount}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{(item.Mods.Length > 0 ? string.Join(", ", item.Mods) : "None")}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP - item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                            {
                                Align = Align.Center
                            },
                        })
                    }
                })
                               );
            }
        }
Example #3
0
        public override void Execute()
        {
            var displayPlays = new List <UserPlayInfo>();

            var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);

            Console.WriteLine("Getting user data...");
            dynamic userData = getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={Ruleset}")[0];

            Console.WriteLine("Getting user top scores...");

            foreach (var play in getJsonFromApi($"get_user_best?k={Key}&u={ProfileName}&m={Ruleset}&limit=100"))
            {
                string beatmapID = play.beatmap_id;
                string cachePath = Path.Combine("cache", $"{beatmapID}.osu");

                if (!File.Exists(cachePath))
                {
                    Console.WriteLine($"Downloading {beatmapID}.osu...");
                    new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").Perform();
                }

                var working   = new ProcessorWorkingBeatmap(cachePath, (int)play.beatmap_id);
                var scoreInfo = new ScoreInfo
                {
                    Ruleset    = ruleset.RulesetInfo,
                    TotalScore = play.score,
                    MaxCombo   = play.maxcombo,
                    Mods       = ruleset.ConvertFromLegacyMods((LegacyMods)play.enabled_mods).ToArray(),
                    Statistics = new Dictionary <HitResult, int>()
                };

                scoreInfo.SetCount300((int)play.count300);
                scoreInfo.SetCountGeki((int)play.countgeki);
                scoreInfo.SetCount100((int)play.count100);
                scoreInfo.SetCountKatu((int)play.countkatu);
                scoreInfo.SetCount50((int)play.count50);
                scoreInfo.SetCountMiss((int)play.countmiss);

                var score = new ProcessorScoreDecoder(working).Parse(scoreInfo);

                var difficultyCalculator  = ruleset.CreateDifficultyCalculator(working);
                var difficultyAttributes  = difficultyCalculator.Calculate(LegacyHelper.TrimNonDifficultyAdjustmentMods(ruleset, scoreInfo.Mods).ToArray());
                var performanceCalculator = ruleset.CreatePerformanceCalculator(difficultyAttributes, score.ScoreInfo);

                var categories = new Dictionary <string, double>();
                var localPP    = performanceCalculator.Calculate(categories);
                var thisPlay   = new UserPlayInfo
                {
                    Beatmap   = working.BeatmapInfo,
                    LocalPP   = localPP,
                    LivePP    = play.pp,
                    Mods      = scoreInfo.Mods.Select(m => m.Acronym).ToArray(),
                    MissCount = play.countmiss,
                    Accuracy  = scoreInfo.Accuracy * 100,
                    Combo     = play.maxcombo,
                    MaxCombo  = (int)categories.GetValueOrDefault("Max Combo")
                };

                displayPlays.Add(thisPlay);
            }

            var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
            var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

            int    index        = 0;
            double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);
            double totalLivePP  = userData.pp_raw;

            index = 0;
            double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

            //todo: implement properly. this is pretty damn wrong.
            var playcountBonusPP = (totalLivePP - nonBonusLivePP);

            totalLocalPP += playcountBonusPP;
            double totalDiffPP = totalLocalPP - totalLivePP;

            if (OutputJson)
            {
                var json = JsonConvert.SerializeObject(new
                {
                    Username    = userData.username,
                    LivePp      = totalLivePP,
                    LocalPp     = totalLocalPP,
                    PlaycountPp = playcountBonusPP,
                    Scores      = localOrdered.Select(item => new
                    {
                        BeatmapId   = item.Beatmap.OnlineBeatmapID,
                        BeatmapName = item.Beatmap.ToString(),
                        item.Combo,
                        item.Accuracy,
                        item.MissCount,
                        item.Mods,
                        LivePp         = item.LivePP,
                        LocalPp        = item.LocalPP,
                        PositionChange = liveOrdered.IndexOf(item) - localOrdered.IndexOf(item)
                    })
                });

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                OutputDocument(new Document(
                                   new Span($"User:     {userData.username}"), "\n",
                                   new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                                   new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                                   new Grid
                {
                    Columns  = { GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto },
                    Children =
                    {
                        new Cell("#"),
                        new Cell("beatmap"),
                        new Cell("max combo"),
                        new Cell("accuracy"),
                        new Cell("misses"),
                        new Cell("mods"),
                        new Cell("live pp"),
                        new Cell("local pp"),
                        new Cell("pp change"),
                        new Cell("position change"),
                        localOrdered.Select(item => new[]
                        {
                            new Cell($"{localOrdered.IndexOf(item) + 1}"),
                            new Cell($"{item.Beatmap.OnlineBeatmapID} - {item.Beatmap}"),
                            new Cell($"{item.Combo}/{item.MaxCombo}x")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{Math.Round(item.Accuracy, 2)}%")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.MissCount}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{(item.Mods.Length > 0 ? string.Join(", ", item.Mods) : "None")}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP - item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                            {
                                Align = Align.Center
                            },
                        })
                    }
                })
                               );
            }
        }
Example #4
0
        public override void Execute()
        {
            if (Database == "false")
            {
                var displayPlays = new List <UserPlayInfo>();

                var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);

                Console.WriteLine("Getting user data...");
                dynamic userData = getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={Ruleset}")[0];

                Console.WriteLine("Getting user top scores...");

                foreach (var play in getJsonFromApi($"get_user_best?k={Key}&u={ProfileName}&m={Ruleset}&limit=100"))
                {
                    string beatmapID = play.beatmap_id;

                    string cachePath = Path.Combine("cache", $"{beatmapID}.osu");

                    if (!File.Exists(cachePath))
                    {
                        Console.WriteLine($"Downloading {beatmapID}.osu...");
                        new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").Perform();
                    }

                    Mod[] mods = ruleset.ConvertLegacyMods((LegacyMods)play.enabled_mods).ToArray();

                    var working = new ProcessorWorkingBeatmap(cachePath, (int)play.beatmap_id);

                    var score = new ProcessorScoreParser(working).Parse(new ScoreInfo
                    {
                        Ruleset    = ruleset.RulesetInfo,
                        MaxCombo   = play.maxcombo,
                        Mods       = mods,
                        Statistics = new Dictionary <HitResult, int>
                        {
                            { HitResult.Perfect, (int)play.countgeki },
                            { HitResult.Great, (int)play.count300 },
                            { HitResult.Good, (int)play.count100 },
                            { HitResult.Ok, (int)play.countkatu },
                            { HitResult.Meh, (int)play.count50 },
                            { HitResult.Miss, (int)play.countmiss }
                        }
                    });

                    var thisPlay = new UserPlayInfo
                    {
                        Beatmap = working.BeatmapInfo,
                        LocalPP = ruleset.CreatePerformanceCalculator(working, score.ScoreInfo).Calculate(),
                        LivePP  = play.pp,
                        Mods    = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}") : "None"
                    };

                    displayPlays.Add(thisPlay);
                }

                var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
                var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

                int    index        = 0;
                double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);
                double totalLivePP  = userData.pp_raw;

                index = 0;
                double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

                //todo: implement properly. this is pretty damn wrong.
                var playcountBonusPP = (totalLivePP - nonBonusLivePP);
                totalLocalPP += playcountBonusPP;
                double totalDiffPP = totalLocalPP - totalLivePP;

                OutputDocument(new Document(
                                   new Span($"User:     {userData.username}"), "\n",
                                   new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                                   new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                                   new Grid
                {
                    Columns  = { GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto },
                    Children =
                    {
                        new Cell("beatmap"),
                        new Cell("live pp"),
                        new Cell("local pp"),
                        new Cell("pp change"),
                        new Cell("position change"),
                        localOrdered.Select(item => new[]
                        {
                            new Cell($"{item.Beatmap.OnlineBeatmapID} - {item.Beatmap}"),
                            new Cell($"{item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP - item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                            {
                                Align = Align.Center
                            },
                        })
                    }
                }
                                   ));
            }
            else
            {
                var displayPlays = new List <UserPlayInfo>();

                var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);

                Console.WriteLine("Getting user data...");
                dynamic userData = getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={Ruleset}")[0];

                string[] config = { };

                if (File.Exists("db.cfg"))
                {
                    config = File.ReadAllLines("db.cfg");
                }
                else
                {
                    File.AppendAllLines("db.cfg", new string[] { "server=", "database=", "mysqlUsername="******"mySqlPassword="******"config file generated, fill it in, and rerun this program");
                    Environment.Exit(-1);
                }

                MySqlConnection connection = new MySqlConnection($"server={config[0].Split("=")[1]};database={config[1].Split("=")[1]};uid={config[2].Split("=")[1]};password={config[3].Split("=")[1]}");
                MySqlCommand    cmd        = new MySqlCommand($"SELECT * FROM `osu_scores_high` WHERE `user_id` = {userData.user_id}", connection);
                connection.Open();
                MySqlDataReader rdr = cmd.ExecuteReader();

                List <string> buffer = new List <string>();

                while (rdr.Read())
                {
                    int pp = 0;
                    try
                    {
                        pp = rdr.GetInt32("pp");
                        string beatmap_id = rdr.GetString("beatmap_id");

                        string[] blacklist = { "1257904" };

                        if (beatmap_id != blacklist[0])
                        {
                            buffer.Add($"{beatmap_id}|{rdr.GetString("enabled_mods")}|{rdr.GetInt32("maxcombo")}|{rdr.GetInt32("countgeki")}|{rdr.GetInt32("count300")}|{rdr.GetInt32("count100")}|{rdr.GetInt32("countkatu")}|{rdr.GetInt32("count50")}|{rdr.GetInt32("countmiss")}|{pp}\n");
                        }
                    }
                    catch (Exception e)
                    {
                        if (e.Message.Contains("null"))
                        {
                            pp = 0;
                        }
                        continue;
                    }
                }

                foreach (string s in buffer)
                {
                    string[] split     = s.Split('|');
                    string   beatmapID = split[0];
                    string   cachePath = Path.Combine("cache", $"{beatmapID}.osu");

                    if (!File.Exists(cachePath))
                    {
                        Console.WriteLine($"Downloading {beatmapID}.osu...");
                        new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").Perform();
                    }

                    Mod[] mods = ruleset.ConvertLegacyMods((LegacyMods)int.Parse(split[1])).ToArray();

                    var working = new ProcessorWorkingBeatmap(cachePath, int.Parse(split[0]));

                    var score = new ProcessorScoreParser(working).Parse(new ScoreInfo
                    {
                        Ruleset    = ruleset.RulesetInfo,
                        MaxCombo   = int.Parse(split[2]),
                        Mods       = mods,
                        Statistics = new Dictionary <HitResult, int>
                        {
                            { HitResult.Perfect, int.Parse(split[3]) },
                            { HitResult.Great, int.Parse(split[4]) },
                            { HitResult.Good, int.Parse(split[5]) },
                            { HitResult.Ok, int.Parse(split[6]) },
                            { HitResult.Meh, int.Parse(split[7]) },
                            { HitResult.Miss, int.Parse(split[8]) }
                        }
                    });

                    var thisPlay = new UserPlayInfo
                    {
                        Beatmap = working.BeatmapInfo,
                        LocalPP = ruleset.CreatePerformanceCalculator(working, score.ScoreInfo).Calculate(),
                        LivePP  = int.Parse(split[9]),
                        Mods    = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}") : "None"
                    };
                    displayPlays.Add(thisPlay);
                }
                var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
                var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

                int    index        = 0;
                double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);
                double totalLivePP  = userData.pp_raw;

                index = 0;
                double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

                //todo: implement properly. this is pretty damn wrong.
                var playcountBonusPP = (totalLivePP - nonBonusLivePP);
                totalLocalPP += playcountBonusPP;
                double totalDiffPP = totalLocalPP - totalLivePP;

                OutputDocument(new Document(
                                   new Span($"User:     {userData.username}"), "\n",
                                   new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                                   new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                                   new Grid
                {
                    Columns  = { GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto },
                    Children =
                    {
                        new Cell("beatmap"),
                        new Cell("live pp"),
                        new Cell("local pp"),
                        new Cell("pp change"),
                        new Cell("position change"),
                        localOrdered.Select(item => new[]
                        {
                            new Cell($"{item.Beatmap.OnlineBeatmapID} - {item.Beatmap}"),
                            new Cell($"{item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{item.LocalPP - item.LivePP:F1}")
                            {
                                Align = Align.Right
                            },
                            new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                            {
                                Align = Align.Center
                            },
                        })
                    }
                }
                                   ));
            }
        }
Example #5
0
        public override void Execute()
        {
            var displayPlays = new List <UserPlayInfo>();

            var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? 0);

            Console.WriteLine("Getting user data...");
            dynamic userData = getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={Ruleset}")[0];

            Console.WriteLine("Getting user top scores...");

            foreach (var play in getJsonFromApi($"get_user_best?k={Key}&u={ProfileName}&m={Ruleset}&limit=100"))
            {
                string beatmapID = play.beatmap_id;

                string cachePath = Path.Combine("cache", $"{beatmapID}.osu");

                if (!File.Exists(cachePath))
                {
                    Console.WriteLine($"Downloading {beatmapID}.osu...");
                    new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").Perform();
                }

                Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)play.enabled_mods).ToArray();

                var working = new ProcessorWorkingBeatmap(cachePath, (int)play.beatmap_id);

                var scoreInfo = new ScoreInfo
                {
                    Ruleset    = ruleset.RulesetInfo,
                    MaxCombo   = play.maxcombo,
                    Mods       = mods,
                    Statistics = new Dictionary <HitResult, int>
                    {
                        { HitResult.Perfect, (int)play.countgeki },
                        { HitResult.Great, (int)play.count300 },
                        { HitResult.Good, (int)play.countkatu },
                        { HitResult.Ok, (int)play.count100 },
                        { HitResult.Meh, (int)play.count50 },
                        { HitResult.Miss, (int)play.countmiss }
                    }
                };
                var score = new ProcessorScoreDecoder(working).Parse(scoreInfo);

                var categoryAttribs = new Dictionary <string, double>();
                OsuPerformanceCalculator calculator = (OsuPerformanceCalculator)ruleset.CreatePerformanceCalculator(working, score.ScoreInfo);
                double localPP = calculator.Calculate(categoryAttribs);

                var thisPlay = new UserPlayInfo
                {
                    Beatmap            = working.BeatmapInfo,
                    LocalPP            = localPP,
                    MapCategoryAttribs = categoryAttribs,
                    LivePP             = play.pp,
                    Mods            = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}|{n}") : "",
                    PlayMaxCombo    = scoreInfo.MaxCombo,
                    BeatmapMaxCombo = calculator.Attributes.MaxCombo,
                    PlayAccuracy    = scoreInfo.Accuracy,
                    MissCount       = scoreInfo.Statistics[HitResult.Miss]
                };

                displayPlays.Add(thisPlay);
            }

            var localOrdered = displayPlays.OrderByDescending(p => p.LocalPP).ToList();
            var liveOrdered  = displayPlays.OrderByDescending(p => p.LivePP).ToList();

            int    index        = 0;
            double totalLocalPP = localOrdered.Sum(play => Math.Pow(0.95, index++) * play.LocalPP);

            double totalLivePP = userData.pp_raw;

            index = 0;
            double nonBonusLivePP = liveOrdered.Sum(play => Math.Pow(0.95, index++) * play.LivePP);

            //todo: implement properly. this is pretty damn wrong.
            var playcountBonusPP = (totalLivePP - nonBonusLivePP);

            totalLocalPP += playcountBonusPP;
            double totalDiffPP = totalLocalPP - totalLivePP;

            for (int i = 0; i < localOrdered.Count; i++)
            {
                localOrdered[i].Position = i + 1;
            }

            if (SortColumnName != null)
            {
                localOrdered.Sort((s1, s2) =>
                                  s2.MapCategoryAttribs[SortColumnName].CompareTo(s1.MapCategoryAttribs[SortColumnName]));
            }

            foreach (var playInfo in localOrdered)
            {
                if (playInfo.Beatmap.ToString().Length > max_name_length)
                {
                    playInfo.MapName = "..." + playInfo.Beatmap.ToString().Substring(playInfo.Beatmap.ToString().Length - max_name_length);
                }
                else
                {
                    playInfo.MapName = playInfo.Beatmap.ToString();
                }
            }

            Grid grid = new Grid();

            ExtraColumns = new string[] { "Aim",
                                          "Speed",
                                          "Accuracy" };
            grid.Columns.Add(createColumns(10 + (ExtraColumns?.Length ?? 0)));
            grid.Children.Add(
                new Cell("#")
            {
                Align = Align.Center
            },
                new Cell("beatmap"),
                new Cell("mods")
            {
                Align = Align.Center
            },
                new Cell("live pp"),
                new Cell("acc")
            {
                Align = Align.Center
            },
                new Cell("miss"),
                new Cell("combo")
            {
                Align = Align.Center
            }
                );

            if (ExtraColumns != null)
            {
                foreach (var extraColumn in ExtraColumns)
                {
                    grid.Children.Add(new Cell(extraColumn)
                    {
                        Align = Align.Center
                    });
                }
            }

            grid.Children.Add(
                new Cell("local pp"),
                new Cell("pp change"),
                new Cell("position change")
                );

            grid.Children.Add(localOrdered.Select((item) =>
            {
                List <Cell> cells = new List <Cell>
                {
                    new Cell(item.Position)
                    {
                        Align = Align.Left
                    },
                    new Cell($" {item.Beatmap.OnlineBeatmapID} - {item.MapName}"),
                    new Cell(item.Mods)
                    {
                        Align = Align.Right
                    },
                    new Cell($"{item.LivePP:F1}")
                    {
                        Align = Align.Right
                    },
                    new Cell($"{item.PlayAccuracy * 100f:F2}" + " %")
                    {
                        Align = Align.Right
                    },
                    new Cell($"{item.MissCount}")
                    {
                        Align = Align.Right
                    },
                    new Cell($"{item.PlayMaxCombo}/{item.BeatmapMaxCombo}")
                    {
                        Align = Align.Right
                    },
                };

                if (ExtraColumns != null)
                {
                    cells.AddRange(ExtraColumns.Select(extraColumn => new Cell($"{item.MapCategoryAttribs[extraColumn]:F1}")
                    {
                        Align = Align.Right
                    }));
                }

                cells.AddRange(new List <Cell>
                {
                    new Cell($"{item.LocalPP:F1}")
                    {
                        Align = Align.Right
                    },
                    new Cell($"{item.LocalPP - item.LivePP:F1}")
                    {
                        Align = Align.Right
                    },
                    new Cell($"{liveOrdered.IndexOf(item) - localOrdered.IndexOf(item):+0;-0;-}")
                    {
                        Align = Align.Center
                    },
                }
                               );

                return(cells);
            }));

            OutputDocument(new Document(
                               new Span($"User:     {userData.username}"), "\n",
                               new Span($"Live PP:  {totalLivePP:F1} (including {playcountBonusPP:F1}pp from playcount)"), "\n",
                               new Span($"Local PP: {totalLocalPP:F1} ({totalDiffPP:+0.0;-0.0;-})"), "\n",
                               grid
                               ));
        }