mirror of
https://github.com/ppy/osu.git
synced 2025-01-30 02:22:55 +08:00
Merge pull request #15684 from frenzibyte/fix-ios-online
Fix MessagePack workaround formatter potentially initializing on iOS
This commit is contained in:
commit
8c72f4843d
@ -17,8 +17,9 @@ namespace osu.Game.Online
|
|||||||
public class SignalRDerivedTypeWorkaroundJsonConverter : JsonConverter
|
public class SignalRDerivedTypeWorkaroundJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType) =>
|
public override bool CanConvert(Type objectType) =>
|
||||||
SignalRUnionWorkaroundResolver.BASE_TYPES.Contains(objectType) ||
|
SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Any(t =>
|
||||||
SignalRUnionWorkaroundResolver.DERIVED_TYPES.Contains(objectType);
|
objectType == t.baseType ||
|
||||||
|
objectType == t.derivedType);
|
||||||
|
|
||||||
public override object? ReadJson(JsonReader reader, Type objectType, object? o, JsonSerializer jsonSerializer)
|
public override object? ReadJson(JsonReader reader, Type objectType, object? o, JsonSerializer jsonSerializer)
|
||||||
{
|
{
|
||||||
@ -29,7 +30,7 @@ namespace osu.Game.Online
|
|||||||
|
|
||||||
string type = (string)obj[@"$dtype"]!;
|
string type = (string)obj[@"$dtype"]!;
|
||||||
|
|
||||||
var resolvedType = SignalRUnionWorkaroundResolver.DERIVED_TYPES.Single(t => t.Name == type);
|
var resolvedType = SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Select(t => t.derivedType).Single(t => t.Name == type);
|
||||||
|
|
||||||
object? instance = Activator.CreateInstance(resolvedType);
|
object? instance = Activator.CreateInstance(resolvedType);
|
||||||
|
|
||||||
|
@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using MessagePack;
|
using MessagePack;
|
||||||
using MessagePack.Formatters;
|
using MessagePack.Formatters;
|
||||||
using MessagePack.Resolvers;
|
using MessagePack.Resolvers;
|
||||||
using osu.Game.Online.Multiplayer;
|
|
||||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
|
||||||
|
|
||||||
namespace osu.Game.Online
|
namespace osu.Game.Online
|
||||||
{
|
{
|
||||||
@ -20,34 +19,22 @@ namespace osu.Game.Online
|
|||||||
public static readonly MessagePackSerializerOptions OPTIONS =
|
public static readonly MessagePackSerializerOptions OPTIONS =
|
||||||
MessagePackSerializerOptions.Standard.WithResolver(new SignalRUnionWorkaroundResolver());
|
MessagePackSerializerOptions.Standard.WithResolver(new SignalRUnionWorkaroundResolver());
|
||||||
|
|
||||||
public static readonly IReadOnlyList<Type> BASE_TYPES = new[]
|
private static readonly IReadOnlyDictionary<Type, IMessagePackFormatter> formatter_map = createFormatterMap();
|
||||||
{
|
|
||||||
typeof(MatchServerEvent),
|
|
||||||
typeof(MatchUserRequest),
|
|
||||||
typeof(MatchRoomState),
|
|
||||||
typeof(MatchUserState),
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly IReadOnlyList<Type> DERIVED_TYPES = new[]
|
private static IReadOnlyDictionary<Type, IMessagePackFormatter> createFormatterMap()
|
||||||
{
|
{
|
||||||
typeof(ChangeTeamRequest),
|
IEnumerable<(Type derivedType, Type baseType)> baseMap = SignalRWorkaroundTypes.BASE_TYPE_MAPPING;
|
||||||
typeof(TeamVersusRoomState),
|
|
||||||
typeof(TeamVersusUserState),
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly IReadOnlyDictionary<Type, IMessagePackFormatter> formatter_map = new Dictionary<Type, IMessagePackFormatter>
|
// This should not be required. The fallback should work. But something is weird with the way caching is done.
|
||||||
{
|
|
||||||
{ typeof(TeamVersusUserState), new TypeRedirectingFormatter<TeamVersusUserState, MatchUserState>() },
|
|
||||||
{ typeof(TeamVersusRoomState), new TypeRedirectingFormatter<TeamVersusRoomState, MatchRoomState>() },
|
|
||||||
{ typeof(ChangeTeamRequest), new TypeRedirectingFormatter<ChangeTeamRequest, MatchUserRequest>() },
|
|
||||||
|
|
||||||
// These should not be required. The fallback should work. But something is weird with the way caching is done.
|
|
||||||
// For future adventurers, I would not advise looking into this further. It's likely not worth the effort.
|
// For future adventurers, I would not advise looking into this further. It's likely not worth the effort.
|
||||||
{ typeof(MatchUserState), new TypeRedirectingFormatter<MatchUserState, MatchUserState>() },
|
baseMap = baseMap.Concat(baseMap.Select(t => (t.baseType, t.baseType)));
|
||||||
{ typeof(MatchRoomState), new TypeRedirectingFormatter<MatchRoomState, MatchRoomState>() },
|
|
||||||
{ typeof(MatchUserRequest), new TypeRedirectingFormatter<MatchUserRequest, MatchUserRequest>() },
|
return new Dictionary<Type, IMessagePackFormatter>(baseMap.Select(t =>
|
||||||
{ typeof(MatchServerEvent), new TypeRedirectingFormatter<MatchServerEvent, MatchServerEvent>() },
|
{
|
||||||
};
|
var formatter = (IMessagePackFormatter)Activator.CreateInstance(typeof(TypeRedirectingFormatter<,>).MakeGenericType(t.derivedType, t.baseType));
|
||||||
|
return new KeyValuePair<Type, IMessagePackFormatter>(t.derivedType, formatter);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
public IMessagePackFormatter<T> GetFormatter<T>()
|
public IMessagePackFormatter<T> GetFormatter<T>()
|
||||||
{
|
{
|
||||||
|
25
osu.Game/Online/SignalRWorkaroundTypes.cs
Normal file
25
osu.Game/Online/SignalRWorkaroundTypes.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
|
|
||||||
|
namespace osu.Game.Online
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 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[]
|
||||||
|
{
|
||||||
|
(typeof(ChangeTeamRequest), typeof(MatchUserRequest)),
|
||||||
|
(typeof(TeamVersusRoomState), typeof(MatchRoomState)),
|
||||||
|
(typeof(TeamVersusUserState), typeof(MatchUserState)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user