1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 19:22:56 +08:00

Merge branch 'master' into beatmap-card/extra

This commit is contained in:
Bartłomiej Dach 2021-12-20 15:49:00 +01:00
commit f1a03aced5
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
23 changed files with 179 additions and 150 deletions

View File

@ -48,7 +48,7 @@ You can see some examples of custom rulesets by visiting the [custom ruleset dir
Please make sure you have the following prerequisites: Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 5.0 SDK](https://dotnet.microsoft.com/download) or higher installed. - A desktop platform with the [.NET 5.0 SDK](https://dotnet.microsoft.com/download) installed.
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). - When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). - When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding. - When running on Linux, please have a system-wide FFmpeg installation available to support video decoding.

View File

@ -52,7 +52,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1217.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2021.1220.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. --> <!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->

View File

@ -85,6 +85,7 @@ namespace osu.Game.Tests.Visual.Background
// of note, this needs to be a type that doesn't match BackgroundScreenDefault else it is silently not pushed by the background stack. // of note, this needs to be a type that doesn't match BackgroundScreenDefault else it is silently not pushed by the background stack.
AddStep("push new background to stack", () => stack.Push(nestedScreen = new BackgroundScreenBeatmap(Beatmap.Value))); AddStep("push new background to stack", () => stack.Push(nestedScreen = new BackgroundScreenBeatmap(Beatmap.Value)));
AddUntilStep("wait for screen to load", () => nestedScreen.IsLoaded && nestedScreen.IsCurrentScreen()); AddUntilStep("wait for screen to load", () => nestedScreen.IsLoaded && nestedScreen.IsCurrentScreen());
AddUntilStep("previous background hidden", () => !screen.IsAlive);
AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null); AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null);

View File

@ -31,17 +31,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
protected BeatmapInfo InitialBeatmap { get; private set; } protected BeatmapInfo InitialBeatmap { get; private set; }
protected BeatmapInfo OtherBeatmap { get; private set; } protected BeatmapInfo OtherBeatmap { get; private set; }
protected IScreen CurrentScreen => multiplayerScreenStack.CurrentScreen; protected IScreen CurrentScreen => multiplayerComponents.CurrentScreen;
protected IScreen CurrentSubScreen => multiplayerScreenStack.MultiplayerScreen.CurrentSubScreen; protected IScreen CurrentSubScreen => multiplayerComponents.MultiplayerScreen.CurrentSubScreen;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets; private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private TestMultiplayerScreenStack multiplayerScreenStack; private TestMultiplayerComponents multiplayerComponents;
protected TestMultiplayerClient Client => multiplayerScreenStack.Client; protected TestMultiplayerClient Client => multiplayerComponents.Client;
protected TestMultiplayerRoomManager RoomManager => multiplayerScreenStack.RoomManager;
[Cached(typeof(UserLookupCache))] [Cached(typeof(UserLookupCache))]
private UserLookupCache lookupCache = new TestUserLookupCache(); private UserLookupCache lookupCache = new TestUserLookupCache();
@ -65,12 +64,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0); OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0);
}); });
AddStep("load multiplayer", () => LoadScreen(multiplayerScreenStack = new TestMultiplayerScreenStack())); AddStep("load multiplayer", () => LoadScreen(multiplayerComponents = new TestMultiplayerComponents()));
AddUntilStep("wait for multiplayer to load", () => multiplayerScreenStack.IsLoaded); AddUntilStep("wait for multiplayer to load", () => multiplayerComponents.IsLoaded);
AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for lounge", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true);
AddStep("open room", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().Single().Open(new Room AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open(new Room
{ {
Name = { Value = "Test Room" }, Name = { Value = "Test Room" },
QueueMode = { Value = Mode }, QueueMode = { Value = Mode },
@ -93,7 +92,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddUntilStep("wait for join", () => RoomManager.RoomJoined); AddUntilStep("wait for join", () => Client.RoomJoined);
} }
[Test] [Test]
@ -110,8 +109,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready); AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
clickReadyButton(); clickReadyButton();
AddUntilStep("wait for player", () => multiplayerScreenStack.CurrentScreen is Player player && player.IsLoaded); AddUntilStep("wait for player", () => multiplayerComponents.CurrentScreen is Player player && player.IsLoaded);
AddStep("exit player", () => multiplayerScreenStack.MultiplayerScreen.MakeCurrent()); AddStep("exit player", () => multiplayerComponents.MultiplayerScreen.MakeCurrent());
} }
private void clickReadyButton() private void clickReadyButton()

View File

