From 188c80374e2401032d9522a0a1f596882228be1c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 18:14:23 +0300 Subject: [PATCH 01/23] Add sorting by BPM --- osu.Game/Beatmaps/BeatmapManager.cs | 6 +++++- osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 7ef50da7d3..c2d8e06d53 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -271,7 +271,11 @@ namespace osu.Game.Beatmaps OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID, Beatmaps = new List(), Metadata = beatmap.Metadata, - DateAdded = DateTimeOffset.UtcNow + DateAdded = DateTimeOffset.UtcNow, + OnlineInfo = new BeatmapSetOnlineInfo + { + BPM = beatmap.ControlPointInfo.BPMMode, + } }; } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index f1951e27ab..c51638277d 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -48,6 +48,9 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.DateAdded: return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); + case SortMode.BPM: + return BeatmapSet.OnlineInfo.BPM.CompareTo(otherSet.BeatmapSet.OnlineInfo.BPM); + case SortMode.Difficulty: return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty); } From 65c8249c94212dacfff06683b0156e2a2eea0fb7 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 18:25:52 +0300 Subject: [PATCH 02/23] Add beatmap extension for calculating length --- osu.Game/Beatmaps/Beatmap.cs | 12 ++++++++++++ osu.Game/Screens/Select/BeatmapInfoWedge.cs | 5 +---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 4ebeee40bf..7fca13a1e2 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -8,6 +8,7 @@ using System.Linq; using osu.Game.Beatmaps.ControlPoints; using Newtonsoft.Json; using osu.Game.IO.Serialization.Converters; +using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { @@ -61,4 +62,15 @@ namespace osu.Game.Beatmaps { public new Beatmap Clone() => (Beatmap)base.Clone(); } + + public static class BeatmapExtensions + { + public static double CalculateLength(this IBeatmap b) + { + HitObject lastObject = b.HitObjects.LastOrDefault(); + var endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + + return endTime - b.HitObjects.FirstOrDefault()?.StartTime ?? 0; + } + } } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index fa9ffd0706..e0521307fc 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -289,14 +289,11 @@ namespace osu.Game.Screens.Select if (b?.HitObjects?.Any() == true) { - HitObject lastObject = b.HitObjects.LastOrDefault(); - double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; - labels.Add(new InfoLabel(new BeatmapStatistic { Name = "Length", Icon = FontAwesome.Regular.Clock, - Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"), + Content = TimeSpan.FromMilliseconds(b.CalculateLength()).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic From b4ef64fa61a56cc02f09294ab8442fe5739da944 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 18:26:56 +0300 Subject: [PATCH 03/23] Add sorting by Length --- osu.Game/Beatmaps/BeatmapManager.cs | 5 +++++ osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 ++ osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 7 +++++++ osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 3 +++ 4 files changed, 17 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c2d8e06d53..b4c211ad53 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -307,6 +307,11 @@ namespace osu.Game.Beatmaps // TODO: this should be done in a better place once we actually need to dynamically update it. beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0; + beatmap.BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo + { + Length = beatmap.CalculateLength(), + }; + beatmapInfos.Add(beatmap.BeatmapInfo); } } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 524ed0ed56..cdf8ddb5a1 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -37,6 +37,8 @@ namespace osu.Game.Beatmaps public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; + public double MaxLength => Beatmaps?.Max(b => b.OnlineInfo.Length) ?? 0; + [NotMapped] public bool DeletePending { get; set; } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 712ab7b571..fa24a64d51 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -47,6 +47,13 @@ namespace osu.Game.Screens.Select.Carousel if (ruleset != 0) return ruleset; return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty); + + case SortMode.Length: + // Length comparing must be in seconds + if (TimeSpan.FromMilliseconds(Beatmap.OnlineInfo.Length).Seconds != TimeSpan.FromMilliseconds(otherBeatmap.Beatmap.OnlineInfo.Length).Seconds) + return Beatmap.OnlineInfo.Length.CompareTo(otherBeatmap.Beatmap.OnlineInfo.Length); + + goto case SortMode.Difficulty; } } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index c51638277d..7934cf388f 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -51,6 +51,9 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.BPM: return BeatmapSet.OnlineInfo.BPM.CompareTo(otherSet.BeatmapSet.OnlineInfo.BPM); + case SortMode.Length: + return BeatmapSet.MaxLength.CompareTo(otherSet.BeatmapSet.MaxLength); + case SortMode.Difficulty: return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty); } From 31e1d204d4d1d63debe92159443e09db9ddb1cd1 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 18:27:12 +0300 Subject: [PATCH 04/23] Add test for sorting by BPM and Length --- .../SongSelect/TestScenePlaySongSelect.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 962e0fb362..04c75d70e3 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -133,6 +133,9 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; }); + AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.Sort = SortMode.DateAdded; }); + AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.Sort = SortMode.BPM; }); + AddStep(@"Sort by Length", delegate { songSelect.FilterControl.Sort = SortMode.Length; }); AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; }); } @@ -264,20 +267,26 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 0; i < 6; i++) { int beatmapId = setId * 10 + i; + int length = RNG.Next(30000, 200000); beatmaps.Add(new BeatmapInfo { Ruleset = getRuleset(), OnlineBeatmapID = beatmapId, Path = "normal.osu", - Version = $"{beatmapId}", + Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss})", BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = 3.5f, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = length, } }); } + double bpm = RNG.NextSingle(80, 200); return new BeatmapSetInfo { OnlineBeatmapSetID = setId, @@ -286,10 +295,15 @@ namespace osu.Game.Tests.Visual.SongSelect { // Create random metadata, then we can check if sorting works based on these Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id {setId})", + Title = $"Some Song (set id {setId}, bpm {bpm:0.#})", AuthorString = "Some Guy " + RNG.Next(0, 9), }, - Beatmaps = beatmaps + Beatmaps = beatmaps, + DateAdded = DateTimeOffset.UtcNow, + OnlineInfo = new BeatmapSetOnlineInfo + { + BPM = bpm, + } }; } } From 28cc797fb61ee60fa82193982e84f2dc86c2d48f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 18:29:25 +0300 Subject: [PATCH 05/23] Add migrations --- ...7134040_AddBPMAndLengthSorting.Designer.cs | 500 ++++++++++++++++++ .../20190707134040_AddBPMAndLengthSorting.cs | 17 + 2 files changed, 517 insertions(+) create mode 100644 osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs create mode 100644 osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs diff --git a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs new file mode 100644 index 0000000000..7038fcba6e --- /dev/null +++ b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs @@ -0,0 +1,500 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using osu.Game.Database; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20190707134040_AddBPMAndLengthSorting")] + partial class AddBPMAndLengthSorting + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.4-servicing-10062"); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("ApproachRate"); + + b.Property("CircleSize"); + + b.Property("DrainRate"); + + b.Property("OverallDifficulty"); + + b.Property("SliderMultiplier"); + + b.Property("SliderTickRate"); + + b.HasKey("ID"); + + b.ToTable("BeatmapDifficulty"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("AudioLeadIn"); + + b.Property("BaseDifficultyID"); + + b.Property("BeatDivisor"); + + b.Property("BeatmapSetInfoID"); + + b.Property("Countdown"); + + b.Property("DistanceSpacing"); + + b.Property("GridSize"); + + b.Property("Hash"); + + b.Property("Hidden"); + + b.Property("LetterboxInBreaks"); + + b.Property("MD5Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapID"); + + b.Property("Path"); + + b.Property("RulesetID"); + + b.Property("SpecialStyle"); + + b.Property("StackLeniency"); + + b.Property("StarDifficulty"); + + b.Property("Status"); + + b.Property("StoredBookmarks"); + + b.Property("TimelineZoom"); + + b.Property("Version"); + + b.Property("WidescreenStoryboard"); + + b.HasKey("ID"); + + b.HasIndex("BaseDifficultyID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("Hash"); + + b.HasIndex("MD5Hash"); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("BeatmapInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Artist"); + + b.Property("ArtistUnicode"); + + b.Property("AudioFile"); + + b.Property("AuthorString") + .HasColumnName("Author"); + + b.Property("BackgroundFile"); + + b.Property("PreviewTime"); + + b.Property("Source"); + + b.Property("Tags"); + + b.Property("Title"); + + b.Property("TitleUnicode"); + + b.HasKey("ID"); + + b.ToTable("BeatmapMetadata"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BeatmapSetInfoID"); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.HasKey("ID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("FileInfoID"); + + b.ToTable("BeatmapSetFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapSetID"); + + b.Property("Protected"); + + b.Property("Status"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + + b.ToTable("BeatmapSetInfo"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Key") + .HasColumnName("Key"); + + b.Property("RulesetID"); + + b.Property("SkinInfoID"); + + b.Property("StringValue") + .HasColumnName("Value"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("SkinInfoID"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("osu.Game.IO.FileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Hash"); + + b.Property("ReferenceCount"); + + b.HasKey("ID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("ReferenceCount"); + + b.ToTable("FileInfo"); + }); + + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntAction") + .HasColumnName("Action"); + + b.Property("KeysString") + .HasColumnName("Keys"); + + b.Property("RulesetID"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("IntAction"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("KeyBinding"); + }); + + modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Available"); + + b.Property("InstantiationInfo"); + + b.Property("Name"); + + b.Property("ShortName"); + + b.HasKey("ID"); + + b.HasIndex("Available"); + + b.HasIndex("ShortName") + .IsUnique(); + + b.ToTable("RulesetInfo"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.Property("ScoreInfoID"); + + b.HasKey("ID"); + + b.HasIndex("FileInfoID"); + + b.HasIndex("ScoreInfoID"); + + b.ToTable("ScoreFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Accuracy") + .HasColumnType("DECIMAL(1,4)"); + + b.Property("BeatmapInfoID"); + + b.Property("Combo"); + + b.Property("Date"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MaxCombo"); + + b.Property("ModsJson") + .HasColumnName("Mods"); + + b.Property("OnlineScoreID"); + + b.Property("PP"); + + b.Property("Rank"); + + b.Property("RulesetID"); + + b.Property("StatisticsJson") + .HasColumnName("Statistics"); + + b.Property("TotalScore"); + + b.Property("UserID") + .HasColumnName("UserID"); + + b.Property("UserString") + .HasColumnName("User"); + + b.HasKey("ID"); + + b.HasIndex("BeatmapInfoID"); + + b.HasIndex("OnlineScoreID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("ScoreInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.Property("SkinInfoID"); + + b.HasKey("ID"); + + b.HasIndex("FileInfoID"); + + b.HasIndex("SkinInfoID"); + + b.ToTable("SkinFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Creator"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("Name"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.ToTable("SkinInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") + .WithMany() + .HasForeignKey("BaseDifficultyID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") + .WithMany("Beatmaps") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("Beatmaps") + .HasForeignKey("MetadataID"); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") + .WithMany("Files") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("BeatmapSets") + .HasForeignKey("MetadataID"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.HasOne("osu.Game.Skinning.SkinInfo") + .WithMany("Settings") + .HasForeignKey("SkinInfoID"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => + { + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Scoring.ScoreInfo") + .WithMany("Files") + .HasForeignKey("ScoreInfoID"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap") + .WithMany("Scores") + .HasForeignKey("BeatmapInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Skinning.SkinInfo") + .WithMany("Files") + .HasForeignKey("SkinInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs new file mode 100644 index 0000000000..98a94b1c4e --- /dev/null +++ b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace osu.Game.Migrations +{ + public partial class AddBPMAndLengthSorting : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} From 6ee10640e31f5343fc3eeba33913ab43a1b96591 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 19:26:41 +0300 Subject: [PATCH 06/23] Remove unnecessary migration + Fix CI issues --- ...7134040_AddBPMAndLengthSorting.Designer.cs | 500 ------------------ .../20190707134040_AddBPMAndLengthSorting.cs | 17 - osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 - 3 files changed, 519 deletions(-) delete mode 100644 osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs delete mode 100644 osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs diff --git a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs deleted file mode 100644 index 7038fcba6e..0000000000 --- a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.Designer.cs +++ /dev/null @@ -1,500 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using osu.Game.Database; - -namespace osu.Game.Migrations -{ - [DbContext(typeof(OsuDbContext))] - [Migration("20190707134040_AddBPMAndLengthSorting")] - partial class AddBPMAndLengthSorting - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "2.2.4-servicing-10062"); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("ApproachRate"); - - b.Property("CircleSize"); - - b.Property("DrainRate"); - - b.Property("OverallDifficulty"); - - b.Property("SliderMultiplier"); - - b.Property("SliderTickRate"); - - b.HasKey("ID"); - - b.ToTable("BeatmapDifficulty"); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("AudioLeadIn"); - - b.Property("BaseDifficultyID"); - - b.Property("BeatDivisor"); - - b.Property("BeatmapSetInfoID"); - - b.Property("Countdown"); - - b.Property("DistanceSpacing"); - - b.Property("GridSize"); - - b.Property("Hash"); - - b.Property("Hidden"); - - b.Property("LetterboxInBreaks"); - - b.Property("MD5Hash"); - - b.Property("MetadataID"); - - b.Property("OnlineBeatmapID"); - - b.Property("Path"); - - b.Property("RulesetID"); - - b.Property("SpecialStyle"); - - b.Property("StackLeniency"); - - b.Property("StarDifficulty"); - - b.Property("Status"); - - b.Property("StoredBookmarks"); - - b.Property("TimelineZoom"); - - b.Property("Version"); - - b.Property("WidescreenStoryboard"); - - b.HasKey("ID"); - - b.HasIndex("BaseDifficultyID"); - - b.HasIndex("BeatmapSetInfoID"); - - b.HasIndex("Hash"); - - b.HasIndex("MD5Hash"); - - b.HasIndex("MetadataID"); - - b.HasIndex("OnlineBeatmapID") - .IsUnique(); - - b.HasIndex("RulesetID"); - - b.ToTable("BeatmapInfo"); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Artist"); - - b.Property("ArtistUnicode"); - - b.Property("AudioFile"); - - b.Property("AuthorString") - .HasColumnName("Author"); - - b.Property("BackgroundFile"); - - b.Property("PreviewTime"); - - b.Property("Source"); - - b.Property("Tags"); - - b.Property("Title"); - - b.Property("TitleUnicode"); - - b.HasKey("ID"); - - b.ToTable("BeatmapMetadata"); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("BeatmapSetInfoID"); - - b.Property("FileInfoID"); - - b.Property("Filename") - .IsRequired(); - - b.HasKey("ID"); - - b.HasIndex("BeatmapSetInfoID"); - - b.HasIndex("FileInfoID"); - - b.ToTable("BeatmapSetFileInfo"); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("DateAdded"); - - b.Property("DeletePending"); - - b.Property("Hash"); - - b.Property("MetadataID"); - - b.Property("OnlineBeatmapSetID"); - - b.Property("Protected"); - - b.Property("Status"); - - b.HasKey("ID"); - - b.HasIndex("DeletePending"); - - b.HasIndex("Hash") - .IsUnique(); - - b.HasIndex("MetadataID"); - - b.HasIndex("OnlineBeatmapSetID") - .IsUnique(); - - b.ToTable("BeatmapSetInfo"); - }); - - modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Key") - .HasColumnName("Key"); - - b.Property("RulesetID"); - - b.Property("SkinInfoID"); - - b.Property("StringValue") - .HasColumnName("Value"); - - b.Property("Variant"); - - b.HasKey("ID"); - - b.HasIndex("SkinInfoID"); - - b.HasIndex("RulesetID", "Variant"); - - b.ToTable("Settings"); - }); - - modelBuilder.Entity("osu.Game.IO.FileInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Hash"); - - b.Property("ReferenceCount"); - - b.HasKey("ID"); - - b.HasIndex("Hash") - .IsUnique(); - - b.HasIndex("ReferenceCount"); - - b.ToTable("FileInfo"); - }); - - modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("IntAction") - .HasColumnName("Action"); - - b.Property("KeysString") - .HasColumnName("Keys"); - - b.Property("RulesetID"); - - b.Property("Variant"); - - b.HasKey("ID"); - - b.HasIndex("IntAction"); - - b.HasIndex("RulesetID", "Variant"); - - b.ToTable("KeyBinding"); - }); - - modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Available"); - - b.Property("InstantiationInfo"); - - b.Property("Name"); - - b.Property("ShortName"); - - b.HasKey("ID"); - - b.HasIndex("Available"); - - b.HasIndex("ShortName") - .IsUnique(); - - b.ToTable("RulesetInfo"); - }); - - modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("FileInfoID"); - - b.Property("Filename") - .IsRequired(); - - b.Property("ScoreInfoID"); - - b.HasKey("ID"); - - b.HasIndex("FileInfoID"); - - b.HasIndex("ScoreInfoID"); - - b.ToTable("ScoreFileInfo"); - }); - - modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Accuracy") - .HasColumnType("DECIMAL(1,4)"); - - b.Property("BeatmapInfoID"); - - b.Property("Combo"); - - b.Property("Date"); - - b.Property("DeletePending"); - - b.Property("Hash"); - - b.Property("MaxCombo"); - - b.Property("ModsJson") - .HasColumnName("Mods"); - - b.Property("OnlineScoreID"); - - b.Property("PP"); - - b.Property("Rank"); - - b.Property("RulesetID"); - - b.Property("StatisticsJson") - .HasColumnName("Statistics"); - - b.Property("TotalScore"); - - b.Property("UserID") - .HasColumnName("UserID"); - - b.Property("UserString") - .HasColumnName("User"); - - b.HasKey("ID"); - - b.HasIndex("BeatmapInfoID"); - - b.HasIndex("OnlineScoreID") - .IsUnique(); - - b.HasIndex("RulesetID"); - - b.ToTable("ScoreInfo"); - }); - - modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("FileInfoID"); - - b.Property("Filename") - .IsRequired(); - - b.Property("SkinInfoID"); - - b.HasKey("ID"); - - b.HasIndex("FileInfoID"); - - b.HasIndex("SkinInfoID"); - - b.ToTable("SkinFileInfo"); - }); - - modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b => - { - b.Property("ID") - .ValueGeneratedOnAdd(); - - b.Property("Creator"); - - b.Property("DeletePending"); - - b.Property("Hash"); - - b.Property("Name"); - - b.HasKey("ID"); - - b.HasIndex("DeletePending"); - - b.HasIndex("Hash") - .IsUnique(); - - b.ToTable("SkinInfo"); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => - { - b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") - .WithMany() - .HasForeignKey("BaseDifficultyID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") - .WithMany("Beatmaps") - .HasForeignKey("BeatmapSetInfoID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") - .WithMany("Beatmaps") - .HasForeignKey("MetadataID"); - - b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") - .WithMany() - .HasForeignKey("RulesetID") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => - { - b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") - .WithMany("Files") - .HasForeignKey("BeatmapSetInfoID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.IO.FileInfo", "FileInfo") - .WithMany() - .HasForeignKey("FileInfoID") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => - { - b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") - .WithMany("BeatmapSets") - .HasForeignKey("MetadataID"); - }); - - modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => - { - b.HasOne("osu.Game.Skinning.SkinInfo") - .WithMany("Settings") - .HasForeignKey("SkinInfoID"); - }); - - modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => - { - b.HasOne("osu.Game.IO.FileInfo", "FileInfo") - .WithMany() - .HasForeignKey("FileInfoID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.Scoring.ScoreInfo") - .WithMany("Files") - .HasForeignKey("ScoreInfoID"); - }); - - modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => - { - b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap") - .WithMany("Scores") - .HasForeignKey("BeatmapInfoID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") - .WithMany() - .HasForeignKey("RulesetID") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => - { - b.HasOne("osu.Game.IO.FileInfo", "FileInfo") - .WithMany() - .HasForeignKey("FileInfoID") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("osu.Game.Skinning.SkinInfo") - .WithMany("Files") - .HasForeignKey("SkinInfoID") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs b/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs deleted file mode 100644 index 98a94b1c4e..0000000000 --- a/osu.Game/Migrations/20190707134040_AddBPMAndLengthSorting.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace osu.Game.Migrations -{ - public partial class AddBPMAndLengthSorting : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index e0521307fc..26a83f930c 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -18,8 +18,6 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Types; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; From 3ea9629daf6cdbd22658ec4ef5f457d8f86f4d3d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 20:11:44 +0300 Subject: [PATCH 07/23] Move BPM out of OnlineInfo --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs | 2 +- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 5 +---- osu.Game.Tournament/Components/SongBar.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 5 +---- osu.Game/Beatmaps/BeatmapSetInfo.cs | 5 +++++ osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 5 ----- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 2 +- 10 files changed, 14 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index a9c44c9020..75e8c88f9d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -96,11 +96,11 @@ namespace osu.Game.Tests.Visual.Online FavouriteCount = 456, Submitted = DateTime.Now, Ranked = DateTime.Now, - BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, + BPM = 111, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { @@ -169,11 +169,11 @@ namespace osu.Game.Tests.Visual.Online FavouriteCount = 456, Submitted = DateTime.Now, Ranked = DateTime.Now, - BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, + BPM = 111, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 53dbaeddda..5f80223541 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -47,11 +47,11 @@ namespace osu.Game.Tests.Visual.Online Preview = @"https://b.ppy.sh/preview/12345.mp3", PlayCount = 123, FavouriteCount = 456, - BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, + BPM = 111, Beatmaps = new List { new BeatmapInfo diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 04c75d70e3..5813e9e6d5 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -300,10 +300,7 @@ namespace osu.Game.Tests.Visual.SongSelect }, Beatmaps = beatmaps, DateAdded = DateTimeOffset.UtcNow, - OnlineInfo = new BeatmapSetOnlineInfo - { - BPM = bpm, - } + BPM = bpm, }; } } diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index c07882ddd0..06541bc264 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -158,7 +158,7 @@ namespace osu.Game.Tournament.Components return; } - var bpm = beatmap.BeatmapSet.OnlineInfo.BPM; + var bpm = beatmap.BeatmapSet.BPM; var length = beatmap.OnlineInfo.Length; string hardRockExtra = ""; string srExtra = ""; diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b4c211ad53..f94c461c9a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -272,10 +272,7 @@ namespace osu.Game.Beatmaps Beatmaps = new List(), Metadata = beatmap.Metadata, DateAdded = DateTimeOffset.UtcNow, - OnlineInfo = new BeatmapSetOnlineInfo - { - BPM = beatmap.ControlPointInfo.BPMMode, - } + BPM = beatmap.ControlPointInfo.BPMMode, }; } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index cdf8ddb5a1..2b4ef961ce 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -35,6 +35,11 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapSetMetrics Metrics { get; set; } + /// + /// The beats per minute of this beatmap set's song. + /// + public double BPM { get; set; } + public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; public double MaxLength => Beatmaps?.Max(b => b.OnlineInfo.Length) ?? 0; diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index ea3f0b61b9..903d07bea0 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -51,11 +51,6 @@ namespace osu.Game.Beatmaps /// public string Preview { get; set; } - /// - /// The beats per minute of this beatmap set's song. - /// - public double BPM { get; set; } - /// /// The amount of plays this beatmap set has. /// diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 200a705500..50128bde7a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -77,13 +77,13 @@ namespace osu.Game.Online.API.Requests.Responses Metadata = this, Status = Status, Metrics = ratings == null ? null : new BeatmapSetMetrics { Ratings = ratings }, + BPM = bpm, OnlineInfo = new BeatmapSetOnlineInfo { Covers = covers, Preview = preview, PlayCount = playCount, FavouriteCount = favouriteCount, - BPM = bpm, Status = Status, HasVideo = hasVideo, HasStoryboard = hasStoryboard, diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index 6a583baf38..651ef30bdc 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateDisplay() { - bpm.Value = BeatmapSet?.OnlineInfo?.BPM.ToString(@"0.##") ?? "-"; + bpm.Value = BeatmapSet?.BPM.ToString(@"0.##") ?? "-"; if (beatmap == null) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 7934cf388f..6457f78746 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Select.Carousel return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); case SortMode.BPM: - return BeatmapSet.OnlineInfo.BPM.CompareTo(otherSet.BeatmapSet.OnlineInfo.BPM); + return BeatmapSet.BPM.CompareTo(otherSet.BeatmapSet.BPM); case SortMode.Length: return BeatmapSet.MaxLength.CompareTo(otherSet.BeatmapSet.MaxLength); From 729f0901f7bca3595c2834822a440f2f92433910 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 20:25:36 +0300 Subject: [PATCH 08/23] Move Length out of OnlineInfo --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 5 +---- osu.Game.Tournament/Components/SongBar.cs | 2 +- osu.Game/Beatmaps/BeatmapInfo.cs | 5 +++++ osu.Game/Beatmaps/BeatmapManager.cs | 6 +----- osu.Game/Beatmaps/BeatmapOnlineInfo.cs | 5 ----- osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 +- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 2 +- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 4 ++-- 10 files changed, 15 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 75e8c88f9d..02b26acb7c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -108,6 +108,7 @@ namespace osu.Game.Tests.Visual.Online { StarDifficulty = 9.99, Version = @"TEST", + Length = 456000, Ruleset = maniaRuleset, BaseDifficulty = new BeatmapDifficulty { @@ -118,7 +119,6 @@ namespace osu.Game.Tests.Visual.Online }, OnlineInfo = new BeatmapOnlineInfo { - Length = 456000, CircleCount = 111, SliderCount = 12, PlayCount = 222, @@ -181,6 +181,7 @@ namespace osu.Game.Tests.Visual.Online { StarDifficulty = 5.67, Version = @"ANOTHER TEST", + Length = 123000, Ruleset = taikoRuleset, BaseDifficulty = new BeatmapDifficulty { @@ -191,7 +192,6 @@ namespace osu.Game.Tests.Visual.Online }, OnlineInfo = new BeatmapOnlineInfo { - Length = 123000, CircleCount = 123, SliderCount = 45, PlayCount = 567, diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 5813e9e6d5..0b0f65f572 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -275,14 +275,11 @@ namespace osu.Game.Tests.Visual.SongSelect OnlineBeatmapID = beatmapId, Path = "normal.osu", Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss})", + Length = length, BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = 3.5f, }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = length, - } }); } diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index 06541bc264..938fbba303 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -159,7 +159,7 @@ namespace osu.Game.Tournament.Components } var bpm = beatmap.BeatmapSet.BPM; - var length = beatmap.OnlineInfo.Length; + var length = beatmap.Length; string hardRockExtra = ""; string srExtra = ""; diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3c082bb71e..1610e37620 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -51,6 +51,11 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapOnlineInfo OnlineInfo { get; set; } + /// + /// The length in milliseconds of this beatmap's song. + /// + public double Length { get; set; } + public string Path { get; set; } [JsonProperty("file_sha2")] diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f94c461c9a..810db1589e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -303,11 +303,7 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Ruleset = ruleset; // TODO: this should be done in a better place once we actually need to dynamically update it. beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0; - - beatmap.BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo - { - Length = beatmap.CalculateLength(), - }; + beatmap.BeatmapInfo.Length = beatmap.CalculateLength(); beatmapInfos.Add(beatmap.BeatmapInfo); } diff --git a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs index faae74db88..bfeacd9bfc 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs @@ -8,11 +8,6 @@ namespace osu.Game.Beatmaps /// public class BeatmapOnlineInfo { - /// - /// The length in milliseconds of this beatmap's song. - /// - public double Length { get; set; } - /// /// The amount of circles in this beatmap. /// diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 2b4ef961ce..62366cab4e 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; - public double MaxLength => Beatmaps?.Max(b => b.OnlineInfo.Length) ?? 0; + public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; [NotMapped] public bool DeletePending { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index bcbe060f82..ff4d240bf0 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -71,6 +71,7 @@ namespace osu.Game.Online.API.Requests.Responses StarDifficulty = starDifficulty, OnlineBeatmapID = OnlineBeatmapID, Version = version, + Length = length, Status = Status, BeatmapSet = set, Metrics = metrics, @@ -85,7 +86,6 @@ namespace osu.Game.Online.API.Requests.Responses { PlayCount = playCount, PassCount = passCount, - Length = length, CircleCount = circleCount, SliderCount = sliderCount, }, diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index 651ef30bdc..f97212f180 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.BeatmapSet } else { - length.Value = TimeSpan.FromSeconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss"); + length.Value = TimeSpan.FromSeconds(beatmap.Length).ToString(@"m\:ss"); circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString(); sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString(); } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index fa24a64d51..490012da61 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -50,8 +50,8 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.Length: // Length comparing must be in seconds - if (TimeSpan.FromMilliseconds(Beatmap.OnlineInfo.Length).Seconds != TimeSpan.FromMilliseconds(otherBeatmap.Beatmap.OnlineInfo.Length).Seconds) - return Beatmap.OnlineInfo.Length.CompareTo(otherBeatmap.Beatmap.OnlineInfo.Length); + if (TimeSpan.FromMilliseconds(Beatmap.Length).Seconds != TimeSpan.FromMilliseconds(otherBeatmap.Beatmap.Length).Seconds) + return Beatmap.Length.CompareTo(otherBeatmap.Beatmap.Length); goto case SortMode.Difficulty; } From d8745746129c26f25d6ac40ac67a5d1c2b52effc Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 7 Jul 2019 20:25:59 +0300 Subject: [PATCH 09/23] Add migration --- ...7172237_AddBPMAndLengthColumns.Designer.cs | 504 ++++++++++++++++++ .../20190707172237_AddBPMAndLengthColumns.cs | 33 ++ .../Migrations/OsuDbContextModelSnapshot.cs | 4 + 3 files changed, 541 insertions(+) create mode 100644 osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs create mode 100644 osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs diff --git a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs b/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs new file mode 100644 index 0000000000..c1e9f5071a --- /dev/null +++ b/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs @@ -0,0 +1,504 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using osu.Game.Database; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20190707172237_AddBPMAndLengthColumns")] + partial class AddBPMAndLengthColumns + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.4-servicing-10062"); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("ApproachRate"); + + b.Property("CircleSize"); + + b.Property("DrainRate"); + + b.Property("OverallDifficulty"); + + b.Property("SliderMultiplier"); + + b.Property("SliderTickRate"); + + b.HasKey("ID"); + + b.ToTable("BeatmapDifficulty"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("AudioLeadIn"); + + b.Property("BaseDifficultyID"); + + b.Property("BeatDivisor"); + + b.Property("BeatmapSetInfoID"); + + b.Property("Countdown"); + + b.Property("DistanceSpacing"); + + b.Property("GridSize"); + + b.Property("Hash"); + + b.Property("Hidden"); + + b.Property("Length"); + + b.Property("LetterboxInBreaks"); + + b.Property("MD5Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapID"); + + b.Property("Path"); + + b.Property("RulesetID"); + + b.Property("SpecialStyle"); + + b.Property("StackLeniency"); + + b.Property("StarDifficulty"); + + b.Property("Status"); + + b.Property("StoredBookmarks"); + + b.Property("TimelineZoom"); + + b.Property("Version"); + + b.Property("WidescreenStoryboard"); + + b.HasKey("ID"); + + b.HasIndex("BaseDifficultyID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("Hash"); + + b.HasIndex("MD5Hash"); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("BeatmapInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Artist"); + + b.Property("ArtistUnicode"); + + b.Property("AudioFile"); + + b.Property("AuthorString") + .HasColumnName("Author"); + + b.Property("BackgroundFile"); + + b.Property("PreviewTime"); + + b.Property("Source"); + + b.Property("Tags"); + + b.Property("Title"); + + b.Property("TitleUnicode"); + + b.HasKey("ID"); + + b.ToTable("BeatmapMetadata"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BeatmapSetInfoID"); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.HasKey("ID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("FileInfoID"); + + b.ToTable("BeatmapSetFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BPM"); + + b.Property("DateAdded"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapSetID"); + + b.Property("Protected"); + + b.Property("Status"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + + b.ToTable("BeatmapSetInfo"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Key") + .HasColumnName("Key"); + + b.Property("RulesetID"); + + b.Property("SkinInfoID"); + + b.Property("StringValue") + .HasColumnName("Value"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("SkinInfoID"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("osu.Game.IO.FileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Hash"); + + b.Property("ReferenceCount"); + + b.HasKey("ID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("ReferenceCount"); + + b.ToTable("FileInfo"); + }); + + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntAction") + .HasColumnName("Action"); + + b.Property("KeysString") + .HasColumnName("Keys"); + + b.Property("RulesetID"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("IntAction"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("KeyBinding"); + }); + + modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Available"); + + b.Property("InstantiationInfo"); + + b.Property("Name"); + + b.Property("ShortName"); + + b.HasKey("ID"); + + b.HasIndex("Available"); + + b.HasIndex("ShortName") + .IsUnique(); + + b.ToTable("RulesetInfo"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.Property("ScoreInfoID"); + + b.HasKey("ID"); + + b.HasIndex("FileInfoID"); + + b.HasIndex("ScoreInfoID"); + + b.ToTable("ScoreFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Accuracy") + .HasColumnType("DECIMAL(1,4)"); + + b.Property("BeatmapInfoID"); + + b.Property("Combo"); + + b.Property("Date"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MaxCombo"); + + b.Property("ModsJson") + .HasColumnName("Mods"); + + b.Property("OnlineScoreID"); + + b.Property("PP"); + + b.Property("Rank"); + + b.Property("RulesetID"); + + b.Property("StatisticsJson") + .HasColumnName("Statistics"); + + b.Property("TotalScore"); + + b.Property("UserID") + .HasColumnName("UserID"); + + b.Property("UserString") + .HasColumnName("User"); + + b.HasKey("ID"); + + b.HasIndex("BeatmapInfoID"); + + b.HasIndex("OnlineScoreID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("ScoreInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.Property("SkinInfoID"); + + b.HasKey("ID"); + + b.HasIndex("FileInfoID"); + + b.HasIndex("SkinInfoID"); + + b.ToTable("SkinFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Creator"); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("Name"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.ToTable("SkinInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") + .WithMany() + .HasForeignKey("BaseDifficultyID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") + .WithMany("Beatmaps") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("Beatmaps") + .HasForeignKey("MetadataID"); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") + .WithMany("Files") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("BeatmapSets") + .HasForeignKey("MetadataID"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.HasOne("osu.Game.Skinning.SkinInfo") + .WithMany("Settings") + .HasForeignKey("SkinInfoID"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b => + { + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Scoring.ScoreInfo") + .WithMany("Files") + .HasForeignKey("ScoreInfoID"); + }); + + modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap") + .WithMany("Scores") + .HasForeignKey("BeatmapInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Skinning.SkinInfo") + .WithMany("Files") + .HasForeignKey("SkinInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs b/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs new file mode 100644 index 0000000000..b14722daf6 --- /dev/null +++ b/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace osu.Game.Migrations +{ + public partial class AddBPMAndLengthColumns : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BPM", + table: "BeatmapSetInfo", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "Length", + table: "BeatmapInfo", + nullable: false, + defaultValue: 0.0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BPM", + table: "BeatmapSetInfo"); + + migrationBuilder.DropColumn( + name: "Length", + table: "BeatmapInfo"); + } + } +} diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs index 11b032a941..9e65dc7f0f 100644 --- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs +++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs @@ -61,6 +61,8 @@ namespace osu.Game.Migrations b.Property("Hidden"); + b.Property("Length"); + b.Property("LetterboxInBreaks"); b.Property("MD5Hash"); @@ -166,6 +168,8 @@ namespace osu.Game.Migrations b.Property("ID") .ValueGeneratedOnAdd(); + b.Property("BPM"); + b.Property("DateAdded"); b.Property("DeletePending"); From 90d5484818b9e0372694a1d99a3801d340699bd3 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 09:10:41 +0300 Subject: [PATCH 10/23] Return BPM back to OnlineInfo Revert commit of "Move BPM out of OnlineInfo" --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs | 2 +- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 5 ++++- osu.Game/Beatmaps/BeatmapManager.cs | 5 ++++- osu.Game/Beatmaps/BeatmapSetInfo.cs | 5 ----- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 5 +++++ osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 2 +- 9 files changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 02b26acb7c..daee419b52 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -96,11 +96,11 @@ namespace osu.Game.Tests.Visual.Online FavouriteCount = 456, Submitted = DateTime.Now, Ranked = DateTime.Now, + BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, - BPM = 111, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { @@ -169,11 +169,11 @@ namespace osu.Game.Tests.Visual.Online FavouriteCount = 456, Submitted = DateTime.Now, Ranked = DateTime.Now, + BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, - BPM = 111, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 5f80223541..53dbaeddda 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -47,11 +47,11 @@ namespace osu.Game.Tests.Visual.Online Preview = @"https://b.ppy.sh/preview/12345.mp3", PlayCount = 123, FavouriteCount = 456, + BPM = 111, HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, - BPM = 111, Beatmaps = new List { new BeatmapInfo diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 0b0f65f572..27a341ffb7 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -297,7 +297,10 @@ namespace osu.Game.Tests.Visual.SongSelect }, Beatmaps = beatmaps, DateAdded = DateTimeOffset.UtcNow, - BPM = bpm, + OnlineInfo = new BeatmapSetOnlineInfo + { + BPM = bpm, + } }; } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 810db1589e..34a8ddf5c9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -272,7 +272,10 @@ namespace osu.Game.Beatmaps Beatmaps = new List(), Metadata = beatmap.Metadata, DateAdded = DateTimeOffset.UtcNow, - BPM = beatmap.ControlPointInfo.BPMMode, + OnlineInfo = new BeatmapSetOnlineInfo + { + BPM = beatmap.ControlPointInfo.BPMMode, + } }; } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 62366cab4e..a77dfa2148 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -35,11 +35,6 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapSetMetrics Metrics { get; set; } - /// - /// The beats per minute of this beatmap set's song. - /// - public double BPM { get; set; } - public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 903d07bea0..ea3f0b61b9 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -51,6 +51,11 @@ namespace osu.Game.Beatmaps /// public string Preview { get; set; } + /// + /// The beats per minute of this beatmap set's song. + /// + public double BPM { get; set; } + /// /// The amount of plays this beatmap set has. /// diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 50128bde7a..200a705500 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -77,13 +77,13 @@ namespace osu.Game.Online.API.Requests.Responses Metadata = this, Status = Status, Metrics = ratings == null ? null : new BeatmapSetMetrics { Ratings = ratings }, - BPM = bpm, OnlineInfo = new BeatmapSetOnlineInfo { Covers = covers, Preview = preview, PlayCount = playCount, FavouriteCount = favouriteCount, + BPM = bpm, Status = Status, HasVideo = hasVideo, HasStoryboard = hasStoryboard, diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index f97212f180..2926c82631 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateDisplay() { - bpm.Value = BeatmapSet?.BPM.ToString(@"0.##") ?? "-"; + bpm.Value = BeatmapSet?.OnlineInfo?.BPM.ToString(@"0.##") ?? "-"; if (beatmap == null) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 6457f78746..7934cf388f 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Select.Carousel return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); case SortMode.BPM: - return BeatmapSet.BPM.CompareTo(otherSet.BeatmapSet.BPM); + return BeatmapSet.OnlineInfo.BPM.CompareTo(otherSet.BeatmapSet.OnlineInfo.BPM); case SortMode.Length: return BeatmapSet.MaxLength.CompareTo(otherSet.BeatmapSet.MaxLength); From 79ddb8d5d36f76131d5c75da5f6650d91ffa22c9 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 09:23:01 +0300 Subject: [PATCH 11/23] Change to a more convenient xmldoc --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 1610e37620..609f75461c 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -52,7 +52,7 @@ namespace osu.Game.Beatmaps public BeatmapOnlineInfo OnlineInfo { get; set; } /// - /// The length in milliseconds of this beatmap's song. + /// The playable length of this beatmap. /// public double Length { get; set; } From 2d0c924bdf579bd935f1eaf9fa19ce50aba39d5f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 09:35:12 +0300 Subject: [PATCH 12/23] Add xmldoc for MaxStarDifficulty and MaxLength --- osu.Game/Beatmaps/BeatmapSetInfo.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index a77dfa2148..3e6385bdd5 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -35,8 +35,14 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapSetMetrics Metrics { get; set; } + /// + /// The maximum star difficulty of all beatmaps in this set. + /// public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; + /// + /// The maximum playable length of all beatmaps in this set. + /// public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; [NotMapped] From 129899f41950da4d0f11557000e5af1a617777d7 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 10:43:35 +0300 Subject: [PATCH 13/23] Add a BPM property in BeatmapInfo --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 12 +++++------- osu.Game.Tournament/Components/SongBar.cs | 2 +- osu.Game/Beatmaps/BeatmapInfo.cs | 5 +++++ osu.Game/Beatmaps/BeatmapManager.cs | 7 ++----- osu.Game/Beatmaps/BeatmapSetInfo.cs | 5 +++++ .../Screens/Select/Carousel/CarouselBeatmapSet.cs | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 27a341ffb7..f3255814f2 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -267,15 +267,18 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 0; i < 6; i++) { int beatmapId = setId * 10 + i; + int length = RNG.Next(30000, 200000); + double bpm = RNG.NextSingle(80, 200); beatmaps.Add(new BeatmapInfo { Ruleset = getRuleset(), OnlineBeatmapID = beatmapId, Path = "normal.osu", - Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss})", + Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})", Length = length, + BPM = bpm, BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = 3.5f, @@ -283,7 +286,6 @@ namespace osu.Game.Tests.Visual.SongSelect }); } - double bpm = RNG.NextSingle(80, 200); return new BeatmapSetInfo { OnlineBeatmapSetID = setId, @@ -292,15 +294,11 @@ namespace osu.Game.Tests.Visual.SongSelect { // Create random metadata, then we can check if sorting works based on these Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id {setId}, bpm {bpm:0.#})", + Title = $"Some Song (set id {setId}, max bpm {beatmaps.Max(b => b.BPM):0.#})", AuthorString = "Some Guy " + RNG.Next(0, 9), }, Beatmaps = beatmaps, DateAdded = DateTimeOffset.UtcNow, - OnlineInfo = new BeatmapSetOnlineInfo - { - BPM = bpm, - } }; } } diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index 938fbba303..ec021a8d1f 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -158,7 +158,7 @@ namespace osu.Game.Tournament.Components return; } - var bpm = beatmap.BeatmapSet.BPM; + var bpm = beatmap.BeatmapSet.OnlineInfo.BPM; var length = beatmap.Length; string hardRockExtra = ""; string srExtra = ""; diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 609f75461c..fa1282647e 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -56,6 +56,11 @@ namespace osu.Game.Beatmaps /// public double Length { get; set; } + /// + /// The most common BPM of this beatmap. + /// + public double BPM { get; set; } + public string Path { get; set; } [JsonProperty("file_sha2")] diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 34a8ddf5c9..56816607ee 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -271,11 +271,7 @@ namespace osu.Game.Beatmaps OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID, Beatmaps = new List(), Metadata = beatmap.Metadata, - DateAdded = DateTimeOffset.UtcNow, - OnlineInfo = new BeatmapSetOnlineInfo - { - BPM = beatmap.ControlPointInfo.BPMMode, - } + DateAdded = DateTimeOffset.UtcNow }; } @@ -307,6 +303,7 @@ namespace osu.Game.Beatmaps // TODO: this should be done in a better place once we actually need to dynamically update it. beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0; beatmap.BeatmapInfo.Length = beatmap.CalculateLength(); + beatmap.BeatmapInfo.BPM = beatmap.ControlPointInfo.BPMMode; beatmapInfos.Add(beatmap.BeatmapInfo); } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 3e6385bdd5..4075263e12 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -45,6 +45,11 @@ namespace osu.Game.Beatmaps /// public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; + /// + /// The maximum BPM of all beatmaps in this set. + /// + public double MaxBPM => Beatmaps?.Max(b => b.BPM) ?? 0; + [NotMapped] public bool DeletePending { get; set; } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 7934cf388f..5a3996bb49 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Select.Carousel return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); case SortMode.BPM: - return BeatmapSet.OnlineInfo.BPM.CompareTo(otherSet.BeatmapSet.OnlineInfo.BPM); + return BeatmapSet.MaxBPM.CompareTo(otherSet.BeatmapSet.MaxBPM); case SortMode.Length: return BeatmapSet.MaxLength.CompareTo(otherSet.BeatmapSet.MaxLength); From 574d9a51b393a1baae947eab18d08ff1fa74da85 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 10:44:23 +0300 Subject: [PATCH 14/23] Update migrations --- ...cs => 20190708070844_AddBPMAndLengthColumns.Designer.cs} | 6 +++--- ...hColumns.cs => 20190708070844_AddBPMAndLengthColumns.cs} | 4 ++-- osu.Game/Migrations/OsuDbContextModelSnapshot.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename osu.Game/Migrations/{20190707172237_AddBPMAndLengthColumns.Designer.cs => 20190708070844_AddBPMAndLengthColumns.Designer.cs} (99%) rename osu.Game/Migrations/{20190707172237_AddBPMAndLengthColumns.cs => 20190708070844_AddBPMAndLengthColumns.cs} (91%) diff --git a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs b/osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.Designer.cs similarity index 99% rename from osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs rename to osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.Designer.cs index c1e9f5071a..c5fcc16f84 100644 --- a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.Designer.cs +++ b/osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.Designer.cs @@ -9,7 +9,7 @@ using osu.Game.Database; namespace osu.Game.Migrations { [DbContext(typeof(OsuDbContext))] - [Migration("20190707172237_AddBPMAndLengthColumns")] + [Migration("20190708070844_AddBPMAndLengthColumns")] partial class AddBPMAndLengthColumns { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -47,6 +47,8 @@ namespace osu.Game.Migrations b.Property("AudioLeadIn"); + b.Property("BPM"); + b.Property("BaseDifficultyID"); b.Property("BeatDivisor"); @@ -170,8 +172,6 @@ namespace osu.Game.Migrations b.Property("ID") .ValueGeneratedOnAdd(); - b.Property("BPM"); - b.Property("DateAdded"); b.Property("DeletePending"); diff --git a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs b/osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.cs similarity index 91% rename from osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs rename to osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.cs index b14722daf6..f5963ebf5e 100644 --- a/osu.Game/Migrations/20190707172237_AddBPMAndLengthColumns.cs +++ b/osu.Game/Migrations/20190708070844_AddBPMAndLengthColumns.cs @@ -8,7 +8,7 @@ namespace osu.Game.Migrations { migrationBuilder.AddColumn( name: "BPM", - table: "BeatmapSetInfo", + table: "BeatmapInfo", nullable: false, defaultValue: 0.0); @@ -23,7 +23,7 @@ namespace osu.Game.Migrations { migrationBuilder.DropColumn( name: "BPM", - table: "BeatmapSetInfo"); + table: "BeatmapInfo"); migrationBuilder.DropColumn( name: "Length", diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs index 9e65dc7f0f..761dca2801 100644 --- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs +++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs @@ -45,6 +45,8 @@ namespace osu.Game.Migrations b.Property("AudioLeadIn"); + b.Property("BPM"); + b.Property("BaseDifficultyID"); b.Property("BeatDivisor"); @@ -168,8 +170,6 @@ namespace osu.Game.Migrations b.Property("ID") .ValueGeneratedOnAdd(); - b.Property("BPM"); - b.Property("DateAdded"); b.Property("DeletePending"); From 5f3f59629ec04a69132f3419d8e2667795500ffb Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 11:55:07 +0300 Subject: [PATCH 15/23] Use the length field instead of recalculating --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 26a83f930c..2551ffe2fc 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -291,7 +291,7 @@ namespace osu.Game.Screens.Select { Name = "Length", Icon = FontAwesome.Regular.Clock, - Content = TimeSpan.FromMilliseconds(b.CalculateLength()).ToString(@"m\:ss"), + Content = TimeSpan.FromMilliseconds(b.BeatmapInfo.Length).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic From b62e69d170ebd0ed24c704a2a1ebf6397af32a82 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 11:56:48 +0300 Subject: [PATCH 16/23] Calculate length inside BeatmapManager --- osu.Game/Beatmaps/BeatmapManager.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 56816607ee..6fe70b6ec6 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -23,6 +23,7 @@ using osu.Game.IO.Archives; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; +using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { @@ -302,7 +303,7 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Ruleset = ruleset; // TODO: this should be done in a better place once we actually need to dynamically update it. beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0; - beatmap.BeatmapInfo.Length = beatmap.CalculateLength(); + beatmap.BeatmapInfo.Length = calculateLength(beatmap); beatmap.BeatmapInfo.BPM = beatmap.ControlPointInfo.BPMMode; beatmapInfos.Add(beatmap.BeatmapInfo); @@ -312,6 +313,14 @@ namespace osu.Game.Beatmaps return beatmapInfos; } + private double calculateLength(IBeatmap b) + { + var lastObject = b.HitObjects.LastOrDefault(); + var endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + + return endTime - b.HitObjects.FirstOrDefault()?.StartTime ?? 0; + } + /// /// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation. /// From 11ef65e3e2d72cd750f4dc1626c3373f0df92864 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 8 Jul 2019 11:57:02 +0300 Subject: [PATCH 17/23] Remove unnecessary extension --- osu.Game/Beatmaps/Beatmap.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 7fca13a1e2..4ebeee40bf 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Game.Beatmaps.ControlPoints; using Newtonsoft.Json; using osu.Game.IO.Serialization.Converters; -using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { @@ -62,15 +61,4 @@ namespace osu.Game.Beatmaps { public new Beatmap Clone() => (Beatmap)base.Clone(); } - - public static class BeatmapExtensions - { - public static double CalculateLength(this IBeatmap b) - { - HitObject lastObject = b.HitObjects.LastOrDefault(); - var endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; - - return endTime - b.HitObjects.FirstOrDefault()?.StartTime ?? 0; - } - } } From e0c1fb78181571b926f12e84e4f6a508861191ad Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 9 Jul 2019 14:47:54 +0300 Subject: [PATCH 18/23] Compare by milliseconds for length --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 490012da61..c38b13cfca 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -49,11 +49,7 @@ namespace osu.Game.Screens.Select.Carousel return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty); case SortMode.Length: - // Length comparing must be in seconds - if (TimeSpan.FromMilliseconds(Beatmap.Length).Seconds != TimeSpan.FromMilliseconds(otherBeatmap.Beatmap.Length).Seconds) - return Beatmap.Length.CompareTo(otherBeatmap.Beatmap.Length); - - goto case SortMode.Difficulty; + return Beatmap.Length.CompareTo(otherBeatmap.Beatmap.Length); } } From 38bc652bf2b8b740fcf1008dcb67759f93fccc52 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 9 Jul 2019 17:02:51 +0300 Subject: [PATCH 19/23] Remove sorting by length for beatmaps --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index c38b13cfca..712ab7b571 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -47,9 +47,6 @@ namespace osu.Game.Screens.Select.Carousel if (ruleset != 0) return ruleset; return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty); - - case SortMode.Length: - return Beatmap.Length.CompareTo(otherBeatmap.Beatmap.Length); } } From f3329f4d792dc97f064f5ab0f0e51384b9ae795c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 9 Jul 2019 17:22:21 +0300 Subject: [PATCH 20/23] Use a more readable code for calculating length --- osu.Game/Beatmaps/BeatmapManager.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6fe70b6ec6..4f67139706 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -315,10 +315,15 @@ namespace osu.Game.Beatmaps private double calculateLength(IBeatmap b) { - var lastObject = b.HitObjects.LastOrDefault(); - var endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + if (!b.HitObjects.Any()) + return 0; - return endTime - b.HitObjects.FirstOrDefault()?.StartTime ?? 0; + var lastObject = b.HitObjects.Last(); + + double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime; + double startTime = b.HitObjects.First().StartTime; + + return endTime - startTime; } /// From 1485c273ab1f3b36f7357823db220536e79c4a6b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 9 Jul 2019 17:31:15 +0300 Subject: [PATCH 21/23] Describe the xmldoc mo --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index fa1282647e..8042f6b4b9 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -52,7 +52,7 @@ namespace osu.Game.Beatmaps public BeatmapOnlineInfo OnlineInfo { get; set; } /// - /// The playable length of this beatmap. + /// The playable length in milliseconds of this beatmap. /// public double Length { get; set; } From e73f22eff8844b3ee429764801c8b4164a194eb6 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 9 Jul 2019 17:53:34 +0300 Subject: [PATCH 22/23] Convert length retrieved from online to milliseconds --- osu.Game.Tournament/Components/SongBar.cs | 2 +- osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 +- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index ec021a8d1f..7005c068ae 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -180,7 +180,7 @@ namespace osu.Game.Tournament.Components panelContents.Children = new Drawable[] { - new DiffPiece(("Length", TimeSpan.FromSeconds(length).ToString(@"mm\:ss"))) + new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss"))) { Anchor = Anchor.CentreLeft, Origin = Anchor.BottomLeft, diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 4075263e12..03bc7c7312 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -41,7 +41,7 @@ namespace osu.Game.Beatmaps public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; /// - /// The maximum playable length of all beatmaps in this set. + /// The maximum playable length in milliseconds of all beatmaps in this set. /// public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index ff4d240bf0..f50e281dd0 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; @@ -71,7 +72,7 @@ namespace osu.Game.Online.API.Requests.Responses StarDifficulty = starDifficulty, OnlineBeatmapID = OnlineBeatmapID, Version = version, - Length = length, + Length = TimeSpan.FromSeconds(length).Milliseconds, Status = Status, BeatmapSet = set, Metrics = metrics, From c3315e805f92e2cb2e38d3ad42bdca7fa8283416 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 10 Jul 2019 16:49:32 +0300 Subject: [PATCH 23/23] Use milliseconds for BasicStats' beatmap length --- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index 2926c82631..5b10c4e0bb 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.BeatmapSet } else { - length.Value = TimeSpan.FromSeconds(beatmap.Length).ToString(@"m\:ss"); + length.Value = TimeSpan.FromMilliseconds(beatmap.Length).ToString(@"m\:ss"); circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString(); sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString(); }