private static async Task <PlayResult[]> GetPlayResultAsync(string token, uint mode, string json, Task <UserProfile> userDataTask, uint count) { JArray arr = JArray.Parse(json); List <PlayResult> results = new List <PlayResult>(arr.Count); using (HttpClient httpClient = new HttpClient()) { foreach (JToken jsonResult in arr) { Task <Beatmap> beatmapDataTask = GetBeatmapAsync(token, jsonResult["beatmap_id"].ToObject <ulong>(), mode); PlayResult result = jsonResult.ToObject <PlayResult>(); result.Mode = mode; result.Accuracy = JsonConvert.DeserializeObject <OsuAccuracy>(jsonResult.ToString(), new OsuAccuracyConverter(mode)); await Task.WhenAll(userDataTask, beatmapDataTask); result.PlayerData = userDataTask.Result; result.BeatmapData = beatmapDataTask.Result; if (result.BeatmapData == null || result.PlayerData == null) { continue; } Stream beatmap = await httpClient.GetStreamAsync($"https://osu.ppy.sh/osu/{result.BeatmapData.Id}"); if (float.IsNaN(result.PP)) { result.PP = GetPP(beatmap, result, false); } if (float.IsNaN(result.SSPP)) { result.SSPP = GetPP(beatmap, result, true); } results.Add(result); if (results.Count >= count) { break; } } ; } return(results.ToArray()); }
public static float GetPP(Stream beatmapStream, PlayResult result, bool ifSs) { Ruleset ruleset = result.Mode switch { 0 => new OsuRuleset(), 1 => new TaikoRuleset(), 2 => new CatchRuleset(), 3 => new ManiaRuleset(), _ => throw new Exception("Invalid mode"), }; BeatmapInfo beatmapInfo = new BeatmapInfo() { BaseDifficulty = new BeatmapDifficulty() { DrainRate = result.BeatmapData.DrainRate, ApproachRate = result.BeatmapData.ApproachRate, CircleSize = result.BeatmapData.CircleSize, OverallDifficulty = result.BeatmapData.OverallDifficulty, }, Ruleset = ruleset.RulesetInfo, }; FakeWorkingBeatmap beatmap = new FakeWorkingBeatmap(beatmapStream, beatmapInfo); ScoreInfo score = new ScoreInfo() { MaxCombo = (int)result.Combo, Mods = ruleset.GetAllMods().Where(mod => result.Mods.GetFromBitflag().Select(m => m.ToShortString()).Contains(mod.Acronym)).ToArray(), Accuracy = (float)result.Accuracy.Accuracy, Statistics = result.Accuracy.Statistics, }; if (ifSs) { score.Statistics = new Dictionary <HitResult, int>() { { HitResult.Miss, 0 }, { HitResult.Ok, 0 }, { HitResult.Meh, 0 }, { HitResult.Good, 0 }, { HitResult.Perfect, 0 }, { HitResult.Great, result.Accuracy.Statistics.Sum(k => k.Value) } }; } PerformanceCalculator calc = ruleset.CreatePerformanceCalculator(beatmap, score); return((float)calc.Calculate()); }