From 9c1badd2e3771a36c2eea89d090c0db873991f71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jul 2019 15:42:54 +0900 Subject: [PATCH 1/3] Fix rulesets not matching in dictionary lookups due to missing GetHashCode implementation --- osu.Game/Rulesets/RulesetInfo.cs | 14 ++++++++++++++ osu.Game/Rulesets/RulesetStore.cs | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index ca331ec339..8eb2abec79 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; namespace osu.Game.Rulesets @@ -23,6 +24,19 @@ namespace osu.Game.Rulesets public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; + [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] + public override int GetHashCode() + { + unchecked + { + var hashCode = ID.HasValue ? ID.GetHashCode() : 0; + hashCode = (hashCode * 397) ^ (InstantiationInfo != null ? InstantiationInfo.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Available.GetHashCode(); + return hashCode; + } + } + public override string ToString() => $"{Name} ({ShortName}) ID: {ID}"; } } diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index fd42f96c92..2d8c9f5b49 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets public RulesetStore(IDatabaseContextFactory factory) : base(factory) { - AddMissingRulesets(); + addMissingRulesets(); } /// @@ -52,13 +52,13 @@ namespace osu.Game.Rulesets /// /// All available rulesets. /// - public IEnumerable AvailableRulesets; + public IEnumerable AvailableRulesets { get; private set; } private static Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args) => loaded_assemblies.Keys.FirstOrDefault(a => a.FullName == args.Name); private const string ruleset_library_prefix = "osu.Game.Rulesets"; - protected void AddMissingRulesets() + private void addMissingRulesets() { using (var usage = ContextFactory.GetForWrite()) { From d0c8aaba4e1f6442e188f7042deb4d8a0a5b5b3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jul 2019 15:50:50 +0900 Subject: [PATCH 2/3] Override basic equality function too --- osu.Game/Rulesets/RulesetInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 8eb2abec79..d9cff86265 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -24,6 +24,8 @@ namespace osu.Game.Rulesets public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; + public override bool Equals(object obj) => obj is RulesetInfo rulesetInfo && Equals(rulesetInfo); + [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] public override int GetHashCode() { From d4c1005c7e820bfa7d7cb1a5b1791e3ba1b0a5a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jul 2019 15:53:19 +0900 Subject: [PATCH 3/3] Fix incorrect comparison in line updating logic --- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 361ff62155..2a484fc122 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -248,7 +248,7 @@ namespace osu.Game } // Use first beatmap available for current ruleset, else switch ruleset. - var first = databasedSet.Beatmaps.Find(b => b.Ruleset == Ruleset.Value) ?? databasedSet.Beatmaps.First(); + var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); Ruleset.Value = first.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index f4272ab15c..bf0cd91321 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Toolbar { foreach (var tabItem in TabContainer) { - if (tabItem.Value == Current.Value) + if (tabItem.Value.Equals(Current.Value)) { ModeButtonLine.MoveToX(tabItem.DrawPosition.X, !hasInitialPosition ? 0 : 200, Easing.OutQuint); break; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0eeffda5eb..b3c3925a26 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -329,7 +329,7 @@ namespace osu.Game.Screens.Select if (this.IsCurrentScreen() && !Carousel.SelectBeatmap(e.NewValue?.BeatmapInfo, false)) // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch - if (e.NewValue?.BeatmapInfo?.Ruleset != null && e.NewValue.BeatmapInfo.Ruleset != decoupledRuleset.Value) + if (e.NewValue?.BeatmapInfo?.Ruleset != null && !e.NewValue.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) { Ruleset.Value = e.NewValue.BeatmapInfo.Ruleset; Carousel.SelectBeatmap(e.NewValue.BeatmapInfo);