1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-12 06:47:25 +08:00
osu-lazer/osu.Game/Online/Multiplayer/MultiplayerClient.cs

156 lines
5.9 KiB
C#
Raw Normal View History

2020-12-20 22:26:31 +08:00
// 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.
#nullable enable
2021-02-01 16:57:32 +08:00
using System.Collections.Generic;
2020-12-20 22:26:31 +08:00
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
using osu.Framework.Allocation;
2020-12-20 22:26:31 +08:00
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
2020-12-20 22:26:31 +08:00
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.Rooms;
2020-12-20 22:26:31 +08:00
2020-12-25 12:38:11 +08:00
namespace osu.Game.Online.Multiplayer
2020-12-20 22:26:31 +08:00
{
2020-12-25 12:38:11 +08:00
public class MultiplayerClient : StatefulMultiplayerClient
2020-12-20 22:26:31 +08:00
{
private readonly string endpoint;
private IHubClientConnector? connector;
2020-12-20 22:26:31 +08:00
public override IBindable<bool> IsConnected { get; } = new BindableBool();
2020-12-20 22:26:31 +08:00
private HubConnection? connection => connector?.CurrentConnection;
2020-12-25 12:38:11 +08:00
public MultiplayerClient(EndpointConfiguration endpoints)
{
endpoint = endpoints.MultiplayerEndpointUrl;
}
[BackgroundDependencyLoader]
private void load(IAPIProvider api)
{
connector = api.GetHubConnector(nameof(MultiplayerClient), endpoint);
if (connector != null)
2020-12-20 22:26:31 +08:00
{
connector.ConfigureConnection = connection =>
2020-12-20 22:26:31 +08:00
{
// this is kind of SILLY
// https://github.com/dotnet/aspnetcore/issues/15198
connection.On<MultiplayerRoomState>(nameof(IMultiplayerClient.RoomStateChanged), ((IMultiplayerClient)this).RoomStateChanged);
connection.On<MultiplayerRoomUser>(nameof(IMultiplayerClient.UserJoined), ((IMultiplayerClient)this).UserJoined);
connection.On<MultiplayerRoomUser>(nameof(IMultiplayerClient.UserLeft), ((IMultiplayerClient)this).UserLeft);
connection.On<int>(nameof(IMultiplayerClient.HostChanged), ((IMultiplayerClient)this).HostChanged);
connection.On<MultiplayerRoomSettings>(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged);
connection.On<int, MultiplayerUserState>(nameof(IMultiplayerClient.UserStateChanged), ((IMultiplayerClient)this).UserStateChanged);
connection.On(nameof(IMultiplayerClient.LoadRequested), ((IMultiplayerClient)this).LoadRequested);
connection.On(nameof(IMultiplayerClient.MatchStarted), ((IMultiplayerClient)this).MatchStarted);
connection.On(nameof(IMultiplayerClient.ResultsReady), ((IMultiplayerClient)this).ResultsReady);
connection.On<int, IEnumerable<APIMod>>(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged);
connection.On<int, BeatmapAvailability>(nameof(IMultiplayerClient.UserBeatmapAvailabilityChanged), ((IMultiplayerClient)this).UserBeatmapAvailabilityChanged);
};
IsConnected.BindTo(connector.IsConnected);
}
2020-12-20 22:26:31 +08:00
}
protected override Task<MultiplayerRoom> JoinRoom(long roomId)
{
if (!IsConnected.Value)
return Task.FromCanceled<MultiplayerRoom>(new CancellationToken(true));
2020-12-20 22:26:31 +08:00
return connection.InvokeAsync<MultiplayerRoom>(nameof(IMultiplayerServer.JoinRoom), roomId);
}
protected override Task LeaveRoomInternal()
2020-12-20 22:26:31 +08:00
{
if (!IsConnected.Value)
return Task.FromCanceled(new CancellationToken(true));
2020-12-20 22:26:31 +08:00
return connection.InvokeAsync(nameof(IMultiplayerServer.LeaveRoom));
2020-12-20 22:26:31 +08:00
}
public override Task TransferHost(int userId)
{
if (!IsConnected.Value)
2020-12-20 22:26:31 +08:00
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.TransferHost), userId);
}
public override Task ChangeSettings(MultiplayerRoomSettings settings)
{
if (!IsConnected.Value)
2020-12-20 22:26:31 +08:00
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeSettings), settings);
}
public override Task ChangeState(MultiplayerUserState newState)
{
if (!IsConnected.Value)
2020-12-20 22:26:31 +08:00
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeState), newState);
}
public override Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability)
{
if (!IsConnected.Value)
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeBeatmapAvailability), newBeatmapAvailability);
}
2021-02-01 16:57:32 +08:00
public override Task ChangeUserMods(IEnumerable<APIMod> newMods)
{
if (!IsConnected.Value)
2021-02-01 16:57:32 +08:00
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeUserMods), newMods);
}
2020-12-20 22:26:31 +08:00
public override Task StartMatch()
{
if (!IsConnected.Value)
2020-12-20 22:26:31 +08:00
return Task.CompletedTask;
return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch));
}
protected override Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<BeatmapSetInfo>();
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
req.Success += res =>
{
if (cancellationToken.IsCancellationRequested)
{
tcs.SetCanceled();
return;
}
tcs.SetResult(res.ToBeatmapSet(Rulesets));
};
req.Failure += e => tcs.SetException(e);
API.Queue(req);
return tcs.Task;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
connector?.Dispose();
}
2020-12-20 22:26:31 +08:00
}
}