@ -46,10 +46,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
private RulesetStore rulesets; private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private TestMultiplayerScreenStack multiplayerScreenStack; private TestMultiplayerComponents multiplayerComponents;
private TestMultiplayerClient client => multiplayerScreenStack.Client; private TestMultiplayerClient client => multiplayerComponents.Client;
private TestMultiplayerRoomManager roomManager => multiplayerScreenStack.RoomManager; private TestMultiplayerRoomManager roomManager => multiplayerComponents.RoomManager;
[Cached(typeof(UserLookupCache))] [Cached(typeof(UserLookupCache))]
private UserLookupCache lookupCache = new TestUserLookupCache(); private UserLookupCache lookupCache = new TestUserLookupCache();
@ -71,8 +71,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });
AddStep("load multiplayer", () => LoadScreen(multiplayerScreenStack = new TestMultiplayerScreenStack())); AddStep("load multiplayer", () => LoadScreen(multiplayerComponents = new TestMultiplayerComponents()));
AddUntilStep("wait for multiplayer to load", () => multiplayerScreenStack.IsLoaded); AddUntilStep("wait for multiplayer to load", () => multiplayerComponents.IsLoaded);
AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true);
} }
@ -216,7 +216,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("Press select", () => InputManager.Key(Key.Enter)); AddStep("Press select", () => InputManager.Key(Key.Enter));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for join", () => roomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
} }
[Test] [Test]
@ -295,7 +295,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join room", () => InputManager.Key(Key.Enter)); AddStep("join room", () => InputManager.Key(Key.Enter));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for join", () => roomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
AddAssert("Check participant count correct", () => client.APIRoom?.ParticipantCount.Value == 1); AddAssert("Check participant count correct", () => client.APIRoom?.ParticipantCount.Value == 1);
AddAssert("Check participant list contains user", () => client.APIRoom?.RecentParticipants.Count(u => u.Id == API.LocalUser.Value.Id) == 1); AddAssert("Check participant list contains user", () => client.APIRoom?.RecentParticipants.Count(u => u.Id == API.LocalUser.Value.Id) == 1);
@ -353,7 +353,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick()); AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for join", () => roomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
} }
[Test] [Test]
@ -419,7 +419,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("Enter song select", () => AddStep("Enter song select", () =>
{ {
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen; var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId); ((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
}); });
@ -433,7 +433,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("start match externally", () => client.StartMatch()); AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerScreenStack.CurrentScreen is Player); AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID); AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
} }
@ -473,7 +473,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("start match externally", () => client.StartMatch()); AddStep("start match externally", () => client.StartMatch());
AddAssert("play not started", () => multiplayerScreenStack.IsCurrentScreen()); AddAssert("play not started", () => multiplayerComponents.IsCurrentScreen());
} }
[Test] [Test]
@ -517,7 +517,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });
AddUntilStep("play started", () => multiplayerScreenStack.CurrentScreen is SpectatorScreen); AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is SpectatorScreen);
} }
[Test] [Test]
@ -559,16 +559,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("open mod overlay", () => this.ChildrenOfType<RoomSubScreen.UserModSelectButton>().Single().TriggerClick()); AddStep("open mod overlay", () => this.ChildrenOfType<RoomSubScreen.UserModSelectButton>().Single().TriggerClick());
AddStep("invoke on back button", () => multiplayerScreenStack.OnBackButton()); AddStep("invoke on back button", () => multiplayerComponents.OnBackButton());
AddAssert("mod overlay is hidden", () => this.ChildrenOfType<UserModSelectOverlay>().Single().State.Value == Visibility.Hidden); AddAssert("mod overlay is hidden", () => this.ChildrenOfType<UserModSelectOverlay>().Single().State.Value == Visibility.Hidden);
AddAssert("dialog overlay is hidden", () => DialogOverlay.State.Value == Visibility.Hidden); AddAssert("dialog overlay is hidden", () => DialogOverlay.State.Value == Visibility.Hidden);
testLeave("back button", () => multiplayerScreenStack.OnBackButton()); testLeave("back button", () => multiplayerComponents.OnBackButton());
// mimics home button and OS window close // mimics home button and OS window close
testLeave("forced exit", () => multiplayerScreenStack.Exit()); testLeave("forced exit", () => multiplayerComponents.Exit());
void testLeave(string actionName, Action action) void testLeave(string actionName, Action action)
{ {
@ -605,7 +605,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep($"wait for time > {i}", () => this.ChildrenOfType<GameplayClockContainer>().SingleOrDefault()?.GameplayClock.CurrentTime > time); AddUntilStep($"wait for time > {i}", () => this.ChildrenOfType<GameplayClockContainer>().SingleOrDefault()?.GameplayClock.CurrentTime > time);
} }
AddUntilStep("wait for results", () => multiplayerScreenStack.CurrentScreen is ResultsScreen); AddUntilStep("wait for results", () => multiplayerComponents.CurrentScreen is ResultsScreen);
} }
[Test] [Test]
@ -646,7 +646,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join room", () => InputManager.Key(Key.Enter)); AddStep("join room", () => InputManager.Key(Key.Enter));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for join", () => roomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
AddAssert("local room has correct settings", () => AddAssert("local room has correct settings", () =>
{ {
@ -680,15 +680,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("set other user ready", () => client.ChangeUserState(1234, MultiplayerUserState.Ready)); AddStep("set other user ready", () => client.ChangeUserState(1234, MultiplayerUserState.Ready));
pressReadyButton(1234); pressReadyButton(1234);
AddUntilStep("wait for gameplay", () => (multiplayerScreenStack.CurrentScreen as MultiSpectatorScreen)?.IsLoaded == true); AddUntilStep("wait for gameplay", () => (multiplayerComponents.CurrentScreen as MultiSpectatorScreen)?.IsLoaded == true);
AddStep("press back button and exit", () => AddStep("press back button and exit", () =>
{ {
multiplayerScreenStack.OnBackButton(); multiplayerComponents.OnBackButton();
multiplayerScreenStack.Exit(); multiplayerComponents.Exit();
}); });
AddUntilStep("wait for return to match subscreen", () => multiplayerScreenStack.MultiplayerScreen.IsCurrentScreen()); AddUntilStep("wait for return to match subscreen", () => multiplayerComponents.MultiplayerScreen.IsCurrentScreen());
AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle); AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle);
} }
@ -716,17 +716,17 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("set other user ready", () => client.ChangeUserState(1234, MultiplayerUserState.Ready)); AddStep("set other user ready", () => client.ChangeUserState(1234, MultiplayerUserState.Ready));
pressReadyButton(1234); pressReadyButton(1234);
AddUntilStep("wait for gameplay", () => (multiplayerScreenStack.CurrentScreen as MultiSpectatorScreen)?.IsLoaded == true); AddUntilStep("wait for gameplay", () => (multiplayerComponents.CurrentScreen as MultiSpectatorScreen)?.IsLoaded == true);
AddStep("set other user loaded", () => client.ChangeUserState(1234, MultiplayerUserState.Loaded)); AddStep("set other user loaded", () => client.ChangeUserState(1234, MultiplayerUserState.Loaded));
AddStep("set other user finished play", () => client.ChangeUserState(1234, MultiplayerUserState.FinishedPlay)); AddStep("set other user finished play", () => client.ChangeUserState(1234, MultiplayerUserState.FinishedPlay));
AddStep("press back button and exit", () => AddStep("press back button and exit", () =>
{ {
multiplayerScreenStack.OnBackButton(); multiplayerComponents.OnBackButton();
multiplayerScreenStack.Exit(); multiplayerComponents.Exit();
}); });
AddUntilStep("wait for return to match subscreen", () => multiplayerScreenStack.MultiplayerScreen.IsCurrentScreen()); AddUntilStep("wait for return to match subscreen", () => multiplayerComponents.MultiplayerScreen.IsCurrentScreen());
AddWaitStep("wait for possible state change", 5); AddWaitStep("wait for possible state change", 5);
AddUntilStep("user state is spectating", () => client.LocalUser?.State == MultiplayerUserState.Spectating); AddUntilStep("user state is spectating", () => client.LocalUser?.State == MultiplayerUserState.Spectating);
} }
@ -758,7 +758,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("item arrived in playlist", () => client.Room?.Playlist.Count == 2); AddUntilStep("item arrived in playlist", () => client.Room?.Playlist.Count == 2);
AddStep("exit gameplay as initial user", () => multiplayerScreenStack.MultiplayerScreen.MakeCurrent()); AddStep("exit gameplay as initial user", () => multiplayerComponents.MultiplayerScreen.MakeCurrent());
AddUntilStep("queue contains item", () => this.ChildrenOfType<MultiplayerQueueList>().Single().Items.Single().ID == 2); AddUntilStep("queue contains item", () => this.ChildrenOfType<MultiplayerQueueList>().Single().Items.Single().ID == 2);
} }
@ -792,7 +792,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("delete item as other user", () => client.RemoveUserPlaylistItem(1234, 2)); AddStep("delete item as other user", () => client.RemoveUserPlaylistItem(1234, 2));
AddUntilStep("item removed from playlist", () => client.Room?.Playlist.Count == 1); AddUntilStep("item removed from playlist", () => client.Room?.Playlist.Count == 1);
AddStep("exit gameplay as initial user", () => multiplayerScreenStack.MultiplayerScreen.MakeCurrent()); AddStep("exit gameplay as initial user", () => multiplayerComponents.MultiplayerScreen.MakeCurrent());
AddUntilStep("queue is empty", () => this.ChildrenOfType<MultiplayerQueueList>().Single().Items.Count == 0); AddUntilStep("queue is empty", () => this.ChildrenOfType<MultiplayerQueueList>().Single().Items.Count == 0);
} }
@ -800,7 +800,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
pressReadyButton(); pressReadyButton();
pressReadyButton(); pressReadyButton();
AddUntilStep("wait for player", () => multiplayerScreenStack.CurrentScreen is Player); AddUntilStep("wait for player", () => multiplayerComponents.CurrentScreen is Player);
} }
private ReadyButton readyButton => this.ChildrenOfType<ReadyButton>().Single(); private ReadyButton readyButton => this.ChildrenOfType<ReadyButton>().Single();
@ -826,8 +826,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void createRoom(Func<Room> room) private void createRoom(Func<Room> room)
{ {
AddUntilStep("wait for lounge", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true);
AddStep("open room", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().Single().Open(room())); AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open(room()));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddWaitStep("wait for transition", 2); AddWaitStep("wait for transition", 2);
@ -838,7 +838,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddUntilStep("wait for join", () => roomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
} }
} }
} }

