public async Task<IActionResult> PostSubmitModular() { if (!Directory.Exists("data/replays")) Directory.CreateDirectory("data/replays"); string encScore = Request.Form["score"]; string iv = Request.Form["iv"]; string osuver = Request.Form["osuver"]; string passwd = Request.Form["pass"]; var (pass, score) = ScoreSubmissionParser.ParseScore(encScore, iv, osuver); var dbUser = await DbUser.GetDbUser(_ctx, score.UserName); if (dbUser == null) return Ok("error: pass"); if (!dbUser.IsPassword(passwd)) return Ok("error: pass"); if (!_ps.TryGet(dbUser.Id, out var pr)) return Ok("error: pass"); // User not logged in in Bancho! if (!pass || !RankedMods.IsRanked(score.Mods)) { var lb = await DbLeaderboard.GetLeaderboardAsync(_ctx, dbUser); lb.IncreasePlaycount(score.PlayMode); lb.IncreaseScore((ulong) score.TotalScore, false, score.PlayMode); await lb.SaveChanges(_ctx); // Send to other People await _ev.RunEvent( EventType.BanchoUserStatsRequest, new BanchoUserStatsRequestArgs {UserIds = new List<int> {score.Id}, Pr = pr} ); // Send to self await _ev.RunEvent( EventType.BanchoSendUserStatus, new BanchoSendUserStatusArgs {Status = pr.Status, Pr = pr} ); return Ok("Thanks for your hard work! onii-chyan~"); // even though, we're Sora, we can still be cute! } var replayFileData = Request.Form.Files.GetFile("score"); var dbScore = new DbScore { Accuracy = score.ComputeAccuracy(), Count100 = score.Count100, Count50 = score.Count50, Count300 = score.Count300, Date = score.Date, Mods = score.Mods, CountGeki = score.CountGeki, CountKatu = score.CountKatu, CountMiss = score.CountMiss, FileMd5 = score.FileMd5, MaxCombo = score.MaxCombo, PlayMode = score.PlayMode, ScoreOwner = dbUser, TotalScore = score.TotalScore, UserId = dbUser.Id }; await _pisstaube.DownloadBeatmapAsync(dbScore.FileMd5); await using (var m = new MemoryStream()) { replayFileData.CopyTo(m); m.Position = 0; dbScore.ReplayMd5 = Hex.ToHex(Crypto.GetMd5(m)) ?? string.Empty; if (!string.IsNullOrEmpty(dbScore.ReplayMd5)) { await using var replayFile = System.IO.File.Create($"data/replays/{dbScore.ReplayMd5}"); m.Position = 0; m.WriteTo(replayFile); m.Close(); replayFile.Close(); } } dbScore.PerformancePoints = dbScore.ComputePerformancePoints(); var oldScore = await DbScore.GetLatestScore(_ctx, dbScore); var oldLb = await DbLeaderboard.GetLeaderboardAsync(_ctx, dbScore.ScoreOwner); var oldStdPos = oldLb.GetPosition(_ctx, dbScore.PlayMode); var oldAcc = oldLb.GetAccuracy(_ctx, dbScore.PlayMode); double newAcc; if (oldScore != null && oldScore.TotalScore <= dbScore.TotalScore) { _ctx.Remove(oldScore); System.IO.File.Delete($"data/replays/{oldScore.ReplayMd5}"); await DbScore.InsertScore(_ctx, dbScore); } else if (oldScore == null) { await DbScore.InsertScore(_ctx, dbScore); } else { System.IO.File.Delete($"data/replays/{oldScore.ReplayMd5}"); } var newlb = await DbLeaderboard.GetLeaderboardAsync(_ctx, dbScore.ScoreOwner); newlb.IncreasePlaycount(dbScore.PlayMode); newlb.IncreaseScore((ulong) dbScore.TotalScore, true, dbScore.PlayMode); newlb.IncreaseScore((ulong) dbScore.TotalScore, false, dbScore.PlayMode); newlb.UpdatePp(_ctx, dbScore.PlayMode); await newlb.SaveChanges(_ctx); var newStdPos = newlb.GetPosition(_ctx, dbScore.PlayMode); newAcc = newlb.GetAccuracy(_ctx, dbScore.PlayMode); var newScore = await DbScore.GetLatestScore(_ctx, dbScore); var set = await _pisstaube.FetchBeatmapSetAsync(dbScore.FileMd5); var bm = set?.ChildrenBeatmaps.First(x => x.FileMD5 == dbScore.FileMd5) ?? new Beatmap(); ulong oldRankedScore; ulong newRankedScore; double oldPp; double newPp; switch (dbScore.PlayMode) { case PlayMode.Osu: oldRankedScore = oldLb.RankedScoreOsu; newRankedScore = newlb.RankedScoreOsu; oldPp = oldLb.PerformancePointsOsu; newPp = newlb.PerformancePointsOsu; break; case PlayMode.Taiko: oldRankedScore = oldLb.RankedScoreTaiko; newRankedScore = newlb.RankedScoreTaiko; oldPp = oldLb.PerformancePointsTaiko; newPp = newlb.PerformancePointsTaiko; break; case PlayMode.Ctb: oldRankedScore = oldLb.RankedScoreCtb; newRankedScore = newlb.RankedScoreCtb; oldPp = oldLb.PerformancePointsCtb; newPp = newlb.PerformancePointsCtb; break; case PlayMode.Mania: oldRankedScore = oldLb.RankedScoreMania; newRankedScore = newlb.RankedScoreMania; oldPp = oldLb.PerformancePointsMania; newPp = newlb.PerformancePointsMania; break; default: return Ok(""); } var newScorePosition = newScore != null ? await newScore.Position(_ctx) : 0; var oldScorePosition = oldScore != null ? await oldScore.Position(_ctx) : 0; if (newScorePosition == 1) _sora.SendMessage( $"[http://{_config.Server.ScreenShotHostname}/{dbScore.ScoreOwner.Id} {dbScore.ScoreOwner.UserName}] " + $"has reached #1 on [https://osu.ppy.sh/b/{bm.BeatmapID} {set?.Title} [{bm.DiffName}]] " + $"using {ModUtil.ToString(newScore.Mods)} " + $"Good job! +{newScore.PerformancePoints:F}PP", "#announce", false ); Logger.Info( $"{LCol.RED}{dbScore.ScoreOwner.UserName}", $"{LCol.PURPLE}( {dbScore.ScoreOwner.Id} ){LCol.WHITE}", $"has just submitted a Score! he earned {LCol.BLUE}{newScore?.PerformancePoints:F}PP", $"{LCol.WHITE}with an Accuracy of {LCol.RED}{newScore?.Accuracy * 100:F}", $"{LCol.WHITE}on {LCol.YELLOW}{set?.Title} [{bm.DiffName}]", $"{LCol.WHITE}using {LCol.BLUE}{ModUtil.ToString(newScore?.Mods ?? Mod.None)}" ); var bmChart = new Chart( "beatmap", "Beatmap Ranking", $"https://osu.ppy.sh/b/{bm.BeatmapID}", oldScorePosition, newScorePosition, oldScore?.MaxCombo ?? 0, newScore?.MaxCombo ?? 0, oldScore?.Accuracy * 100 ?? 0, newScore?.Accuracy * 100 ?? 0, (ulong) (oldScore?.TotalScore ?? 0), (ulong) (newScore?.TotalScore ?? 0), oldScore?.PerformancePoints ?? 0, newScore?.PerformancePoints ?? 0, newScore?.Id ?? 0 ); var overallChart = new Chart( "overall", "Global Ranking", $"https://osu.ppy.sh/u/{dbUser.Id}", (int) oldStdPos, (int) newStdPos, 0, 0, oldAcc * 100, newAcc * 100, oldRankedScore, newRankedScore, oldPp, newPp, newScore?.Id ?? 0, AchievementProcessor.ProcessAchievements( _ctx, dbScore.ScoreOwner, score, bm, set, oldLb, newlb ) ); pr["LB"] = newlb; pr.Stats.Accuracy = (float) newlb.GetAccuracy(_ctx, score.PlayMode); pr.Stats.Position = newlb.GetPosition(_ctx, score.PlayMode); switch (score.PlayMode) { case PlayMode.Osu: pr.Stats.PerformancePoints = (ushort) newlb.PerformancePointsOsu; pr.Stats.TotalScore = (ushort) newlb.TotalScoreOsu; pr.Stats.RankedScore = (ushort) newlb.RankedScoreOsu; pr.Stats.PlayCount = (ushort) newlb.PlayCountOsu; break; case PlayMode.Taiko: pr.Stats.PerformancePoints = (ushort) newlb.PerformancePointsTaiko; pr.Stats.TotalScore = (ushort) newlb.TotalScoreTaiko; pr.Stats.RankedScore = (ushort) newlb.RankedScoreTaiko; pr.Stats.PlayCount = (ushort) newlb.PlayCountTaiko; break; case PlayMode.Ctb: pr.Stats.PerformancePoints = (ushort) newlb.PerformancePointsCtb; pr.Stats.TotalScore = (ushort) newlb.TotalScoreCtb; pr.Stats.RankedScore = (ushort) newlb.RankedScoreCtb; pr.Stats.PlayCount = (ushort) newlb.PlayCountCtb; break; case PlayMode.Mania: pr.Stats.PerformancePoints = (ushort) newlb.PerformancePointsMania; pr.Stats.TotalScore = (ushort) newlb.TotalScoreMania; pr.Stats.RankedScore = (ushort) newlb.RankedScoreMania; pr.Stats.PlayCount = (ushort) newlb.PlayCountMania; break; } // Send to other People await _ev.RunEvent( EventType.BanchoUserStatsRequest, new BanchoUserStatsRequestArgs {UserIds = new List<int> {score.Id}, Pr = pr} ); // Send to self await _ev.RunEvent( EventType.BanchoSendUserStatus, new BanchoSendUserStatusArgs {Status = pr.Status, Pr = pr} ); return Ok( $"beatmapId:{bm.BeatmapID}|beatmapSetId:{bm.ParentSetID}|beatmapPlaycount:0|beatmapPasscount:0|approvedDate:\n\n" + bmChart.ToOsuString() + "\n" + overallChart.ToOsuString() ); }
public async Task <IActionResult> PostSubmitModular() { string score = Request.Form["score"]; string iv = Request.Form["iv"]; string osuver = Request.Form["osuver"]; string pass = Request.Form["pass"]; var(b, scores) = ScoreSubmissionParser.ParseScore(_factory, score, iv, osuver); if (scores.UserId == -1) { return(Ok("error: pass")); } if (scores.ScoreOwner == null) { scores.ScoreOwner = Users.GetUser(_factory, scores.UserId); } if (scores.ScoreOwner == null) { return(Ok("error: pass")); } if (!scores.ScoreOwner.IsPassword(pass)) { return(Ok("error: pass")); } var isRelaxing = (scores.Mods & Mod.Relax) != 0; var pr = _ps.GetPresence(scores.ScoreOwner.Id); if (!b || !RankedMods.IsRanked(scores.Mods)) { if (isRelaxing) { var rx = LeaderboardRx.GetLeaderboard(_factory, scores.ScoreOwner); rx.IncreasePlaycount(_factory, scores.PlayMode); rx.IncreaseScore(_factory, (ulong)scores.TotalScore, false, scores.PlayMode); } else { var std = LeaderboardStd.GetLeaderboard(_factory, scores.ScoreOwner); std.IncreasePlaycount(_factory, scores.PlayMode); std.IncreaseScore(_factory, (ulong)scores.TotalScore, false, scores.PlayMode); } await _ev.RunEvent( EventType.BanchoUserStatsRequest, new BanchoUserStatsRequestArgs { userIds = new List <int> { scores.ScoreOwner.Id }, pr = pr } ); return(Ok("Thanks for your hard work!")); } /* * switch (scores.PlayMode) * { * case PlayMode.Osu: * oppai op = new oppai(BeatmapDownloader.GetBeatmap(scores.FileMd5, _config)); * op.SetAcc((int) scores.Count300, (int) scores.Count50, (int) scores.CountMiss); * op.SetCombo(scores.MaxCombo); * op.SetMods(scores.Mods); * op.Calculate(); * * scores.PeppyPoints = op.GetPP(); * Logger.Info("Peppy Points:", scores.PeppyPoints); * break; * } */ var ReplayFile = Request.Form.Files.GetFile("score"); if (!Directory.Exists("data/replays")) { Directory.CreateDirectory("data/replays"); } await using (var m = new MemoryStream()) { ReplayFile.CopyTo(m); m.Position = 0; scores.ReplayMd5 = Hex.ToHex(Crypto.GetMd5(m)) ?? string.Empty; if (!string.IsNullOrEmpty(scores.ReplayMd5)) { await using (var replayFile = System.IO.File.Create($"data/replays/{scores.ReplayMd5}")) { m.Position = 0; m.WriteTo(replayFile); m.Close(); replayFile.Close(); } } } BeatmapDownloader.GetBeatmap(scores.FileMd5, _config); if (isRelaxing) { scores.Mods -= Mod.Relax; } scores.PeppyPoints = PerformancePointsProcessor.Compute(scores); if (isRelaxing) { scores.Mods |= Mod.Relax; } var oldScore = Scores.GetScores( _factory, scores.FileMd5, scores.ScoreOwner, scores.PlayMode, isRelaxing, false, false, false, scores.Mods, true ).FirstOrDefault(); var oldStd = LeaderboardStd.GetLeaderboard(_factory, scores.ScoreOwner); var oldStdPos = oldStd.GetPosition(_factory, scores.PlayMode); if (oldScore != null && oldScore.TotalScore <= scores.TotalScore) { using var db = _factory.GetForWrite(); db.Context.Scores.Remove(oldScore); System.IO.File.Delete($"data/replays/{oldScore.ReplayMd5}"); Scores.InsertScore(_factory, scores); } else if (oldScore == null) { Scores.InsertScore(_factory, scores); } else { System.IO.File.Delete($"data/replays/{scores.ReplayMd5}"); } if (isRelaxing) { var rx = LeaderboardRx.GetLeaderboard(_factory, scores.ScoreOwner); rx.IncreasePlaycount(_factory, scores.PlayMode); rx.IncreaseCount300(_factory, scores.Count300, scores.PlayMode); rx.IncreaseCount100(_factory, scores.Count100, scores.PlayMode); rx.IncreaseCount50(_factory, scores.Count50, scores.PlayMode); rx.IncreaseCountMiss(_factory, scores.CountMiss, scores.PlayMode); rx.IncreaseScore(_factory, (ulong)scores.TotalScore, true, scores.PlayMode); rx.IncreaseScore(_factory, (ulong)scores.TotalScore, false, scores.PlayMode); rx.UpdatePP(_factory, scores.PlayMode); pr.LeaderboardRx = rx; await _ev.RunEvent( EventType.BanchoUserStatsRequest, new BanchoUserStatsRequestArgs { userIds = new List <int> { scores.ScoreOwner.Id }, pr = pr } ); } else { var std = LeaderboardStd.GetLeaderboard(_factory, scores.ScoreOwner); std.IncreasePlaycount(_factory, scores.PlayMode); std.IncreaseCount300(_factory, scores.Count300, scores.PlayMode); std.IncreaseCount100(_factory, scores.Count100, scores.PlayMode); std.IncreaseCount50(_factory, scores.Count50, scores.PlayMode); std.IncreaseCountMiss(_factory, scores.CountMiss, scores.PlayMode); std.IncreaseScore(_factory, (ulong)scores.TotalScore, true, scores.PlayMode); std.IncreaseScore(_factory, (ulong)scores.TotalScore, false, scores.PlayMode); std.UpdatePP(_factory, scores.PlayMode); } var newStd = LeaderboardStd.GetLeaderboard(_factory, scores.ScoreOwner); var newStdPos = newStd.GetPosition(_factory, scores.PlayMode); var NewScore = Scores.GetScores( _factory, scores.FileMd5, scores.ScoreOwner, scores.PlayMode, isRelaxing, false, false, false, scores.Mods, true ).FirstOrDefault(); var cg = new Cheesegull(_config); cg.SetBM(scores.FileMd5); var sets = cg.GetSets(); var bm = sets?[0].ChildrenBeatmaps.First(x => x.FileMD5 == scores.FileMd5) ?? new CheesegullBeatmap(); double oldAcc; double newAcc; ulong oldRankedScore; ulong newRankedScore; double oldPP; double newPP; switch (scores.PlayMode) { case PlayMode.Osu: oldAcc = Accuracy.GetAccuracy( oldStd.Count300Osu, oldStd.Count100Osu, oldStd.Count50Osu, oldStd.Count300Osu, 0, 0, PlayMode.Osu ); newAcc = Accuracy.GetAccuracy( newStd.Count300Osu, newStd.Count100Osu, newStd.Count50Osu, newStd.Count300Osu, 0, 0, PlayMode.Osu ); oldRankedScore = oldStd.RankedScoreOsu; newRankedScore = newStd.RankedScoreOsu; oldPP = oldStd.PerformancePointsOsu; newPP = newStd.PerformancePointsOsu; break; case PlayMode.Taiko: oldAcc = Accuracy.GetAccuracy( oldStd.Count300Taiko, oldStd.Count100Taiko, oldStd.Count50Taiko, oldStd.Count300Taiko, 0, 0, PlayMode.Taiko ); newAcc = Accuracy.GetAccuracy( newStd.Count300Taiko, newStd.Count100Taiko, newStd.Count50Taiko, newStd.Count300Taiko, 0, 0, PlayMode.Taiko ); oldRankedScore = oldStd.RankedScoreTaiko; newRankedScore = newStd.RankedScoreTaiko; oldPP = oldStd.PerformancePointsTaiko; newPP = newStd.PerformancePointsTaiko; break; case PlayMode.Ctb: oldAcc = Accuracy.GetAccuracy( oldStd.Count300Ctb, oldStd.Count100Ctb, oldStd.Count50Ctb, oldStd.Count300Ctb, 0, 0, PlayMode.Ctb ); newAcc = Accuracy.GetAccuracy( newStd.Count300Ctb, newStd.Count100Ctb, newStd.Count50Ctb, newStd.Count300Ctb, 0, 0, PlayMode.Ctb ); oldRankedScore = oldStd.RankedScoreCtb; newRankedScore = newStd.RankedScoreCtb; oldPP = oldStd.PerformancePointsCtb; newPP = newStd.PerformancePointsCtb; break; case PlayMode.Mania: oldAcc = Accuracy.GetAccuracy( oldStd.Count300Mania, oldStd.Count100Mania, oldStd.Count50Mania, oldStd.Count300Mania, 0, 0, PlayMode.Mania ); newAcc = Accuracy.GetAccuracy( newStd.Count300Mania, newStd.Count100Mania, newStd.Count50Mania, newStd.Count300Mania, 0, 0, PlayMode.Mania ); oldRankedScore = oldStd.RankedScoreMania; newRankedScore = newStd.RankedScoreMania; oldPP = oldStd.PerformancePointsMania; newPP = newStd.PerformancePointsMania; break; default: return(Ok("")); } if (NewScore?.Position == 1 && (oldScore == null || oldScore.TotalScore < NewScore.TotalScore)) { _sora.SendMessage( $"[http://{_config.Server.Hostname}/{scores.ScoreOwner.Id} {scores.ScoreOwner.Username}] " + $"has reached #1 on [https://osu.ppy.sh/b/{bm.BeatmapID} {sets?[0].Title} [{bm.DiffName}]] " + $"using {ModUtil.ToString(NewScore.Mods)} " + $"Good job! +{NewScore.PeppyPoints:F}PP", "#announce", false ); } Logger.Info( $"{L_COL.RED}{scores.ScoreOwner.Username}", $"{L_COL.PURPLE}( {scores.ScoreOwner.Id} ){L_COL.WHITE}", $"has just submitted a Score! he earned {L_COL.BLUE}{NewScore?.PeppyPoints:F}PP", $"{L_COL.WHITE}with an Accuracy of {L_COL.RED}{NewScore?.Accuracy * 100:F}", $"{L_COL.WHITE}on {L_COL.YELLOW}{sets?[0].Title} [{bm.DiffName}]", $"{L_COL.WHITE}using {L_COL.BLUE}{ModUtil.ToString(NewScore?.Mods ?? Mod.None)}" ); var bmChart = new Chart( "beatmap", "Beatmap Ranking", $"https://osu.ppy.sh/b/{bm.BeatmapID}", oldScore?.Position ?? 0, NewScore?.Position ?? 0, oldScore?.MaxCombo ?? 0, NewScore?.MaxCombo ?? 0, oldScore?.Accuracy * 100 ?? 0, NewScore?.Accuracy * 100 ?? 0, (ulong)(oldScore?.TotalScore ?? 0), (ulong)(NewScore?.TotalScore ?? 0), oldScore?.PeppyPoints ?? 0, NewScore?.PeppyPoints ?? 0, NewScore?.Id ?? 0 ); cg.SetBMSet(bm.ParentSetID); var overallChart = new Chart( "overall", "Global Ranking", $"https://osu.ppy.sh/u/{scores.ScoreOwner.Id}", (int)oldStdPos, (int)newStdPos, 0, 0, oldAcc * 100, newAcc * 100, oldRankedScore, newRankedScore, oldPP, newPP, NewScore?.Id ?? 0, AchievementProcessor.ProcessAchievements( _factory, scores.ScoreOwner, scores, bm, cg.GetSets()[0], oldStd, newStd ) ); pr.LeaderboardStd = newStd; await _ev.RunEvent( EventType.BanchoUserStatsRequest, new BanchoUserStatsRequestArgs { userIds = new List <int> { scores.ScoreOwner.Id }, pr = pr } ); return(Ok( $"beatmapId:{bm.BeatmapID}|beatmapSetId:{bm.ParentSetID}|beatmapPlaycount:0|beatmapPasscount:0|approvedDate:\n\n" + bmChart.ToOsuString() + "\n" + overallChart.ToOsuString() )); }