mirror of
https://github.com/ppy/osu.git
synced 2025-01-18 11:02:57 +08:00
Add client methods allowing users to be notified of who is watching them
This commit is contained in:
parent
582c5180b9
commit
43fc48a3f3
@ -7,6 +7,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Spectator;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
||||
@ -15,7 +16,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public partial class TestSceneSpectatorList : OsuTestScene
|
||||
{
|
||||
private readonly BindableList<SpectatorList.Spectator> spectators = new BindableList<SpectatorList.Spectator>();
|
||||
private readonly BindableList<SpectatorUser> spectators = new BindableList<SpectatorUser>();
|
||||
private readonly Bindable<LocalUserPlayingState> localUserPlayingState = new Bindable<LocalUserPlayingState>();
|
||||
|
||||
private int counter;
|
||||
@ -36,7 +37,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("add a user", () =>
|
||||
{
|
||||
int id = Interlocked.Increment(ref counter);
|
||||
spectators.Add(new SpectatorList.Spectator(id, $"User {id}"));
|
||||
spectators.Add(new SpectatorUser
|
||||
{
|
||||
OnlineID = id,
|
||||
Username = $"User {id}"
|
||||
});
|
||||
});
|
||||
AddStep("remove random user", () => spectators.RemoveAt(RNG.Next(0, spectators.Count)));
|
||||
AddStep("enter break", () => localUserPlayingState.Value = LocalUserPlayingState.Break);
|
||||
|
@ -37,5 +37,17 @@ namespace osu.Game.Online.Spectator
|
||||
/// <param name="userId">The ID of the user who achieved the score.</param>
|
||||
/// <param name="scoreId">The ID of the score.</param>
|
||||
Task UserScoreProcessed(int userId, long scoreId);
|
||||
|
||||
/// <summary>
|
||||
/// Signals that another user has <see cref="ISpectatorServer.StartWatchingUser">started watching this client</see>.
|
||||
/// </summary>
|
||||
/// <param name="user">The information about the user who started watching.</param>
|
||||
Task UserStartedWatching(SpectatorUser[] user);
|
||||
|
||||
/// <summary>
|
||||
/// Signals that another user has <see cref="ISpectatorServer.EndWatchingUser">ended watching this client</see>
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the user who ended watching.</param>
|
||||
Task UserEndedWatching(int userId);
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ namespace osu.Game.Online.Spectator
|
||||
connection.On<int, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
|
||||
connection.On<int, SpectatorState>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
|
||||
connection.On<int, long>(nameof(ISpectatorClient.UserScoreProcessed), ((ISpectatorClient)this).UserScoreProcessed);
|
||||
connection.On<SpectatorUser[]>(nameof(ISpectatorClient.UserStartedWatching), ((ISpectatorClient)this).UserStartedWatching);
|
||||
connection.On<int>(nameof(ISpectatorClient.UserEndedWatching), ((ISpectatorClient)this).UserEndedWatching);
|
||||
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IStatefulUserHubClient)this).DisconnectRequested);
|
||||
};
|
||||
|
||||
|
@ -36,9 +36,14 @@ namespace osu.Game.Online.Spectator
|
||||
public abstract IBindable<bool> IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The states of all users currently being watched.
|
||||
/// The states of all users currently being watched by the local user.
|
||||
/// </summary>
|
||||
public virtual IBindableDictionary<int, SpectatorState> WatchedUserStates => watchedUserStates;
|
||||
public IBindableDictionary<int, SpectatorState> WatchedUserStates => watchedUserStates;
|
||||
|
||||
/// <summary>
|
||||
/// All users who are currently watching the local user.
|
||||
/// </summary>
|
||||
public IBindableList<SpectatorUser> WatchingUsers => watchingUsers;
|
||||
|
||||
/// <summary>
|
||||
/// A global list of all players currently playing.
|
||||
@ -82,6 +87,7 @@ namespace osu.Game.Online.Spectator
|
||||
|
||||
private readonly BindableDictionary<int, SpectatorState> watchedUserStates = new BindableDictionary<int, SpectatorState>();
|
||||
|
||||
private readonly BindableList<SpectatorUser> watchingUsers = new BindableList<SpectatorUser>();
|
||||
private readonly BindableList<int> playingUsers = new BindableList<int>();
|
||||
private readonly SpectatorState currentState = new SpectatorState();
|
||||
|
||||
@ -127,6 +133,7 @@ namespace osu.Game.Online.Spectator
|
||||
{
|
||||
playingUsers.Clear();
|
||||
watchedUserStates.Clear();
|
||||
watchingUsers.Clear();
|
||||
}
|
||||
}), true);
|
||||
}
|
||||
@ -179,6 +186,30 @@ namespace osu.Game.Online.Spectator
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task ISpectatorClient.UserStartedWatching(SpectatorUser[] users)
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
foreach (var user in users)
|
||||
{
|
||||
if (!watchingUsers.Contains(user))
|
||||
watchingUsers.Add(user);
|
||||
}
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task ISpectatorClient.UserEndedWatching(int userId)
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
watchingUsers.RemoveAll(u => u.OnlineID == userId);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task IStatefulUserHubClient.DisconnectRequested()
|
||||
{
|
||||
Schedule(() => DisconnectInternal());
|
||||
|
39
osu.Game/Online/Spectator/SpectatorUser.cs
Normal file
39
osu.Game/Online/Spectator/SpectatorUser.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// 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;
|
||||
using MessagePack;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Spectator
|
||||
{
|
||||
[Serializable]
|
||||
[MessagePackObject]
|
||||
public class SpectatorUser : IUser, IEquatable<SpectatorUser>
|
||||
{
|
||||
[Key(0)]
|
||||
public int OnlineID { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string Username { get; set; } = string.Empty;
|
||||
|
||||
[IgnoreMember]
|
||||
public CountryCode CountryCode => CountryCode.Unknown;
|
||||
|
||||
[IgnoreMember]
|
||||
public bool IsBot => false;
|
||||
|
||||
public bool Equals(SpectatorUser? other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return OnlineID == other.OnlineID;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) => Equals(obj as SpectatorUser);
|
||||
|
||||
// ReSharper disable once NonReadonlyMemberInGetHashCode
|
||||
public override int GetHashCode() => OnlineID;
|
||||
}
|
||||
}
|
@ -13,9 +13,9 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Localisation.HUD;
|
||||
using osu.Game.Localisation.SkinComponents;
|
||||
using osu.Game.Online.Spectator;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
private const int max_spectators_displayed = 10;
|
||||
|
||||
public BindableList<Spectator> Spectators { get; } = new BindableList<Spectator>();
|
||||
public BindableList<SpectatorUser> Spectators { get; } = new BindableList<SpectatorUser>();
|
||||
public Bindable<LocalUserPlayingState> UserPlayingState { get; } = new Bindable<LocalUserPlayingState>();
|
||||
|
||||
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))]
|
||||
@ -91,7 +91,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
for (int i = 0; i < e.NewItems!.Count; i++)
|
||||
{
|
||||
var spectator = (Spectator)e.NewItems![i]!;
|
||||
var spectator = (SpectatorUser)e.NewItems![i]!;
|
||||
int index = e.NewStartingIndex + i;
|
||||
|
||||
if (index >= max_spectators_displayed)
|
||||
@ -157,7 +157,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
private partial class SpectatorListEntry : PoolableDrawable
|
||||
{
|
||||
public Bindable<Spectator> Current { get; } = new Bindable<Spectator>();
|
||||
public Bindable<SpectatorUser> Current { get; } = new Bindable<SpectatorUser>();
|
||||
|
||||
private readonly BindableWithCurrent<LocalUserPlayingState> current = new BindableWithCurrent<LocalUserPlayingState>();
|
||||
|
||||
@ -209,11 +209,5 @@ namespace osu.Game.Screens.Play.HUD
|
||||
linkCompiler.Enabled.Value = UserPlayingState.Value != LocalUserPlayingState.Playing;
|
||||
}
|
||||
}
|
||||
|
||||
public record Spectator(int OnlineID, string Username) : IUser
|
||||
{
|
||||
public CountryCode CountryCode => CountryCode.Unknown;
|
||||
public bool IsBot => false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user