View File

@ -163,10 +163,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
}); });
addClickButtonStep(); addClickButtonStep();
AddUntilStep("user is ready", () => Client.Room?.Users[0].State == MultiplayerUserState.Ready);
AddStep("transfer host", () => Client.TransferHost(Client.Room?.Users[1].UserID ?? 0)); AddStep("transfer host", () => Client.TransferHost(Client.Room?.Users[1].UserID ?? 0));
addClickButtonStep(); addClickButtonStep();
AddAssert("match not started", () => Client.Room?.Users[0].State == MultiplayerUserState.Idle); AddUntilStep("user is idle (match not started)", () => Client.Room?.Users[0].State == MultiplayerUserState.Idle);
AddAssert("ready button enabled", () => button.ChildrenOfType<OsuButton>().Single().Enabled.Value);
} }
[TestCase(true)] [TestCase(true)]

View File

@ -31,9 +31,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
private RulesetStore rulesets; private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private TestMultiplayerScreenStack multiplayerScreenStack; private TestMultiplayerComponents multiplayerComponents;
private TestMultiplayerClient client => multiplayerScreenStack.Client; private TestMultiplayerClient client => multiplayerComponents.Client;
[Cached(typeof(UserLookupCache))] [Cached(typeof(UserLookupCache))]
private UserLookupCache lookupCache = new TestUserLookupCache(); private UserLookupCache lookupCache = new TestUserLookupCache();
@ -55,8 +55,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });
AddStep("load multiplayer", () => LoadScreen(multiplayerScreenStack = new TestMultiplayerScreenStack())); AddStep("load multiplayer", () => LoadScreen(multiplayerComponents = new TestMultiplayerComponents()));
AddUntilStep("wait for multiplayer to load", () => multiplayerScreenStack.IsLoaded); AddUntilStep("wait for multiplayer to load", () => multiplayerComponents.IsLoaded);
AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true);
} }
@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("press own button", () => AddStep("press own button", () =>
{ {
InputManager.MoveMouseTo(multiplayerScreenStack.ChildrenOfType<TeamDisplay>().First()); InputManager.MoveMouseTo(multiplayerComponents.ChildrenOfType<TeamDisplay>().First());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("user on team 1", () => (client.Room?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 1); AddAssert("user on team 1", () => (client.Room?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 1);
@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("press other user's button", () => AddStep("press other user's button", () =>
{ {
InputManager.MoveMouseTo(multiplayerScreenStack.ChildrenOfType<TeamDisplay>().ElementAt(1)); InputManager.MoveMouseTo(multiplayerComponents.ChildrenOfType<TeamDisplay>().ElementAt(1));
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("user still on team 0", () => (client.Room?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 0); AddAssert("user still on team 0", () => (client.Room?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 0);
@ -164,18 +164,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("room type is head to head", () => client.Room?.Settings.MatchType == MatchType.HeadToHead); AddUntilStep("room type is head to head", () => client.Room?.Settings.MatchType == MatchType.HeadToHead);
AddUntilStep("team displays are not displaying teams", () => multiplayerScreenStack.ChildrenOfType<TeamDisplay>().All(d => d.DisplayedTeam == null)); AddUntilStep("team displays are not displaying teams", () => multiplayerComponents.ChildrenOfType<TeamDisplay>().All(d => d.DisplayedTeam == null));
AddStep("change to team vs", () => client.ChangeSettings(matchType: MatchType.TeamVersus)); AddStep("change to team vs", () => client.ChangeSettings(matchType: MatchType.TeamVersus));
AddUntilStep("room type is team vs", () => client.Room?.Settings.MatchType == MatchType.TeamVersus); AddUntilStep("room type is team vs", () => client.Room?.Settings.MatchType == MatchType.TeamVersus);
AddUntilStep("team displays are displaying teams", () => multiplayerScreenStack.ChildrenOfType<TeamDisplay>().All(d => d.DisplayedTeam != null)); AddUntilStep("team displays are displaying teams", () => multiplayerComponents.ChildrenOfType<TeamDisplay>().All(d => d.DisplayedTeam != null));
} }
private void createRoom(Func<Room> room) private void createRoom(Func<Room> room)
{ {
AddStep("open room", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().Single().Open(room())); AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open(room()));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true); AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddWaitStep("wait for transition", 2); AddWaitStep("wait for transition", 2);
@ -187,7 +187,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddUntilStep("wait for join", () => multiplayerScreenStack.RoomManager.RoomJoined); AddUntilStep("wait for join", () => client.RoomJoined);
} }
} }
} }

View File

@ -336,12 +336,12 @@ namespace osu.Game.Tests.Visual.Navigation
[Test] [Test]
public void TestPushMatchSubScreenAndPressBackButtonImmediately() public void TestPushMatchSubScreenAndPressBackButtonImmediately()
{ {
TestMultiplayerScreenStack multiplayerScreenStack = null; TestMultiplayerComponents multiplayerComponents = null;
PushAndConfirm(() => multiplayerScreenStack = new TestMultiplayerScreenStack()); PushAndConfirm(() => multiplayerComponents = new TestMultiplayerComponents());
AddUntilStep("wait for lounge", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true); AddUntilStep("wait for lounge", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true);
AddStep("open room", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().Single().Open()); AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open());
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action()); AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
AddWaitStep("wait two frames", 2); AddWaitStep("wait two frames", 2);
} }

View File

@ -2,9 +2,10 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Online.API; using osu.Framework.Testing;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
@ -14,72 +15,77 @@ namespace osu.Game.Tests.Visual.Online
{ {
public class TestSceneUserProfileHeader : OsuTestScene public class TestSceneUserProfileHeader : OsuTestScene
{ {
protected override bool UseOnlineAPI => true;
[Cached] [Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
[Resolved] private ProfileHeader header;
private IAPIProvider api { get; set; }
private readonly ProfileHeader header; [SetUpSteps]
public void SetUpSteps()
public TestSceneUserProfileHeader()
{ {
header = new ProfileHeader(); AddStep("create header", () => Child = header = new ProfileHeader());
Add(header); }
AddStep("Show test dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER); [Test]
public void TestBasic()
{
AddStep("Show example user", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER);
}
AddStep("Show null dummy", () => header.User.Value = new APIUser [Test]
{ public void TestOnlineState()
Username = "Null" {
}); AddStep("Show online user", () => header.User.Value = new APIUser
AddStep("Show online dummy", () => header.User.Value = new APIUser
{ {
Id = 1001,
Username = "IAmOnline", Username = "IAmOnline",
LastVisit = DateTimeOffset.Now, LastVisit = DateTimeOffset.Now,
IsOnline = true, IsOnline = true,
}); });
AddStep("Show offline dummy", () => header.User.Value = new APIUser AddStep("Show offline user", () => header.User.Value = new APIUser
{ {
Id = 1002,
Username = "IAmOffline", Username = "IAmOffline",
LastVisit = DateTimeOffset.Now, LastVisit = DateTimeOffset.Now.AddDays(-10),
IsOnline = false, IsOnline = false,
}); });
addOnlineStep("Show ppy", new APIUser
{
Username = @"peppy",
Id = 2,
IsSupporter = true,
Country = new Country { FullName = @"Australia", FlagName = @"AU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
});
addOnlineStep("Show flyte", new APIUser
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FullName = @"Japan", FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
});
} }
private void addOnlineStep(string name, APIUser fallback) [Test]
public void TestRankedState()
{ {
AddStep(name, () => AddStep("Show ranked user", () => header.User.Value = new APIUser
{ {
if (api.IsLoggedIn) Id = 2001,
Username = "RankedUser",
Statistics = new UserStatistics
{ {
var request = new GetUserRequest(fallback.Id); IsRanked = true,
request.Success += user => header.User.Value = user; GlobalRank = 15000,
api.Queue(request); CountryRank = 1500,
RankHistory = new APIRankHistory
{
Mode = @"osu",
Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray()
},
}
});
AddStep("Show unranked user", () => header.User.Value = new APIUser
{
Id = 2002,
Username = "UnrankedUser",
Statistics = new UserStatistics
{
IsRanked = false,
// web will sometimes return non-empty rank history even for unranked users.
RankHistory = new APIRankHistory
{
Mode = @"osu",
Data = Enumerable.Range(2345, 85).ToArray()
},
} }
else
header.User.Value = fallback;
}); });
} }
} }

View File

@ -29,6 +29,7 @@ namespace osu.Game.Tests.Visual.Online
ProfileOrder = new[] { "me" }, ProfileOrder = new[] { "me" },
Statistics = new UserStatistics Statistics = new UserStatistics
{ {
IsRanked = true,
GlobalRank = 2148, GlobalRank = 2148,
CountryRank = 1, CountryRank = 1,
PP = 4567.89m, PP = 4567.89m,

View File

@ -168,12 +168,13 @@ namespace osu.Game.Tests.Visual.Playlists
})); }));
}); });
AddUntilStep("wait for screen to load", () => resultsScreen.IsLoaded);
waitForDisplay(); waitForDisplay();
} }
private void waitForDisplay() private void waitForDisplay()
{ {
AddUntilStep("wait for load to complete", () => AddUntilStep("wait for scores loaded", () =>
requestComplete requestComplete
&& resultsScreen.ScorePanelList.GetScorePanels().Count() == totalCount && resultsScreen.ScorePanelList.GetScorePanels().Count() == totalCount
&& resultsScreen.ScorePanelList.AllPanelsVisible); && resultsScreen.ScorePanelList.AllPanelsVisible);

View File

@ -466,7 +466,9 @@ namespace osu.Game.Tests.Visual.SongSelect
public void TestExternalBeatmapChangeWhileFiltered(bool differentRuleset) public void TestExternalBeatmapChangeWhileFiltered(bool differentRuleset)
{ {
createSongSelect(); createSongSelect();
addManyTestMaps(); // ensure there is at least 1 difficulty for each of the rulesets
// (catch is excluded inside of addManyTestMaps).
addManyTestMaps(3);
changeRuleset(0); changeRuleset(0);
@ -488,8 +490,9 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select beatmap externally", () => AddStep("select beatmap externally", () =>
{ {
target = manager.GetAllUsableBeatmapSets() target = manager.GetAllUsableBeatmapSets()
.Where(b => b.Beatmaps.Any(bi => bi.RulesetID == targetRuleset)) .First(b => b.Beatmaps.Any(bi => bi.RulesetID == targetRuleset))
.ElementAt(5).Beatmaps.First(bi => bi.RulesetID == targetRuleset); .Beatmaps
.First(bi => bi.RulesetID == targetRuleset);
Beatmap.Value = manager.GetWorkingBeatmap(target); Beatmap.Value = manager.GetWorkingBeatmap(target);
}); });
@ -518,7 +521,9 @@ namespace osu.Game.Tests.Visual.SongSelect
public void TestExternalBeatmapChangeWhileFilteredThenRefilter() public void TestExternalBeatmapChangeWhileFilteredThenRefilter()
{ {
createSongSelect(); createSongSelect();
addManyTestMaps(); // ensure there is at least 1 difficulty for each of the rulesets
// (catch is excluded inside of addManyTestMaps).
addManyTestMaps(3);
changeRuleset(0); changeRuleset(0);
@ -534,8 +539,10 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select beatmap externally", () => AddStep("select beatmap externally", () =>
{ {
target = manager.GetAllUsableBeatmapSets().Where(b => b.Beatmaps.Any(bi => bi.RulesetID == 1)) target = manager
.ElementAt(5).Beatmaps.First(); .GetAllUsableBeatmapSets()
.First(b => b.Beatmaps.Any(bi => bi.RulesetID == 1))
.Beatmaps.First();
Beatmap.Value = manager.GetWorkingBeatmap(target); Beatmap.Value = manager.GetWorkingBeatmap(target);
}); });
@ -877,14 +884,21 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("wait for carousel loaded", () => songSelect.Carousel.IsAlive); AddUntilStep("wait for carousel loaded", () => songSelect.Carousel.IsAlive);
} }
private void addManyTestMaps() /// <summary>
/// Imports test beatmap sets to show in the carousel.
/// </summary>
/// <param name="difficultyCountPerSet">
/// The exact count of difficulties to create for each beatmap set.
/// A <see langword="null"/> value causes the count of difficulties to be selected randomly.
/// </param>
private void addManyTestMaps(int? difficultyCountPerSet = null)
{ {
AddStep("import test maps", () => AddStep("import test maps", () =>
{ {
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
for (int i = 0; i < 100; i += 10) for (int i = 0; i < 10; i++)
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait(); manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).Wait();
}); });
} }

