1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-20 04:23:14 +08:00

Begin shaping the spectator streaming component

This commit is contained in:
Dean Herbert 2020-10-22 13:41:54 +09:00
parent db4dd3182b
commit 93db75bd41
3 changed files with 58 additions and 23 deletions

View File

@ -3,8 +3,6 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -264,25 +262,13 @@ namespace osu.Game.Tests.Visual.Gameplay
internal class TestReplayRecorder : ReplayRecorder<TestAction>
{
private readonly SpectatorClient client;
public TestReplayRecorder(Replay target)
: base(target)
{
var connection = new HubConnectionBuilder()
.WithUrl("http://localhost:5009/spectator")
.AddMessagePackProtocol()
// .ConfigureLogging(logging => { logging.AddConsole(); })
.Build();
connection.StartAsync().Wait();
client = new SpectatorClient(connection);
}
protected override ReplayFrame HandleFrame(Vector2 mousePosition, List<TestAction> actions, ReplayFrame previousFrame)
{
client.SendFrames(new FrameDataBundle(new[] { new LegacyReplayFrame(Time.Current, mousePosition.X, mousePosition.Y, ReplayButtonState.None) }));
return new TestReplayFrame(Time.Current, mousePosition, actions.ToArray());
}
}

View File

@ -3,24 +3,70 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Online.API;
namespace osu.Game.Online.Spectator
{
public class SpectatorClient : ISpectatorClient
public class SpectatorStreamingClient : Component, ISpectatorClient
{
private readonly HubConnection connection;
private HubConnection connection;
private readonly List<string> watchingUsers = new List<string>();
public SpectatorClient(HubConnection connection)
{
this.connection = connection;
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
// this is kind of SILLY
// https://github.com/dotnet/aspnetcore/issues/15198
[Resolved]
private APIAccess api { get; set; }
[BackgroundDependencyLoader]
private void load()
{
apiState.BindTo(api.State);
apiState.BindValueChanged(apiStateChanged, true);
}
private void apiStateChanged(ValueChangedEvent<APIState> state)
{
switch (state.NewValue)
{
case APIState.Failing:
case APIState.Offline:
connection?.StopAsync();
connection = null;
break;
case APIState.Online:
connect();
break;
}
}
#if DEBUG
private const string endpoint = "http://localhost:5009/spectator";
#else
private const string endpoint = "https://spectator.ppy.sh/spectator";
#endif
private void connect()
{
connection = new HubConnectionBuilder()
.WithUrl(endpoint, options =>
{
options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
})
.AddMessagePackProtocol()
.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, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
connection.On<string, int>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
connection.StartAsync();
}
Task ISpectatorClient.UserBeganPlaying(string userId, int beatmapId)

View File

@ -30,6 +30,7 @@ using osu.Game.Database;
using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.IO;
using osu.Game.Online.Spectator;
using osu.Game.Overlays;
using osu.Game.Resources;
using osu.Game.Rulesets;
@ -74,6 +75,8 @@ namespace osu.Game
protected IAPIProvider API;
private SpectatorStreamingClient spectatorStreaming;
protected MenuCursorContainer MenuCursorContainer;
protected MusicController MusicController;
@ -189,9 +192,9 @@ namespace osu.Game
dependencies.Cache(SkinManager = new SkinManager(Storage, contextFactory, Host, Audio, new NamespacedResourceStore<byte[]>(Resources, "Skins/Legacy")));
dependencies.CacheAs<ISkinSource>(SkinManager);
API ??= new APIAccess(LocalConfig);
dependencies.CacheAs(API ??= new APIAccess(LocalConfig));
dependencies.CacheAs(API);
dependencies.CacheAs(spectatorStreaming = new SpectatorStreamingClient());
var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures);