diff --git a/osu.Game/Screens/Play/SoloPlayer.cs b/osu.Game/Screens/Play/SoloPlayer.cs
index f7ae3eb62b..f4cf2da364 100644
--- a/osu.Game/Screens/Play/SoloPlayer.cs
+++ b/osu.Game/Screens/Play/SoloPlayer.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play
Scores = { BindTarget = LeaderboardScores }
};
- protected override bool HandleTokenRetrievalFailure(Exception exception) => false;
+ protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override Task ImportScore(Score score)
{
diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs
index c45d46e993..ecb507f382 100644
--- a/osu.Game/Screens/Play/SubmittingPlayer.cs
+++ b/osu.Game/Screens/Play/SubmittingPlayer.cs
@@ -118,7 +118,7 @@ namespace osu.Game.Screens.Play
token = r.ID;
tcs.SetResult(true);
};
- req.Failure += handleTokenFailure;
+ req.Failure += ex => handleTokenFailure(ex, displayNotification: true);
api.Queue(req);
@@ -128,40 +128,49 @@ namespace osu.Game.Screens.Play
return true;
- void handleTokenFailure(Exception exception)
+ void handleTokenFailure(Exception exception, bool displayNotification = false)
{
tcs.SetResult(false);
- if (HandleTokenRetrievalFailure(exception))
+ bool shouldExit = ShouldExitOnTokenRetrievalFailure(exception);
+
+ if (displayNotification || shouldExit)
{
+ string whatWillHappen = shouldExit
+ ? "Play in this state is not permitted."
+ : "Your score will not be submitted.";
+
if (string.IsNullOrEmpty(exception.Message))
- Logger.Error(exception, "Failed to retrieve a score submission token.");
+ Logger.Error(exception, $"Failed to retrieve a score submission token.\n\n{whatWillHappen}");
else
{
switch (exception.Message)
{
- case "expired token":
- Logger.Log("Score submission failed because your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important);
+ case @"missing token header":
+ case @"invalid client hash":
+ case @"invalid verification hash":
+ Logger.Log($"Please ensure that you are using the latest version of the official game releases.\n\n{whatWillHappen}", level: LogLevel.Important);
+ break;
+
+ case @"expired token":
+ Logger.Log($"Your system clock is set incorrectly. Please check your system time, date and timezone.\n\n{whatWillHappen}", level: LogLevel.Important);
break;
default:
- Logger.Log($"You are not able to submit a score: {exception.Message}", level: LogLevel.Important);
+ Logger.Log($"{whatWillHappen} {exception.Message}", level: LogLevel.Important);
break;
}
}
+ }
+ if (shouldExit)
+ {
Schedule(() =>
{
ValidForResume = false;
this.Exit();
});
}
- else
- {
- // Gameplay is allowed to continue, but we still should keep track of the error.
- // In the future, this should be visible to the user in some way.
- Logger.Log($"Score submission token retrieval failed ({exception.Message})");
- }
}
}
@@ -170,7 +179,7 @@ namespace osu.Game.Screens.Play
///
/// The error causing the failure.
/// Whether gameplay should be immediately exited as a result. Returning false allows the gameplay session to continue. Defaults to true.
- protected virtual bool HandleTokenRetrievalFailure(Exception exception) => true;
+ protected virtual bool ShouldExitOnTokenRetrievalFailure(Exception exception) => true;
protected override async Task PrepareScoreForResultsAsync(Score score)
{
@@ -231,7 +240,7 @@ namespace osu.Game.Screens.Play
///
/// Construct a request to be used for retrieval of the score token.
- /// Can return null, at which point will be fired.
+ /// Can return null, at which point will be fired.
///
[CanBeNull]
protected abstract APIRequest CreateTokenRequest();
diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs
index d9cae6b03b..579a1934e0 100644
--- a/osu.Game/Tests/Visual/TestPlayer.cs
+++ b/osu.Game/Tests/Visual/TestPlayer.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual
PauseOnFocusLost = pauseOnFocusLost;
}
- protected override bool HandleTokenRetrievalFailure(Exception exception) => false;
+ protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override APIRequest CreateTokenRequest()
{