View File

@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual
/// </list> /// </list>
/// </p> /// </p>
/// </summary> /// </summary>
public class TestMultiplayerScreenStack : OsuScreen public class TestMultiplayerComponents : OsuScreen
{ {
public Screens.OnlinePlay.Multiplayer.Multiplayer MultiplayerScreen => multiplayerScreen; public Screens.OnlinePlay.Multiplayer.Multiplayer MultiplayerScreen => multiplayerScreen;
@ -42,14 +42,18 @@ namespace osu.Game.Tests.Visual
private readonly OsuScreenStack screenStack; private readonly OsuScreenStack screenStack;
private readonly TestMultiplayer multiplayerScreen; private readonly TestMultiplayer multiplayerScreen;
public TestMultiplayerScreenStack() public TestMultiplayerComponents()
{ {
multiplayerScreen = new TestMultiplayer(); multiplayerScreen = new TestMultiplayer();
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
Client = new TestMultiplayerClient(RoomManager), Client = new TestMultiplayerClient(RoomManager),
screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both } screenStack = new OsuScreenStack
{
Name = nameof(TestMultiplayerComponents),
RelativeSizeAxes = Axes.Both
}
}; };
screenStack.Push(multiplayerScreen); screenStack.Push(multiplayerScreen);

View File

@ -26,6 +26,8 @@ namespace osu.Game.Database
public bool Equals(ILive<T>? other) => ID == other?.ID; public bool Equals(ILive<T>? other) => ID == other?.ID;
public override string ToString() => Value.ToString();
public Guid ID => Value.ID; public Guid ID => Value.ID;
public void PerformRead(Action<T> perform) => perform(Value); public void PerformRead(Action<T> perform) => perform(Value);

View File

@ -42,7 +42,9 @@ namespace osu.Game.Overlays.Profile.Header.Components
private void updateStatistics(UserStatistics statistics) private void updateStatistics(UserStatistics statistics)
{ {
int[] userRanks = statistics?.RankHistory?.Data; // checking both IsRanked and RankHistory is required.
// see https://github.com/ppy/osu-web/blob/154ceafba0f35a1dd935df53ec98ae2ea5615f9f/resources/assets/lib/profile-page/rank-chart.tsx#L46
int[] userRanks = statistics?.IsRanked == true ? statistics.RankHistory?.Data : null;
Data = userRanks?.Select((x, index) => new KeyValuePair<int, int>(index, x)).Where(x => x.Value != 0).ToArray(); Data = userRanks?.Select((x, index) => new KeyValuePair<int, int>(index, x)).Where(x => x.Value != 0).ToArray();
} }

View File

@ -87,7 +87,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
gameplayContent.Child = new PlayerIsolationContainer(beatmapManager.GetWorkingBeatmap(Score.ScoreInfo.BeatmapInfo), Score.ScoreInfo.Ruleset, Score.ScoreInfo.Mods) gameplayContent.Child = new PlayerIsolationContainer(beatmapManager.GetWorkingBeatmap(Score.ScoreInfo.BeatmapInfo), Score.ScoreInfo.Ruleset, Score.ScoreInfo.Mods)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = stack = new OsuScreenStack() Child = stack = new OsuScreenStack
{
Name = nameof(PlayerArea),
}
}; };
stack.Push(new MultiSpectatorPlayerLoader(Score, () => new MultiSpectatorPlayer(Score, GameplayClock))); stack.Push(new MultiSpectatorPlayerLoader(Score, () => new MultiSpectatorPlayer(Score, GameplayClock)));

