diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs
index 3642f70a56..d87b25a4c7 100644
--- a/osu.Desktop/DiscordRichPresence.cs
+++ b/osu.Desktop/DiscordRichPresence.cs
@@ -10,6 +10,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Configuration;
+using osu.Game.Extensions;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
@@ -108,10 +109,7 @@ namespace osu.Desktop
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
// update ruleset
- int onlineID = ruleset.Value.OnlineID;
- bool isLegacyRuleset = onlineID >= 0 && onlineID <= ILegacyRuleset.MAX_LEGACY_RULESET_ID;
-
- presence.Assets.SmallImageKey = isLegacyRuleset ? $"mode_{onlineID}" : "mode_custom";
+ presence.Assets.SmallImageKey = ruleset.Value.IsLegacyRuleset() ? $"mode_{ruleset.Value.OnlineID}" : "mode_custom";
presence.Assets.SmallImageText = ruleset.Value.Name;
client.SetPresence(presence);
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 31bd3a203c..1ed6648131 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -119,7 +119,8 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Network failure", () => leaderboard.SetErrorState(LeaderboardState.NetworkFailure));
AddStep(@"No supporter", () => leaderboard.SetErrorState(LeaderboardState.NotSupporter));
AddStep(@"Not logged in", () => leaderboard.SetErrorState(LeaderboardState.NotLoggedIn));
- AddStep(@"Unavailable", () => leaderboard.SetErrorState(LeaderboardState.Unavailable));
+ AddStep(@"Ruleset unavailable", () => leaderboard.SetErrorState(LeaderboardState.RulesetUnavailable));
+ AddStep(@"Beatmap unavailable", () => leaderboard.SetErrorState(LeaderboardState.BeatmapUnavailable));
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardState.NoneSelected));
}
diff --git a/osu.Game/Beatmaps/DifficultyRecommender.cs b/osu.Game/Beatmaps/DifficultyRecommender.cs
index 3949e84f4a..93c2fccbc7 100644
--- a/osu.Game/Beatmaps/DifficultyRecommender.cs
+++ b/osu.Game/Beatmaps/DifficultyRecommender.cs
@@ -9,6 +9,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
+using osu.Game.Extensions;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
@@ -83,7 +84,7 @@ namespace osu.Game.Beatmaps
requestedUserId = api.LocalUser.Value.Id;
// only query API for built-in rulesets
- rulesets.AvailableRulesets.Where(ruleset => ruleset.OnlineID >= 0 && ruleset.OnlineID <= ILegacyRuleset.MAX_LEGACY_RULESET_ID).ForEach(rulesetInfo =>
+ rulesets.AvailableRulesets.Where(ruleset => ruleset.IsLegacyRuleset()).ForEach(rulesetInfo =>
{
var req = new GetUserRequest(api.LocalUser.Value.Id, rulesetInfo);
diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs
index f178a5c97b..13c25e45c8 100644
--- a/osu.Game/Extensions/ModelExtensions.cs
+++ b/osu.Game/Extensions/ModelExtensions.cs
@@ -72,6 +72,11 @@ namespace osu.Game.Extensions
return result;
}
+ ///
+ /// Check whether this 's online ID is within the range that defines it as a legacy ruleset (ie. either osu!, osu!taiko, osu!catch or osu!mania).
+ ///
+ public static bool IsLegacyRuleset(this IRulesetInfo ruleset) => ruleset.OnlineID >= 0 && ruleset.OnlineID <= ILegacyRuleset.MAX_LEGACY_RULESET_ID;
+
///
/// Check whether the online ID of two s match.
///
diff --git a/osu.Game/Localisation/LeaderboardStrings.cs b/osu.Game/Localisation/LeaderboardStrings.cs
new file mode 100644
index 0000000000..8e53f8e88c
--- /dev/null
+++ b/osu.Game/Localisation/LeaderboardStrings.cs
@@ -0,0 +1,49 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Localisation;
+
+namespace osu.Game.Localisation
+{
+ public static class LeaderboardStrings
+ {
+ private const string prefix = @"osu.Game.Resources.Localisation.Leaderboard";
+
+ ///
+ /// "Couldn't fetch scores!"
+ ///
+ public static LocalisableString CouldntFetchScores => new TranslatableString(getKey(@"couldnt_fetch_scores"), @"Couldn't fetch scores!");
+
+ ///
+ /// "Please select a beatmap!"
+ ///
+ public static LocalisableString PleaseSelectABeatmap => new TranslatableString(getKey(@"please_select_a_beatmap"), @"Please select a beatmap!");
+
+ ///
+ /// "Leaderboards are not available for this ruleset!"
+ ///
+ public static LocalisableString LeaderboardsAreNotAvailableForThisRuleset => new TranslatableString(getKey(@"leaderboards_are_not_available_for_this_ruleset"), @"Leaderboards are not available for this ruleset!");
+
+ ///
+ /// "Leaderboards are not available for this beatmap!"
+ ///
+ public static LocalisableString LeaderboardsAreNotAvailableForThisBeatmap => new TranslatableString(getKey(@"leaderboards_are_not_available_for_this_beatmap"), @"Leaderboards are not available for this beatmap!");
+
+ ///
+ /// "No records yet!"
+ ///
+ public static LocalisableString NoRecordsYet => new TranslatableString(getKey(@"no_records_yet"), @"No records yet!");
+
+ ///
+ /// "Please sign in to view online leaderboards!"
+ ///
+ public static LocalisableString PleaseSignInToViewOnlineLeaderboards => new TranslatableString(getKey(@"please_sign_in_to_view_online_leaderboards"), @"Please sign in to view online leaderboards!");
+
+ ///
+ /// "Please invest in an osu!supporter tag to view this leaderboard!"
+ ///
+ public static LocalisableString PleaseInvestInAnOsuSupporterTagToViewThisLeaderboard => new TranslatableString(getKey(@"please_invest_in_an_osu_supporter_tag_to_view_this_leaderboard"), @"Please invest in an osu!supporter tag to view this leaderboard!");
+
+ private static string getKey(string key) => $@"{prefix}:{key}";
+ }
+}
diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs
index 5dd3e46b4a..c94a6d3361 100644
--- a/osu.Game/Online/Leaderboards/Leaderboard.cs
+++ b/osu.Game/Online/Leaderboards/Leaderboard.cs
@@ -22,6 +22,7 @@ using osu.Game.Online.API;
using osu.Game.Online.Placeholders;
using osuTK;
using osuTK.Graphics;
+using osu.Game.Localisation;
namespace osu.Game.Online.Leaderboards
{
@@ -311,25 +312,28 @@ namespace osu.Game.Online.Leaderboards
switch (state)
{
case LeaderboardState.NetworkFailure:
- return new ClickablePlaceholder(@"Couldn't fetch scores!", FontAwesome.Solid.Sync)
+ return new ClickablePlaceholder(LeaderboardStrings.CouldntFetchScores, FontAwesome.Solid.Sync)
{
Action = RefetchScores
};
case LeaderboardState.NoneSelected:
- return new MessagePlaceholder(@"Please select a beatmap!");
+ return new MessagePlaceholder(LeaderboardStrings.PleaseSelectABeatmap);
- case LeaderboardState.Unavailable:
- return new MessagePlaceholder(@"Leaderboards are not available for this beatmap!");
+ case LeaderboardState.RulesetUnavailable:
+ return new MessagePlaceholder(LeaderboardStrings.LeaderboardsAreNotAvailableForThisRuleset);
+
+ case LeaderboardState.BeatmapUnavailable:
+ return new MessagePlaceholder(LeaderboardStrings.LeaderboardsAreNotAvailableForThisBeatmap);
case LeaderboardState.NoScores:
- return new MessagePlaceholder(@"No records yet!");
+ return new MessagePlaceholder(LeaderboardStrings.NoRecordsYet);
case LeaderboardState.NotLoggedIn:
- return new LoginPlaceholder(@"Please sign in to view online leaderboards!");
+ return new LoginPlaceholder(LeaderboardStrings.PleaseSignInToViewOnlineLeaderboards);
case LeaderboardState.NotSupporter:
- return new MessagePlaceholder(@"Please invest in an osu!supporter tag to view this leaderboard!");
+ return new MessagePlaceholder(LeaderboardStrings.PleaseInvestInAnOsuSupporterTagToViewThisLeaderboard);
case LeaderboardState.Retrieving:
return null;
diff --git a/osu.Game/Online/Leaderboards/LeaderboardState.cs b/osu.Game/Online/Leaderboards/LeaderboardState.cs
index 75e2c6e6db..6b07500a98 100644
--- a/osu.Game/Online/Leaderboards/LeaderboardState.cs
+++ b/osu.Game/Online/Leaderboards/LeaderboardState.cs
@@ -8,7 +8,8 @@ namespace osu.Game.Online.Leaderboards
Success,
Retrieving,
NetworkFailure,
- Unavailable,
+ BeatmapUnavailable,
+ RulesetUnavailable,
NoneSelected,
NoScores,
NotLoggedIn,
diff --git a/osu.Game/Online/Placeholders/LoginPlaceholder.cs b/osu.Game/Online/Placeholders/LoginPlaceholder.cs
index f8a326a52e..d03b3d8ffc 100644
--- a/osu.Game/Online/Placeholders/LoginPlaceholder.cs
+++ b/osu.Game/Online/Placeholders/LoginPlaceholder.cs
@@ -3,6 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
+using osu.Framework.Localisation;
using osu.Game.Overlays;
namespace osu.Game.Online.Placeholders
@@ -12,7 +13,7 @@ namespace osu.Game.Online.Placeholders
[Resolved(CanBeNull = true)]
private LoginOverlay login { get; set; }
- public LoginPlaceholder(string actionMessage)
+ public LoginPlaceholder(LocalisableString actionMessage)
: base(actionMessage, FontAwesome.Solid.UserLock)
{
Action = () => login?.Show();
diff --git a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs
index 1326395695..f0ead05280 100644
--- a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs
+++ b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs
@@ -7,9 +7,9 @@ using System.Linq;
using System.Text;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
+using osu.Game.Extensions;
using osu.Game.IO.Legacy;
using osu.Game.Replays.Legacy;
-using osu.Game.Rulesets;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
using SharpCompress.Compressors.LZMA;
@@ -48,7 +48,7 @@ namespace osu.Game.Scoring.Legacy
if (beatmap == null && !score.Replay.Frames.All(f => f is LegacyReplayFrame))
throw new ArgumentException(@"Beatmap must be provided if frames are not already legacy frames.", nameof(beatmap));
- if (score.ScoreInfo.Ruleset.OnlineID < 0 || score.ScoreInfo.Ruleset.OnlineID > ILegacyRuleset.MAX_LEGACY_RULESET_ID)
+ if (!score.ScoreInfo.Ruleset.IsLegacyRuleset())
throw new ArgumentException(@"Only scores in the osu, taiko, catch, or mania rulesets can be encoded to the legacy score format.", nameof(score));
}
diff --git a/osu.Game/Screens/Play/SoloPlayer.cs b/osu.Game/Screens/Play/SoloPlayer.cs
index 824c0072e3..a935ce49eb 100644
--- a/osu.Game/Screens/Play/SoloPlayer.cs
+++ b/osu.Game/Screens/Play/SoloPlayer.cs
@@ -4,10 +4,10 @@
using System;
using System.Diagnostics;
using osu.Game.Beatmaps;
+using osu.Game.Extensions;
using osu.Game.Online.API;
using osu.Game.Online.Rooms;
using osu.Game.Online.Solo;
-using osu.Game.Rulesets;
using osu.Game.Scoring;
namespace osu.Game.Screens.Play
@@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play
if (beatmapId <= 0)
return null;
- if (rulesetId < 0 || rulesetId > ILegacyRuleset.MAX_LEGACY_RULESET_ID)
+ if (!Ruleset.Value.IsLegacyRuleset())
return null;
return new CreateSoloScoreRequest(beatmapId, rulesetId, Game.VersionHash);
diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
index 907a2c9bda..eb0addd377 100644
--- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
@@ -11,6 +11,7 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Database;
+using osu.Game.Extensions;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.Leaderboards;
@@ -98,6 +99,7 @@ namespace osu.Game.Screens.Select.Leaderboards
protected override APIRequest FetchScores(CancellationToken cancellationToken)
{
var fetchBeatmapInfo = BeatmapInfo;
+ var fetchRuleset = ruleset.Value ?? fetchBeatmapInfo.Ruleset;
if (fetchBeatmapInfo == null)
{
@@ -117,9 +119,15 @@ namespace osu.Game.Screens.Select.Leaderboards
return null;
}
+ if (!fetchRuleset.IsLegacyRuleset())
+ {
+ SetErrorState(LeaderboardState.RulesetUnavailable);
+ return null;
+ }
+
if (fetchBeatmapInfo.OnlineID <= 0 || fetchBeatmapInfo.Status <= BeatmapOnlineStatus.Pending)
{
- SetErrorState(LeaderboardState.Unavailable);
+ SetErrorState(LeaderboardState.BeatmapUnavailable);
return null;
}
@@ -137,7 +145,7 @@ namespace osu.Game.Screens.Select.Leaderboards
else if (filterMods)
requestMods = mods.Value;
- var req = new GetScoresRequest(fetchBeatmapInfo, ruleset.Value ?? fetchBeatmapInfo.Ruleset, Scope, requestMods);
+ var req = new GetScoresRequest(fetchBeatmapInfo, fetchRuleset, Scope, requestMods);
req.Success += r =>
{