mirror of
https://github.com/ppy/osu.git
synced 2025-03-15 14:47:18 +08:00
Add spectator state object support
This commit is contained in:
parent
2021945a8c
commit
05697dfe68
@ -11,15 +11,15 @@ namespace osu.Game.Online.Spectator
|
||||
/// Signals that a user has begun a new play session.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user.</param>
|
||||
/// <param name="beatmapId">The beatmap the user is playing.</param>
|
||||
Task UserBeganPlaying(string userId, int beatmapId);
|
||||
/// <param name="state">The state of gameplay.</param>
|
||||
Task UserBeganPlaying(string userId, SpectatorState state);
|
||||
|
||||
/// <summary>
|
||||
/// Signals that a user has finished a play session.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user.</param>
|
||||
/// <param name="beatmapId">The beatmap the user has finished playing.</param>
|
||||
Task UserFinishedPlaying(string userId, int beatmapId);
|
||||
/// <param name="state">The state of gameplay.</param>
|
||||
Task UserFinishedPlaying(string userId, SpectatorState state);
|
||||
|
||||
/// <summary>
|
||||
/// Called when new frames are available for a subscribed user's play session.
|
||||
|
@ -10,8 +10,8 @@ namespace osu.Game.Online.Spectator
|
||||
/// <summary>
|
||||
/// Signal the start of a new play session.
|
||||
/// </summary>
|
||||
/// <param name="beatmapId">The beatmap currently being played. Eventually this should be replaced with more complete metadata.</param>
|
||||
Task BeginPlaySession(int beatmapId);
|
||||
/// <param name="state">The state of gameplay.</param>
|
||||
Task BeginPlaySession(SpectatorState state);
|
||||
|
||||
/// <summary>
|
||||
/// Send a bundle of frame data for the current play session.
|
||||
@ -22,15 +22,14 @@ namespace osu.Game.Online.Spectator
|
||||
/// <summary>
|
||||
/// Signal the end of a play session.
|
||||
/// </summary>
|
||||
/// <param name="beatmapId">The beatmap that was completed. This should be replaced with a play token once that flow is established.</param>
|
||||
Task EndPlaySession(int beatmapId);
|
||||
/// <param name="state">The state of gameplay.</param>
|
||||
Task EndPlaySession(SpectatorState state);
|
||||
|
||||
/// <summary>
|
||||
/// Request spectating data for the specified user. May be called on multiple users and offline users.
|
||||
/// For offline users, a subscription will be created and data will begin streaming on next play.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user to subscribe to.</param>
|
||||
/// <returns></returns>
|
||||
Task StartWatchingUser(string userId);
|
||||
|
||||
/// <summary>
|
||||
|
32
osu.Game/Online/Spectator/SpectatorState.cs
Normal file
32
osu.Game/Online/Spectator/SpectatorState.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Online.Spectator
|
||||
{
|
||||
[Serializable]
|
||||
public class SpectatorState : IEquatable<SpectatorState>
|
||||
{
|
||||
public int? BeatmapID { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public IEnumerable<Mod> Mods { get; set; } = Enumerable.Empty<Mod>();
|
||||
|
||||
public SpectatorState(int? beatmapId = null, IEnumerable<Mod> mods = null)
|
||||
{
|
||||
BeatmapID = beatmapId;
|
||||
if (mods != null)
|
||||
Mods = mods;
|
||||
}
|
||||
|
||||
public SpectatorState()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(SpectatorState other) => this.BeatmapID == other?.BeatmapID && this.Mods.SequenceEqual(other?.Mods);
|
||||
|
||||
public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods.SelectMany(m => m.Acronym))}";
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
|
||||
@ -30,6 +31,11 @@ namespace osu.Game.Online.Spectator
|
||||
[Resolved]
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||
|
||||
private readonly SpectatorState currentState = new SpectatorState();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -73,9 +79,9 @@ namespace osu.Game.Online.Spectator
|
||||
.Build();
|
||||
|
||||
// until strong typed client support is added, each method must be manually bound (see https://github.com/dotnet/aspnetcore/issues/15198)
|
||||
connection.On<string, int>(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying);
|
||||
connection.On<string, SpectatorState>(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying);
|
||||
connection.On<string, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
|
||||
connection.On<string, int>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
|
||||
connection.On<string, SpectatorState>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
|
||||
|
||||
connection.Closed += async ex =>
|
||||
{
|
||||
@ -106,7 +112,7 @@ namespace osu.Game.Online.Spectator
|
||||
}
|
||||
}
|
||||
|
||||
Task ISpectatorClient.UserBeganPlaying(string userId, int beatmapId)
|
||||
Task ISpectatorClient.UserBeganPlaying(string userId, SpectatorState state)
|
||||
{
|
||||
if (connection.ConnectionId != userId)
|
||||
{
|
||||
@ -123,15 +129,15 @@ namespace osu.Game.Online.Spectator
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{connection.ConnectionId} Received user playing event for self {beatmapId}");
|
||||
Console.WriteLine($"{connection.ConnectionId} Received user playing event for self {state}");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task ISpectatorClient.UserFinishedPlaying(string userId, int beatmapId)
|
||||
Task ISpectatorClient.UserFinishedPlaying(string userId, SpectatorState state)
|
||||
{
|
||||
Console.WriteLine($"{connection.ConnectionId} Received user finished event {beatmapId}");
|
||||
Console.WriteLine($"{connection.ConnectionId} Received user finished event {state}");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@ -155,11 +161,11 @@ namespace osu.Game.Online.Spectator
|
||||
connection.SendAsync(nameof(ISpectatorServer.SendFrameData), data);
|
||||
}
|
||||
|
||||
public void EndPlaying(int beatmapId)
|
||||
public void EndPlaying()
|
||||
{
|
||||
if (!isConnected) return;
|
||||
|
||||
connection.SendAsync(nameof(ISpectatorServer.EndPlaySession), beatmapId);
|
||||
connection.SendAsync(nameof(ISpectatorServer.EndPlaySession), currentState);
|
||||
}
|
||||
|
||||
public void WatchUser(string userId)
|
||||
@ -171,6 +177,7 @@ namespace osu.Game.Online.Spectator
|
||||
|
||||
public void HandleFrame(ReplayFrame frame)
|
||||
{
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global (implemented by rulesets)
|
||||
if (frame is IConvertibleReplayFrame convertible)
|
||||
// TODO: don't send a bundle for each individual frame
|
||||
SendFrames(new FrameDataBundle(new[] { convertible.ToLegacy(beatmap.Value.Beatmap) }));
|
||||
|
@ -50,13 +50,13 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
inputManager = GetContainingInputManager();
|
||||
|
||||
spectatorStreaming?.BeginPlaying(beatmap.Value.BeatmapInfo.ID);
|
||||
spectatorStreaming?.BeginPlaying();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
spectatorStreaming?.EndPlaying(beatmap.Value.BeatmapInfo.ID);
|
||||
spectatorStreaming?.EndPlaying();
|
||||
}
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
|
Loading…
x
Reference in New Issue
Block a user