Skip to content

Commit

Permalink
Merge pull request #224 from bdach/skip-upload-scores-without-hits
Browse files Browse the repository at this point in the history
Skip score uploads when nothing was hit in score
  • Loading branch information
smoogipoo authored Mar 14, 2024
2 parents cc1d36d + e08c3b2 commit 1c622f6
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
49 changes: 47 additions & 2 deletions osu.Server.Spectator.Tests/SpectatorHubTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ public async Task ReplayDataIsSaved(bool savingEnabled)

await hub.BeginPlaySession(1234, state);
await hub.SendFrameData(new FrameDataBundle(
new FrameHeader(new ScoreInfo(), new ScoreProcessorStatistics()),
new FrameHeader(new ScoreInfo
{
Statistics =
{
[HitResult.Great] = 1
}
}, new ScoreProcessorStatistics()),
new[] { new LegacyReplayFrame(1234, 0, 0, ReplayButtonState.None) }));
await hub.EndPlaySession(state);

Expand All @@ -145,6 +151,39 @@ await hub.SendFrameData(new FrameDataBundle(
mockScoreStorage.Verify(s => s.WriteAsync(It.IsAny<Score>()), Times.Never);
}

[Fact]
public async Task ReplaysWithoutAnyHitsAreDiscarded()
{
AppSettings.SaveReplays = true;

Mock<IHubCallerClients<ISpectatorClient>> mockClients = new Mock<IHubCallerClients<ISpectatorClient>>();
Mock<ISpectatorClient> mockReceiver = new Mock<ISpectatorClient>();
mockClients.Setup(clients => clients.All).Returns(mockReceiver.Object);
mockClients.Setup(clients => clients.Group(SpectatorHub.GetGroupId(streamer_id))).Returns(mockReceiver.Object);

Mock<HubCallerContext> mockContext = new Mock<HubCallerContext>();

mockContext.Setup(context => context.UserIdentifier).Returns(streamer_id.ToString());
hub.Context = mockContext.Object;
hub.Clients = mockClients.Object;

mockDatabase.Setup(db => db.GetScoreFromToken(1234)).Returns(Task.FromResult<SoloScore?>(new SoloScore
{
id = 456,
passed = true
}));

await hub.BeginPlaySession(1234, state);
await hub.SendFrameData(new FrameDataBundle(
new FrameHeader(new ScoreInfo(), new ScoreProcessorStatistics()),
new[] { new LegacyReplayFrame(1234, 0, 0, ReplayButtonState.None) }));
await hub.EndPlaySession(state);

await scoreUploader.Flush();

mockScoreStorage.Verify(s => s.WriteAsync(It.IsAny<Score>()), Times.Never);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
Expand Down Expand Up @@ -287,7 +326,13 @@ public async Task ScoresAreOnlySavedOnRankedBeatmaps(BeatmapOnlineStatus status,

await hub.BeginPlaySession(1234, state);
await hub.SendFrameData(new FrameDataBundle(
new FrameHeader(new ScoreInfo(), new ScoreProcessorStatistics()),
new FrameHeader(new ScoreInfo
{
Statistics =
{
[HitResult.Great] = 10
}
}, new ScoreProcessorStatistics()),
new[] { new LegacyReplayFrame(1234, 0, 0, ReplayButtonState.None) }));
await hub.EndPlaySession(state);

Expand Down
13 changes: 10 additions & 3 deletions osu.Server.Spectator/Hubs/Spectator/SpectatorHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.Extensions.Caching.Distributed;
using osu.Game.Beatmaps;
using osu.Game.Online.Spectator;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Server.Spectator.Database;
using osu.Server.Spectator.Database.Models;
Expand Down Expand Up @@ -145,10 +146,16 @@ public async Task EndPlaySession(SpectatorState state)
if (status < min_beatmap_status_for_replays || status > max_beatmap_status_for_replays)
return;

score.ScoreInfo.Date = DateTimeOffset.UtcNow;
// if the user never hit anything, further processing that depends on the score existing can be waived because the client won't have submitted the score anyway.
// note that this isn't an early return as we still want to end the play session.
// see: https://github.com/ppy/osu/blob/a47ccb8edd2392258b6b7e176b222a9ecd511fc0/osu.Game/Screens/Play/SubmittingPlayer.cs#L281
if (score.ScoreInfo.Statistics.Any(s => s.Key.IsHit() && s.Value > 0))
{
score.ScoreInfo.Date = DateTimeOffset.UtcNow;

scoreUploader.Enqueue(scoreToken.Value, score);
await scoreProcessedSubscriber.RegisterForNotificationAsync(Context.ConnectionId, Context.GetUserId(), scoreToken.Value);
scoreUploader.Enqueue(scoreToken.Value, score);
await scoreProcessedSubscriber.RegisterForNotificationAsync(Context.ConnectionId, Context.GetUserId(), scoreToken.Value);
}
}
finally
{
Expand Down

0 comments on commit 1c622f6

Please sign in to comment.