View File

@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
protected new MultiplayerTestSceneDependencies OnlinePlayDependencies => (MultiplayerTestSceneDependencies)base.OnlinePlayDependencies; protected new MultiplayerTestSceneDependencies OnlinePlayDependencies => (MultiplayerTestSceneDependencies)base.OnlinePlayDependencies;
public bool RoomJoined => RoomManager.RoomJoined; public bool RoomJoined => Client.RoomJoined;
private readonly bool joinRoom; private readonly bool joinRoom;

View File

@ -31,9 +31,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
private readonly Bindable<bool> isConnected = new Bindable<bool>(true); private readonly Bindable<bool> isConnected = new Bindable<bool>(true);
public new Room? APIRoom => base.APIRoom; public new Room? APIRoom => base.APIRoom;
public Action<MultiplayerRoom>? RoomSetupAction; public Action<MultiplayerRoom>? RoomSetupAction;
public bool RoomJoined { get; private set; }
[Resolved] [Resolved]
private IAPIProvider api { get; set; } = null!; private IAPIProvider api { get; set; } = null!;
@ -49,7 +50,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
private MultiplayerPlaylistItem? currentItem => Room?.Playlist[currentIndex]; private MultiplayerPlaylistItem? currentItem => Room?.Playlist[currentIndex];
private int currentIndex; private int currentIndex;
private long lastPlaylistItemId; private long lastPlaylistItemId;
public TestMultiplayerClient(TestMultiplayerRoomManager roomManager) public TestMultiplayerClient(TestMultiplayerRoomManager roomManager)
@ -217,9 +217,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
// emulate the server sending this after the join room. scheduler required to make sure the join room event is fired first (in Join). // emulate the server sending this after the join room. scheduler required to make sure the join room event is fired first (in Join).
changeMatchType(Room.Settings.MatchType).Wait(); changeMatchType(Room.Settings.MatchType).Wait();
RoomJoined = true;
} }
protected override Task LeaveRoomInternal() => Task.CompletedTask; protected override Task LeaveRoomInternal()
{
RoomJoined = false;
return Task.CompletedTask;
}
public override Task TransferHost(int userId) => ((IMultiplayerClient)this).HostChanged(userId); public override Task TransferHost(int userId) => ((IMultiplayerClient)this).HostChanged(userId);

