From e44751c275918bcf19da500e40dd57e7c1672591 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 6 Dec 2021 15:35:08 +0900 Subject: [PATCH] Add required properties for compatibility with existing code --- osu.Game/Scoring/ScoreInfo.cs | 133 ++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 1938271989..11cd26dd3c 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -3,11 +3,17 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using Newtonsoft.Json; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Models; +using osu.Game.Online.API; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Users; using Realms; @@ -80,5 +86,132 @@ namespace osu.Game.Scoring IBeatmapInfo IScoreInfo.Beatmap => Beatmap; IUser IScoreInfo.User => User; IEnumerable IHasNamedFiles.Files => Files; + + #region Properties required to make things work with existing usages + + private APIMod[]? localAPIMods; + + private Mod[]? mods; + + [Ignored] + public List HitEvents { get; set; } = new List(); + + public ScoreInfo DeepClone() + { + var clone = (ScoreInfo)MemberwiseClone(); + + clone.Statistics = new Dictionary(clone.Statistics); + + return clone; + } + + [Ignored] + public bool Passed { get; set; } = true; + + /// + /// The position of this score, starting at 1. + /// + [Ignored] + public int? Position { get; set; } // TODO: remove after all calls to `CreateScoreInfo` are gone. + + /// + /// Whether this represents a legacy (osu!stable) score. + /// + [Ignored] + public bool IsLegacyScore => Mods.OfType().Any(); + + [Ignored] + public Mod[] Mods + { + get + { + var rulesetInstance = Ruleset.CreateInstance(); + + Mod[] scoreMods = Array.Empty(); + + if (mods != null) + scoreMods = mods; + else if (localAPIMods != null) + scoreMods = APIMods.Select(m => m.ToMod(rulesetInstance)).ToArray(); + + return scoreMods; + } + set + { + localAPIMods = null; + mods = value; + } + } + + // Used for API serialisation/deserialisation. + [Ignored] + public APIMod[] APIMods + { + get + { + if (localAPIMods != null) + return localAPIMods; + + if (mods == null) + return Array.Empty(); + + 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. + [Column("Mods")] + public string ModsJson + { + get => JsonConvert.SerializeObject(APIMods); + set => APIMods = JsonConvert.DeserializeObject(value) ?? Array.Empty(); + } + + public IEnumerable GetStatisticsForDisplay() + { + foreach (var r in Ruleset.CreateInstance().GetHitResults()) + { + int value = Statistics.GetValueOrDefault(r.result); + + switch (r.result) + { + case HitResult.SmallTickHit: + { + int total = value + Statistics.GetValueOrDefault(HitResult.SmallTickMiss); + if (total > 0) + yield return new HitResultDisplayStatistic(r.result, value, total, r.displayName); + + break; + } + + case HitResult.LargeTickHit: + { + int total = value + Statistics.GetValueOrDefault(HitResult.LargeTickMiss); + if (total > 0) + yield return new HitResultDisplayStatistic(r.result, value, total, r.displayName); + + break; + } + + case HitResult.SmallTickMiss: + case HitResult.LargeTickMiss: + break; + + default: + yield return new HitResultDisplayStatistic(r.result, value, null, r.displayName); + + break; + } + } + } + + #endregion } }