diff --git a/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs b/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs index dd854acc32..81ecc74ddb 100644 --- a/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs +++ b/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs @@ -3,11 +3,10 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; using System.Text; using MessagePack; using MessagePack.Formatters; -using osu.Framework.Bindables; +using osu.Game.Utils; namespace osu.Game.Online.API { @@ -24,36 +23,7 @@ namespace osu.Game.Online.API var stringBytes = new ReadOnlySequence(Encoding.UTF8.GetBytes(kvp.Key)); writer.WriteString(in stringBytes); - switch (kvp.Value) - { - case Bindable d: - primitiveFormatter.Serialize(ref writer, d.Value, options); - break; - - case Bindable i: - primitiveFormatter.Serialize(ref writer, i.Value, options); - break; - - case Bindable f: - primitiveFormatter.Serialize(ref writer, f.Value, options); - break; - - case Bindable b: - primitiveFormatter.Serialize(ref writer, b.Value, options); - break; - - case IBindable u: - // A mod with unknown (e.g. enum) generic type. - var valueMethod = u.GetType().GetProperty(nameof(IBindable.Value)); - Debug.Assert(valueMethod != null); - primitiveFormatter.Serialize(ref writer, valueMethod.GetValue(u), options); - break; - - default: - // fall back for non-bindable cases. - primitiveFormatter.Serialize(ref writer, kvp.Value, options); - break; - } + primitiveFormatter.Serialize(ref writer, ModUtils.GetSettingUnderlyingValue(kvp.Value), options); } } diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index c12b5a9fd4..596880f2e7 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -3,8 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; +using osu.Framework.Bindables; +using osu.Game.Online.API; using osu.Game.Rulesets.Mods; #nullable enable @@ -129,5 +132,38 @@ namespace osu.Game.Utils else yield return mod; } + + /// + /// Returns the underlying value of the given mod setting object. + /// Used in for serialization and equality comparison purposes. + /// + /// The mod setting. + public static object GetSettingUnderlyingValue(object setting) + { + switch (setting) + { + case Bindable d: + return d.Value; + + case Bindable i: + return i.Value; + + case Bindable f: + return f.Value; + + case Bindable b: + return b.Value; + + case IBindable u: + // A mod with unknown (e.g. enum) generic type. + var valueMethod = u.GetType().GetProperty(nameof(IBindable.Value)); + Debug.Assert(valueMethod != null); + return valueMethod.GetValue(u); + + default: + // fall back for non-bindable cases. + return setting; + } + } } }