mirror of
https://github.com/ppy/osu.git
synced 2026-05-20 06:39:54 +08:00
Always use MessagePack to talk to spectator server
This commit is contained in:
@@ -409,8 +409,8 @@ namespace osu.Game.Online.API
|
||||
SecondFactorCode = code;
|
||||
}
|
||||
|
||||
public IHubClientConnector GetHubConnector(string clientName, string endpoint, bool preferMessagePack) =>
|
||||
new HubClientConnector(clientName, endpoint, this, versionHash, preferMessagePack);
|
||||
public IHubClientConnector GetHubConnector(string clientName, string endpoint) =>
|
||||
new HubClientConnector(clientName, endpoint, this, versionHash);
|
||||
|
||||
public IChatClient GetChatClient() => new WebSocketChatClient(this);
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace osu.Game.Online.API
|
||||
{
|
||||
}
|
||||
|
||||
public IHubClientConnector? GetHubConnector(string clientName, string endpoint, bool preferMessagePack) => null;
|
||||
public IHubClientConnector? GetHubConnector(string clientName, string endpoint) => null;
|
||||
|
||||
public IChatClient GetChatClient() => new TestChatClientConnector(this);
|
||||
|
||||
|
||||
@@ -138,8 +138,7 @@ namespace osu.Game.Online.API
|
||||
/// </summary>
|
||||
/// <param name="clientName">The name of the client this connector connects for, used for logging.</param>
|
||||
/// <param name="endpoint">The endpoint to the hub.</param>
|
||||
/// <param name="preferMessagePack">Whether to use MessagePack for serialisation if available on this platform.</param>
|
||||
IHubClientConnector? GetHubConnector(string clientName, string endpoint, bool preferMessagePack = true);
|
||||
IHubClientConnector? GetHubConnector(string clientName, string endpoint);
|
||||
|
||||
/// <summary>
|
||||
/// Accesses the <see cref="INotificationsClient"/> used to receive asynchronous notifications from web.
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework;
|
||||
using osu.Game.Online.API;
|
||||
|
||||
@@ -29,7 +26,6 @@ namespace osu.Game.Online
|
||||
|
||||
private readonly string endpoint;
|
||||
private readonly string versionHash;
|
||||
private readonly bool preferMessagePack;
|
||||
|
||||
/// <summary>
|
||||
/// The current connection opened by this connector.
|
||||
@@ -43,14 +39,12 @@ namespace osu.Game.Online
|
||||
/// <param name="endpoint">The endpoint to the hub.</param>
|
||||
/// <param name="api"> An API provider used to react to connection state changes.</param>
|
||||
/// <param name="versionHash">The hash representing the current game version, used for verification purposes.</param>
|
||||
/// <param name="preferMessagePack">Whether to use MessagePack for serialisation if available on this platform.</param>
|
||||
public HubClientConnector(string clientName, string endpoint, IAPIProvider api, string versionHash, bool preferMessagePack = true)
|
||||
public HubClientConnector(string clientName, string endpoint, IAPIProvider api, string versionHash)
|
||||
: base(api)
|
||||
{
|
||||
ClientName = clientName;
|
||||
this.endpoint = endpoint;
|
||||
this.versionHash = versionHash;
|
||||
this.preferMessagePack = preferMessagePack;
|
||||
|
||||
// Automatically start these connections.
|
||||
Start();
|
||||
@@ -78,26 +72,10 @@ namespace osu.Game.Online
|
||||
options.Headers.Add(CLIENT_SESSION_ID_HEADER, API.SessionIdentifier.ToString());
|
||||
});
|
||||
|
||||
if (RuntimeFeature.IsDynamicCodeCompiled && preferMessagePack)
|
||||
builder.AddMessagePackProtocol(options =>
|
||||
{
|
||||
builder.AddMessagePackProtocol(options =>
|
||||
{
|
||||
options.SerializerOptions = SignalRUnionWorkaroundResolver.OPTIONS;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// eventually we will precompile resolvers for messagepack, but this isn't working currently
|
||||
// see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
|
||||
builder.AddNewtonsoftJsonProtocol(options =>
|
||||
{
|
||||
options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
options.PayloadSerializerSettings.Converters = new List<JsonConverter>
|
||||
{
|
||||
new SignalRDerivedTypeWorkaroundJsonConverter(),
|
||||
};
|
||||
});
|
||||
}
|
||||
options.SerializerOptions = SignalRUnionWorkaroundResolver.OPTIONS;
|
||||
});
|
||||
|
||||
var newConnection = builder.Build();
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace osu.Game.Online.Metadata
|
||||
{
|
||||
// Importantly, we are intentionally not using MessagePack here to correctly support derived class serialization.
|
||||
// More information on the limitations / reasoning can be found in osu-server-spectator's initialisation code.
|
||||
connector = api.GetHubConnector(nameof(OnlineMetadataClient), endpoint, false);
|
||||
connector = api.GetHubConnector(nameof(OnlineMetadataClient), endpoint);
|
||||
|
||||
if (connector != null)
|
||||
{
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// 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 System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace osu.Game.Online
|
||||
{
|
||||
/// <summary>
|
||||
/// A type of <see cref="JsonConverter"/> that serializes a subset of types used in multiplayer/spectator communication that
|
||||
/// derive from a known base type. This is a safe alternative to using <see cref="TypeNameHandling.Auto"/> or <see cref="TypeNameHandling.All"/>,
|
||||
/// which are known to have security issues.
|
||||
/// </summary>
|
||||
public class SignalRDerivedTypeWorkaroundJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) =>
|
||||
SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Any(t =>
|
||||
objectType == t.baseType ||
|
||||
objectType == t.derivedType);
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? o, JsonSerializer jsonSerializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
JObject obj = JObject.Load(reader);
|
||||
|
||||
string type = (string)obj[@"$dtype"]!;
|
||||
|
||||
var resolvedType = SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Select(t => t.derivedType).Single(t => t.Name == type);
|
||||
|
||||
object? instance = Activator.CreateInstance(resolvedType);
|
||||
|
||||
if (instance != null)
|
||||
jsonSerializer.Populate(obj["$value"]!.CreateReader(), instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? o, JsonSerializer serializer)
|
||||
{
|
||||
if (o == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteStartObject();
|
||||
|
||||
writer.WritePropertyName(@"$dtype");
|
||||
serializer.Serialize(writer, o.GetType().Name);
|
||||
|
||||
writer.WritePropertyName(@"$value");
|
||||
writer.WriteRawValue(JsonConvert.SerializeObject(o));
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ namespace osu.Game.Online
|
||||
/// A static class providing the list of types requiring workarounds for serialisation in SignalR.
|
||||
/// </summary>
|
||||
/// <seealso cref="SignalRUnionWorkaroundResolver"/>
|
||||
/// <seealso cref="SignalRDerivedTypeWorkaroundJsonConverter"/>
|
||||
internal static class SignalRWorkaroundTypes
|
||||
{
|
||||
internal static readonly IReadOnlyList<(Type derivedType, Type baseType)> BASE_TYPE_MAPPING = new[]
|
||||
|
||||
Reference in New Issue
Block a user