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(); } }
private Result processBeatmap(WorkingBeatmap beatmap) { // Get the ruleset var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? beatmap.BeatmapInfo.RulesetID); var attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(LegacyHelper.TrimNonDifficultyAdjustmentMods(ruleset, getMods(ruleset).ToArray())); var result = new Result { RulesetId = ruleset.RulesetInfo.ID ?? 0, Beatmap = $"{beatmap.BeatmapInfo.OnlineBeatmapID} - {beatmap.BeatmapInfo}", Stars = attributes.StarRating.ToString("N2") }; switch (attributes) { case OsuDifficultyAttributes osu: result.AttributeData = new List <(string, object)> { ("aim rating", osu.AimStrain.ToString("N2")), ("speed rating", osu.SpeedStrain.ToString("N2")), ("max combo", osu.MaxCombo), ("approach rate", osu.ApproachRate.ToString("N2")), ("overall difficulty", osu.OverallDifficulty.ToString("N2")) }; break; case TaikoDifficultyAttributes taiko: result.AttributeData = new List <(string, object)> { ("hit window", taiko.GreatHitWindow.ToString("N2")), ("max combo", taiko.MaxCombo) }; break; case CatchDifficultyAttributes @catch: result.AttributeData = new List <(string, object)> { ("max combo", @catch.MaxCombo), ("approach rate", @catch.ApproachRate.ToString("N2")) }; break; case ManiaDifficultyAttributes mania: result.AttributeData = new List <(string, object)> { ("hit window", mania.GreatHitWindow.ToString("N2")) }; break; } return(result); }
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); } }
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 }, }) } }) ); } }