From 6a4198d0d67b77294916ebd0767a1817bf30e2d4 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Wed, 4 Oct 2017 22:52:12 +0300 Subject: [PATCH] Initial EF Core commit --- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 2 +- .../Patterns/Legacy/PatternGenerator.cs | 2 +- .../ManiaDifficultyCalculator.cs | 2 +- .../Scoring/ManiaScoreProcessor.cs | 2 +- .../UI/ManiaRulesetContainer.cs | 10 +- .../Scoring/OsuScoreProcessor.cs | 2 +- .../UI/Cursor/GameplayCursor.cs | 2 +- .../Beatmaps/TaikoBeatmapConverter.cs | 12 +-- .../Scoring/TaikoScoreProcessor.cs | 4 +- .../Tests/TestCaseTaikoPlayfield.cs | 4 +- .../UI/TaikoRulesetContainer.cs | 2 +- .../Beatmaps/Formats/OsuLegacyDecoderTest.cs | 8 +- .../Beatmaps/IO/ImportBeatmapTest.cs | 16 +-- .../Beatmaps/IO/OszArchiveReaderTest.cs | 2 +- osu.Game.Tests/app.config | 4 + osu.Game.Tests/osu.Game.Tests.csproj | 9 -- osu.Game.Tests/packages.config | 2 - osu.Game/Beatmaps/Beatmap.cs | 2 +- osu.Game/Beatmaps/BeatmapDifficulty.cs | 7 +- osu.Game/Beatmaps/BeatmapInfo.cs | 67 +++++------- osu.Game/Beatmaps/BeatmapManager.cs | 63 +++++------ osu.Game/Beatmaps/BeatmapMetadata.cs | 9 +- osu.Game/Beatmaps/BeatmapOnlineInfo.cs | 4 + osu.Game/Beatmaps/BeatmapSetFileInfo.cs | 21 ++-- osu.Game/Beatmaps/BeatmapSetInfo.cs | 23 ++-- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 16 ++- osu.Game/Beatmaps/BeatmapStore.cs | 102 +++++++----------- osu.Game/Beatmaps/DifficultyCalculator.cs | 2 +- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 2 +- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 8 +- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 4 +- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 24 ++--- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 +- osu.Game/Database/DatabaseBackedStore.cs | 79 +------------- osu.Game/Database/DbContextBase.cs | 8 ++ osu.Game/Database/OsuDbContext.cs | 55 ++++++++++ osu.Game/Database/StoreVersion.cs | 15 --- osu.Game/IO/FileInfo.cs | 9 +- osu.Game/IO/FileStore.cs | 91 +++++----------- .../Input/Bindings/DatabasedKeyBinding.cs | 17 ++- .../DatabasedKeyBindingInputManager.cs | 2 +- osu.Game/Input/KeyBindingStore.cs | 55 ++++------ .../API/Requests/DownloadBeatmapSetRequest.cs | 2 +- .../API/Requests/GetBeatmapDetailsRequest.cs | 2 +- .../API/Requests/GetBeatmapSetsRequest.cs | 10 +- .../Online/API/Requests/GetScoresRequest.cs | 8 +- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 42 +++++--- osu.Game/Overlays/BeatmapSet/Header.cs | 4 +- osu.Game/Overlays/BeatmapSet/Info.cs | 4 +- osu.Game/Overlays/Direct/DirectGridPanel.cs | 10 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 10 +- osu.Game/Overlays/Direct/FilterControl.cs | 2 +- osu.Game/Overlays/DirectOverlay.cs | 12 +-- .../KeyBinding/KeyBindingsSubsection.cs | 2 +- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- osu.Game/Overlays/Music/PlaylistList.cs | 4 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 2 +- osu.Game/Overlays/MusicController.cs | 4 +- .../Overlays/Toolbar/ToolbarModeSelector.cs | 2 +- osu.Game/Rulesets/RulesetInfo.cs | 11 +- osu.Game/Rulesets/RulesetStore.cs | 91 +++++++++------- osu.Game/Rulesets/Scoring/ScoreStore.cs | 3 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 4 +- osu.Game/Screens/Menu/Intro.cs | 2 +- osu.Game/Screens/Multiplayer/DrawableRoom.cs | 6 +- osu.Game/Screens/Multiplayer/RoomInspector.cs | 8 +- osu.Game/Screens/Play/Player.cs | 6 +- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- osu.Game/Screens/Ranking/ResultsPageScore.cs | 6 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 12 +-- .../Screens/Select/BeatmapDeleteDialog.cs | 2 +- osu.Game/Screens/Select/BeatmapDetails.cs | 6 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +- .../Screens/Select/Details/AdvancedStats.cs | 12 +-- osu.Game/Screens/Select/FilterCriteria.cs | 10 +- .../Select/Leaderboards/Leaderboard.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 4 +- osu.Game/Storyboards/Storyboard.cs | 2 +- osu.Game/Tests/Platform/TestStorage.cs | 17 +-- .../Tests/Visual/TestCaseBeatmapDetails.cs | 16 +-- .../Tests/Visual/TestCaseBeatmapSetOverlay.cs | 44 ++++---- osu.Game/Tests/Visual/TestCaseDirect.cs | 52 ++++----- osu.Game/Tests/Visual/TestCaseDrawableRoom.cs | 12 +-- .../Tests/Visual/TestCasePlaySongSelect.cs | 34 +++--- osu.Game/Tests/Visual/TestCasePlayer.cs | 7 +- osu.Game/Tests/Visual/TestCaseResults.cs | 2 +- .../Tests/Visual/TestCaseRoomInspector.cs | 12 +-- .../Visual/TestCaseScrollingPlayfield.cs | 4 +- osu.Game/osu.Game.csproj | 100 ++++++++++++++--- osu.Game/packages.config | 43 +++++++- 93 files changed, 730 insertions(+), 708 deletions(-) create mode 100644 osu.Game/Database/DbContextBase.cs create mode 100644 osu.Game/Database/OsuDbContext.cs delete mode 100644 osu.Game/Database/StoreVersion.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d7c86e1f89..713ee6bb44 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { beatmap = original; - BeatmapDifficulty difficulty = original.BeatmapInfo.Difficulty; + BeatmapDifficulty difficulty = original.BeatmapInfo.BeatmapDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); random = new FastRandom(seed); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 20966a75f7..07a7c47f82 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy // The true distance, accounting for any repeats double distance = (distanceData?.Distance ?? 0) * repeatCount; // The velocity of the osu! hit object - calculated as the velocity of a slider - double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength; + double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BeatmapDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index a3173f9784..d3b743062d 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (drainTime == 0) drainTime = 10000; - BeatmapDifficulty difficulty = Beatmap.BeatmapInfo.Difficulty; + BeatmapDifficulty difficulty = Beatmap.BeatmapInfo.BeatmapDifficulty; conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + Beatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15; conversionDifficulty = Math.Min(conversionDifficulty.Value, 12); diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs index b98802db69..6a96bc0a7d 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs @@ -21,6 +21,6 @@ namespace osu.Game.Rulesets.Mania return 0; } - protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize))); + protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.BeatmapDifficulty.CircleSize))); } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index a200ba31e2..d6c076803d 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Mania.Scoring protected override void SimulateAutoplay(Beatmap beatmap) { - BeatmapDifficulty difficulty = beatmap.BeatmapInfo.Difficulty; + BeatmapDifficulty difficulty = beatmap.BeatmapInfo.BeatmapDifficulty; hpMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_min, hp_multiplier_mid, hp_multiplier_max); hpMissMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_miss_min, hp_multiplier_miss_mid, hp_multiplier_miss_max); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 3b49d81674..3858c60367 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -88,18 +88,18 @@ namespace osu.Game.Rulesets.Mania.UI protected override BeatmapConverter CreateBeatmapConverter() { if (IsForCurrentRuleset) - AvailableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); + AvailableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.BeatmapDifficulty.CircleSize)); else { float percentSliderOrSpinner = (float)WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count; if (percentSliderOrSpinner < 0.2) AvailableColumns = 7; - else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize) >= 5) - AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 5 ? 7 : 6; + else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.BeatmapDifficulty.CircleSize) >= 5) + AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.BeatmapDifficulty.OverallDifficulty) > 5 ? 7 : 6; else if (percentSliderOrSpinner > 0.6) - AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 4 ? 5 : 4; + AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.BeatmapDifficulty.OverallDifficulty) > 4 ? 5 : 4; else - AvailableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) + 1, 7)); + AvailableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.BeatmapDifficulty.OverallDifficulty) + 1, 7)); } return new ManiaBeatmapConverter(IsForCurrentRuleset, AvailableColumns); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 50239bf16c..b320940e67 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Scoring protected override void SimulateAutoplay(Beatmap beatmap) { - hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; + hpDrainRate = beatmap.BeatmapInfo.BeatmapDifficulty.DrainRate; foreach (var obj in beatmap.HitObjects) { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index adfc946f86..724a5f2b7a 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor if (autoCursorScale && beatmap.Value != null) { // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. - scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.Difficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY); + scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.BeatmapDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY); } cursorContainer.Scale = new Vector2(scale); diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 4f2707ff88..6a8f046800 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { // Rewrite the beatmap info to add the slider velocity multiplier BeatmapInfo info = original.BeatmapInfo.DeepClone(); - info.Difficulty.SliderMultiplier *= legacy_velocity_multiplier; + info.BeatmapDifficulty.SliderMultiplier *= legacy_velocity_multiplier; Beatmap converted = base.ConvertBeatmap(original); @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps double distance = distanceData.Distance * repeats * legacy_velocity_multiplier; // The velocity of the taiko hit object - calculated as the velocity of a drum roll - double taikoVelocity = taiko_base_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; + double taikoVelocity = taiko_base_distance * beatmap.BeatmapInfo.BeatmapDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; // The duration of the taiko hit object double taikoDuration = distance / taikoVelocity; @@ -103,12 +103,12 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps speedAdjustedBeatLength *= speedAdjustment; // The velocity of the osu! hit object - calculated as the velocity of a slider - double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; + double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BeatmapDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; // If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat - double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats); + double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.BeatmapDifficulty.SliderTickRate, taikoDuration / repeats); if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { @@ -151,13 +151,13 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Samples = obj.Samples, IsStrong = strong, Duration = taikoDuration, - TickRate = beatmap.BeatmapInfo.Difficulty.SliderTickRate == 3 ? 3 : 4, + TickRate = beatmap.BeatmapInfo.BeatmapDifficulty.SliderTickRate == 3 ? 3 : 4, }; } } else if (endTimeData != null) { - double hitMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.OverallDifficulty, 3, 5, 7.5) * swell_hit_multiplier; + double hitMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BeatmapDifficulty.OverallDifficulty, 3, 5, 7.5) * swell_hit_multiplier; yield return new Swell { diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index abdda9676f..9b208813dc 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -71,12 +71,12 @@ namespace osu.Game.Rulesets.Taiko.Scoring protected override void SimulateAutoplay(Beatmap beatmap) { - double hpMultiplierNormal = 1 / (hp_hit_great * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, 0.5, 0.75, 0.98)); + double hpMultiplierNormal = 1 / (hp_hit_great * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BeatmapDifficulty.DrainRate, 0.5, 0.75, 0.98)); hpIncreaseTick = hp_hit_tick; hpIncreaseGreat = hpMultiplierNormal * hp_hit_great; hpIncreaseGood = hpMultiplierNormal * hp_hit_good; - hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max); + hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BeatmapDifficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max); foreach (var obj in beatmap.HitObjects) { diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs index 79ee2945ad..8e93d52492 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs @@ -67,8 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Tests HitObjects = new List { new CentreHit() }, BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty(), - Metadata = new BeatmapMetadata + BeatmapDifficulty = new BeatmapDifficulty(), + BeatmapMetadata = new BeatmapMetadata { Artist = @"Unknown", Title = @"Sample Beatmap", diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index f0853aef0e..ca0a7e058f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI StartTime = time, }; - barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty); + barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BeatmapDifficulty); bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0; Playfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine)); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs index da3b448f74..4c71601eed 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs @@ -23,8 +23,8 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) { var beatmap = decoder.Decode(new StreamReader(stream)); - var meta = beatmap.BeatmapInfo.Metadata; - Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + var meta = beatmap.BeatmapInfo.BeatmapMetadata; + Assert.AreEqual(241526, meta.BeatmapSetOnlineInfoId); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(false, beatmapInfo.Countdown); Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); Assert.AreEqual(false, beatmapInfo.SpecialStyle); - Assert.IsTrue(beatmapInfo.RulesetID == 0); + Assert.IsTrue(beatmapInfo.RulesetInfoId == 0); Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks); Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard); } @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) { var beatmap = decoder.Decode(new StreamReader(stream)); - var difficulty = beatmap.BeatmapInfo.Difficulty; + var difficulty = beatmap.BeatmapInfo.BeatmapDifficulty; Assert.AreEqual(6.5f, difficulty.DrainRate); Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 35bebf2d4f..4b704fe242 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -111,7 +111,7 @@ namespace osu.Game.Tests.Beatmaps.IO var store = osu.Dependencies.Get(); - waitForOrAssert(() => (resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any(), + waitForOrAssert(() => (resultSets = store.QueryBeatmapSets(s => s.BeatmapSetOnlineInfoId == 241526)).Any(), @"BeatmapSet did not import to the database in allocated time.", timeout); //ensure we were stored to beatmap database backing... @@ -120,29 +120,29 @@ namespace osu.Game.Tests.Beatmaps.IO IEnumerable resultBeatmaps = null; //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. - waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, + waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.BeatmapSetOnlineInfoId == 241526 && s.BeatmapDifficultyId > 0)).Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout); - var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First(); + var set = store.QueryBeatmapSets(s => s.BeatmapSetOnlineInfoId == 241526).First(); Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(), $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count})."); foreach (BeatmapInfo b in resultBeatmaps) - Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); + Assert.IsTrue(set.Beatmaps.Any(c => c.BeatmapOnlineInfoId == b.BeatmapOnlineInfoId)); Assert.IsTrue(set.Beatmaps.Count > 0); - var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap; + var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetInfoId == 0))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Count > 0); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetInfoId == 1))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Count > 0); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetInfoId == 2))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Count > 0); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetInfoId == 3))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Count > 0); } diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 7a7a8a58bc..9ca3089944 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Beatmaps.IO using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) meta = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata; - Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + Assert.AreEqual(241526, meta.BeatmapSetOnlineInfoId); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); diff --git a/osu.Game.Tests/app.config b/osu.Game.Tests/app.config index faeaf001de..11af32e2cf 100644 --- a/osu.Game.Tests/app.config +++ b/osu.Game.Tests/app.config @@ -6,6 +6,10 @@ + + + + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8ebd38022e..e188c82e79 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -39,15 +39,6 @@ True - - $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll - - - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll - - - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll - diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index af47f642e3..b94c0c6e2d 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -6,6 +6,4 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - - \ No newline at end of file diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 458c2304f2..0d6cd6f49a 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps new Color4(121, 9, 13, 255) }; - public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata; + public BeatmapMetadata Metadata => BeatmapInfo?.BeatmapMetadata ?? BeatmapInfo?.BeatmapSetInfo?.BeatmapMetadata; /// /// The HitObjects this Beatmap contains. diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index 7c2294cae9..e354f3703e 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -1,7 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using SQLite.Net.Attributes; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; namespace osu.Game.Beatmaps { @@ -12,8 +13,8 @@ namespace osu.Game.Beatmaps /// public const float DEFAULT_DIFFICULTY = 5; - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } public float DrainRate { get; set; } = DEFAULT_DIFFICULTY; public float CircleSize { get; set; } = DEFAULT_DIFFICULTY; public float OverallDifficulty { get; set; } = DEFAULT_DIFFICULTY; diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 5e4e122fb5..565e1b97d6 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -2,49 +2,43 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; using osu.Game.IO.Serialization; using osu.Game.Rulesets; -using SQLite.Net.Attributes; -using SQLiteNetExtensions.Attributes; namespace osu.Game.Beatmaps { public class BeatmapInfo : IEquatable, IJsonSerializable { - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } //TODO: should be in database public int BeatmapVersion; - public int? OnlineBeatmapID { get; set; } + public int? BeatmapOnlineInfoId { get; set; } - public int? OnlineBeatmapSetID { get; set; } + public int? BeatmapSetOnlineInfoId { get; set; } - [ForeignKey(typeof(BeatmapSetInfo))] - public int BeatmapSetInfoID { get; set; } + [ForeignKey(nameof(BeatmapSetInfo))] + public int BeatmapSetInfoId { get; set; } + public BeatmapSetInfo BeatmapSetInfo { get; set; } - [ManyToOne] - public BeatmapSetInfo BeatmapSet { get; set; } + [ForeignKey(nameof(BeatmapMetadata))] + public int BeatmapMetadataId { get; set; } + public BeatmapMetadata BeatmapMetadata { get; set; } - [ForeignKey(typeof(BeatmapMetadata))] - public int BeatmapMetadataID { get; set; } + [ForeignKey(nameof(BeatmapDifficulty))] + public int BeatmapDifficultyId { get; set; } + public BeatmapDifficulty BeatmapDifficulty { get; set; } - [OneToOne(CascadeOperations = CascadeOperation.All)] - public BeatmapMetadata Metadata { get; set; } - - [ForeignKey(typeof(BeatmapDifficulty)), NotNull] - public int BaseDifficultyID { get; set; } - - [OneToOne(CascadeOperations = CascadeOperation.All)] - public BeatmapDifficulty Difficulty { get; set; } - - [Ignore] + [NotMapped] public BeatmapMetrics Metrics { get; set; } - [Ignore] + [NotMapped] public BeatmapOnlineInfo OnlineInfo { get; set; } public string Path { get; set; } @@ -57,7 +51,6 @@ namespace osu.Game.Beatmaps /// /// MD5 is kept for legacy support (matching against replays, osu-web-10 etc.). /// - [Indexed] [JsonProperty("file_md5")] public string MD5Hash { get; set; } @@ -67,11 +60,9 @@ namespace osu.Game.Beatmaps public float StackLeniency { get; set; } public bool SpecialStyle { get; set; } - [ForeignKey(typeof(RulesetInfo))] - public int RulesetID { get; set; } - - [OneToOne(CascadeOperations = CascadeOperation.CascadeRead)] - public RulesetInfo Ruleset { get; set; } + [ForeignKey(nameof(RulesetInfo))] + public int RulesetInfoId { get; set; } + public RulesetInfo RulesetInfo { get; set; } public bool LetterboxInBreaks { get; set; } public bool WidescreenStoryboard { get; set; } @@ -99,7 +90,7 @@ namespace osu.Game.Beatmaps } } - [Ignore] + [NotMapped] public int[] Bookmarks { get; set; } = new int[0]; public double DistanceSpacing { get; set; } @@ -114,20 +105,20 @@ namespace osu.Game.Beatmaps public bool Equals(BeatmapInfo other) { - if (ID == 0 || other?.ID == 0) + if (Id == 0 || other?.Id == 0) // one of the two BeatmapInfos we are comparing isn't sourced from a database. // fall back to reference equality. return ReferenceEquals(this, other); - return ID == other?.ID; + return Id == other?.Id; } - public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && - BeatmapSet.Hash == other.BeatmapSet.Hash && - (Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; + public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSetInfo != null && other.BeatmapSetInfo != null && + BeatmapSetInfo.Hash == other.BeatmapSetInfo.Hash && + (BeatmapMetadata ?? BeatmapSetInfo.BeatmapMetadata).AudioFile == (other.BeatmapMetadata ?? other.BeatmapSetInfo.BeatmapMetadata).AudioFile; - public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && - BeatmapSet.Hash == other.BeatmapSet.Hash && - (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; + public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSetInfo != null && other.BeatmapSetInfo != null && + BeatmapSetInfo.Hash == other.BeatmapSetInfo.Hash && + (BeatmapMetadata ?? BeatmapSetInfo.BeatmapMetadata).BackgroundFile == (other.BeatmapMetadata ?? other.BeatmapSetInfo.BeatmapMetadata).BackgroundFile; } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..3b023e34e4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -19,9 +19,9 @@ using osu.Game.IO; using osu.Game.IPC; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; -using SQLite.Net; using osu.Game.Online.API.Requests; using System.Threading.Tasks; +using osu.Game.Database; using osu.Game.Online.API; namespace osu.Game.Beatmaps @@ -60,7 +60,7 @@ namespace osu.Game.Beatmaps private readonly FileStore files; - private readonly SQLiteConnection connection; + private readonly OsuDbContext connection; private readonly RulesetStore rulesets; @@ -83,7 +83,7 @@ namespace osu.Game.Beatmaps /// public Func GetStableStorage { private get; set; } - public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null) + public BeatmapManager(Storage storage, FileStore files, OsuDbContext connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null) { beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); @@ -168,7 +168,7 @@ namespace osu.Game.Beatmaps // let's only allow one concurrent import at a time for now. lock (importLock) - connection.RunInTransaction(() => Import(set = importToStorage(archiveReader))); + Import(set = importToStorage(archiveReader)); return set; } @@ -180,7 +180,7 @@ namespace osu.Game.Beatmaps public void Import(BeatmapSetInfo beatmapSetInfo) { // If we have an ID then we already exist in the database. - if (beatmapSetInfo.ID != 0) return; + if (beatmapSetInfo.Id != 0) return; beatmaps.Add(beatmapSetInfo); } @@ -200,7 +200,7 @@ namespace osu.Game.Beatmaps ProgressNotification downloadNotification = new ProgressNotification { - Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}", + Text = $"Downloading {beatmapSetInfo.BeatmapMetadata.Artist} - {beatmapSetInfo.BeatmapMetadata.Title}", }; var request = new DownloadBeatmapSetRequest(beatmapSetInfo); @@ -251,7 +251,7 @@ namespace osu.Game.Beatmaps /// /// The whose download request is wanted. /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.BeatmapSetOnlineInfoId == beatmap.BeatmapSetOnlineInfoId); /// /// Delete a beatmap from the manager. @@ -302,14 +302,15 @@ namespace osu.Game.Beatmaps if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) return DefaultBeatmap; - lock (beatmaps) - beatmaps.Populate(beatmapInfo); + // TODO Include() + //lock (beatmaps) + // beatmaps.Populate(beatmapInfo); - if (beatmapInfo.BeatmapSet == null) - throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); + if (beatmapInfo.BeatmapSetInfo == null) + throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoId} is not in the local database."); - if (beatmapInfo.Metadata == null) - beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; + if (beatmapInfo.BeatmapMetadata == null) + beatmapInfo.BeatmapMetadata = beatmapInfo.BeatmapSetInfo.BeatmapMetadata; WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(files.Store, beatmapInfo); @@ -336,10 +337,11 @@ namespace osu.Game.Beatmaps { lock (beatmaps) { - BeatmapSetInfo set = beatmaps.Query().FirstOrDefault(query); + BeatmapSetInfo set = beatmaps.QueryBeatmapSet(query); - if (set != null) - beatmaps.Populate(set); + // TODO Include() + //if (set != null) + // beatmaps.Populate(set); return set; } @@ -350,7 +352,7 @@ namespace osu.Game.Beatmaps /// /// A stale instance. /// A fresh instance. - public BeatmapSetInfo Refresh(BeatmapSetInfo beatmapSet) => QueryBeatmapSet(s => s.ID == beatmapSet.ID); + public BeatmapSetInfo Refresh(BeatmapSetInfo beatmapSet) => QueryBeatmapSet(s => s.Id == beatmapSet.Id); /// /// Perform a lookup query on available s. @@ -359,7 +361,7 @@ namespace osu.Game.Beatmaps /// Results from the provided query. public List QueryBeatmapSets(Expression> query) { - return beatmaps.QueryAndPopulate(query); + return beatmaps.QueryBeatmapSets(query); } /// @@ -369,10 +371,11 @@ namespace osu.Game.Beatmaps /// The first result for the provided query, or null if no results were found. public BeatmapInfo QueryBeatmap(Func query) { - BeatmapInfo set = beatmaps.Query().FirstOrDefault(query); + BeatmapInfo set = beatmaps.QueryBeatmap(query); - if (set != null) - beatmaps.Populate(set); + // TODO Include() + //if (set != null) + // beatmaps.Populate(set); return set; } @@ -384,7 +387,7 @@ namespace osu.Game.Beatmaps /// Results from the provided query. public List QueryBeatmaps(Expression> query) { - lock (beatmaps) return beatmaps.QueryAndPopulate(query); + lock (beatmaps) return beatmaps.QueryBeatmaps(query); } /// @@ -424,7 +427,7 @@ namespace osu.Game.Beatmaps // check if this beatmap has already been imported and exit early if so. BeatmapSetInfo beatmapSet; lock (beatmaps) - beatmapSet = beatmaps.QueryAndPopulate(b => b.Hash == hash).FirstOrDefault(); + beatmapSet = beatmaps.QueryBeatmapSet(b => b.Hash == hash); if (beatmapSet != null) { @@ -459,11 +462,11 @@ namespace osu.Game.Beatmaps beatmapSet = new BeatmapSetInfo { - OnlineBeatmapSetID = metadata.OnlineBeatmapSetID, + BeatmapSetOnlineInfoId = metadata.BeatmapSetOnlineInfoId, Beatmaps = new List(), Hash = hash, Files = fileInfos, - Metadata = metadata + BeatmapMetadata = metadata }; var mapNames = reader.Filenames.Where(f => f.EndsWith(".osu")); @@ -485,11 +488,11 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash(); // TODO: Diff beatmap metadata with set metadata and leave it here if necessary - beatmap.BeatmapInfo.Metadata = null; + beatmap.BeatmapInfo.BeatmapMetadata = null; // TODO: this should be done in a better place once we actually need to dynamically update it. - beatmap.BeatmapInfo.Ruleset = rulesets.Query().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID); - beatmap.BeatmapInfo.StarDifficulty = rulesets.Query().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID)?.CreateInstance()?.CreateDifficultyCalculator(beatmap) + beatmap.BeatmapInfo.RulesetInfo = rulesets.QueryRulesetInfo(r => r.Id == beatmap.BeatmapInfo.RulesetInfoId); + beatmap.BeatmapInfo.StarDifficulty = rulesets.QueryRulesetInfo(r => r.Id == beatmap.BeatmapInfo.RulesetInfoId)?.CreateInstance()?.CreateDifficultyCalculator(beatmap) .Calculate() ?? 0; beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); @@ -509,9 +512,9 @@ namespace osu.Game.Beatmaps lock (beatmaps) { if (populate) - return beatmaps.QueryAndPopulate(b => !b.DeletePending).ToList(); + return beatmaps.QueryBeatmapSets(b => !b.DeletePending); else - return beatmaps.Query(b => !b.DeletePending).ToList(); + return beatmaps.QueryBeatmapSets(b => !b.DeletePending); } } diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index cc9a51b4e2..8266dc9161 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -1,18 +1,19 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; -using SQLite.Net.Attributes; namespace osu.Game.Beatmaps { public class BeatmapMetadata { - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } - public int? OnlineBeatmapSetID { get; set; } + public int? BeatmapSetOnlineInfoId { get; set; } public string Title { get; set; } public string TitleUnicode { get; set; } diff --git a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs index 399cabda99..2264a4fc1a 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel.DataAnnotations.Schema; using Newtonsoft.Json; namespace osu.Game.Beatmaps @@ -10,6 +11,9 @@ namespace osu.Game.Beatmaps /// public class BeatmapOnlineInfo { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + /// /// The length in milliseconds of this beatmap's song. /// diff --git a/osu.Game/Beatmaps/BeatmapSetFileInfo.cs b/osu.Game/Beatmaps/BeatmapSetFileInfo.cs index a05362b32d..aec87296a0 100644 --- a/osu.Game/Beatmaps/BeatmapSetFileInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetFileInfo.cs @@ -1,27 +1,26 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using osu.Game.IO; -using SQLite.Net.Attributes; -using SQLiteNetExtensions.Attributes; namespace osu.Game.Beatmaps { public class BeatmapSetFileInfo { - [PrimaryKey, AutoIncrement] + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } - [ForeignKey(typeof(BeatmapSetInfo)), NotNull] - public int BeatmapSetInfoID { get; set; } + [ForeignKey(nameof(BeatmapSetInfo))] + public int BeatmapSetInfoId { get; set; } + public BeatmapSetInfo BeatmapSetInfo { get; set; } - [ForeignKey(typeof(FileInfo)), NotNull] - public int FileInfoID { get; set; } - - [OneToOne(CascadeOperations = CascadeOperation.CascadeRead)] + [ForeignKey(nameof(FileInfo))] + public int FileInfoId { get; set; } public FileInfo FileInfo { get; set; } - [NotNull] + [Required] public string Filename { get; set; } } -} \ No newline at end of file +} diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index f47affcab8..9be00152c3 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -2,41 +2,36 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; -using SQLite.Net.Attributes; -using SQLiteNetExtensions.Attributes; namespace osu.Game.Beatmaps { public class BeatmapSetInfo { - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } - public int? OnlineBeatmapSetID { get; set; } + public int? BeatmapSetOnlineInfoId { get; set; } - [OneToOne(CascadeOperations = CascadeOperation.All)] - public BeatmapMetadata Metadata { get; set; } + [ForeignKey(nameof(BeatmapMetadata))] + public int BeatmapMetadataId { get; set; } + public BeatmapMetadata BeatmapMetadata { get; set; } - [NotNull, ForeignKey(typeof(BeatmapMetadata))] - public int BeatmapMetadataID { get; set; } - - [OneToMany(CascadeOperations = CascadeOperation.All)] public List Beatmaps { get; set; } - [Ignore] + [NotMapped] public BeatmapSetOnlineInfo OnlineInfo { get; set; } public double MaxStarDifficulty => Beatmaps.Max(b => b.StarDifficulty); - [Indexed] public bool DeletePending { get; set; } public string Hash { get; set; } public string StoryboardFile => Files.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename; - [OneToMany(CascadeOperations = CascadeOperation.All)] public List Files { get; set; } public bool Protected { get; set; } diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 6b59f0f298..c33ee66dac 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -2,6 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using Newtonsoft.Json; using osu.Game.Users; @@ -12,11 +15,19 @@ namespace osu.Game.Beatmaps /// public class BeatmapSetOnlineInfo { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + /// /// The author of the beatmaps in this set. /// public User Author; + public int BeatmapSetInfoId { get; set; } + public BeatmapSetInfo BeatmapSetInfo { get; set; } + + public List Beatmaps { get; set; } + /// /// The date this beatmap set was submitted to the online listing. /// @@ -35,7 +46,7 @@ namespace osu.Game.Beatmaps /// /// The different sizes of cover art for this beatmap set. /// - [JsonProperty(@"covers")] + [Required, JsonProperty(@"covers")] public BeatmapSetOnlineCovers Covers { get; set; } /// @@ -64,6 +75,9 @@ namespace osu.Game.Beatmaps public class BeatmapSetOnlineCovers { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public string CoverLowRes { get; set; } [JsonProperty(@"cover@2x")] diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 0f2d8cffa6..ece006a818 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -2,9 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; using osu.Game.Database; -using SQLite.Net; -using SQLiteNetExtensions.Extensions; namespace osu.Game.Beatmaps { @@ -19,13 +21,7 @@ namespace osu.Game.Beatmaps public event Action BeatmapHidden; public event Action BeatmapRestored; - /// - /// The current version of this store. Used for migrations (see ). - /// The initial version is 1. - /// - protected override int StoreVersion => 4; - - public BeatmapStore(SQLiteConnection connection) + public BeatmapStore(OsuDbContext connection) : base(connection) { } @@ -42,18 +38,13 @@ namespace osu.Game.Beatmaps { if (reset) { - Connection.DropTable(); - Connection.DropTable(); - Connection.DropTable(); - Connection.DropTable(); - Connection.DropTable(); + // https://stackoverflow.com/a/10450893 + Connection.Database.ExecuteSqlCommand("DELETE FROM BeatmapMetadata"); + Connection.Database.ExecuteSqlCommand("DELETE FROM BeatmapDifficulty"); + Connection.Database.ExecuteSqlCommand("DELETE FROM BeatmapSetInfo"); + Connection.Database.ExecuteSqlCommand("DELETE FROM BeatmapSetFileInfo"); + Connection.Database.ExecuteSqlCommand("DELETE FROM BeatmapInfo"); } - - Connection.CreateTable(); - Connection.CreateTable(); - Connection.CreateTable(); - Connection.CreateTable(); - Connection.CreateTable(); } protected override void StartupTasks() @@ -62,46 +53,14 @@ namespace osu.Game.Beatmaps cleanupPendingDeletions(); } - /// - /// Perform migrations between two store versions. - /// - /// The current store version. This will be zero on a fresh database initialisation. - /// The target version which we are migrating to (equal to the current ). - protected override void PerformMigration(int currentVersion, int targetVersion) - { - base.PerformMigration(currentVersion, targetVersion); - - while (currentVersion++ < targetVersion) - { - switch (currentVersion) - { - case 1: - case 2: - // cannot migrate; breaking underlying changes. - Reset(); - break; - case 3: - // Added MD5Hash column to BeatmapInfo - Connection.MigrateTable(); - break; - case 4: - // Added Hidden column to BeatmapInfo - Connection.MigrateTable(); - break; - } - } - } - /// /// Add a to the database. /// /// The beatmap to add. public void Add(BeatmapSetInfo beatmapSet) { - Connection.RunInTransaction(() => - { - Connection.InsertOrReplaceWithChildren(beatmapSet, true); - }); + Connection.BeatmapSetInfo.Update(beatmapSet); + Connection.SaveChanges(); BeatmapSetAdded?.Invoke(beatmapSet); } @@ -116,7 +75,8 @@ namespace osu.Game.Beatmaps if (beatmapSet.DeletePending) return false; beatmapSet.DeletePending = true; - Connection.Update(beatmapSet); + Connection.BeatmapSetInfo.Remove(beatmapSet); + Connection.SaveChanges(); BeatmapSetRemoved?.Invoke(beatmapSet); return true; @@ -132,7 +92,7 @@ namespace osu.Game.Beatmaps if (!beatmapSet.DeletePending) return false; beatmapSet.DeletePending = false; - Connection.Update(beatmapSet); + Connection.BeatmapSetInfo.Update(beatmapSet); BeatmapSetAdded?.Invoke(beatmapSet); return true; @@ -148,7 +108,7 @@ namespace osu.Game.Beatmaps if (beatmap.Hidden) return false; beatmap.Hidden = true; - Connection.Update(beatmap); + Connection.BeatmapInfo.Update(beatmap); BeatmapHidden?.Invoke(beatmap); return true; @@ -164,7 +124,7 @@ namespace osu.Game.Beatmaps if (!beatmap.Hidden) return false; beatmap.Hidden = false; - Connection.Update(beatmap); + Connection.BeatmapInfo.Update(beatmap); BeatmapRestored?.Invoke(beatmap); return true; @@ -172,11 +132,27 @@ namespace osu.Game.Beatmaps private void cleanupPendingDeletions() { - Connection.RunInTransaction(() => - { - foreach (var b in QueryAndPopulate(b => b.DeletePending && !b.Protected)) - Connection.Delete(b, true); - }); + Connection.BeatmapSetInfo.RemoveRange(Connection.BeatmapSetInfo.Where(b => b.DeletePending && !b.Protected)); + } + + public BeatmapSetInfo QueryBeatmapSet(Func query) + { + return Connection.BeatmapSetInfo.FirstOrDefault(query); + } + + public List QueryBeatmapSets(Expression> query) + { + return Connection.BeatmapSetInfo.Where(query).ToList(); + } + + public BeatmapInfo QueryBeatmap(Func query) + { + return Connection.BeatmapInfo.FirstOrDefault(query); + } + + public List QueryBeatmaps(Expression> query) + { + return Connection.BeatmapInfo.Where(query).ToList(); } } } diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 60cbf0ac61..1cd0516b0e 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects; foreach (var h in Objects) - h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.Difficulty); + h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BeatmapDifficulty); PreprocessHitObjects(); } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index e216f1b83e..dfff949fe9 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -135,7 +135,7 @@ namespace osu.Game.Beatmaps.Drawables new OsuSpriteText { Font = @"Exo2.0-MediumItalic", - Text = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author}", + Text = $"{(beatmap.BeatmapMetadata ?? beatmap.BeatmapSetInfo.BeatmapMetadata).Author}", TextSize = 16, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 42db025a40..2981b3b053 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -35,7 +35,7 @@ namespace osu.Game.Beatmaps.Drawables new ConstrainedIconContainer { RelativeSizeAxes = Axes.Both, - Icon = beatmap.Ruleset.CreateInstance().CreateIcon() + Icon = beatmap.RulesetInfo.CreateInstance().CreateIcon() } }; } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index d8cd58d939..3746a1fabe 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -18,14 +18,14 @@ namespace osu.Game.Beatmaps public DummyWorkingBeatmap(OsuGameBase game) : base(new BeatmapInfo { - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Artist = "please load a beatmap!", Title = "no beatmaps available!", Author = "no one", }, - BeatmapSet = new BeatmapSetInfo(), - Difficulty = new BeatmapDifficulty + BeatmapSetInfo = new BeatmapSetInfo(), + BeatmapDifficulty = new BeatmapDifficulty { DrainRate = 0, CircleSize = 0, @@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps SliderMultiplier = 0, SliderTickRate = 0, }, - Ruleset = new DummyRulesetInfo() + RulesetInfo = new DummyRulesetInfo() }) { this.game = game; diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 81695c3b5a..9d97ca8602 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -48,8 +48,8 @@ namespace osu.Game.Beatmaps.Formats { BeatmapInfo = new BeatmapInfo { - Metadata = new BeatmapMetadata(), - Difficulty = new BeatmapDifficulty(), + BeatmapMetadata = new BeatmapMetadata(), + BeatmapDifficulty = new BeatmapDifficulty(), }, }; diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 21fee0f465..9d6586ef26 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -72,7 +72,7 @@ namespace osu.Game.Beatmaps.Formats { var pair = splitKeyVal(line, ':'); - var metadata = beatmap.BeatmapInfo.Metadata; + var metadata = beatmap.BeatmapInfo.BeatmapMetadata; switch (pair.Key) { case @"AudioFilename": @@ -97,9 +97,9 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.StackLeniency = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; case @"Mode": - beatmap.BeatmapInfo.RulesetID = int.Parse(pair.Value); + beatmap.BeatmapInfo.RulesetInfoId = int.Parse(pair.Value); - switch (beatmap.BeatmapInfo.RulesetID) + switch (beatmap.BeatmapInfo.RulesetInfoId) { case 0: parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(); @@ -155,7 +155,7 @@ namespace osu.Game.Beatmaps.Formats { var pair = splitKeyVal(line, ':'); - var metadata = beatmap.BeatmapInfo.Metadata; + var metadata = beatmap.BeatmapInfo.BeatmapMetadata; switch (pair.Key) { case @"Title": @@ -177,17 +177,17 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.Version = pair.Value; break; case @"Source": - beatmap.BeatmapInfo.Metadata.Source = pair.Value; + beatmap.BeatmapInfo.BeatmapMetadata.Source = pair.Value; break; case @"Tags": - beatmap.BeatmapInfo.Metadata.Tags = pair.Value; + beatmap.BeatmapInfo.BeatmapMetadata.Tags = pair.Value; break; case @"BeatmapID": - beatmap.BeatmapInfo.OnlineBeatmapID = int.Parse(pair.Value); + beatmap.BeatmapInfo.BeatmapOnlineInfoId = int.Parse(pair.Value); break; case @"BeatmapSetID": - beatmap.BeatmapInfo.OnlineBeatmapSetID = int.Parse(pair.Value); - metadata.OnlineBeatmapSetID = int.Parse(pair.Value); + beatmap.BeatmapInfo.BeatmapSetOnlineInfoId = int.Parse(pair.Value); + metadata.BeatmapSetOnlineInfoId = int.Parse(pair.Value); break; } } @@ -196,7 +196,7 @@ namespace osu.Game.Beatmaps.Formats { var pair = splitKeyVal(line, ':'); - var difficulty = beatmap.BeatmapInfo.Difficulty; + var difficulty = beatmap.BeatmapInfo.BeatmapDifficulty; switch (pair.Key) { case @"HPDrainRate": @@ -270,7 +270,7 @@ namespace osu.Game.Beatmaps.Formats string filename = split[2].Trim('"'); if (type == EventType.Background) - beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; + beatmap.BeatmapInfo.BeatmapMetadata.BackgroundFile = filename; break; case EventType.Break: @@ -674,7 +674,7 @@ namespace osu.Game.Beatmaps.Formats } foreach (var hitObject in beatmap.HitObjects) - hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.Difficulty); + hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BeatmapDifficulty); } private KeyValuePair splitKeyVal(string line, char separator) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 277846ee80..4b50e50efe 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -24,8 +24,8 @@ namespace osu.Game.Beatmaps protected WorkingBeatmap(BeatmapInfo beatmapInfo) { BeatmapInfo = beatmapInfo; - BeatmapSetInfo = beatmapInfo.BeatmapSet; - Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); + BeatmapSetInfo = beatmapInfo.BeatmapSetInfo; + Metadata = beatmapInfo.BeatmapMetadata ?? BeatmapSetInfo?.BeatmapMetadata ?? new BeatmapMetadata(); Mods.ValueChanged += mods => applyRateAdjustments(); } diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index d8e2e35bd7..f4b6a866dc 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -2,27 +2,23 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; using osu.Framework.Logging; using osu.Framework.Platform; -using SQLite.Net; -using SQLiteNetExtensions.Extensions; namespace osu.Game.Database { public abstract class DatabaseBackedStore { protected readonly Storage Storage; - protected readonly SQLiteConnection Connection; + protected readonly OsuDbContext Connection; - protected virtual int StoreVersion => 1; - - protected DatabaseBackedStore(SQLiteConnection connection, Storage storage = null) + protected DatabaseBackedStore(OsuDbContext connection, Storage storage = null) { Storage = storage; Connection = connection; + Connection.Database.SetCommandTimeout(new TimeSpan(TimeSpan.TicksPerSecond * 10)); try { @@ -33,36 +29,6 @@ namespace osu.Game.Database Logger.Error(e, $@"Failed to initialise the {GetType()}! Trying again with a clean database..."); Prepare(true); } - - checkMigrations(); - } - - private void checkMigrations() - { - var storeName = GetType().Name; - - var reportedVersion = Connection.Table().Where(s => s.StoreName == storeName).FirstOrDefault() ?? new StoreVersion - { - StoreName = storeName, - Version = 0 - }; - - if (reportedVersion.Version != StoreVersion) - PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion); - - Connection.InsertOrReplace(reportedVersion); - - StartupTasks(); - } - - /// - /// Called when the database version of this store doesn't match the local version. - /// Any manual migration operations should be performed in this. - /// - /// The current store version. This will be zero on a fresh database initialisation. - /// The target version which we are migrating to (equal to the current ). - protected virtual void PerformMigration(int currentVersion, int targetVersion) - { } /// @@ -83,43 +49,6 @@ namespace osu.Game.Database /// public void Reset() => Prepare(true); - - public TableQuery Query(Expression> filter = null) where T : class - { - checkType(typeof(T)); - - var query = Connection.Table(); - - if (filter != null) - query = query.Where(filter); - - return query; - } - - /// - /// Query and populate results. - /// - /// An filter to refine results. - /// - public List QueryAndPopulate(Expression> filter) - where T : class - { - checkType(typeof(T)); - - return Connection.GetAllWithChildren(filter, true); - } - - /// - /// Populate a database-backed item. - /// - /// - /// Whether population should recurse beyond a single level. - public void Populate(T item, bool recursive = true) - { - checkType(item.GetType()); - Connection.GetChildren(item, recursive); - } - private void checkType(Type type) { if (!ValidTypes.Contains(type)) diff --git a/osu.Game/Database/DbContextBase.cs b/osu.Game/Database/DbContextBase.cs new file mode 100644 index 0000000000..93f4ac4c23 --- /dev/null +++ b/osu.Game/Database/DbContextBase.cs @@ -0,0 +1,8 @@ +using Microsoft.EntityFrameworkCore; + +namespace osu.Game.Database +{ + public abstract class DbContextBase:DbContext + { + } +} diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs new file mode 100644 index 0000000000..41ae0711f4 --- /dev/null +++ b/osu.Game/Database/OsuDbContext.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore; +using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; +using osu.Game.IO; +using osu.Game.Rulesets; + +namespace osu.Game.Database +{ + public class OsuDbContext : DbContext + { + private readonly string connectionString; + + public OsuDbContext() + { + connectionString = "DataSource=:memory:"; + } + + public OsuDbContext(string connectionString) + { + this.connectionString = connectionString; + } + + public DbSet BeatmapMetadata { get; set; } + public DbSet BeatmapDifficulty { get; set; } + public DbSet BeatmapInfo { get; set; } + public DbSet BeatmapSetInfo { get; set; } + public DbSet BeatmapSetFileInfo { get; set; } + public DbSet DatabasedKeyBinding { get; set; } + public DbSet FileInfo { get; set; } + public DbSet RulesetInfo { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + optionsBuilder.UseSqlite(connectionString); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity().HasIndex(b => b.MD5Hash); + modelBuilder.Entity().HasIndex(b => b.DeletePending); + modelBuilder.Entity().HasIndex(b => b.Variant); + modelBuilder.Entity().HasIndex(b => b.IntAction); + modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); + modelBuilder.Entity().HasIndex(b => b.ReferenceCount); + modelBuilder.Entity().HasIndex(b => b.Name).IsUnique(); + modelBuilder.Entity().HasIndex(b => b.InstantiationInfo).IsUnique(); + modelBuilder.Entity().HasIndex(b => b.Available); + //modelBuilder.Entity().HasOne(b => b.BeatmapSetOnlineInfo).WithOne(bs => bs.BeatmapMetadata).OnDelete(DeleteBehavior.SetNull); + //modelBuilder.Entity().HasOne(b => b.BeatmapSetOnlineInfo).WithOne(bs => bs.BeatmapSetInfo).OnDelete(DeleteBehavior.SetNull); + //modelBuilder.Entity().HasOne(b => b.BeatmapSetOnlineInfo).WithMany(bs => bs.Beatmaps).OnDelete(DeleteBehavior.SetNull); + } + } +} diff --git a/osu.Game/Database/StoreVersion.cs b/osu.Game/Database/StoreVersion.cs deleted file mode 100644 index 00314875a6..0000000000 --- a/osu.Game/Database/StoreVersion.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using SQLite.Net.Attributes; - -namespace osu.Game.Database -{ - public class StoreVersion - { - [PrimaryKey] - public string StoreName { get; set; } - - public int Version { get; set; } - } -} diff --git a/osu.Game/IO/FileInfo.cs b/osu.Game/IO/FileInfo.cs index 367fd68f7b..7ba75eeb0c 100644 --- a/osu.Game/IO/FileInfo.cs +++ b/osu.Game/IO/FileInfo.cs @@ -1,22 +1,21 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.IO; -using SQLite.Net.Attributes; namespace osu.Game.IO { public class FileInfo { - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } - [Indexed(Unique = true)] public string Hash { get; set; } public string StoragePath => Path.Combine(Hash.Remove(1), Hash.Remove(2), Hash); - [Indexed] public int ReferenceCount { get; set; } } } diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index c3d8c1df46..416b6c2989 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -4,12 +4,12 @@ using System; using System.IO; using System.Linq; +using Microsoft.EntityFrameworkCore; using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Database; -using SQLite.Net; namespace osu.Game.IO { @@ -22,9 +22,7 @@ namespace osu.Game.IO public readonly ResourceStore Store; - protected override int StoreVersion => 2; - - public FileStore(SQLiteConnection connection, Storage storage) : base(connection, storage) + public FileStore(OsuDbContext connection, Storage storage) : base(connection, storage) { Store = new NamespacedResourceStore(new StorageBackedResourceStore(storage), prefix); } @@ -44,10 +42,8 @@ namespace osu.Game.IO if (Storage.ExistsDirectory(prefix)) Storage.DeleteDirectory(prefix); - Connection.DropTable(); + Connection.Database.ExecuteSqlCommand("DELETE FROM FileInfo"); } - - Connection.CreateTable(); } protected override void StartupTasks() @@ -56,33 +52,11 @@ namespace osu.Game.IO deletePending(); } - /// - /// Perform migrations between two store versions. - /// - /// The current store version. This will be zero on a fresh database initialisation. - /// The target version which we are migrating to (equal to the current ). - protected override void PerformMigration(int currentVersion, int targetVersion) - { - base.PerformMigration(currentVersion, targetVersion); - - while (currentVersion++ < targetVersion) - { - switch (currentVersion) - { - case 1: - case 2: - // cannot migrate; breaking underlying changes. - Reset(); - break; - } - } - } - public FileInfo Add(Stream data, bool reference = true) { string hash = data.ComputeSHA2Hash(); - var existing = Connection.Table().Where(f => f.Hash == hash).FirstOrDefault(); + var existing = Connection.FileInfo.Where(f => f.Hash == hash).FirstOrDefault(); var info = existing ?? new FileInfo { Hash = hash }; @@ -100,61 +74,54 @@ namespace osu.Game.IO } if (existing == null) - Connection.Insert(info); + Connection.FileInfo.Add(info); if (reference || existing == null) Reference(info); + Connection.SaveChanges(); return info; } public void Reference(params FileInfo[] files) { - Connection.RunInTransaction(() => + var incrementedFiles = files.GroupBy(f => f.Id).Select(f => { - var incrementedFiles = files.GroupBy(f => f.ID).Select(f => - { - var accurateRefCount = Connection.Get(f.First().ID); - accurateRefCount.ReferenceCount += f.Count(); - return accurateRefCount; - }); - - Connection.UpdateAll(incrementedFiles); + var accurateRefCount = Connection.Find(f.First().Id); + accurateRefCount.ReferenceCount += f.Count(); + return accurateRefCount; }); + //Connection.FileInfo.UpdateRange(incrementedFiles); + Connection.SaveChanges(); } public void Dereference(params FileInfo[] files) { - Connection.RunInTransaction(() => + var incrementedFiles = files.GroupBy(f => f.Id).Select(f => { - var incrementedFiles = files.GroupBy(f => f.ID).Select(f => - { - var accurateRefCount = Connection.Get(f.First().ID); - accurateRefCount.ReferenceCount -= f.Count(); - return accurateRefCount; - }); - - Connection.UpdateAll(incrementedFiles); + var accurateRefCount = Connection.Find(f.First().Id); + accurateRefCount.ReferenceCount -= f.Count(); + return accurateRefCount; }); + + //Connection.FileInfo.UpdateRange(incrementedFiles); + Connection.SaveChanges(); } private void deletePending() { - Connection.RunInTransaction(() => + foreach (var f in Connection.FileInfo.Where(f => f.ReferenceCount < 1)) { - foreach (var f in Query(f => f.ReferenceCount < 1)) + try { - try - { - Storage.Delete(Path.Combine(prefix, f.StoragePath)); - Connection.Delete(f); - } - catch (Exception e) - { - Logger.Error(e, $@"Could not delete beatmap {f}"); - } + Storage.Delete(Path.Combine(prefix, f.StoragePath)); + Connection.FileInfo.Remove(f); } - }); + catch (Exception e) + { + Logger.Error(e, $@"Could not delete beatmap {f}"); + } + } } } -} \ No newline at end of file +} diff --git a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs index cbf74d6984..73a8e117d3 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs @@ -1,23 +1,23 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using osu.Framework.Input.Bindings; using osu.Game.Rulesets; -using SQLite.Net.Attributes; -using SQLiteNetExtensions.Attributes; namespace osu.Game.Input.Bindings { [Table("KeyBinding")] public class DatabasedKeyBinding : KeyBinding { - [PrimaryKey, AutoIncrement] - public int ID { get; set; } + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } - [ForeignKey(typeof(RulesetInfo))] - public int? RulesetID { get; set; } + [ForeignKey(nameof(RulesetInfo))] + public int? RulesetInfoId { get; set; } + public RulesetInfo RulesetInfo; - [Indexed] public int? Variant { get; set; } [Column("Keys")] @@ -27,7 +27,6 @@ namespace osu.Game.Input.Bindings private set { KeyCombination = value; } } - [Indexed] [Column("Action")] public int IntAction { @@ -35,4 +34,4 @@ namespace osu.Game.Input.Bindings set { Action = value; } } } -} \ No newline at end of file +} diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs index 0a4fcf4389..41a2f54277 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Input.Bindings protected override void ReloadMappings() { - KeyBindings = store.Query(ruleset?.ID, variant); + KeyBindings = store.Query(ruleset?.Id, variant); } } } \ No newline at end of file diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index c5ba1683dd..3157bee6a7 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -4,78 +4,54 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.EntityFrameworkCore; using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Input.Bindings; using osu.Game.Rulesets; -using SQLite.Net; namespace osu.Game.Input { public class KeyBindingStore : DatabaseBackedStore { - public KeyBindingStore(SQLiteConnection connection, RulesetStore rulesets, Storage storage = null) + public KeyBindingStore(OsuDbContext connection, RulesetStore rulesets, Storage storage = null) : base(connection, storage) { foreach (var info in rulesets.AllRulesets) { var ruleset = info.CreateInstance(); foreach (var variant in ruleset.AvailableVariants) - insertDefaults(ruleset.GetDefaultKeyBindings(variant), info.ID, variant); + insertDefaults(ruleset.GetDefaultKeyBindings(variant), info.Id, variant); } } public void Register(KeyBindingInputManager manager) => insertDefaults(manager.DefaultKeyBindings); - protected override int StoreVersion => 3; - - protected override void PerformMigration(int currentVersion, int targetVersion) - { - base.PerformMigration(currentVersion, targetVersion); - - while (currentVersion++ < targetVersion) - { - switch (currentVersion) - { - case 1: - case 2: - case 3: - // cannot migrate; breaking underlying changes. - Reset(); - break; - } - } - } - protected override void Prepare(bool reset = false) { - if (reset) - Connection.DropTable(); - - Connection.CreateTable(); + Connection.Database.ExecuteSqlCommand("DELETE FROM KeyBinding"); } private void insertDefaults(IEnumerable defaults, int? rulesetId = null, int? variant = null) { - var query = Query(rulesetId, variant); - // compare counts in database vs defaults foreach (var group in defaults.GroupBy(k => k.Action)) { int count; - while (group.Count() > (count = query.Count(k => (int)k.Action == (int)group.Key))) + while (group.Count() > (count = Query(rulesetId, variant).Count(k => (int)k.Action == (int)group.Key))) { var insertable = group.Skip(count).First(); // insert any defaults which are missing. - Connection.Insert(new DatabasedKeyBinding + Connection.DatabasedKeyBinding.Add(new DatabasedKeyBinding { KeyCombination = insertable.KeyCombination, Action = insertable.Action, - RulesetID = rulesetId, + RulesetInfoId = rulesetId, Variant = variant }); + Connection.SaveChanges(); } } } @@ -85,9 +61,18 @@ namespace osu.Game.Input typeof(DatabasedKeyBinding) }; - public IEnumerable Query(int? rulesetId = null, int? variant = null) => - Query(b => b.RulesetID == rulesetId && b.Variant == variant); + public List Query(int? rulesetId = null, int? variant = null) => + new List(Connection.DatabasedKeyBinding.Where(b => b.RulesetInfoId == rulesetId && b.Variant == variant)); - public void Update(KeyBinding keyBinding) => Connection.Update(keyBinding); + public void Update(KeyBinding keyBinding) + { + var dbKeyBinding = Connection.DatabasedKeyBinding.FirstOrDefault(kb => kb.ToString() == keyBinding.ToString()); + if (dbKeyBinding!=null) + { + dbKeyBinding.KeyCombination = keyBinding.KeyCombination; + dbKeyBinding.Action = keyBinding.Action; + } + Connection.SaveChanges(); + } } } diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 5a9f609bca..f8e20d1e9f 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -19,6 +19,6 @@ namespace osu.Game.Online.API.Requests Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total); } - protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download"; + protected override string Target => $@"beatmapsets/{BeatmapSet.BeatmapSetOnlineInfoId}/download"; } } diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs index 934ef7ffa2..233e16beb1 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.API.Requests { private readonly BeatmapInfo beatmap; - private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; + private string lookupString => beatmap.BeatmapOnlineInfoId > 0 ? beatmap.BeatmapOnlineInfoId.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; public GetBeatmapDetailsRequest(BeatmapInfo beatmap) { diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index 470e13ea7b..37d7a5e2d6 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -30,7 +30,7 @@ namespace osu.Game.Online.API.Requests this.direction = direction; } - protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; + protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.Id ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; } public class GetBeatmapSetsResponse : BeatmapMetadata @@ -63,8 +63,8 @@ namespace osu.Game.Online.API.Requests { return new BeatmapSetInfo { - OnlineBeatmapSetID = onlineId, - Metadata = this, + BeatmapSetOnlineInfoId = onlineId, + BeatmapMetadata = this, OnlineInfo = new BeatmapSetOnlineInfo { Author = new User @@ -99,8 +99,8 @@ namespace osu.Game.Online.API.Requests { return new BeatmapInfo { - Metadata = this, - Ruleset = rulesets.GetRuleset(ruleset), + BeatmapMetadata = this, + RulesetInfo = rulesets.GetRuleset(ruleset), StarDifficulty = starDifficulty, OnlineInfo = new BeatmapOnlineInfo { diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 537fce2548..6bb654f403 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -18,8 +18,8 @@ namespace osu.Game.Online.API.Requests public GetScoresRequest(BeatmapInfo beatmap) { - if (!beatmap.OnlineBeatmapID.HasValue) - throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}."); + if (!beatmap.BeatmapOnlineInfoId.HasValue) + throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.BeatmapOnlineInfoId)}."); this.beatmap = beatmap; @@ -32,7 +32,7 @@ namespace osu.Game.Online.API.Requests score.ApplyBeatmap(beatmap); } - protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores"; + protected override string Target => $@"beatmaps/{beatmap.BeatmapOnlineInfoId}/scores"; } public class GetScoresResponse @@ -116,7 +116,7 @@ namespace osu.Game.Online.API.Requests public void ApplyBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; - Ruleset = beatmap.Ruleset; + Ruleset = beatmap.RulesetInfo; // Evaluate the mod string Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c137b8f6f5..6dacef6e8d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -110,7 +110,7 @@ namespace osu.Game configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value); - Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; + Ruleset.ValueChanged += r => configRuleset.Value = r.Id ?? 0; } private ScheduledDelegate scoreLoad; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e7bfa8a76..f2ee6effb9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -3,7 +3,9 @@ using System; using System.Diagnostics; +using System.Linq; using System.Reflection; +using Microsoft.EntityFrameworkCore; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Development; @@ -17,7 +19,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Processing; using osu.Game.Online.API; -using SQLite.Net; using osu.Framework.Graphics.Performance; using osu.Game.Database; using osu.Game.Input; @@ -82,14 +83,21 @@ namespace osu.Game protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - private SQLiteConnection createConnection() - { - var conn = Host.Storage.GetDatabase(@"client"); - conn.BusyTimeout = new TimeSpan(TimeSpan.TicksPerSecond * 10); - return conn; - } + //private OsuDbContext dbContext; - private SQLiteConnection connection; + private OsuDbContext createDbContext() + { + var connectionString = Host.Storage.GetDatabaseConnectionString(@"client"); + var context = new OsuDbContext(connectionString); + var connection = context.Database.GetDbConnection(); + connection.Open(); + using (var command = connection.CreateCommand()) + { + command.CommandText = "PRAGMA journal_mode=WAL;"; + command.ExecuteNonQuery(); + } + return context; + } [BackgroundDependencyLoader] private void load() @@ -97,8 +105,10 @@ namespace osu.Game dependencies.Cache(this); dependencies.Cache(LocalConfig); - connection = createConnection(); - connection.CreateTable(); + + using (var dbContext = createDbContext()) + if (dbContext.Database.GetPendingMigrations().Any()) + dbContext.Database.Migrate(); dependencies.Cache(API = new APIAccess { @@ -106,11 +116,11 @@ namespace osu.Game Token = LocalConfig.Get(OsuSetting.Token) }); - dependencies.Cache(RulesetStore = new RulesetStore(connection)); - dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); - dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, API, Host)); - dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore)); - dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore)); + dependencies.Cache(RulesetStore = new RulesetStore(createDbContext())); + dependencies.Cache(FileStore = new FileStore(createDbContext(), Host.Storage)); + dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, createDbContext(), RulesetStore, API, Host)); + dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, createDbContext(), Host, BeatmapManager, RulesetStore)); + dependencies.Cache(KeyBindingStore = new KeyBindingStore(createDbContext(), RulesetStore)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. @@ -237,7 +247,7 @@ namespace osu.Game LocalConfig.Save(); } - connection?.Dispose(); + //dbContext?.Dispose(); base.Dispose(isDisposing); } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index a93ccbf704..25e598ffb9 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -43,8 +43,8 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; Picker.BeatmapSet = author.BeatmapSet = details.BeatmapSet = BeatmapSet; - title.Text = BeatmapSet.Metadata.Title; - artist.Text = BeatmapSet.Metadata.Artist; + title.Text = BeatmapSet.BeatmapMetadata.Title; + artist.Text = BeatmapSet.BeatmapMetadata.Artist; cover?.FadeOut(400, Easing.Out); coverContainer.Add(cover = new DelayedLoadWrapper(new BeatmapSetCover(BeatmapSet) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 4a59591a72..16cb19dbd7 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -33,8 +33,8 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - source.Text = BeatmapSet.Metadata.Source; - tags.Text = BeatmapSet.Metadata.Tags; + source.Text = BeatmapSet.BeatmapMetadata.Source; + tags.Text = BeatmapSet.BeatmapMetadata.Tags; } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 1675a2f663..8d3d91fcd2 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -66,13 +66,13 @@ namespace osu.Game.Overlays.Direct { new OsuSpriteText { - Text = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), + Text = localisation.GetUnicodePreference(SetInfo.BeatmapMetadata.TitleUnicode, SetInfo.BeatmapMetadata.Title), TextSize = 18, Font = @"Exo2.0-BoldItalic", }, new OsuSpriteText { - Text = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), + Text = localisation.GetUnicodePreference(SetInfo.BeatmapMetadata.ArtistUnicode, SetInfo.BeatmapMetadata.Artist), Font = @"Exo2.0-BoldItalic", }, }, @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Direct }, new OsuSpriteText { - Text = SetInfo.Metadata.Author, + Text = SetInfo.BeatmapMetadata.Author, TextSize = 14, Font = @"Exo2.0-SemiBoldItalic", Shadow = false, @@ -132,11 +132,11 @@ namespace osu.Game.Overlays.Direct { new OsuSpriteText { - Text = $"from {SetInfo.Metadata.Source}", + Text = $"from {SetInfo.BeatmapMetadata.Source}", TextSize = 14, Shadow = false, Colour = colours.Gray5, - Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f, + Alpha = string.IsNullOrEmpty(SetInfo.BeatmapMetadata.Source) ? 0f : 1f, }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 6702b7394c..b46ce78654 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -54,13 +54,13 @@ namespace osu.Game.Overlays.Direct { new OsuSpriteText { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), + Current = localisation.GetUnicodePreference(SetInfo.BeatmapMetadata.TitleUnicode, SetInfo.BeatmapMetadata.Title), TextSize = 18, Font = @"Exo2.0-BoldItalic", }, new OsuSpriteText { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), + Current = localisation.GetUnicodePreference(SetInfo.BeatmapMetadata.ArtistUnicode, SetInfo.BeatmapMetadata.Artist), Font = @"Exo2.0-BoldItalic", }, new FillFlowContainer @@ -101,7 +101,7 @@ namespace osu.Game.Overlays.Direct }, new OsuSpriteText { - Text = SetInfo.Metadata.Author, + Text = SetInfo.BeatmapMetadata.Author, TextSize = 14, Font = @"Exo2.0-SemiBoldItalic", }, @@ -109,11 +109,11 @@ namespace osu.Game.Overlays.Direct }, new OsuSpriteText { - Text = $"from {SetInfo.Metadata.Source}", + Text = $"from {SetInfo.BeatmapMetadata.Source}", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 14, - Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f, + Alpha = string.IsNullOrEmpty(SetInfo.BeatmapMetadata.Source) ? 0f : 1f, }, }, }, diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 28d26d0641..1500723680 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.Direct private void Bindable_ValueChanged(RulesetInfo obj) { - iconContainer.FadeTo(Ruleset.ID == obj?.ID ? 1f : 0.5f, 100); + iconContainer.FadeTo(Ruleset.Id == obj?.Id ? 1f : 0.5f, 100); } public RulesetToggleButton(Bindable bindable, RulesetInfo ruleset) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 5b5003b30f..df08400ee9 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -57,9 +57,9 @@ namespace osu.Game.Overlays var tags = new List(); foreach (var s in beatmapSets) { - artists.Add(s.Metadata.Artist); - songs.Add(s.Metadata.Title); - tags.AddRange(s.Metadata.Tags.Split(' ')); + artists.Add(s.BeatmapMetadata.Artist); + songs.Add(s.BeatmapMetadata.Title); + tags.AddRange(s.BeatmapMetadata.Tags.Split(' ')); } ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); @@ -175,8 +175,8 @@ namespace osu.Game.Overlays private void setAdded(BeatmapSetInfo set) { // if a new map was imported, we should remove it from search results (download completed etc.) - panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); - BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); + panels?.FirstOrDefault(p => p.SetInfo.BeatmapSetOnlineInfoId == set.BeatmapSetOnlineInfoId)?.FadeOut(400).Expire(); + BeatmapSets = BeatmapSets?.Where(b => b.BeatmapSetOnlineInfoId != set.BeatmapSetOnlineInfoId); } private void updateResultCounts() @@ -260,7 +260,7 @@ namespace osu.Game.Overlays { BeatmapSets = r?. Select(response => response.ToBeatmapSet(rulesets)). - Where(b => beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null); + Where(b => beatmaps.QueryBeatmapSet(q => q.BeatmapSetOnlineInfoId == b.BeatmapSetOnlineInfoId) == null); recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }; diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index bd69403831..8442203f14 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.KeyBinding [BackgroundDependencyLoader] private void load(KeyBindingStore store) { - var bindings = store.Query(Ruleset?.ID, variant); + var bindings = store.Query(Ruleset?.Id, variant); foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 723b3f4e96..6a8476dddd 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -66,7 +66,7 @@ namespace osu.Game.Overlays.Music hoverColour = colours.Yellow; artistColour = colours.Gray9; - var metadata = BeatmapSetInfo.Metadata; + var metadata = BeatmapSetInfo.BeatmapMetadata; FilterTerms = metadata.SearchableTerms; Children = new Drawable[] diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 6f1eaded7f..b989b1cb1c 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -105,7 +105,7 @@ namespace osu.Game.Overlays.Music public bool RemoveBeatmapSet(BeatmapSetInfo beatmapSet) { - var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == beatmapSet.ID); + var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.Id == beatmapSet.Id); if (itemToRemove == null) return false; return items.Remove(itemToRemove); @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Music set { foreach (PlaylistItem s in items.Children) - s.Selected = s.BeatmapSetInfo.ID == value?.ID; + s.Selected = s.BeatmapSetInfo.Id == value?.Id; } } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index d05ad85726..e78e3d44be 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Music private void itemSelected(BeatmapSetInfo set) { - if (set.ID == (beatmapBacking.Value?.BeatmapSetInfo?.ID ?? -1)) + if (set.Id == (beatmapBacking.Value?.BeatmapSetInfo?.Id ?? -1)) { beatmapBacking.Value?.Track?.Seek(0); return; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 64d0d628f0..4efd395212 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -302,8 +302,8 @@ namespace osu.Game.Overlays else { //figure out the best direction based on order in playlist. - var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); - var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); + var last = playlist.BeatmapSets.TakeWhile(b => b.Id != current.BeatmapSetInfo?.Id).Count(); + var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.Id != beatmap.BeatmapSetInfo?.Id).Count(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 60c1261190..cd18980e32 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Toolbar { foreach (ToolbarModeButton m in modeButtons.Children.Cast()) { - bool isActive = m.Ruleset.ID == ruleset.ID; + bool isActive = m.Ruleset.Id == ruleset.Id; m.Active = isActive; if (isActive) activeButton = m; diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 740369b1b6..9c51e1e66a 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -2,26 +2,23 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using SQLite.Net.Attributes; +using System.ComponentModel.DataAnnotations; namespace osu.Game.Rulesets { public class RulesetInfo : IEquatable { - [PrimaryKey, AutoIncrement] - public int? ID { get; set; } + [Key] + public int? Id { get; set; } - [Indexed(Unique = true)] public string Name { get; set; } - [Indexed(Unique = true)] public string InstantiationInfo { get; set; } - [Indexed] public bool Available { get; set; } public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this); - public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; + public bool Equals(RulesetInfo other) => other != null && Id == other.Id && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; } } diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 5eef4a8470..f29929a6aa 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -6,8 +6,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using Microsoft.EntityFrameworkCore; using osu.Game.Database; -using SQLite.Net; namespace osu.Game.Rulesets { @@ -18,9 +18,9 @@ namespace osu.Game.Rulesets { private static readonly Dictionary loaded_assemblies = new Dictionary(); - public IEnumerable AllRulesets => Query().Where(r => r.Available); + public IEnumerable AllRulesets => Connection.RulesetInfo.Where(r => r.Available); - public RulesetStore(SQLiteConnection connection) : base(connection) + public RulesetStore(OsuDbContext connection) : base(connection) { } @@ -38,54 +38,50 @@ namespace osu.Game.Rulesets protected override void Prepare(bool reset = false) { - - Connection.CreateTable(); - if (reset) { - Connection.DeleteAll(); + Connection.Database.ExecuteSqlCommand("DELETE FROM RulesetInfo"); } - + var instances = loaded_assemblies.Values.Select(r => (Ruleset)Activator.CreateInstance(r, new RulesetInfo())); - Connection.RunInTransaction(() => + //add all legacy modes in correct order + foreach (var r in instances.Where(r => r.LegacyID >= 0).OrderBy(r => r.LegacyID)) { - //add all legacy modes in correct order - foreach (var r in instances.Where(r => r.LegacyID >= 0).OrderBy(r => r.LegacyID)) + var rulesetInfo = createRulesetInfo(r); + if (Connection.RulesetInfo.SingleOrDefault(rsi=>rsi.Id==rulesetInfo.Id)==null) { - Connection.InsertOrReplace(createRulesetInfo(r)); + Connection.RulesetInfo.Add(rulesetInfo); } + } - //add any other modes - foreach (var r in instances.Where(r => r.LegacyID < 0)) - { - var us = createRulesetInfo(r); - - var existing = Query().Where(ri => ri.InstantiationInfo == us.InstantiationInfo).FirstOrDefault(); - - if (existing == null) - Connection.Insert(us); - } - }); - - Connection.RunInTransaction(() => + //add any other modes + foreach (var r in instances.Where(r => r.LegacyID < 0)) { - //perform a consistency check - foreach (var r in Query()) - { - try - { - r.CreateInstance(); - r.Available = true; - } - catch - { - r.Available = false; - } + var us = createRulesetInfo(r); - Connection.Update(r); + var existing = Connection.RulesetInfo.Where(ri => ri.InstantiationInfo == us.InstantiationInfo).FirstOrDefault(); + + if (existing == null) + Connection.RulesetInfo.Add(us); + } + + //perform a consistency check + foreach (var r in Connection.RulesetInfo) + { + try + { + r.CreateInstance(); + r.Available = true; } - }); + catch + { + r.Available = false; + } + + //Connection.RulesetInfo.Update(r); + } + Connection.SaveChanges(); } private static void loadRulesetFromFile(string file) @@ -107,11 +103,24 @@ namespace osu.Game.Rulesets { Name = ruleset.Description, InstantiationInfo = ruleset.GetType().AssemblyQualifiedName, - ID = ruleset.LegacyID + Id = ruleset.LegacyID }; protected override Type[] ValidTypes => new[] { typeof(RulesetInfo) }; - public RulesetInfo GetRuleset(int id) => Query().First(r => r.ID == id); + public RulesetInfo GetRuleset(int id) => Connection.RulesetInfo.First(r => r.Id == id); + + public RulesetInfo QueryRulesetInfo(Func query) + { + return Connection.RulesetInfo.FirstOrDefault(query); + } + + public List QueryRulesets(Func query = null) + { + var rulesets = Connection.RulesetInfo; + if (query != null) + return rulesets.Where(query).ToList(); + return rulesets.ToList(); + } } } diff --git a/osu.Game/Rulesets/Scoring/ScoreStore.cs b/osu.Game/Rulesets/Scoring/ScoreStore.cs index c06d31e38f..1604e8cb1c 100644 --- a/osu.Game/Rulesets/Scoring/ScoreStore.cs +++ b/osu.Game/Rulesets/Scoring/ScoreStore.cs @@ -11,7 +11,6 @@ using osu.Game.IO.Legacy; using osu.Game.IPC; using osu.Game.Rulesets.Replays; using SharpCompress.Compressors.LZMA; -using SQLite.Net; namespace osu.Game.Rulesets.Scoring { @@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Scoring // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private ScoreIPCChannel ipc; - public ScoreStore(Storage storage, SQLiteConnection connection, IIpcHost importHost = null, BeatmapManager beatmaps = null, RulesetStore rulesets = null) : base(connection) + public ScoreStore(Storage storage, OsuDbContext connection, IIpcHost importHost = null, BeatmapManager beatmaps = null, RulesetStore rulesets = null) : base(connection) { this.storage = storage; this.beatmaps = beatmaps; diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 729df02ffd..0e784c06af 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -172,11 +172,11 @@ namespace osu.Game.Rulesets.UI // Apply difficulty adjustments from mods before using Difficulty. foreach (var mod in Mods.OfType()) - mod.ApplyToDifficulty(Beatmap.BeatmapInfo.Difficulty); + mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BeatmapDifficulty); // Apply defaults foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty); + h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BeatmapDifficulty); // Post-process the beatmap processor.PostProcess(Beatmap); diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 3aeef4bbc9..66e6da3af9 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Menu { var sets = beatmaps.GetAllUsableBeatmapSets(false); if (sets.Count > 0) - setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); + setInfo = beatmaps.QueryBeatmapSet(s => s.Id == sets[RNG.Next(0, sets.Count - 1)].Id); } if (setInfo == null) diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index d2f88224c2..f3d648e07b 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -230,7 +230,7 @@ namespace osu.Game.Screens.Multiplayer coverContainer.FadeIn(transition_duration); coverContainer.Children = new[] { - new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSet) + new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSetInfo) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -239,9 +239,9 @@ namespace osu.Game.Screens.Multiplayer }) { RelativeSizeAxes = Axes.Both }, }; - beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); + beatmapTitle.Current = localisation.GetUnicodePreference(value.BeatmapMetadata.TitleUnicode, value.BeatmapMetadata.Title); beatmapDash.Text = @" - "; - beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist); + beatmapArtist.Current = localisation.GetUnicodePreference(value.BeatmapMetadata.ArtistUnicode, value.BeatmapMetadata.Artist); } else { diff --git a/osu.Game/Screens/Multiplayer/RoomInspector.cs b/osu.Game/Screens/Multiplayer/RoomInspector.cs index 66ce51b428..aabbd2be5f 100644 --- a/osu.Game/Screens/Multiplayer/RoomInspector.cs +++ b/osu.Game/Screens/Multiplayer/RoomInspector.cs @@ -331,7 +331,7 @@ namespace osu.Game.Screens.Multiplayer coverContainer.FadeIn(transition_duration); coverContainer.Children = new[] { - new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSet) + new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSetInfo) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -341,10 +341,10 @@ namespace osu.Game.Screens.Multiplayer }) { RelativeSizeAxes = Axes.Both }, }; - beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); + beatmapTitle.Current = localisation.GetUnicodePreference(value.BeatmapMetadata.TitleUnicode, value.BeatmapMetadata.Title); beatmapDash.Text = @" - "; - beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist); - beatmapAuthor.Text = $"mapped by {value.Metadata.Author}"; + beatmapArtist.Current = localisation.GetUnicodePreference(value.BeatmapMetadata.ArtistUnicode, value.BeatmapMetadata.Artist); + beatmapAuthor.Text = $"mapped by {value.BeatmapMetadata.Author}"; } else { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e120c7f193..9b0172a1b2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -99,18 +99,18 @@ namespace osu.Game.Screens.Play if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); - ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; + ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.RulesetInfo; var rulesetInstance = ruleset.CreateInstance(); try { - RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working, ruleset.ID == beatmap.BeatmapInfo.Ruleset.ID); + RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working, ruleset.Id == beatmap.BeatmapInfo.RulesetInfo.Id); } catch (BeatmapInvalidForRulesetException) { // we may fail to create a RulesetContainer if the beatmap cannot be loaded with the user's preferred ruleset // let's try again forcing the beatmap's ruleset. - ruleset = beatmap.BeatmapInfo.Ruleset; + ruleset = beatmap.BeatmapInfo.RulesetInfo; rulesetInstance = ruleset.CreateInstance(); RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap, true); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 9366797f47..92369c4f29 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -177,7 +177,7 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(LocalisationEngine localisation) { - var metadata = beatmap?.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); + var metadata = beatmap?.BeatmapInfo?.BeatmapMetadata ?? new BeatmapMetadata(); AutoSizeAxes = Axes.Both; Children = new Drawable[] diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index b01410cff5..694391a5ff 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -324,9 +324,9 @@ namespace osu.Game.Screens.Ranking title.Colour = artist.Colour = colours.BlueDarker; versionMapper.Colour = colours.Gray8; - versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.Metadata.Author}"; - title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title); - artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist); + versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.BeatmapMetadata.Author}"; + title.Current = localisation.GetUnicodePreference(beatmap.BeatmapMetadata.TitleUnicode, beatmap.BeatmapMetadata.Title); + artist.Current = localisation.GetUnicodePreference(beatmap.BeatmapMetadata.ArtistUnicode, beatmap.BeatmapMetadata.Artist); } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index abd288baf2..0c31f51c2b 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -113,15 +113,15 @@ namespace osu.Game.Screens.Select }); } - public void RemoveBeatmap(BeatmapSetInfo beatmapSet) => removeGroup(groups.Find(b => b.BeatmapSet.ID == beatmapSet.ID)); + public void RemoveBeatmap(BeatmapSetInfo beatmapSet) => removeGroup(groups.Find(b => b.BeatmapSet.Id == beatmapSet.Id)); internal void UpdateBeatmap(BeatmapInfo beatmap) { // todo: this method should not run more than once for the same BeatmapSetInfo. - var set = manager.Refresh(beatmap.BeatmapSet); + var set = manager.Refresh(beatmap.BeatmapSetInfo); // todo: this method should be smarter as to not recreate panels that haven't changed, etc. - var group = groups.Find(b => b.BeatmapSet.ID == set.ID); + var group = groups.Find(b => b.BeatmapSet.Id == set.Id); if (group == null) return; @@ -141,7 +141,7 @@ namespace osu.Game.Screens.Select if (selectedGroup == group && newGroup.BeatmapPanels.Count > 0) { var newSelection = - newGroup.BeatmapPanels.Find(p => p.Beatmap.ID == selectedPanel?.Beatmap.ID) ?? + newGroup.BeatmapPanels.Find(p => p.Beatmap.Id == selectedPanel?.Beatmap.Id) ?? newGroup.BeatmapPanels[Math.Min(newGroup.BeatmapPanels.Count - 1, group.BeatmapPanels.IndexOf(selectedPanel))]; selectGroup(newGroup, newSelection); @@ -337,8 +337,8 @@ namespace osu.Game.Screens.Select { foreach (var b in beatmapSet.Beatmaps) { - if (b.Metadata == null) - b.Metadata = beatmapSet.Metadata; + if (b.BeatmapMetadata == null) + b.BeatmapMetadata = beatmapSet.BeatmapMetadata; } return new BeatmapGroup(beatmapSet, manager) diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index aa37705cdf..7bd50e1fea 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Select public BeatmapDeleteDialog(BeatmapSetInfo beatmap) { - BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; + BodyText = $@"{beatmap.BeatmapMetadata?.Artist} - {beatmap.BeatmapMetadata?.Title}"; Icon = FontAwesome.fa_trash_o; HeaderText = @"Confirm deletion of"; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a98362e89c..9d8c76c1fe 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -188,8 +188,8 @@ namespace osu.Game.Screens.Select ratingsContainer.FadeIn(transition_duration); advanced.Beatmap = Beatmap; description.Text = Beatmap.Version; - source.Text = Beatmap.Metadata.Source; - tags.Text = Beatmap.Metadata.Tags; + source.Text = Beatmap.BeatmapMetadata.Source; + tags.Text = Beatmap.BeatmapMetadata.Tags; var requestedBeatmap = Beatmap; if (requestedBeatmap.Metrics == null) @@ -264,7 +264,7 @@ namespace osu.Game.Screens.Select advanced.Beatmap = new BeatmapInfo { StarDifficulty = 0, - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 0, DrainRate = 0, diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 76c384b84c..a940c49b07 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Select public BufferedWedgeInfo(WorkingBeatmap beatmap) { BeatmapInfo beatmapInfo = beatmap.BeatmapInfo; - BeatmapMetadata metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); + BeatmapMetadata metadata = beatmapInfo.BeatmapMetadata ?? beatmap.BeatmapSetInfo?.BeatmapMetadata ?? new BeatmapMetadata(); List labels = new List(); @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Select })); //get statistics from the current ruleset. - labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); + labels.AddRange(beatmapInfo.RulesetInfo.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); } PixelSnapping = true; diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index f1215ab33d..551f67c51b 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -29,20 +29,20 @@ namespace osu.Game.Screens.Select.Details beatmap = value; //mania specific - if ((Beatmap?.Ruleset?.ID ?? 0) == 3) + if ((Beatmap?.RulesetInfo?.Id ?? 0) == 3) { firstValue.Title = "Key Amount"; - firstValue.Value = (int)Math.Round(Beatmap?.Difficulty?.CircleSize ?? 0); + firstValue.Value = (int)Math.Round(Beatmap?.BeatmapDifficulty?.CircleSize ?? 0); } else { firstValue.Title = "Circle Size"; - firstValue.Value = Beatmap?.Difficulty?.CircleSize ?? 0; + firstValue.Value = Beatmap?.BeatmapDifficulty?.CircleSize ?? 0; } - hpDrain.Value = beatmap.Difficulty?.DrainRate ?? 0; - accuracy.Value = beatmap.Difficulty?.OverallDifficulty ?? 0; - approachRate.Value = beatmap.Difficulty?.ApproachRate ?? 0; + hpDrain.Value = beatmap.BeatmapDifficulty?.DrainRate ?? 0; + accuracy.Value = beatmap.BeatmapDifficulty?.OverallDifficulty ?? 0; + approachRate.Value = beatmap.BeatmapDifficulty?.ApproachRate ?? 0; starDifficulty.Value = (float)beatmap.StarDifficulty; } } diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index a1fea4a41d..f0bf6c94e7 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -23,12 +23,12 @@ namespace osu.Game.Screens.Select { var set = g.BeatmapSet; - bool hasCurrentMode = set.Beatmaps.Any(bm => bm.RulesetID == (Ruleset?.ID ?? 0)); + bool hasCurrentMode = set.Beatmaps.Any(bm => bm.RulesetInfoId == (Ruleset?.Id ?? 0)); bool match = hasCurrentMode; if (!string.IsNullOrEmpty(SearchText)) - match &= set.Metadata.SearchableTerms.Any(term => term.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0); + match &= set.BeatmapMetadata.SearchableTerms.Any(term => term.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0); switch (g.State) { @@ -45,13 +45,13 @@ namespace osu.Game.Screens.Select { default: case SortMode.Artist: - groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Artist, y.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase)); + groups.Sort((x, y) => string.Compare(x.BeatmapSet.BeatmapMetadata.Artist, y.BeatmapSet.BeatmapMetadata.Artist, StringComparison.InvariantCultureIgnoreCase)); break; case SortMode.Title: - groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Title, y.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase)); + groups.Sort((x, y) => string.Compare(x.BeatmapSet.BeatmapMetadata.Title, y.BeatmapSet.BeatmapMetadata.Title, StringComparison.InvariantCultureIgnoreCase)); break; case SortMode.Author: - groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Author, y.BeatmapSet.Metadata.Author, StringComparison.InvariantCultureIgnoreCase)); + groups.Sort((x, y) => string.Compare(x.BeatmapSet.BeatmapMetadata.Author, y.BeatmapSet.BeatmapMetadata.Author, StringComparison.InvariantCultureIgnoreCase)); break; case SortMode.Difficulty: groups.Sort((x, y) => x.BeatmapSet.MaxStarDifficulty.CompareTo(y.BeatmapSet.MaxStarDifficulty)); diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 7d65b8b648..df08d4e6f6 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Select.Leaderboards Scores = null; getScoresRequest?.Cancel(); - if (api == null || Beatmap?.OnlineBeatmapID == null) return; + if (api == null || Beatmap?.BeatmapOnlineInfoId == null) return; loading.Show(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 836ed465c3..6b0d9f1eb7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -238,7 +238,7 @@ namespace osu.Game.Screens.Select // In these cases, the other component has already loaded the beatmap, so we don't need to do so again. if (beatmap?.Equals(Beatmap.Value.BeatmapInfo) != true) { - bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value.BeatmapInfo.BeatmapSetInfoID; + bool preview = beatmap?.BeatmapSetInfoId != Beatmap.Value.BeatmapInfo.BeatmapSetInfoId; Beatmap.Value = manager.GetWorkingBeatmap(beatmap, Beatmap); ensurePlayingSelected(preview); @@ -261,7 +261,7 @@ namespace osu.Game.Screens.Select } else { - if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID) + if (beatmap.BeatmapSetInfoId == beatmapNoDebounce?.BeatmapSetInfoId) sampleChangeDifficulty.Play(); else sampleChangeBeatmap.Play(); diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 59cbe74650..bad31ee55a 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -37,7 +37,7 @@ namespace osu.Game.Storyboards /// public bool ReplacesBackground(BeatmapInfo beatmapInfo) { - var backgroundPath = beatmapInfo.BeatmapSet?.Metadata?.BackgroundFile?.ToLowerInvariant(); + var backgroundPath = beatmapInfo.BeatmapSetInfo?.BeatmapMetadata?.BackgroundFile?.ToLowerInvariant(); if (backgroundPath == null) return false; diff --git a/osu.Game/Tests/Platform/TestStorage.cs b/osu.Game/Tests/Platform/TestStorage.cs index 9f76df2a58..be893f7e9c 100644 --- a/osu.Game/Tests/Platform/TestStorage.cs +++ b/osu.Game/Tests/Platform/TestStorage.cs @@ -1,12 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework; +using Microsoft.Data.Sqlite; using osu.Framework.Platform; -using SQLite.Net; -using SQLite.Net.Interop; -using SQLite.Net.Platform.Generic; -using SQLite.Net.Platform.Win32; namespace osu.Game.Tests.Platform { @@ -16,14 +12,9 @@ namespace osu.Game.Tests.Platform { } - public override SQLiteConnection GetDatabase(string name) + public override string GetDatabaseConnectionString(string name) { - ISQLitePlatform platform; - if (RuntimeInfo.IsWindows) - platform = new SQLitePlatformWin32(); - else - platform = new SQLitePlatformGeneric(); - return new SQLiteConnection(platform, @":memory:"); + return "DataSource=:memory:"; } } -} \ No newline at end of file +} diff --git a/osu.Game/Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Game/Tests/Visual/TestCaseBeatmapDetails.cs index cd4d97425b..e126980edf 100644 --- a/osu.Game/Tests/Visual/TestCaseBeatmapDetails.cs +++ b/osu.Game/Tests/Visual/TestCaseBeatmapDetails.cs @@ -24,12 +24,12 @@ namespace osu.Game.Tests.Visual AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo { Version = "All Metrics", - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Source = "osu!lazer", Tags = "this beatmap has all the metrics", }, - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 7, DrainRate = 1, @@ -48,12 +48,12 @@ namespace osu.Game.Tests.Visual AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo { Version = "Only Ratings", - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Source = "osu!lazer", Tags = "this beatmap has ratings metrics but not retries or fails", }, - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 6, DrainRate = 9, @@ -70,12 +70,12 @@ namespace osu.Game.Tests.Visual AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo { Version = "Only Retries and Fails", - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Source = "osu!lazer", Tags = "this beatmap has retries and fails but no ratings", }, - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 3.7f, DrainRate = 6, @@ -93,12 +93,12 @@ namespace osu.Game.Tests.Visual AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo { Version = "No Metrics", - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Source = "osu!lazer", Tags = "this beatmap has no metrics", }, - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 5, DrainRate = 5, diff --git a/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs b/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs index 76ed9979ca..e8027978b4 100644 --- a/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual { overlay.ShowBeatmapSet(new BeatmapSetInfo { - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Title = @"Lachryma ", Artist = @"Kaneko Chiharu", @@ -64,8 +64,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 1.36, Version = @"BASIC", - Ruleset = mania, - Difficulty = new BeatmapDifficulty + RulesetInfo = mania, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 4, DrainRate = 6.5f, @@ -92,8 +92,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 2.22, Version = @"NOVICE", - Ruleset = mania, - Difficulty = new BeatmapDifficulty + RulesetInfo = mania, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 4, DrainRate = 7, @@ -120,8 +120,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 3.49, Version = @"ADVANCED", - Ruleset = mania, - Difficulty = new BeatmapDifficulty + RulesetInfo = mania, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 4, DrainRate = 7.5f, @@ -148,8 +148,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 4.24, Version = @"EXHAUST", - Ruleset = mania, - Difficulty = new BeatmapDifficulty + RulesetInfo = mania, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 4, DrainRate = 8, @@ -176,8 +176,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 5.26, Version = @"GRAVITY", - Ruleset = mania, - Difficulty = new BeatmapDifficulty + RulesetInfo = mania, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 4, DrainRate = 8.5f, @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual { overlay.ShowBeatmapSet(new BeatmapSetInfo { - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { Title = @"Soumatou Labyrinth", Artist = @"Yunomi with Momobako&miko", @@ -238,8 +238,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 1.40, Version = @"yzrin's Kantan", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty + RulesetInfo = taiko, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 2, DrainRate = 7, @@ -266,8 +266,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 2.23, Version = @"Futsuu", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty + RulesetInfo = taiko, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 2, DrainRate = 6, @@ -294,8 +294,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 3.19, Version = @"Muzukashii", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty + RulesetInfo = taiko, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 2, DrainRate = 6, @@ -322,8 +322,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 3.97, Version = @"Charlotte's Oni", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty + RulesetInfo = taiko, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 5, DrainRate = 6, @@ -350,8 +350,8 @@ namespace osu.Game.Tests.Visual { StarDifficulty = 5.08, Version = @"Labyrinth Oni", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty + RulesetInfo = taiko, + BeatmapDifficulty = new BeatmapDifficulty { CircleSize = 5, DrainRate = 5, diff --git a/osu.Game/Tests/Visual/TestCaseDirect.cs b/osu.Game/Tests/Visual/TestCaseDirect.cs index 1fb9dbea8f..cb34d28578 100644 --- a/osu.Game/Tests/Visual/TestCaseDirect.cs +++ b/osu.Game/Tests/Visual/TestCaseDirect.cs @@ -41,8 +41,8 @@ namespace osu.Game.Tests.Visual { new BeatmapSetInfo { - OnlineBeatmapSetID = 578332, - Metadata = new BeatmapMetadata + BeatmapSetOnlineInfoId = 578332, + BeatmapMetadata = new BeatmapMetadata { Title = @"OrVid", Artist = @"An", @@ -65,16 +65,16 @@ namespace osu.Game.Tests.Visual { new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 5.35f, - Metadata = new BeatmapMetadata(), + BeatmapMetadata = new BeatmapMetadata(), }, }, }, new BeatmapSetInfo { - OnlineBeatmapSetID = 599627, - Metadata = new BeatmapMetadata + BeatmapSetOnlineInfoId = 599627, + BeatmapMetadata = new BeatmapMetadata { Title = @"tiny lamp", Artist = @"fhana", @@ -97,16 +97,16 @@ namespace osu.Game.Tests.Visual { new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 5.81f, - Metadata = new BeatmapMetadata(), + BeatmapMetadata = new BeatmapMetadata(), }, }, }, new BeatmapSetInfo { - OnlineBeatmapSetID = 513268, - Metadata = new BeatmapMetadata + BeatmapSetOnlineInfoId = 513268, + BeatmapMetadata = new BeatmapMetadata { Title = @"At Gwanghwamun", Artist = @"KYUHYUN", @@ -129,31 +129,31 @@ namespace osu.Game.Tests.Visual { new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 0.9f, - Metadata = new BeatmapMetadata(), + BeatmapMetadata = new BeatmapMetadata(), }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 1.1f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 2.02f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 3.49f, }, }, }, new BeatmapSetInfo { - OnlineBeatmapSetID = 586841, - Metadata = new BeatmapMetadata + BeatmapSetOnlineInfoId = 586841, + BeatmapMetadata = new BeatmapMetadata { Title = @"RHAPSODY OF BLUE SKY", Artist = @"fhana", @@ -176,43 +176,43 @@ namespace osu.Game.Tests.Visual { new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 1.26f, - Metadata = new BeatmapMetadata(), + BeatmapMetadata = new BeatmapMetadata(), }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 2.01f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 2.87f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 3.76f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 3.93f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 4.37f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 5.13f, }, new BeatmapInfo { - Ruleset = ruleset, + RulesetInfo = ruleset, StarDifficulty = 5.42f, }, }, diff --git a/osu.Game/Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game/Tests/Visual/TestCaseDrawableRoom.cs index 7113bcbff5..a57bf64c9a 100644 --- a/osu.Game/Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game/Tests/Visual/TestCaseDrawableRoom.cs @@ -43,13 +43,13 @@ namespace osu.Game.Tests.Visual Value = new BeatmapInfo { StarDifficulty = 4.65, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata + RulesetInfo = rulesets.GetRuleset(3), + BeatmapMetadata = new BeatmapMetadata { Title = @"Critical Crystal", Artist = @"Seiryu", }, - BeatmapSet = new BeatmapSetInfo + BeatmapSetInfo = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { @@ -81,13 +81,13 @@ namespace osu.Game.Tests.Visual Value = new BeatmapInfo { StarDifficulty = 1.96, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata + RulesetInfo = rulesets.GetRuleset(0), + BeatmapMetadata = new BeatmapMetadata { Title = @"Serendipity", Artist = @"ZAQ", }, - BeatmapSet = new BeatmapSetInfo + BeatmapSetInfo = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { diff --git a/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs index feff7497d8..12ac7240d6 100644 --- a/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game/Tests/Visual/TestCasePlaySongSelect.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.MathUtils; using osu.Game.Beatmaps; @@ -37,12 +38,11 @@ namespace osu.Game.Tests.Visual { var storage = new TestStorage(@"TestCasePlaySongSelect"); - var backingDatabase = storage.GetDatabase(@"client"); - backingDatabase.CreateTable(); + var dbConnectionString = storage.GetDatabaseConnectionString(@"client"); - dependencies.Cache(rulesets = new RulesetStore(backingDatabase)); - dependencies.Cache(files = new FileStore(backingDatabase, storage)); - dependencies.Cache(manager = new BeatmapManager(storage, files, backingDatabase, rulesets, null)); + dependencies.Cache(rulesets = new RulesetStore(new OsuDbContext(dbConnectionString))); + dependencies.Cache(files = new FileStore(new OsuDbContext(dbConnectionString), storage)); + dependencies.Cache(manager = new BeatmapManager(storage, files, new OsuDbContext(dbConnectionString), rulesets, null)); for (int i = 0; i < 100; i += 10) manager.Import(createTestBeatmapSet(i)); @@ -60,11 +60,11 @@ namespace osu.Game.Tests.Visual { return new BeatmapSetInfo { - OnlineBeatmapSetID = 1234 + i, + BeatmapSetOnlineInfoId = 1234 + i, Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249", - Metadata = new BeatmapMetadata + BeatmapMetadata = new BeatmapMetadata { - OnlineBeatmapSetID = 1234 + i, + BeatmapSetOnlineInfoId = 1234 + i, // Create random metadata, then we can check if sorting works based on these Artist = "MONACA " + RNG.Next(0, 9), Title = "Black Song " + RNG.Next(0, 9), @@ -74,33 +74,33 @@ namespace osu.Game.Tests.Visual { new BeatmapInfo { - OnlineBeatmapID = 1234 + i, - Ruleset = rulesets.Query().First(), + BeatmapOnlineInfoId = 1234 + i, + RulesetInfo = rulesets.QueryRulesets().First(), Path = "normal.osu", Version = "Normal", - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { OverallDifficulty = 3.5f, } }, new BeatmapInfo { - OnlineBeatmapID = 1235 + i, - Ruleset = rulesets.Query().First(), + BeatmapOnlineInfoId = 1235 + i, + RulesetInfo = rulesets.QueryRulesets().First(), Path = "hard.osu", Version = "Hard", - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { OverallDifficulty = 5, } }, new BeatmapInfo { - OnlineBeatmapID = 1236 + i, - Ruleset = rulesets.Query().First(), + BeatmapOnlineInfoId = 1236 + i, + RulesetInfo = rulesets.QueryRulesets().First(), Path = "insane.osu", Version = "Insane", - Difficulty = new BeatmapDifficulty + BeatmapDifficulty = new BeatmapDifficulty { OverallDifficulty = 7, } diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 4a25a52e36..98c573f62c 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -39,10 +39,11 @@ namespace osu.Game.Tests.Visual Colour = Color4.Black, }); - foreach (var r in rulesets.Query()) + var queryRulesets = rulesets.QueryRulesets(r=>true); + foreach (var r in queryRulesets) AddStep(r.Name, () => loadPlayerFor(r)); - loadPlayerFor(rulesets.Query().First()); + loadPlayerFor(queryRulesets.First()); } protected virtual Beatmap CreateBeatmap() @@ -60,7 +61,7 @@ namespace osu.Game.Tests.Visual { var beatmap = CreateBeatmap(); - beatmap.BeatmapInfo.Ruleset = r; + beatmap.BeatmapInfo.RulesetInfo = r; var instance = r.CreateInstance(); diff --git a/osu.Game/Tests/Visual/TestCaseResults.cs b/osu.Game/Tests/Visual/TestCaseResults.cs index 62154a535a..a0146de7d0 100644 --- a/osu.Game/Tests/Visual/TestCaseResults.cs +++ b/osu.Game/Tests/Visual/TestCaseResults.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual if (beatmap == null) { - var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0); + var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetInfoId == 0); if (beatmapInfo != null) beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo); } diff --git a/osu.Game/Tests/Visual/TestCaseRoomInspector.cs b/osu.Game/Tests/Visual/TestCaseRoomInspector.cs index dd773b361a..41b722841c 100644 --- a/osu.Game/Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game/Tests/Visual/TestCaseRoomInspector.cs @@ -32,14 +32,14 @@ namespace osu.Game.Tests.Visual Value = new BeatmapInfo { StarDifficulty = 3.7, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata + RulesetInfo = rulesets.GetRuleset(3), + BeatmapMetadata = new BeatmapMetadata { Title = @"Platina", Artist = @"Maaya Sakamoto", Author = @"uwutm8", }, - BeatmapSet = new BeatmapSetInfo + BeatmapSetInfo = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { @@ -99,14 +99,14 @@ namespace osu.Game.Tests.Visual Value = new BeatmapInfo { StarDifficulty = 7.07, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata + RulesetInfo = rulesets.GetRuleset(0), + BeatmapMetadata = new BeatmapMetadata { Title = @"FREEDOM DIVE", Artist = @"xi", Author = @"Nakagawa-Kanon", }, - BeatmapSet = new BeatmapSetInfo + BeatmapSetInfo = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { diff --git a/osu.Game/Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Game/Tests/Visual/TestCaseScrollingPlayfield.cs index d0761e5841..29623fb05f 100644 --- a/osu.Game/Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Game/Tests/Visual/TestCaseScrollingPlayfield.cs @@ -48,8 +48,8 @@ namespace osu.Game.Tests.Visual HitObjects = objects, BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty(), - Metadata = new BeatmapMetadata() + BeatmapDifficulty = new BeatmapDifficulty(), + BeatmapMetadata = new BeatmapMetadata() } }; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bdca48ccdf..afccbe9dc1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -124,6 +124,49 @@ $(SolutionDir)\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll True + + + ..\packages\Microsoft.Data.Sqlite.Core.2.0.0\lib\netstandard2.0\Microsoft.Data.Sqlite.dll + + + ..\packages\Microsoft.EntityFrameworkCore.2.0.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + + ..\packages\Microsoft.EntityFrameworkCore.Design.2.0.0\lib\net461\Microsoft.EntityFrameworkCore.Design.dll + + + ..\packages\Microsoft.EntityFrameworkCore.Relational.2.0.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Relational.dll + + + ..\packages\Microsoft.EntityFrameworkCore.Sqlite.Core.2.0.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Sqlite.dll + + + ..\packages\Microsoft.Extensions.Caching.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Caching.Memory.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll + + + ..\packages\Microsoft.Extensions.Configuration.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Logging.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Options.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Primitives.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll + $(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll True @@ -157,6 +200,9 @@ $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True + + ..\packages\Remotion.Linq.2.1.2\lib\net45\Remotion.Linq.dll + $(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll True @@ -165,29 +211,43 @@ $(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll True - - $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll - True + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_green.dll - - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll - True + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_v2.dll - - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll - True + + ..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll - - $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll - True + + ..\packages\SQLitePCLRaw.provider.e_sqlite3.net45.1.1.8\lib\net45\SQLitePCLRaw.provider.e_sqlite3.dll $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\Squirrel.dll True + + ..\packages\System.Collections.Immutable.1.4.0\lib\netstandard2.0\System.Collections.Immutable.dll + + + ..\packages\System.ComponentModel.Annotations.4.4.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + + ..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Interactive.Async.3.1.1\lib\net46\System.Interactive.Async.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.4.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + @@ -287,7 +347,7 @@ - + @@ -800,6 +860,9 @@ + + +