mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 14:25:05 +08:00
Merge pull request #12378 from smoogipoo/fix-score-serialisation
Fix mods not being serialised correctly in ScoreInfo
This commit is contained in:
commit
3fd3f36895
@ -11,7 +11,10 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Tests.Online
|
||||
{
|
||||
@ -84,6 +87,36 @@ namespace osu.Game.Tests.Online
|
||||
Assert.That(converted?.OverallDifficulty.Value, Is.EqualTo(11));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserialiseScoreInfoWithEmptyMods()
|
||||
{
|
||||
var score = new ScoreInfo { Ruleset = new OsuRuleset().RulesetInfo };
|
||||
|
||||
var deserialised = JsonConvert.DeserializeObject<ScoreInfo>(JsonConvert.SerializeObject(score));
|
||||
|
||||
if (deserialised != null)
|
||||
deserialised.Ruleset = new OsuRuleset().RulesetInfo;
|
||||
|
||||
Assert.That(deserialised?.Mods.Length, Is.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserialiseScoreInfoWithCustomModSetting()
|
||||
{
|
||||
var score = new ScoreInfo
|
||||
{
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
Mods = new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 2 } } }
|
||||
};
|
||||
|
||||
var deserialised = JsonConvert.DeserializeObject<ScoreInfo>(JsonConvert.SerializeObject(score));
|
||||
|
||||
if (deserialised != null)
|
||||
deserialised.Ruleset = new OsuRuleset().RulesetInfo;
|
||||
|
||||
Assert.That(((OsuModDoubleTime)deserialised?.Mods[0])?.SpeedChange.Value, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
private class TestRuleset : Ruleset
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[]
|
||||
|
@ -10,6 +10,7 @@ using Newtonsoft.Json.Converters;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -55,9 +56,10 @@ namespace osu.Game.Scoring
|
||||
[JsonIgnore]
|
||||
public virtual RulesetInfo Ruleset { get; set; }
|
||||
|
||||
private APIMod[] localAPIMods;
|
||||
private Mod[] mods;
|
||||
|
||||
[JsonProperty("mods")]
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
public Mod[] Mods
|
||||
{
|
||||
@ -66,43 +68,50 @@ namespace osu.Game.Scoring
|
||||
if (mods != null)
|
||||
return mods;
|
||||
|
||||
if (modsJson == null)
|
||||
if (localAPIMods == null)
|
||||
return Array.Empty<Mod>();
|
||||
|
||||
return getModsFromRuleset(JsonConvert.DeserializeObject<DeserializedMod[]>(modsJson));
|
||||
var rulesetInstance = Ruleset.CreateInstance();
|
||||
return apiMods.Select(m => m.ToMod(rulesetInstance)).ToArray();
|
||||
}
|
||||
set
|
||||
{
|
||||
modsJson = null;
|
||||
localAPIMods = null;
|
||||
mods = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Mod[] getModsFromRuleset(DeserializedMod[] mods) => Ruleset.CreateInstance().GetAllMods().Where(mod => mods.Any(d => d.Acronym == mod.Acronym)).ToArray();
|
||||
// Used for API serialisation/deserialisation.
|
||||
[JsonProperty("mods")]
|
||||
[NotMapped]
|
||||
private APIMod[] apiMods
|
||||
{
|
||||
get
|
||||
{
|
||||
if (localAPIMods != null)
|
||||
return localAPIMods;
|
||||
|
||||
private string modsJson;
|
||||
if (mods == null)
|
||||
return Array.Empty<APIMod>();
|
||||
|
||||
return localAPIMods = mods.Select(m => new APIMod(m)).ToArray();
|
||||
}
|
||||
set
|
||||
{
|
||||
localAPIMods = value;
|
||||
|
||||
// We potentially can't update this yet due to Ruleset being late-bound, so instead update on read as necessary.
|
||||
mods = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Used for database serialisation/deserialisation.
|
||||
[JsonIgnore]
|
||||
[Column("Mods")]
|
||||
public string ModsJson
|
||||
{
|
||||
get
|
||||
{
|
||||
if (modsJson != null)
|
||||
return modsJson;
|
||||
|
||||
if (mods == null)
|
||||
return null;
|
||||
|
||||
return modsJson = JsonConvert.SerializeObject(mods.Select(m => new DeserializedMod { Acronym = m.Acronym }));
|
||||
}
|
||||
set
|
||||
{
|
||||
modsJson = value;
|
||||
|
||||
// we potentially can't update this yet due to Ruleset being late-bound, so instead update on read as necessary.
|
||||
mods = null;
|
||||
}
|
||||
get => JsonConvert.SerializeObject(apiMods);
|
||||
set => apiMods = JsonConvert.DeserializeObject<APIMod[]>(value);
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
@ -251,14 +260,6 @@ namespace osu.Game.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
protected class DeserializedMod : IMod
|
||||
{
|
||||
public string Acronym { get; set; }
|
||||
|
||||
public bool Equals(IMod other) => Acronym == other?.Acronym;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{User} playing {Beatmap}";
|
||||
|
||||
public bool Equals(ScoreInfo other)
|
||||
|
Loading…
Reference in New Issue
Block a user