View File

@ -17,8 +17,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
/// </summary> /// </summary>
public class TestMultiplayerRoomManager : MultiplayerRoomManager public class TestMultiplayerRoomManager : MultiplayerRoomManager
{ {
public bool RoomJoined { get; private set; }
private readonly TestRoomRequestsHandler requestsHandler; private readonly TestRoomRequestsHandler requestsHandler;
public TestMultiplayerRoomManager(TestRoomRequestsHandler requestsHandler) public TestMultiplayerRoomManager(TestRoomRequestsHandler requestsHandler)
@ -29,28 +27,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
public IReadOnlyList<Room> ServerSideRooms => requestsHandler.ServerSideRooms; public IReadOnlyList<Room> ServerSideRooms => requestsHandler.ServerSideRooms;
public override void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) public override void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
{ => base.CreateRoom(room, r => onSuccess?.Invoke(r), onError);
base.CreateRoom(room, r =>
{
onSuccess?.Invoke(r);
RoomJoined = true;
}, onError);
}
public override void JoinRoom(Room room, string password = null, Action<Room> onSuccess = null, Action<string> onError = null) public override void JoinRoom(Room room, string password = null, Action<Room> onSuccess = null, Action<string> onError = null)
{ => base.JoinRoom(room, password, r => onSuccess?.Invoke(r), onError);
base.JoinRoom(room, password, r =>
{
onSuccess?.Invoke(r);
RoomJoined = true;
}, onError);
}
public override void PartRoom()
{
base.PartRoom();
RoomJoined = false;
}
/// <summary> /// <summary>
/// Adds a room to a local "server-side" list that's returned when a <see cref="GetRoomsRequest"/> is fired. /// Adds a room to a local "server-side" list that's returned when a <see cref="GetRoomsRequest"/> is fired.

View File

@ -29,7 +29,11 @@ namespace osu.Game.Tests.Visual
{ {
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {
Stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }, Stack = new OsuScreenStack
{
Name = nameof(ScreenTestScene),
RelativeSizeAxes = Axes.Both
},
content = new Container { RelativeSizeAxes = Axes.Both }, content = new Container { RelativeSizeAxes = Axes.Both },
DialogOverlay = new DialogOverlay() DialogOverlay = new DialogOverlay()
}); });

View File

@ -27,6 +27,9 @@ namespace osu.Game.Users
public int Progress; public int Progress;
} }
[JsonProperty(@"is_ranked")]
public bool IsRanked;
[JsonProperty(@"global_rank")] [JsonProperty(@"global_rank")]
public int? GlobalRank; public int? GlobalRank;

View File

@ -36,7 +36,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Realm" Version="10.7.1" /> <PackageReference Include="Realm" Version="10.7.1" />
<PackageReference Include="ppy.osu.Framework" Version="2021.1217.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.1220.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="Sentry" Version="3.12.1" /> <PackageReference Include="Sentry" Version="3.12.1" />
<PackageReference Include="SharpCompress" Version="0.30.1" /> <PackageReference Include="SharpCompress" Version="0.30.1" />

View File

@ -60,7 +60,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1217.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1220.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
</ItemGroup> </ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) --> <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
@ -83,7 +83,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2021.1217.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.1220.0" />
<PackageReference Include="SharpCompress" Version="0.30.0" /> <PackageReference Include="SharpCompress" Version="0.30.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />