From 5ca9a6a98018544d67f61ef1912596084a70999a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:05:48 +0900 Subject: [PATCH 1/7] Add xmldoc on UserLookupCache's lookup method --- osu.Game/Database/UserLookupCache.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Database/UserLookupCache.cs b/osu.Game/Database/UserLookupCache.cs index 05d6930992..8a99e27708 100644 --- a/osu.Game/Database/UserLookupCache.cs +++ b/osu.Game/Database/UserLookupCache.cs @@ -17,6 +17,12 @@ namespace osu.Game.Database [Resolved] private IAPIProvider api { get; set; } + /// + /// Perform an API lookup on the specified user, populating a model. + /// + /// The user to lookup. + /// An optional cancellation token. + /// The populated user, or null if the user does not exist or the request could not be satisfied. public Task GetUserAsync(int userId, CancellationToken token = default) => GetAsync(userId, token); protected override async Task ComputeValueAsync(int lookup, CancellationToken token = default) From 545dcac4ec0950f2ade486c55a88f9f39b1802ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:13:24 +0900 Subject: [PATCH 2/7] Add null hinting on UserLookupCache query method --- osu.Game/Database/UserLookupCache.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Database/UserLookupCache.cs b/osu.Game/Database/UserLookupCache.cs index 8a99e27708..49ea82a4fe 100644 --- a/osu.Game/Database/UserLookupCache.cs +++ b/osu.Game/Database/UserLookupCache.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -23,6 +24,7 @@ namespace osu.Game.Database /// The user to lookup. /// An optional cancellation token. /// The populated user, or null if the user does not exist or the request could not be satisfied. + [ItemCanBeNull] public Task GetUserAsync(int userId, CancellationToken token = default) => GetAsync(userId, token); protected override async Task ComputeValueAsync(int lookup, CancellationToken token = default) From 447a55ce11cf144eddc85dea8e37d99c2dbb46e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:16:53 +0900 Subject: [PATCH 3/7] Fix incorrect null handling in GameplayLeaderboard --- osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs | 6 ++++-- osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index 83b70911c6..cb20deb272 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -56,6 +57,7 @@ namespace osu.Game.Screens.Play.HUD } } + [CanBeNull] public User User { get; } private readonly bool trackedPlayer; @@ -68,7 +70,7 @@ namespace osu.Game.Screens.Play.HUD /// /// The score's player. /// Whether the player is the local user or a replay player. - public GameplayLeaderboardScore(User user, bool trackedPlayer) + public GameplayLeaderboardScore([CanBeNull] User user, bool trackedPlayer) { User = user; this.trackedPlayer = trackedPlayer; @@ -180,7 +182,7 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.CentreLeft, Colour = Color4.White, Font = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold), - Text = User.Username, + Text = User?.Username, Truncate = true, Shadow = false, } diff --git a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs index 00e2b8bfa7..e7e5459f76 100644 --- a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.Play.HUD var trackedUser = new TrackedUserData(); userScores[userId] = trackedUser; - var leaderboardScore = AddPlayer(resolvedUser, resolvedUser.Id == api.LocalUser.Value.Id); + var leaderboardScore = AddPlayer(resolvedUser, resolvedUser?.Id == api.LocalUser.Value.Id); ((IBindable)leaderboardScore.Accuracy).BindTo(trackedUser.Accuracy); ((IBindable)leaderboardScore.TotalScore).BindTo(trackedUser.Score); From 8f0413472cfd57b480d0feedd365a5ce22aae3ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:30:08 +0900 Subject: [PATCH 4/7] Add test coverage of null users in scoreboard --- .../Visual/Online/TestSceneCurrentlyPlayingDisplay.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs index 1666c9cde4..1baa07f208 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs @@ -90,11 +90,17 @@ namespace osu.Game.Tests.Visual.Online }; protected override Task ComputeValueAsync(int lookup, CancellationToken token = default) - => Task.FromResult(new User + { + // tests against failed lookups + if (lookup == 13) + return Task.FromResult(null); + + return Task.FromResult(new User { Id = lookup, Username = usernames[lookup % usernames.Length], }); + } } } } From 6254907ef984032f158bb0a3164862cc13a5d435 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:31:08 +0900 Subject: [PATCH 5/7] Move multiplayer leaderboard test to correct namespace --- .../TestSceneMultiplayerGameplayLeaderboard.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename osu.Game.Tests/Visual/{Gameplay => Multiplayer}/TestSceneMultiplayerGameplayLeaderboard.cs (98%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneMultiplayerGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs similarity index 98% rename from osu.Game.Tests/Visual/Gameplay/TestSceneMultiplayerGameplayLeaderboard.cs rename to osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs index 975c54c3f6..d0b1e77549 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneMultiplayerGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs @@ -20,10 +20,9 @@ using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Play.HUD; -using osu.Game.Tests.Visual.Multiplayer; using osu.Game.Tests.Visual.Online; -namespace osu.Game.Tests.Visual.Gameplay +namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneMultiplayerGameplayLeaderboard : MultiplayerTestScene { From 92d74a9343df3fd7378205fe26ff1753ebf52134 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Dec 2020 20:48:14 +0900 Subject: [PATCH 6/7] Fix potential nullref in test scene --- osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs index c0a021436e..17fe09f2c6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.Gameplay { public bool CheckPositionByUsername(string username, int? expectedPosition) { - var scoreItem = this.FirstOrDefault(i => i.User.Username == username); + var scoreItem = this.FirstOrDefault(i => i.User?.Username == username); return scoreItem != null && scoreItem.ScorePosition == expectedPosition; } From a9822800fc368986a152723b883d9842b920f54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 28 Dec 2020 13:00:05 +0100 Subject: [PATCH 7/7] Add more null hinting in GameplayLeaderboard --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index e33cc05e64..7b94bf19ec 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -42,7 +43,7 @@ namespace osu.Game.Screens.Play.HUD /// Whether the player should be tracked on the leaderboard. /// Set to true for the local player or a player whose replay is currently being played. /// - public ILeaderboardScore AddPlayer(User user, bool isTracked) + public ILeaderboardScore AddPlayer([CanBeNull] User user, bool isTracked) { var drawable = new GameplayLeaderboardScore(user, isTracked) {