public void TestSinglePlay() { const int id = 774965; if (!File.Exists($"{id}.osu")) { new WebClient().DownloadFile($"https://osu.ppy.sh/osu/{id}", $"{id}.osu"); } var reader = new StreamReader($"{id}.osu"); //read a beatmap var beatmap = Beatmap.Read(reader); //calculate star ratings for HDDT Mods mods = Mods.Hidden | Mods.DoubleTime; var stars = new DiffCalc().Calc(beatmap, mods); output.WriteLine($"Star rating: {stars.Total:F2} (aim stars: {stars.Aim:F2}, speed stars: {stars.Speed:F2})"); //calculate the PP for this map //the play has no misses or 50's, so we don't specify it var pp = new PPv2(new PPv2Parameters(beatmap, stars, c100: 8, mods: mods, combo: 1773)); output.WriteLine($"Play is worth {pp.Total:F2}pp ({pp.Aim:F2} aim pp, {pp.Acc:F2} acc pp, {pp.Speed:F2} " + $"speed pp) and has an accuracy of {pp.ComputedAccuracy.Value() * 100:F2}%"); Assert.InRange(775.99, pp.Total - 1, pp.Total + 1); }
private OsuJsonUserRecent[] ProcessJson(OsuJsonUserRecent[] array, bool retrycount) { foreach (var item in array) { if (retrycount) { continue; } //Get Beatmap last update var beatmapBuilder = new OsuBeatmapBuilder { Mode = Mode, ConvertedIncluded = "1", BeatmapId = item.beatmap_id }; item.Beatmap = beatmapBuilder.Execute().First(); OsuUtil.GetCalculatedAccuracy(item, Mode); var data = OsuDlBeatmap.FindMap(item.beatmap_id, item.Beatmap.last_update.DateTime); var beatmapData = Beatmap.Read(new StreamReader(new MemoryStream(data, false))); var diff = new DiffCalc().Calc(beatmapData, (Mods)item.enabled_mods); var rawPp = new PPv2(new PPv2Parameters(beatmapData, diff, new Accuracy(item.count300, item.count100, item.count50, item.countmiss).Value(), item.countmiss, item.maxcombo, (Mods)item.enabled_mods)); item.nochokeaccuracy = new Accuracy(item.count300 + item.countmiss, item.count100, item.count50, 0).Value() * 100; var nochokePp = new PPv2(new PPv2Parameters(beatmapData, diff, item.nochokeaccuracy / 100, 0, diff.Beatmap.GetMaxCombo(), (Mods)item.enabled_mods)); item.pp = rawPp.Total; item.nochokepp = nochokePp.Total; item.rounded_score = item.score.ToString("C0", _nfi); if (item.maxcombo <= (beatmapData.GetMaxCombo() - (item.count100 + item.count50)) || item.rank == "XH" || item.rank == "SH") { item.choked = true; } else if (item.countmiss > 0) { item.choked = true; } item.starrating = diff.Total; item.counttotal = beatmapData.CountCircles + beatmapData.CountSliders + beatmapData.CountSpinners; item.rounded_score = item.score.ToString("C0", _nfi); item.standardhit = item.count300 + item.count100 + item.count50 + item.countmiss; item.hitted = item.countkatu + item.countgeki + item.count300 + item.count100 + item.count50 + item.countmiss; item.completion = item.standardhit / (double)item.counttotal * 100; } return(array); }
public static double ppCalc(Osu.Types.Beatmap beatmap, double accuracy, Mods mods, int misses, int combo) { byte[] data = new WebClient().DownloadData($"https://osu.ppy.sh/osu/{beatmap.beatmap_id}"); var stream = new MemoryStream(data, false); var reader = new StreamReader(stream); var beatmapp = Beatmap.Read(reader); var pp = new PPv2(new PPv2Parameters(beatmapp, accuracy: accuracy / 100, misses, combo, mods: mods)); return(pp.Total); }
internal static void PrintPP(Beatmap map, Mods[] allMods) { Console.WriteLine($"Map: {map.Artist} - {map.Title} [{map.Version}]"); Console.WriteLine($"Mapper: {map.Creator}"); Console.WriteLine(); Console.WriteLine($"CS{map.CS} AR{map.AR} OD{map.OD} HP{map.HP}"); Console.WriteLine(); for (int i = 0; i <= (1 << allMods.Length) - 1; i++) { var mods = Mods.NoMod; for (int j = 0; j <= allMods.Length; j++) { if ((i & 1 << j) != 0) { mods |= allMods[j]; } } var diff = new DiffCalc().Calc(map, mods); var modStr = OppaiSharp.Helpers.ModsToString(mods); if (string.IsNullOrWhiteSpace(modStr)) { modStr = "NoMod"; } void ShowWithPercent(double percent) { var acc = new Accuracy(percent, map.Objects.Count, 0); var pp = new PPv2(new PPv2Parameters { Beatmap = map, Mods = mods, AimStars = diff.Aim, SpeedStars = diff.Speed, Count300 = acc.Count300, Count100 = acc.Count100, Count50 = acc.Count50, CountMiss = acc.CountMiss }); Console.Write($" | {$"{pp.Total:F2}pp".PadRight(9)} ({percent.ToString(CultureInfo.InvariantCulture)}%)"); } Console.Write($"{modStr.PadRight(6)}| {diff.Total:F2}* (Aim: {diff.Aim:F2}*, Speed: {diff.Speed:F2}*)"); ShowWithPercent(92.5); ShowWithPercent(95); ShowWithPercent(97.5); ShowWithPercent(100); Console.WriteLine(); } }
public void TestManyHundreds() { const int id = 706711; if (!File.Exists($"{id}.osu")) { new WebClient().DownloadFile($"https://osu.ppy.sh/osu/{id}", $"{id}.osu"); } var reader = new StreamReader($"{id}.osu"); //read a beatmap var beatmap = Beatmap.Read(reader); var stars = new DiffCalc().Calc(beatmap); var pp = new PPv2(new PPv2Parameters(beatmap, stars, beatmap.CountCircles + 1)); //not checking the actual value, just making sure that it doesn't throw }
private static double CheckCase(Beatmap bm, ExpectedOutcome outcome, out double margin) { const double errorMargin = 0.02; margin = errorMargin * outcome.PP; var pp = new PPv2(outcome.ToParameters(bm)); if (outcome.PP < 100) { margin *= 3; } else if (outcome.PP < 200) { margin *= 2; } else if (outcome.PP < 300) { margin *= 1.5; } return(pp.Total); }
public async Task LinkParserMethod(SocketMessage s, EmbedBuilder embed, SocketCommandContext context) { stopWatch.Start(); string link = $"{s}"; string mapID = link.Split('/').Last(); //Gets the map's ID from the link. if (mapID.Contains('?')) { mapID = mapID.Replace("?m=0", ""); } string jsonMapParse; string jsonOsuMapData; using (WebClient client = new WebClient()) { jsonMapParse = client.DownloadString($"https://api.tillerino.org/beatmapinfo?beatmapid={mapID}&k={tillerinoapikey}"); } using (WebClient client = new WebClient()) { jsonOsuMapData = client.DownloadString($"https://osu.ppy.sh/api/get_beatmaps?k={osuapikey}&b={mapID}"); } var mapObject = JsonConvert.DeserializeObject <dynamic>(jsonMapParse); var mapData = JsonConvert.DeserializeObject <dynamic>(jsonOsuMapData)[0]; //osu! API Data string mapTitle = mapData.title; string beatmapSetID = mapData.beatmapset_id; string artist = mapData.artist; string creator = mapData.creator; string creatorID = mapData.creator_id; string difficulty = mapData.version; double starRating = mapData.difficultyrating; double cs = mapData.diff_size; double od = mapData.diff_overall; double ar = mapData.diff_approach; double hp = mapData.diff_drain; TimeSpan length = TimeSpan.FromSeconds((int)mapData.total_length); double bpm = mapData.bpm; int maxCombo = mapData.max_combo; int favoriteCount = mapData.favourite_count; int playCount = mapData.playcount; int passCount = mapData.passcount; string status = mapData.approved; if (status == "-2" || status == "-1" || status == "0") { switch (status) { case "-2": status = "Graveyard"; break; case "-1": status = "Work in Progress"; break; case "0": status = "Pending"; break; } } else { DateTime approvedDate = mapData.approved_date; switch (status) { case "-2": status = "Graveyard"; break; case "-1": status = "Work in Progress"; break; case "0": status = "Pending"; break; case "1": status = $"Ranked on {approvedDate.ToShortDateString()}"; break; case "2": status = $"Approved on {approvedDate.ToShortDateString()}"; break; case "3": status = $"Qualified on {approvedDate.ToShortDateString()}"; break; case "4": status = $"Loved 💙 on {approvedDate.ToShortDateString()}"; break; } } string lengthValue = length.ToString(@"mm\:ss"); if (status.ToLower() == "graveyard" || status.ToLower() == "work in progress" || status.ToLower() == "pending") { byte[] data = new WebClient().DownloadData($"https://osu.ppy.sh/osu/{mapID}"); var stream = new MemoryStream(data, false); var reader = new StreamReader(stream); var mods = Mods.NoMod; var beatmap = Beatmap.Read(reader); var diff = new DiffCalc().Calc(beatmap, mods: mods); var unranked95 = new PPv2(new PPv2Parameters(beatmap, diff, accuracy: .95, mods: mods)); var unranked98 = new PPv2(new PPv2Parameters(beatmap, diff, accuracy: .98, mods: mods)); var unranked99 = new PPv2(new PPv2Parameters(beatmap, diff, accuracy: .99, mods: mods)); var unranked100 = new PPv2(new PPv2Parameters(beatmap, diff, accuracy: 1, mods: mods)); embed.WithAuthor(author => { author.Name = $"{mapTitle} by {creator}"; author.Url = $"https://osu.ppy.sh/b/{mapID}"; author.IconUrl = $"https://a.ppy.sh/{creatorID}"; }); embed.WithDescription( $"**{mapTitle} [{difficulty}]** by **{artist}**" + $"\n" + $"\n<:total_length:567812515346513932> **Total Length:** {lengthValue} <:bpm:567813349820071937> **BPM:** {bpm.ToString("N0")}" + $"\n**Star Rating:** `{starRating.ToString("N2")} ☆` **Maximum Combo:** `{maxCombo.ToString("N0")}x`" + $"\n**Download:** [[Beatmap]](https://osu.ppy.sh/beatmapsets/{beatmapSetID}/download)" + $"[(without video)](https://osu.ppy.sh/d/{beatmapSetID}n)" + $"\n" + $"\n**CS:** `{(float)cs} ` **AR:** `{(float)ar}` **OD:** `{(float)od}` **HP:** `{(float)hp}`" + $"\n" + $"\n**95% FC:** `{unranked95.Total.ToString("N0")}pp` **98% FC:** `{unranked98.Total.ToString("N0")}pp`" + $"\n**99% FC:** `{unranked99.Total.ToString("N0")}pp` **100% FC (SS):** `{unranked100.Total.ToString("N0")}pp`"); embed.WithFooter($"Status: {status} | 💙 Amount: {favoriteCount}"); embed.WithColor(Pink); await context.Channel.SendMessageAsync("", false, embed.Build()); stopWatch.Stop(); logger.ConsoleCommandLog(context, stopWatch.ElapsedMilliseconds); return; } double passRate = (playCount / passCount); //Tillerino API Data: Performance Point values for full combos on the map with the given accuracy. double value75 = mapObject.ppForAcc.entry[0].value; double value90 = mapObject.ppForAcc.entry[3].value; double value95 = mapObject.ppForAcc.entry[5].value; double value98 = mapObject.ppForAcc.entry[9].value; double value99 = mapObject.ppForAcc.entry[11].value; double value100 = mapObject.ppForAcc.entry[13].value; embed.WithAuthor(author => { author.Name = $"{mapTitle} by {creator}"; author.Url = $"https://osu.ppy.sh/b/{mapID}"; author.IconUrl = $"https://a.ppy.sh/{creatorID}"; }); embed.WithDescription($"**{mapTitle} [{difficulty}]** by **{artist}**" + $"\n" + $"\n<:total_length:567812515346513932> **Total Length:** {lengthValue} <:bpm:567813349820071937> **BPM:** {bpm.ToString("N0")}" + $"\n**Star Rating:** `{starRating.ToString("N2")} ☆` **Maximum Combo:** `{maxCombo}x`" + $"\n**Download:** [[Beatmap]](https://osu.ppy.sh/beatmapsets/{beatmapSetID}/download)" + $"[(without video)](https://osu.ppy.sh/d/{beatmapSetID}n) [[Bloodcat Mirror]](https://bloodcat.com/osu/s/{beatmapSetID})" + $"\n" + $"\n**CS:** `{(float)cs} ` **AR:** `{(float)ar}` **OD:** `{(float)od}` **HP:** `{(float)hp}`" + $"\n" + $"\n**75% FC:** `{(int)value75}pp` **90% FC:** `{(int)value90}pp`" + $"\n**95% FC:** `{(int)value95}pp` **98% FC:** `{(int)value98}pp`" + $"\n**99% FC:** `{(int)value99}pp` **100% FC (SS):** `{(int)value100}pp`"); embed.WithFooter($"Status: {status} | 💙 Amount: {favoriteCount} | Pass Rate: {passRate.ToString("N2")}%"); embed.WithColor(Pink); await context.Channel.SendMessageAsync("", false, embed.Build()); stopWatch.Stop(); logger.ConsoleCommandLog(context, stopWatch.ElapsedMilliseconds); return; }
public async Task osuRecent(string player = null) { stopWatch.Start(); string cmdPrefix = Servers.GetServer(Context.Guild).commandPrefix; string osuapikey = Config.bot.OsuApiKey; if (player == null || player == "") { player = UserAccounts.GetAccount(Context.User).OsuUsername; if (player == null || player == "") { embed.WithTitle("osu! Recent"); embed.WithDescription($"**{Context.User.Mention} Failed to acquire username! Please specify a player or set your osu! username with `{cmdPrefix}osuset`!**"); embed.WithColor(Red); await BE(); return; } } string jsonRecent; using (WebClient client = new WebClient()) { jsonRecent = client.DownloadString($"https://osu.ppy.sh/api/get_user_recent?k={osuapikey}&u=" + player); } if (jsonRecent == "[]") { string jsonUserData; using (WebClient client = new WebClient()) { jsonUserData = client.DownloadString($"https://osu.ppy.sh/api/get_user?k={osuapikey}&u=" + player); } var mapUserNameObject = JsonConvert.DeserializeObject <dynamic>(jsonUserData)[0]; embed.WithAuthor(author => { author .WithName("" + mapUserNameObject.username + " hasn't got any recent plays") .WithIconUrl("https://a.ppy.sh/" + mapUserNameObject.user_id); }); embed.WithColor(Pink); await BE(); } else { var playerRecentObject = JsonConvert.DeserializeObject <dynamic>(jsonRecent)[0]; string mapID = playerRecentObject.beatmap_id; string mapRecent = ""; using (WebClient client = new WebClient()) { mapRecent = client.DownloadString($"https://osu.ppy.sh/api/get_beatmaps?k={osuapikey}&b={mapID}"); } var mapRecentObject = JsonConvert.DeserializeObject <dynamic>(mapRecent)[0]; string mapTitle = mapRecentObject.title; string difficulty = mapRecentObject.version; string score = playerRecentObject.score; double maxCombo = playerRecentObject.maxcombo; string artist = mapRecentObject.artist; double count50 = playerRecentObject.count50; double count100 = playerRecentObject.count100; double count300 = playerRecentObject.count300; double countMiss = playerRecentObject.countmiss; string fullCombo = playerRecentObject.perfect; if (fullCombo == "1") { fullCombo = " **Full Combo!**"; } else { fullCombo = null; } string mods = playerRecentObject.enabled_mods; double maxPossibleCombo = mapRecentObject.max_combo; var modnum = playerRecentObject.enabled_mods; mods = ((AllMods)modnum).ToString().Replace(",", ""); mods = mods.Replace(" ", ""); mods = mods.Replace("NM", ""); string date = playerRecentObject.date; double starRating = mapRecentObject.difficultyrating; double accuracy = 100 * ((50 * count50) + (100 * count100) + (300 * count300)) / ((300 * (countMiss + count50 + count100 + count300))); string grade = playerRecentObject.rank; switch (grade) { case "XH": grade = "<:XH:553119188089176074>"; break; case "X": grade = "<:X_:553119217109565470>"; break; case "SH": grade = "<:SH:553119233463025691>"; break; case "S": grade = "<:S_:553119252329267240>"; break; case "A": grade = "<:A_:553119274256826406>"; break; case "B": grade = "<:B_:553119304925577228>"; break; case "C": grade = "<:C_:553119325565878272>"; break; case "D": grade = "<:D_:553119338035675138>"; break; case "F": grade = "<:F_:557297028263051288>"; break; } string NormalUserName = ""; using (WebClient client = new WebClient()) { NormalUserName = client.DownloadString($"https://osu.ppy.sh/api/get_user?k={osuapikey}&u=" + player); } if (NormalUserName == "[]") { embed.WithDescription($"{Context.User.Mention} **ERROR: Could not download data for {player}!**"); embed.WithColor(Red); await BE(); stopWatch.Stop(); logger.ConsoleCommandLog(Context, stopWatch.ElapsedMilliseconds, CommandError.Unsuccessful, "osu! API did not return any data for the given username."); return; } var mapUserNameObject = JsonConvert.DeserializeObject <dynamic>(NormalUserName)[0]; //PPv2 byte[] data = new WebClient().DownloadData($"https://osu.ppy.sh/osu/{mapID}"); var stream = new MemoryStream(data, false); var reader = new StreamReader(stream); var enabledMods = Mods.NoMod; switch (mods) { case "": enabledMods = Mods.NoMod; break; case "HD": enabledMods = Mods.Hidden; break; case "HR": enabledMods = Mods.Hardrock; break; case "DT": case "NC": enabledMods = Mods.DoubleTime; break; case "FL": enabledMods = Mods.Flashlight; break; case "HDDT": case "HDNC": enabledMods = (int)Mods.DoubleTime + Mods.Hidden; break; case "HDHR": enabledMods = (int)Mods.Hidden + Mods.Hardrock; break; case "HDFL": enabledMods = (int)Mods.Hidden + Mods.Flashlight; break; case "EZ": enabledMods = Mods.Easy; break; case "HDHRDT": case "HDHRNC": enabledMods = (int)Mods.Hidden + (int)Mods.Hardrock + Mods.DoubleTime; break; default: enabledMods = Mods.NoMod; break; } var beatmap = Beatmap.Read(reader); var diff = new DiffCalc().Calc(beatmap, mods: enabledMods); var fullComboPP = new PPv2(new PPv2Parameters(beatmap, diff, accuracy: (accuracy / 100), mods: enabledMods)); //PPv2 End string plus = "+"; var objectsEncountered = (count300 + count100 + count50 + countMiss); var mapCompletion = ((objectsEncountered / beatmap.Objects.Count()) * 100).ToString("N2"); if (plus == "+" && mods == "") { plus = ""; } mods = mods.Replace("576", "NC"); string playerRecentString = $"▸ **{grade}{plus}{mods}** ▸ **[{mapTitle} [{difficulty}]](https://osu.ppy.sh/b/{mapID})** by **{artist}**\n" + $"▸ **☆{starRating.ToString("F")}** ▸ **{accuracy.ToString("F")}%**\n" + $"▸ **Combo:** `{maxCombo.ToString("N0")}x / {maxPossibleCombo.ToString("N0")}x`\n" + $"▸ [300 / 100 / 50 / X]: `[{count300} / {count100} / {count50} / {countMiss}]`\n" + $"▸ **Map Completion:** `{mapCompletion}`%\n" + $"▸ **Full Combo Percentage:** `{((maxCombo / maxPossibleCombo) * 100).ToString("N2")}%`\n" + $"▸ **PP for FC**: `{fullComboPP.Total.ToString("N0")}pp`"; var difference = DateTime.UtcNow - (DateTime)playerRecentObject.date; string footer = $"{mapUserNameObject.username} performed this play {(int)difference.TotalHours} hours {difference.Minutes} minutes and {difference.Seconds} seconds ago."; embed.WithAuthor(author => { author .WithName($"Most Recent osu! Standard Play for " + mapUserNameObject.username) .WithIconUrl("https://a.ppy.sh/" + playerRecentObject.user_id); }); embed.WithDescription($"{playerRecentString}"); embed.WithFooter(footer); embed.WithColor(Pink); await BE(); stopWatch.Stop(); logger.ConsoleCommandLog(Context, stopWatch.ElapsedMilliseconds); } }
private double GetPp(Beatmap beatmap, double acc, Mods mods = Mods.NoMod) { _accCalculator = new Accuracy(acc, beatmap.Objects.Count, 0); _ppCalculator = new PPv2(new PPv2Parameters(beatmap, _accCalculator.Count100, _accCalculator.Count50, _accCalculator.CountMiss, -1, _accCalculator.Count300, mods)); return(Math.Round(_ppCalculator.Total, 2)); }