Example #1
0
        public override void Execute()
        {
            var workingBeatmap = new ProcessorWorkingBeatmap(Beatmap);
            var scoreParser    = new ProcessorScoreDecoder(workingBeatmap);

            foreach (var f in Replays)
            {
                Score score;
                using (var stream = File.OpenRead(f))
                    score = scoreParser.Parse(stream);

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

                var    categoryAttribs = new Dictionary <string, double>();
                double pp = performanceCalculator.Calculate(categoryAttribs);

                Console.WriteLine(f);
                writeAttribute("Player", score.ScoreInfo.User.Username);
                writeAttribute("Mods", score.ScoreInfo.Mods.Length > 0
                    ? score.ScoreInfo.Mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None");

                foreach (var kvp in categoryAttribs)
                {
                    writeAttribute(kvp.Key, kvp.Value.ToString(CultureInfo.InvariantCulture));
                }

                writeAttribute("pp", pp.ToString(CultureInfo.InvariantCulture));
                Console.WriteLine();
            }
        }
        public void SetNewMap(MapSearchResult map)
        {
            lock (_lockingObject)
            {
                if ((map.Action & OsuStatus.ResultsScreen) != 0)
                {
                    return;
                }

                if (map.FoundBeatmaps &&
                    map.BeatmapsFound[0].IsValidBeatmap(_settings, out var mapLocation))
                {
                    _sliderBreaks = 0;
                    _lastMisses   = 0;
                    _lastCombo    = 0;
                    if (map.SearchArgs.EventType == OsuEventType.MapChange)
                    {
                        var workingBeatmap = new ProcessorWorkingBeatmap(mapLocation);
                        var mods           = map.Mods?.WorkingMods ?? "";
                        _rawData.SetCurrentMap(map.BeatmapsFound[0], mods, mapLocation,
                                               (PlayMode)PpCalculatorHelpers.GetRulesetId(workingBeatmap.RulesetID, map.PlayMode.HasValue ? (int?)map.PlayMode : null));
                    }

                    _newPlayStarted.Set();
                }
            }
        }
        public void Execute()
        {
            var workingBeatmap = new ProcessorWorkingBeatmap(command.Beatmap);
            var scoreParser    = new ProcessorScoreParser(workingBeatmap);

            foreach (var f in command.Replays)
            {
                Score score;
                using (var stream = File.OpenRead(f))
                    score = scoreParser.Parse(stream);

                workingBeatmap.Mods.Value = score.ScoreInfo.Mods;

                // Convert + process beatmap
                var    categoryAttribs = new Dictionary <string, double>();
                double pp = score.ScoreInfo.Ruleset.CreateInstance().CreatePerformanceCalculator(workingBeatmap, score.ScoreInfo).Calculate(categoryAttribs);

                command.Console.WriteLine(f);
                writeAttribute("Player", score.ScoreInfo.User.Username);
                writeAttribute("Mods", score.ScoreInfo.Mods.Length > 0
                    ? score.ScoreInfo.Mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None");

                foreach (var kvp in categoryAttribs)
                {
                    writeAttribute(kvp.Key, kvp.Value.ToString(CultureInfo.InvariantCulture));
                }

                writeAttribute("pp", pp.ToString(CultureInfo.InvariantCulture));
                command.Console.WriteLine();
            }
        }
        public void SetNewMap(MapSearchResult map)
        {
            lock (_lockingObject)
            {
                if ((map.Action & OsuStatus.ResultsScreen) != 0)
                {
                    return;
                }

                OutputPatterns.Clear();

                if (map.FoundBeatmaps &&
                    map.BeatmapsFound[0].IsValidBeatmap(_settings, out var mapLocation))
                {
                    var workingBeatmap = new ProcessorWorkingBeatmap(mapLocation);
                    var mods           = map.Mods?.WorkingMods ?? "";

                    _rawData.SetCurrentMap(map.BeatmapsFound[0], mods, mapLocation,
                                           (PlayMode)PpCalculatorHelpers.GetRulesetId(workingBeatmap.RulesetID, map.PlayMode.HasValue ? (int?)map.PlayMode : null));

                    CopyPatterns(map.FormatedStrings);
                }
                else
                {
                    _rawData.SetCurrentMap(null, "", null, PlayMode.Osu);
                }
            }
        }
Example #5
0
        public override void Execute()
        {
            var ruleset = Ruleset;

            var mods = getMods(ruleset).ToArray();

            var workingBeatmap = new ProcessorWorkingBeatmap(Beatmap);

            var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

            var beatmapMaxCombo = GetMaxCombo(beatmap);
            var maxCombo        = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo);
            var statistics      = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
            var score           = Score;
            var accuracy        = GetAccuracy(statistics);

            var scoreInfo = new ScoreInfo
            {
                Accuracy   = accuracy,
                MaxCombo   = maxCombo,
                Statistics = statistics,
                Mods       = mods,
                TotalScore = score,
                RulesetID  = Ruleset.RulesetInfo.ID ?? 0
            };

            var    categoryAttribs = new Dictionary <string, double>();
            double pp = ruleset.CreatePerformanceCalculator(workingBeatmap, scoreInfo).Calculate(categoryAttribs);

            System.Console.WriteLine(pp);
        }
Example #6
0
        public override void Execute()
        {
            var ruleset = Ruleset;

            var mods = getMods(ruleset).ToArray();

            var workingBeatmap = new ProcessorWorkingBeatmap(Beatmap);

            var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

            var beatmapMaxCombo = GetMaxCombo(beatmap);
            var maxCombo        = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo);
            var statistics      = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
            var score           = Score;
            var accuracy        = GetAccuracy(statistics);

            var scoreInfo = new ScoreInfo
            {
                Accuracy   = accuracy,
                MaxCombo   = maxCombo,
                Statistics = statistics,
                Mods       = mods,
                TotalScore = score
            };

            var    categoryAttribs = new Dictionary <string, double>();
            double pp = ruleset.CreatePerformanceCalculator(workingBeatmap, scoreInfo).Calculate(categoryAttribs);

            if (OutputAsJSON ?? false)
            {
                var playInfo = new Dictionary <string, dynamic>();
                WritePlayInfoToDict(playInfo, scoreInfo, beatmap);

                OutputJSON(new SimulationResults
                {
                    BeatmapInfo     = workingBeatmap.BeatmapInfo.ToString(),
                    Mods            = mods.Select(m => m.Acronym).ToList(),
                    CategoryAttribs = categoryAttribs,
                    PlayInfo        = playInfo,
                    PP = pp
                });
            }
            else
            {
                Console.WriteLine(workingBeatmap.BeatmapInfo.ToString());

                WritePlayInfo(scoreInfo, beatmap);

                WriteAttribute("Mods", mods.Length > 0
                    ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None");

                foreach (var kvp in categoryAttribs)
                {
                    WriteAttribute(kvp.Key, kvp.Value.ToString(CultureInfo.InvariantCulture));
                }

                WriteAttribute("pp", pp.ToString(CultureInfo.InvariantCulture));
            }
        }
Example #7
0
        public override void Execute()
        {
            var results = new List <Result>();

            if (Directory.Exists(Path))
            {
                foreach (string file in Directory.GetFiles(Path, "*.osu", SearchOption.AllDirectories))
                {
                    var beatmap = new ProcessorWorkingBeatmap(file);
                    results.Add(processBeatmap(beatmap));
                }
            }
            else
            {
                results.Add(processBeatmap(new ProcessorWorkingBeatmap(Path)));
            }

            var document = new Document();

            foreach (var group in results.GroupBy(r => r.RulesetId))
            {
                var ruleset = LegacyHelper.GetRulesetFromLegacyID(group.First().RulesetId);

                document.Children.Add(new Span($"Ruleset: {ruleset.ShortName}"), "\n");

                var grid = new Grid();

                grid.Columns.Add(GridLength.Auto, GridLength.Auto);
                grid.Children.Add(new Cell("beatmap"), new Cell("star rating"));

                foreach (var attribute in group.First().AttributeData)
                {
                    grid.Columns.Add(GridLength.Auto);
                    grid.Children.Add(new Cell(attribute.name));
                }

                foreach (var result in group)
                {
                    grid.Children.Add(new Cell(result.Beatmap), new Cell(result.Stars)
                    {
                        Align = Align.Right
                    });
                    foreach (var attribute in result.AttributeData)
                    {
                        grid.Children.Add(new Cell(attribute.value)
                        {
                            Align = Align.Right
                        });
                    }
                }

                document.Children.Add(grid);

                document.Children.Add("\n");
            }

            OutputDocument(document);
        }
Example #8
0
        public void ProcessBeatmap(string beatmap_path, string[] mods)
        {
            ProcessorWorkingBeatmap beatmap = new ProcessorWorkingBeatmap(beatmap_path);
            // Get the ruleset
            var ruleset    = LegacyHelper.GetRulesetFromLegacyID(beatmap.BeatmapInfo.RulesetID);
            var attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(getMods(ruleset, mods).ToArray());

            var beatmapName = $"{beatmap.BeatmapInfo.OnlineBeatmapID} - {beatmap.BeatmapInfo}";

            if (beatmapName.Length > 100)
            {
                beatmapName = beatmapName.Substring(0, 100) + "...";
            }

            var result = new Result
            {
                RulesetId = ruleset.RulesetInfo.ID ?? 0,
                Beatmap   = beatmapName,
                Stars     = attributes.StarRating.ToString("N3")
            };

            result.AttributeData = new List <(string, object)>
            {
            };

            CalcResults = new Document();

            CalcResults.Children.Add(new Span($"Ruleset: {ruleset.ShortName}"), "\n");

            var grid = new Grid();

            grid.Columns.Add(GridLength.Auto, GridLength.Auto);
            grid.Children.Add(new Cell("beatmap"), new Cell("star rating"));

            foreach (var attribute in result.AttributeData)
            {
                grid.Columns.Add(GridLength.Auto);
                grid.Children.Add(new Cell(attribute.name));
            }

            grid.Children.Add(new Cell(result.Beatmap), new Cell(result.Stars)
            {
                Align = Align.Right
            });
            foreach (var attribute in result.AttributeData)
            {
                grid.Children.Add(new Cell(attribute.value)
                {
                    Align = Align.Right
                });
            }

            CalcResults.Children.Add(grid);

            CalcResults.Children.Add("\n");
        }
        private static StrainsResult GetStrains(string mapLocation, PlayMode?desiredPlayMode)
        {
            var workingBeatmap = new ProcessorWorkingBeatmap(mapLocation);

            var playMode = (PlayMode)PpCalculatorHelpers.GetRulesetId(workingBeatmap.RulesetID,
                                                                      desiredPlayMode.HasValue ? (int?)desiredPlayMode : null);

            var ppCalculator = PpCalculatorHelpers.GetPpCalculator((int)playMode, mapLocation, null);

            //Length refers to beatmap time, not song total time
            var mapLength    = workingBeatmap.Length;
            var strainLength = 5000;
            var interval     = 1500;
            var time         = 0;
            var strains      = new Dictionary <int, double>(300);

            if (ppCalculator == null)
            {
                while (time + strainLength / 2 < mapLength)
                {
                    strains.Add(time, 50);
                    time += interval;
                }
            }
            else if (playMode == PlayMode.Osu || playMode == PlayMode.Taiko || playMode == PlayMode.OsuMania)
            {
                var a = new Dictionary <string, double>();
                while (time + strainLength / 2 < mapLength)
                {
                    var strain = ppCalculator.Calculate(time, time + strainLength, a);

                    if (double.IsNaN(strain) || strain < 0)
                    {
                        strain = 0;
                    }
                    else if (strain > 2000)
                    {
                        strain = 2000; //lets not freeze everything with aspire/fancy 100* maps
                    }
                    strains.Add(time, strain);
                    time += interval;
                    a.Clear();
                }
            }

            return(new StrainsResult
            {
                Strains = strains,
                PpCalculator = ppCalculator,
                WorkingBeatmap = workingBeatmap,
                PlayMode = playMode,
                MapLocation = mapLocation
            });
        }
Example #10
0
        public static async Task <double> CalculatePerformancePoints(Score score)
        {
            var beatmapMd5 = await GetBeatmap(score.FileChecksum, score.Beatmap.Id);

            var beatmap = new ProcessorWorkingBeatmap($"./data/beatmaps/{beatmapMd5}.osu");

            var psp         = new ProcessorScoreDecoder(beatmap);
            var parsedScore = psp.Parse(score, $"./data/osr/{score.ReplayChecksum}.osr");

            var categoryAttribs = new Dictionary <string, double>();
            var pp = parsedScore.ScoreInfo.Ruleset
                     .CreateInstance()
                     .CreatePerformanceCalculator(beatmap, parsedScore.ScoreInfo)
                     .Calculate(categoryAttribs);

            return(pp);
        }
Example #11
0
        public override void Execute()
        {
            if (Directory.Exists(Path))
            {
                foreach (string file in Directory.GetFiles(Path, "*.osu", SearchOption.AllDirectories))
                {
                    var beatmap = new ProcessorWorkingBeatmap(file);
                    Console.WriteLine(beatmap.BeatmapInfo.ToString());

                    processBeatmap(beatmap);
                }
            }
            else
            {
                processBeatmap(new ProcessorWorkingBeatmap(Path));
            }
        }
Example #12
0
        public override void Execute()
        {
            var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(Beatmap);
            var scoreParser    = new ProcessorScoreDecoder(workingBeatmap);

            foreach (var f in Replays)
            {
                Score score;
                using (var stream = File.OpenRead(f))
                    score = scoreParser.Parse(stream);

                var ruleset = score.ScoreInfo.Ruleset.CreateInstance();
                var difficultyCalculator = ruleset.CreateDifficultyCalculator(workingBeatmap);

                Mod[] mods = score.ScoreInfo.Mods;
                if (score.ScoreInfo.IsLegacyScore)
                {
                    mods = LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(ruleset, mods);
                }

                var difficultyAttributes  = difficultyCalculator.Calculate(mods);
                var performanceCalculator = score.ScoreInfo.Ruleset.CreateInstance().CreatePerformanceCalculator();

                var ppAttributes = performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes);

                Console.WriteLine(f);
                writeAttribute("Player", score.ScoreInfo.User.Username);
                writeAttribute("Mods", score.ScoreInfo.Mods.Length > 0
                    ? score.ScoreInfo.Mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None");

                var ppAttributeValues = JsonConvert.DeserializeObject <Dictionary <string, object> >(JsonConvert.SerializeObject(ppAttributes)) ?? new Dictionary <string, object>();
                foreach (var attrib in ppAttributeValues)
                {
                    writeAttribute(attrib.Key.Humanize(), FormattableString.Invariant($"{attrib.Value:N2}"));
                }

                Console.WriteLine();
            }
        }
Example #13
0
        public static async Task <double> CalculatePerformancePoints(DbScore score)
        {
            var beatmapMd5 = await GetBeatmapByMd5(score.FileChecksum);

            if (beatmapMd5 == string.Empty)
            {
                return(0.0);
            }

            var workingBeatmap = new ProcessorWorkingBeatmap($"./data/beatmaps/{beatmapMd5}.osu");

            var psp         = new ProcessorScoreDecoder(workingBeatmap);
            var parsedScore = psp.Parse(score);

            var categoryAttribs = new Dictionary <string, double>();
            var pp = parsedScore.ScoreInfo.Ruleset
                     .CreateInstance()
                     .CreatePerformanceCalculator(workingBeatmap, parsedScore.ScoreInfo)
                     .Calculate(categoryAttribs);

            return(pp);
        }
Example #14
0
        public override void Execute()
        {
            var document = new Document();

            if (Directory.Exists(Path))
            {
                foreach (string file in Directory.GetFiles(Path, "*.osu", SearchOption.AllDirectories))
                {
                    var beatmap = new ProcessorWorkingBeatmap(file);
                    document.Children.Add(new Span(beatmap.BeatmapInfo.ToString()), "\n");

                    processBeatmap(beatmap, document);
                }
            }
            else
            {
                var beatmap = new ProcessorWorkingBeatmap(Path);
                document.Children.Add(new Span(beatmap.BeatmapInfo.ToString()), "\n");

                processBeatmap(beatmap, document);
            }
            OutputDocument(document);
        }
Example #15
0
        public override void Execute()
        {
            var resultSet = new ResultSet();

            if (Directory.Exists(Path))
            {
                foreach (string file in Directory.GetFiles(Path, "*.osu", SearchOption.AllDirectories))
                {
                    try
                    {
                        var beatmap = new ProcessorWorkingBeatmap(file);
                        resultSet.Results.Add(processBeatmap(beatmap));
                    }
                    catch (Exception e)
                    {
                        resultSet.Errors.Add($"Processing beatmap \"{file}\" failed:\n{e.Message}");
                    }
                }
            }
            else
            {
                resultSet.Results.Add(processBeatmap(ProcessorWorkingBeatmap.FromFileOrId(Path)));
            }

            if (OutputJson)
            {
                string json = JsonConvert.SerializeObject(resultSet);

                Console.WriteLine(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                var document = new Document();

                foreach (var error in resultSet.Errors)
                {
                    document.Children.Add(new Span(error), "\n");
                }
                if (resultSet.Errors.Count > 0)
                {
                    document.Children.Add("\n");
                }

                foreach (var group in resultSet.Results.GroupBy(r => r.RulesetId))
                {
                    var ruleset = LegacyHelper.GetRulesetFromLegacyID(group.First().RulesetId);
                    document.Children.Add(new Span($"ruleset: {ruleset.ShortName}"), "\n");

                    Grid grid        = new Grid();
                    bool firstResult = true;

                    foreach (var result in group)
                    {
                        var attributeValues = JsonConvert.DeserializeObject <Dictionary <string, object> >(JsonConvert.SerializeObject(result.Attributes)) ?? new Dictionary <string, object>();

                        // Headers
                        if (firstResult)
                        {
                            grid.Columns.Add(GridLength.Auto);
                            grid.Children.Add(new Cell("beatmap"));

                            foreach (var column in attributeValues)
                            {
                                grid.Columns.Add(GridLength.Auto);
                                grid.Children.Add(new Cell(column.Key.Humanize()));
                            }
                        }

                        // Values
                        grid.Children.Add(new Cell($"{result.BeatmapId} - {result.Beatmap}"));
                        foreach (var column in attributeValues)
                        {
                            grid.Children.Add(new Cell($"{column.Value:N2}")
                            {
                                Align = Align.Right
                            });
                        }

                        firstResult = false;
                    }

                    document.Children.Add(grid, "\n");
                }

                OutputDocument(document);
            }
        }
Example #16
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 #17
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 #18
0
        public override void Execute()
        {
            var ruleset = Ruleset;

            var mods = getMods(ruleset).ToArray();

            var workingBeatmap = new ProcessorWorkingBeatmap(Beatmap);

            var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

            var beatmapMaxCombo = GetMaxCombo(beatmap);
            var maxCombo        = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo);
            var statistics      = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
            var score           = Score;
            var accuracy        = GetAccuracy(statistics);

            var scoreInfo = new ScoreInfo
            {
                Accuracy   = accuracy,
                MaxCombo   = maxCombo,
                Statistics = statistics,
                Mods       = mods,
                TotalScore = score,
                RulesetID  = Ruleset.RulesetInfo.ID ?? 0
            };

            var    categoryAttribs = new Dictionary <string, double>();
            double pp = ruleset.CreatePerformanceCalculator(workingBeatmap, scoreInfo).Calculate(categoryAttribs);

            if (OutputJson)
            {
                var o = new JObject
                {
                    { "Beatmap", workingBeatmap.BeatmapInfo.ToString() }
                };

                foreach (var info in getPlayValues(scoreInfo, beatmap))
                {
                    o[info.Key] = info.Value;
                }

                o["Mods"] = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}") : "None";

                foreach (var kvp in categoryAttribs)
                {
                    o[kvp.Key] = kvp.Value;
                }

                o["pp"] = pp;

                string json = o.ToString();

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                var document = new Document();

                document.Children.Add(new Span(workingBeatmap.BeatmapInfo.ToString()), "\n");

                document.Children.Add(new Span(GetPlayInfo(scoreInfo, beatmap)), "\n");

                document.Children.Add(new Span(GetAttribute("Mods", mods.Length > 0
                    ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None")), "\n");

                foreach (var kvp in categoryAttribs)
                {
                    document.Children.Add(new Span(GetAttribute(kvp.Key, kvp.Value.ToString(CultureInfo.InvariantCulture))), "\n");
                }

                document.Children.Add(new Span(GetAttribute("pp", pp.ToString(CultureInfo.InvariantCulture))));

                OutputDocument(document);
            }
        }
Example #19
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 #20
0
        public override void Execute()
        {
            var ruleset = new OsuRuleset();

            var allLines = File.ReadAllLines(ScoreSetsPath).Select(a => a.Split(','));
            var lines    = allLines.Where(l => l[0] == SetName);

            var sw = new StringWriter();

            sw.WriteLine("ID, Beatmap, Mods, Combo, Max Combo, Accuracy, Aim pp, Tap pp, Acc pp, pp");

            foreach (var l in lines)
            {
                var s    = new Score(l);
                var mods = s.Mods.ToArray();

                string beatmapID = s.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 workingBeatmap = new ProcessorWorkingBeatmap(cachePath);
                var beatmap        = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

                var beatmapMaxCombo = getMaxCombo(beatmap);
                var maxCombo        = (int)Math.Round(s.PercentCombo / 100 * beatmapMaxCombo);
                var accuracy        = s.Accuracy;

                var statistics = generateHitResults(accuracy, beatmap, s.MissCount);

                var scoreInfo = new ScoreInfo
                {
                    Accuracy   = accuracy,
                    MaxCombo   = maxCombo,
                    Statistics = statistics,
                    Mods       = mods,
                };
                var    categoryAttribs = new Dictionary <string, double>();
                double pp = ruleset.CreatePerformanceCalculator(workingBeatmap, scoreInfo).Calculate(categoryAttribs);

                var resultLine = new List <string>()
                {
                    beatmap.BeatmapInfo.OnlineBeatmapID.ToString(),
                    beatmap.BeatmapInfo.ToString().Replace(",", ";"),
                    string.Join("", s.ModStrings),

                    maxCombo.ToString(),
                    beatmapMaxCombo.ToString(),
                    (accuracy * 100).ToString("F2"),
                    categoryAttribs["Aim"].ToString("F2"),
                    categoryAttribs["Tap"].ToString("F2"),
                    categoryAttribs["Accuracy"].ToString("F2"),
                    pp.ToString("F2")
                };

                sw.WriteLine(string.Join(", ", resultLine));
            }
            if (OutputFile == null)
            {
                Console.Write(sw.ToString());
            }
            else
            {
                File.WriteAllText(OutputFile, sw.ToString());
            }

            sw.Dispose();
        }
Example #21
0
        public Tokens GetMapReplacements(MapSearchResult map)
        {
            var ret = new Tokens
            {
                { "GameMode", new Token(null) },
                { "MaxCombo", new Token(null) },

                { "SSPP", new Token(null) },
                { "99.9PP", new Token(null) },
                { "99PP", new Token(null) },
                { "98PP", new Token(null) },
                { "95PP", new Token(null) },
                { "90PP", new Token(null) },


                { "1 000 000PP", new Token(null) },
                { "990 000PP", new Token(null) },
                { "950 000PP", new Token(null) },
                { "900 000PP", new Token(null) },
                { "800 000PP", new Token(null) },
                { "700 000PP", new Token(null) },
                { "600 000PP", new Token(null) },

                { "mMod", new Token(null) },

                { "mSSPP", new Token(null) },
                { "m99.9PP", new Token(null) },
                { "m99PP", new Token(null) },
                { "m98PP", new Token(null) },
                { "m95PP", new Token(null) },
                { "m90PP", new Token(null) },

                { "m1 000 000PP", new Token(null) },
                { "m990 000PP", new Token(null) },
                { "m950 000PP", new Token(null) },
                { "m900 000PP", new Token(null) },
                { "m800 000PP", new Token(null) },
                { "m700 000PP", new Token(null) },
                { "m600 000PP", new Token(null) },
            };

            if (!map.FoundBeatmaps ||
                !map.BeatmapsFound[0].IsValidBeatmap(_settings, out var mapLocation)
                )
            {
                return(ret);
            }


            var workingBeatmap = new ProcessorWorkingBeatmap(mapLocation);

            var playMode = (PlayMode)PpCalculatorHelpers.GetRulesetId(workingBeatmap.RulesetID, map.PlayMode.HasValue ? (int?)map.PlayMode : null);

            _ppCalculator = PpCalculatorHelpers.GetPpCalculator((int)playMode, mapLocation, _ppCalculator);

            if (_ppCalculator == null)
            {
                return(ret);//Ctb not supported :(
            }
            if (playMode == PlayMode.OsuMania)
            {
                _ppCalculator.Score = 1_000_000;
            }
            else
            {
                _ppCalculator.Score = 0;
            }

            _ppCalculator.Mods = null;

            ret["GameMode"] = new TokenWithFormat(playMode.ToString());

            string mods = "";

            if (playMode == PlayMode.OsuMania)
            {
                ret["1 000 000PP"] = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 1_000_000), format: PpFormat);
                ret["990 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 990_000), format: PpFormat);
                ret["950 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 950_000), format: PpFormat);
                ret["900 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 900_000), format: PpFormat);
                ret["800 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 800_000), format: PpFormat);
                ret["700 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 700_000), format: PpFormat);
                ret["600 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 600_000), format: PpFormat);
            }
            else
            {
                ret["SSPP"]   = new TokenWithFormat(GetPp(_ppCalculator, 100d), format: PpFormat);
                ret["99.9PP"] = new TokenWithFormat(GetPp(_ppCalculator, 99.9d), format: PpFormat);
                ret["99PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 99d), format: PpFormat);
                ret["98PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 98d), format: PpFormat);
                ret["95PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 95d), format: PpFormat);
                ret["90PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 90d), format: PpFormat);
            }

            ret["MaxCombo"] = new TokenWithFormat(_ppCalculator.GetMaxCombo());

            string modsStr;

            if (map.Action == OsuStatus.Playing || map.Action == OsuStatus.Watching)
            {
                mods           = map.Mods?.WorkingMods ?? "";
                modsStr        = map.Mods?.ShownMods ?? "";
                _lastShortMods = mods;
                _lastModsStr   = modsStr;
            }
            else
            {
                mods    = _lastShortMods;
                modsStr = _lastModsStr;
            }

            ret["mMod"] = new Token(modsStr);

            if (playMode == PlayMode.OsuMania)
            {
                ret["m1 000 000PP"] = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 1_000_000), format: PpFormat);
                ret["m990 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 990_000), format: PpFormat);
                ret["m950 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 950_000), format: PpFormat);
                ret["m900 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 900_000), format: PpFormat);
                ret["m800 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 800_000), format: PpFormat);
                ret["m700 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 700_000), format: PpFormat);
                ret["m600 000PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 0, mods, 600_000), format: PpFormat);
            }
            else
            {
                ret["mSSPP"]   = new TokenWithFormat(GetPp(_ppCalculator, 100d, mods), format: PpFormat);
                ret["m99.9PP"] = new TokenWithFormat(GetPp(_ppCalculator, 99.9d, mods), format: PpFormat);
                ret["m99PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 99d, mods), format: PpFormat);
                ret["m98PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 98d, mods), format: PpFormat);
                ret["m95PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 95d, mods), format: PpFormat);
                ret["m90PP"]   = new TokenWithFormat(GetPp(_ppCalculator, 90d, mods), format: PpFormat);
            }

            return(ret);
        }
        public void CreateTokens(MapSearchResult map)
        {
            foreach (var tokenkv in Tokens.AllTokens.Where(t => t.Value.PluginName == Name))
            {
                tokenkv.Value.Reset();
            }

            if (!map.FoundBeatmaps ||
                !map.BeatmapsFound[0].IsValidBeatmap(_settings, out var mapLocation))
            {
                return;
            }


            var workingBeatmap = new ProcessorWorkingBeatmap(mapLocation);

            var playMode = (PlayMode)PpCalculatorHelpers.GetRulesetId(workingBeatmap.RulesetID, map.PlayMode.HasValue ? (int?)map.PlayMode : null);

            _ppCalculator = PpCalculatorHelpers.GetPpCalculator((int)playMode, mapLocation, _ppCalculator);

            if (_ppCalculator == null)
            {
                return;//Ctb not supported :(
            }
            if (playMode == PlayMode.OsuMania)
            {
                _ppCalculator.Score = 1_000_000;
            }
            else
            {
                _ppCalculator.Score = 0;
            }

            _ppCalculator.Mods = null;

            _tokenSetter("GameMode", playMode.ToString());

            string mods = "";

            if (playMode == PlayMode.OsuMania)
            {
                _tokenSetter("1 000 000PP", GetPp(_ppCalculator, 0, mods, 1_000_000), format: PpFormat);
                _tokenSetter("990 000PP", GetPp(_ppCalculator, 0, mods, 990_000), format: PpFormat);
                _tokenSetter("950 000PP", GetPp(_ppCalculator, 0, mods, 950_000), format: PpFormat);
                _tokenSetter("900 000PP", GetPp(_ppCalculator, 0, mods, 900_000), format: PpFormat);
                _tokenSetter("800 000PP", GetPp(_ppCalculator, 0, mods, 800_000), format: PpFormat);
                _tokenSetter("700 000PP", GetPp(_ppCalculator, 0, mods, 700_000), format: PpFormat);
                _tokenSetter("600 000PP", GetPp(_ppCalculator, 0, mods, 600_000), format: PpFormat);
            }
            else
            {
                _tokenSetter("SSPP", GetPp(_ppCalculator, 100d), format: PpFormat);
                _tokenSetter("99.9PP", GetPp(_ppCalculator, 99.9d), format: PpFormat);
                _tokenSetter("99PP", GetPp(_ppCalculator, 99d), format: PpFormat);
                _tokenSetter("98PP", GetPp(_ppCalculator, 98d), format: PpFormat);
                _tokenSetter("95PP", GetPp(_ppCalculator, 95d), format: PpFormat);
                _tokenSetter("90PP", GetPp(_ppCalculator, 90d), format: PpFormat);
            }
            _tokenSetter("MaxCombo", _ppCalculator.GetMaxCombo());


            mods = map.Mods?.WorkingMods ?? "";

            if (playMode == PlayMode.OsuMania)
            {
                _tokenSetter("m1 000 000PP", GetPp(_ppCalculator, 0, mods, 1_000_000), format: PpFormat);
                _tokenSetter("m990 000PP", GetPp(_ppCalculator, 0, mods, 990_000), format: PpFormat);
                _tokenSetter("m950 000PP", GetPp(_ppCalculator, 0, mods, 950_000), format: PpFormat);
                _tokenSetter("m900 000PP", GetPp(_ppCalculator, 0, mods, 900_000), format: PpFormat);
                _tokenSetter("m800 000PP", GetPp(_ppCalculator, 0, mods, 800_000), format: PpFormat);
                _tokenSetter("m700 000PP", GetPp(_ppCalculator, 0, mods, 700_000), format: PpFormat);
                _tokenSetter("m600 000PP", GetPp(_ppCalculator, 0, mods, 600_000), format: PpFormat);
            }
            else
            {
                _tokenSetter("mSSPP", GetPp(_ppCalculator, 100d, mods), format: PpFormat);
                _tokenSetter("m99.9PP", GetPp(_ppCalculator, 99.9d, mods), format: PpFormat);
                _tokenSetter("m99PP", GetPp(_ppCalculator, 99d, mods), format: PpFormat);
                _tokenSetter("m98PP", GetPp(_ppCalculator, 98d, mods), format: PpFormat);
                _tokenSetter("m95PP", GetPp(_ppCalculator, 95d, mods), format: PpFormat);
                _tokenSetter("m90PP", GetPp(_ppCalculator, 90d, mods), format: PpFormat);
            }
        }
Example #23
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 #24
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
                               ));
        }
Example #25
0
        public override void Execute()
        {
            var ruleset = Ruleset;

            var mods = GetMods(ruleset).ToArray();

            if (!Beatmap.EndsWith(".osu"))
            {
                if (!int.TryParse(Beatmap, out _))
                {
                    Console.WriteLine("Incorrect beatmap ID.");
                    return;
                }

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

                if (!File.Exists(cachePath))
                {
                    Console.WriteLine($"Downloading {Beatmap}.osu...");
                    new FileWebRequest(cachePath, $"https://osu.ppy.sh/osu/{Beatmap}").Perform();
                }

                Beatmap = cachePath;
            }

            var workingBeatmap = new ProcessorWorkingBeatmap(Beatmap);

            var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

            var beatmapMaxCombo = GetMaxCombo(beatmap);
            var maxCombo        = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo);
            var statistics      = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
            var score           = Score;
            var accuracy        = GetAccuracy(statistics);

            var scoreInfo = new ScoreInfo
            {
                Accuracy   = accuracy,
                MaxCombo   = maxCombo,
                Statistics = statistics,
                Mods       = mods,
                TotalScore = score,
                RulesetID  = Ruleset.RulesetInfo.ID ?? 0
            };

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

            var    categoryAttribs = new Dictionary <string, double>();
            double pp = performanceCalculator.Calculate(categoryAttribs);

            if (OutputJson)
            {
                var o = new JObject
                {
                    { "Beatmap", workingBeatmap.BeatmapInfo.ToString() }
                };

                foreach (var info in getPlayValues(scoreInfo, beatmap))
                {
                    o[info.Key] = info.Value;
                }

                o["Mods"] = mods.Length > 0 ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}") : "None";

                foreach (var kvp in categoryAttribs)
                {
                    o[kvp.Key] = kvp.Value;
                }

                o["pp"] = pp;

                string json = o.ToString();

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                var document = new Document();

                document.Children.Add(new Span(workingBeatmap.BeatmapInfo.ToString()), "\n");

                document.Children.Add(new Span(GetPlayInfo(scoreInfo, beatmap)), "\n");

                document.Children.Add(new Span(GetAttribute("Mods", mods.Length > 0
                    ? mods.Select(m => m.Acronym).Aggregate((c, n) => $"{c}, {n}")
                    : "None")), "\n");

                foreach (var kvp in categoryAttribs)
                {
                    document.Children.Add(new Span(GetAttribute(kvp.Key, kvp.Value.ToString(CultureInfo.InvariantCulture))), "\n");
                }

                document.Children.Add(new Span(GetAttribute("pp", pp.ToString(CultureInfo.InvariantCulture))));

                OutputDocument(document);
            }
        }
Example #26
0
        public override void Execute()
        {
            var rulesetApiName = LegacyHelper.GetRulesetShortNameFromId(Ruleset ?? 0);
            var leaderboard    = GetJsonFromApi($"rankings/{rulesetApiName}/performance?cursor[page]={LeaderboardPage - 1}");

            var calculatedPlayers = new List <LeaderboardPlayerInfo>();

            foreach (var player in leaderboard.ranking)
            {
                if (calculatedPlayers.Count >= Limit)
                {
                    break;
                }

                var plays = new List <(double, double)>(); // (local, live)

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

                Console.WriteLine($"Calculating {player.user.username} top scores...");

                foreach (var play in GetJsonFromApi($"users/{player.user.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();

                    plays.Add((performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes).Total ?? 0, play.pp));
                }

                var localOrdered = plays.Select(x => x.Item1).OrderByDescending(x => x).ToList();
                var liveOrdered  = plays.Select(x => x.Item2).OrderByDescending(x => x).ToList();

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

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

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

                calculatedPlayers.Add(new LeaderboardPlayerInfo
                {
                    LivePP   = totalLivePP,
                    LocalPP  = totalLocalPP,
                    Username = player.user.username
                });
            }

            calculatedPlayers = calculatedPlayers.OrderByDescending(x => x.LocalPP).ToList();
            var liveOrderedPlayers = calculatedPlayers.OrderByDescending(x => x.LivePP).ToList();

            if (OutputJson)
            {
                var json = JsonConvert.SerializeObject(calculatedPlayers);

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                OutputDocument(new Document(
                                   new Grid
                {
                    Columns =
                    {
                        GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto
                    },
                    Children =
                    {
                        new Cell("#"),
                        new Cell("username"),
                        new Cell("live pp"),
                        new Cell("local pp"),
                        new Cell("pp change"),
                        calculatedPlayers.Select(item => new[]
                        {
                            new Cell($"{liveOrderedPlayers.IndexOf(item) - calculatedPlayers.IndexOf(item):+0;-0;-}"),
                            new Cell($"{item.Username}"),
                            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
                            }
                        })
                    }
                })
                               );
            }
        }
Example #27
0
        public async Task ExecuteAsync(Label status_block)
        {
            if (Key == "" || ProfileName == "")
            {
                return;
            }

            var displayPlays = new List <UserPlayInfo>();
            var ruleset      = LegacyHelper.GetRulesetFromLegacyID(0);

            status_block.Dispatcher.Invoke(() =>
            {
                status_block.Content = "Getting user data...";
            });

            dynamic userData = await getJsonFromApi($"get_user?k={Key}&u={ProfileName}&m={0}");

            if (!((JArray)userData).Any())
            {
                ResultsDoc = new Document(new Span("Could not find user " + ProfileName));
                return;
            }

            userData = userData[0];

            status_block.Dispatcher.Invoke(() =>
            {
                status_block.Content = "Getting user top scores...";
            });

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

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

                if (!File.Exists(cachePath))
                {
                    status_block.Dispatcher.Invoke(() =>
                    {
                        status_block.Content = $"Downloading {beatmapID}.osu...";
                    });
                    await new FileWebRequest(cachePath, $"{base_url}/osu/{beatmapID}").PerformAsync();
                }

                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,
                    AimPP           = categoryAttribs["Aim"],
                    TapPP           = categoryAttribs["Speed"],
                    AccPP           = categoryAttribs["Accuracy"],
                    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;

            ResultsDoc = 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 Alba.CsConsoleFormat.Grid
            {
                Columns =
                {
                    GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto,
                    GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto, GridLength.Auto
                },
                Children =
                {
                    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
                    },
                    new Cell("aim pp"),
                    new Cell("tap pp"),
                    new Cell("acc pp"),
                    new Cell("local pp"),
                    new Cell("pp change"),
                    new Cell("position change"),
                    localOrdered.Select(item => new[]
                    {
                        new Cell($"{item.Beatmap.OnlineBeatmapID} - {item.Beatmap.ToString().Substring(0, Math.Min(80, item.Beatmap.ToString().Length))}"),
                        new Cell(item.Mods)
                        {
                            Align = Align.Center
                        },
                        new Cell($"{item.LivePP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{item.PlayAccuracy * 100f:F2}" + " %")
                        {
                            Align = Align.Center
                        },
                        new Cell($"{item.MissCount}")
                        {
                            Align = Align.Center
                        },
                        new Cell($"{item.PlayMaxCombo}/{item.BeatmapMaxCombo}")
                        {
                            Align = Align.Center
                        },
                        new Cell($"{item.AimPP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{item.TapPP:F1}")
                        {
                            Align = Align.Right
                        },
                        new Cell($"{item.AccPP: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 #28
0
        public override void Execute()
        {
            var ruleset = Ruleset;

            var mods           = NoClassicMod ? GetMods(ruleset) : LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(ruleset, GetMods(ruleset));
            var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(Beatmap);
            var beatmap        = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

            var beatmapMaxCombo = GetMaxCombo(beatmap);
            var maxCombo        = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo);
            var statistics      = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
            var score           = Score;
            var accuracy        = GetAccuracy(statistics);

            var difficultyCalculator  = ruleset.CreateDifficultyCalculator(workingBeatmap);
            var difficultyAttributes  = difficultyCalculator.Calculate(mods);
            var performanceCalculator = ruleset.CreatePerformanceCalculator();

            var ppAttributes = performanceCalculator?.Calculate(new ScoreInfo(beatmap.BeatmapInfo, ruleset.RulesetInfo)
            {
                Accuracy   = accuracy,
                MaxCombo   = maxCombo,
                Statistics = statistics,
                Mods       = mods,
                TotalScore = score,
            }, difficultyAttributes);

            var result = new Result
            {
                Score = new ScoreStatistics
                {
                    RulesetId  = ruleset.RulesetInfo.OnlineID,
                    BeatmapId  = workingBeatmap.BeatmapInfo.OnlineID,
                    Beatmap    = workingBeatmap.BeatmapInfo.ToString(),
                    Mods       = mods.Select(m => new APIMod(m)).ToList(),
                    Score      = score,
                    Accuracy   = accuracy * 100,
                    Combo      = maxCombo,
                    Statistics = statistics
                },
                PerformanceAttributes = ppAttributes,
                DifficultyAttributes  = difficultyAttributes
            };

            if (OutputJson)
            {
                string json = JsonConvert.SerializeObject(result);

                Console.Write(json);

                if (OutputFile != null)
                {
                    File.WriteAllText(OutputFile, json);
                }
            }
            else
            {
                var document = new Document();

                AddSectionHeader(document, "Basic score info");

                document.Children.Add(
                    FormatDocumentLine("beatmap", $"{result.Score.BeatmapId} - {result.Score.Beatmap}"),
                    FormatDocumentLine("score", result.Score.Score.ToString(CultureInfo.InvariantCulture)),
                    FormatDocumentLine("accuracy", result.Score.Accuracy.ToString("N2", CultureInfo.InvariantCulture)),
                    FormatDocumentLine("combo", result.Score.Combo.ToString(CultureInfo.InvariantCulture)),
                    FormatDocumentLine("mods", result.Score.Mods.Count > 0 ? result.Score.Mods.Select(m => m.ToString()).Aggregate((c, n) => $"{c}, {n}") : "None")
                    );

                AddSectionHeader(document, "Hit statistics");

                foreach (var stat in result.Score.Statistics)
                {
                    document.Children.Add(FormatDocumentLine(stat.Key.ToString().ToLowerInvariant(), stat.Value.ToString(CultureInfo.InvariantCulture)));
                }

                AddSectionHeader(document, "Performance attributes");

                var ppAttributeValues = JsonConvert.DeserializeObject <Dictionary <string, object> >(JsonConvert.SerializeObject(result.PerformanceAttributes)) ?? new Dictionary <string, object>();
                foreach (var attrib in ppAttributeValues)
                {
                    document.Children.Add(FormatDocumentLine(attrib.Key.Humanize().ToLower(), FormattableString.Invariant($"{attrib.Value:N2}")));
                }

                AddSectionHeader(document, "Difficulty attributes");

                var diffAttributeValues = JsonConvert.DeserializeObject <Dictionary <string, object> >(JsonConvert.SerializeObject(result.DifficultyAttributes)) ?? new Dictionary <string, object>();
                foreach (var attrib in diffAttributeValues)
                {
                    document.Children.Add(FormatDocumentLine(attrib.Key.Humanize(), FormattableString.Invariant($"{attrib.Value:N2}")));
                }

                OutputDocument(document);
            }
        }