mirror of
https://github.com/ppy/osu.git
synced 2025-03-05 11:43:01 +08:00
Merge pull request #11351 from bdach/client-playing-users
Change PlayingUsers population logic to match expectations
This commit is contained in:
commit
d155f2c0e9
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using Humanizer;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Tests.Visual.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.NonVisual.Multiplayer
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestPlayingUserTracking()
|
||||||
|
{
|
||||||
|
int id = 2000;
|
||||||
|
|
||||||
|
AddRepeatStep("add some users", () => Client.AddUser(new User { Id = id++ }), 5);
|
||||||
|
checkPlayingUserCount(0);
|
||||||
|
|
||||||
|
changeState(3, MultiplayerUserState.WaitingForLoad);
|
||||||
|
checkPlayingUserCount(3);
|
||||||
|
|
||||||
|
changeState(3, MultiplayerUserState.Playing);
|
||||||
|
checkPlayingUserCount(3);
|
||||||
|
|
||||||
|
changeState(3, MultiplayerUserState.Results);
|
||||||
|
checkPlayingUserCount(0);
|
||||||
|
|
||||||
|
changeState(6, MultiplayerUserState.WaitingForLoad);
|
||||||
|
checkPlayingUserCount(6);
|
||||||
|
|
||||||
|
AddStep("another user left", () => Client.RemoveUser(Client.Room?.Users.Last().User));
|
||||||
|
checkPlayingUserCount(5);
|
||||||
|
|
||||||
|
AddStep("leave room", () => Client.LeaveRoom());
|
||||||
|
checkPlayingUserCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPlayingUserCount(int expectedCount)
|
||||||
|
=> AddAssert($"{"user".ToQuantity(expectedCount)} playing", () => Client.CurrentMatchPlayingUserIds.Count == expectedCount);
|
||||||
|
|
||||||
|
private void changeState(int userCount, MultiplayerUserState state)
|
||||||
|
=> AddStep($"{"user".ToQuantity(userCount)} in {state}", () =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < userCount; ++i)
|
||||||
|
{
|
||||||
|
var userId = Client.Room?.Users[i].UserID ?? throw new AssertionException("Room cannot be null!");
|
||||||
|
Client.ChangeUserState(userId, state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -62,8 +62,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
streamingClient.Start(Beatmap.Value.BeatmapInfo.OnlineBeatmapID ?? 0);
|
streamingClient.Start(Beatmap.Value.BeatmapInfo.OnlineBeatmapID ?? 0);
|
||||||
|
|
||||||
Client.PlayingUsers.Clear();
|
Client.CurrentMatchPlayingUserIds.Clear();
|
||||||
Client.PlayingUsers.AddRange(streamingClient.PlayingUsers);
|
Client.CurrentMatchPlayingUserIds.AddRange(streamingClient.PlayingUsers);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUserQuit()
|
public void TestUserQuit()
|
||||||
{
|
{
|
||||||
AddRepeatStep("mark user quit", () => Client.PlayingUsers.RemoveAt(0), users);
|
AddRepeatStep("mark user quit", () => Client.CurrentMatchPlayingUserIds.RemoveAt(0), users);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestMultiplayerStreaming : SpectatorStreamingClient
|
public class TestMultiplayerStreaming : SpectatorStreamingClient
|
||||||
|
@ -61,9 +61,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
public MultiplayerRoom? Room { get; private set; }
|
public MultiplayerRoom? Room { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The users currently in gameplay.
|
/// The users in the joined <see cref="Room"/> which are participating in the current gameplay loop.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableList<int> PlayingUsers = new BindableList<int>();
|
public readonly BindableList<int> CurrentMatchPlayingUserIds = new BindableList<int>();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private UserLookupCache userLookupCache { get; set; } = null!;
|
private UserLookupCache userLookupCache { get; set; } = null!;
|
||||||
@ -133,6 +133,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
apiRoom = null;
|
apiRoom = null;
|
||||||
Room = null;
|
Room = null;
|
||||||
|
CurrentMatchPlayingUserIds.Clear();
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
}, false);
|
}, false);
|
||||||
@ -253,7 +254,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Room.Users.Remove(user);
|
Room.Users.Remove(user);
|
||||||
PlayingUsers.Remove(user.UserID);
|
CurrentMatchPlayingUserIds.Remove(user.UserID);
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
}, false);
|
}, false);
|
||||||
@ -302,8 +303,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
Room.Users.Single(u => u.UserID == userId).State = state;
|
Room.Users.Single(u => u.UserID == userId).State = state;
|
||||||
|
|
||||||
if (state != MultiplayerUserState.Playing)
|
updateUserPlayingState(userId, state);
|
||||||
PlayingUsers.Remove(userId);
|
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
}, false);
|
}, false);
|
||||||
@ -337,8 +337,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PlayingUsers.AddRange(Room.Users.Where(u => u.State == MultiplayerUserState.Playing).Select(u => u.UserID));
|
|
||||||
|
|
||||||
MatchStarted?.Invoke();
|
MatchStarted?.Invoke();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
@ -454,5 +452,24 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
apiRoom.Playlist.Clear(); // Clearing should be unnecessary, but here for sanity.
|
apiRoom.Playlist.Clear(); // Clearing should be unnecessary, but here for sanity.
|
||||||
apiRoom.Playlist.Add(playlistItem);
|
apiRoom.Playlist.Add(playlistItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId">The user's ID.</param>
|
||||||
|
/// <param name="state">The new state of the user.</param>
|
||||||
|
private void updateUserPlayingState(int userId, MultiplayerUserState state)
|
||||||
|
{
|
||||||
|
bool wasPlaying = CurrentMatchPlayingUserIds.Contains(userId);
|
||||||
|
bool isPlaying = state >= MultiplayerUserState.WaitingForLoad && state <= MultiplayerUserState.FinishedPlay;
|
||||||
|
|
||||||
|
if (isPlaying == wasPlaying)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isPlaying)
|
||||||
|
CurrentMatchPlayingUserIds.Add(userId);
|
||||||
|
else
|
||||||
|
CurrentMatchPlayingUserIds.Remove(userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
Debug.Assert(client.Room != null);
|
Debug.Assert(client.Room != null);
|
||||||
|
|
||||||
int[] userIds = client.Room.Users.Where(u => u.State >= MultiplayerUserState.WaitingForLoad).Select(u => u.UserID).ToArray();
|
int[] userIds = client.CurrentMatchPlayingUserIds.ToArray();
|
||||||
|
|
||||||
StartPlay(() => new MultiplayerPlayer(SelectedItem.Value, userIds));
|
StartPlay(() => new MultiplayerPlayer(SelectedItem.Value, userIds));
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,11 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
// BindableList handles binding in a really bad way (Clear then AddRange) so we need to do this manually..
|
// BindableList handles binding in a really bad way (Clear then AddRange) so we need to do this manually..
|
||||||
foreach (int userId in playingUsers)
|
foreach (int userId in playingUsers)
|
||||||
{
|
{
|
||||||
if (!multiplayerClient.PlayingUsers.Contains(userId))
|
if (!multiplayerClient.CurrentMatchPlayingUserIds.Contains(userId))
|
||||||
usersChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new[] { userId }));
|
usersChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new[] { userId }));
|
||||||
}
|
}
|
||||||
|
|
||||||
playingUsers.BindTo(multiplayerClient.PlayingUsers);
|
playingUsers.BindTo(multiplayerClient.CurrentMatchPlayingUserIds);
|
||||||
playingUsers.BindCollectionChanged(usersChanged);
|
playingUsers.BindCollectionChanged(usersChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user