1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 14:02:55 +08:00

Merge pull request #26138 from peppy/fix-audio-rate-playback-not-fail

Bail from score submission if audio playback rate is too far from reality
This commit is contained in:
Bartłomiej Dach 2023-12-26 19:13:46 +01:00 committed by GitHub
commit 668ce937a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 0 deletions

View File

@ -8,6 +8,7 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
@ -39,6 +40,14 @@ namespace osu.Game.Screens.Play
Precision = 0.1, Precision = 0.1,
}; };
/// <summary>
/// Whether the audio playback is within acceptable ranges.
/// Will become false if audio playback is not going as expected.
/// </summary>
public IBindable<bool> PlaybackRateValid => playbackRateValid;
private readonly Bindable<bool> playbackRateValid = new Bindable<bool>(true);
private readonly WorkingBeatmap beatmap; private readonly WorkingBeatmap beatmap;
private Track track; private Track track;
@ -128,6 +137,7 @@ namespace osu.Game.Screens.Play
{ {
// Safety in case the clock is seeked while stopped. // Safety in case the clock is seeked while stopped.
LastStopTime = null; LastStopTime = null;
elapsedValidationTime = null;
base.Seek(time); base.Seek(time);
} }
@ -197,6 +207,53 @@ namespace osu.Game.Screens.Play
addAdjustmentsToTrack(); addAdjustmentsToTrack();
} }
protected override void Update()
{
base.Update();
checkPlaybackValidity();
}
#region Clock validation (ensure things are running correctly for local gameplay)
private double elapsedGameplayClockTime;
private double? elapsedValidationTime;
private int playbackDiscrepancyCount;
private const int allowed_playback_discrepancies = 5;
private void checkPlaybackValidity()
{
if (GameplayClock.IsRunning)
{
elapsedGameplayClockTime += GameplayClock.ElapsedFrameTime;
if (elapsedValidationTime == null)
elapsedValidationTime = elapsedGameplayClockTime;
else
elapsedValidationTime += GameplayClock.Rate * Time.Elapsed;
if (Math.Abs(elapsedGameplayClockTime - elapsedValidationTime!.Value) > 300)
{
if (playbackDiscrepancyCount++ > allowed_playback_discrepancies)
{
if (playbackRateValid.Value)
{
playbackRateValid.Value = false;
Logger.Log("System audio playback is not working as expected. Some online functionality will not work.\n\nPlease check your audio drivers.", level: LogLevel.Important);
}
}
else
{
Logger.Log($"Playback discrepancy detected ({playbackDiscrepancyCount} of allowed {allowed_playback_discrepancies}): {elapsedGameplayClockTime:N1} vs {elapsedValidationTime:N1}");
}
elapsedValidationTime = null;
}
}
}
#endregion
private bool speedAdjustmentsApplied; private bool speedAdjustmentsApplied;
private void addAdjustmentsToTrack() private void addAdjustmentsToTrack()

View File

@ -208,6 +208,14 @@ namespace osu.Game.Screens.Play
private Task submitScore(Score score) private Task submitScore(Score score)
{ {
var masterClock = GameplayClockContainer as MasterGameplayClockContainer;
if (masterClock?.PlaybackRateValid.Value != true)
{
Logger.Log("Score submission cancelled due to audio playback rate discrepancy.");
return Task.CompletedTask;
}
// token may be null if the request failed but gameplay was still allowed (see HandleTokenRetrievalFailure). // token may be null if the request failed but gameplay was still allowed (see HandleTokenRetrievalFailure).
if (token == null) if (token == null)
{ {