diff --git a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs index 0ef448cafe..ffa37c29b7 100644 --- a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs @@ -3,10 +3,8 @@ using System.IO; using System.Linq; -using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.IO; using osu.Game.Beatmaps; -using osu.Game.Database; namespace osu.Desktop.Beatmaps.IO { @@ -18,20 +16,17 @@ namespace osu.Desktop.Beatmaps.IO public static void Register() => AddReader((storage, path) => Directory.Exists(path)); private string basePath { get; } - private Beatmap firstMap { get; } public LegacyFilesystemReader(string path) { basePath = path; + BeatmapFilenames = Directory.GetFiles(basePath, @"*.osu").Select(Path.GetFileName).ToArray(); + if (BeatmapFilenames.Length == 0) throw new FileNotFoundException(@"This directory contains no beatmaps"); + StoryboardFilename = Directory.GetFiles(basePath, @"*.osb").Select(Path.GetFileName).FirstOrDefault(); - using (var stream = new StreamReader(GetStream(BeatmapFilenames[0]))) - { - var decoder = BeatmapDecoder.GetDecoder(stream); - firstMap = decoder.Decode(stream); - } } public override Stream GetStream(string name) @@ -39,14 +34,10 @@ namespace osu.Desktop.Beatmaps.IO return File.OpenRead(Path.Combine(basePath, name)); } - public override BeatmapMetadata ReadMetadata() - { - return firstMap.BeatmapInfo.Metadata; - } - public override void Dispose() { // no-op } + } } diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 2a69be92ca..8c44e6c954 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -7,6 +7,9 @@ using osu.Game.Beatmaps.IO; using osu.Game.Modes; using osu.Game.Modes.Osu; using osu.Game.Tests.Resources; +using osu.Game.Beatmaps.Formats; +using osu.Game.Beatmaps; +using osu.Game.Database; namespace osu.Game.Tests.Beatmaps.IO { @@ -53,7 +56,11 @@ namespace osu.Game.Tests.Beatmaps.IO using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz")) { var reader = new OszArchiveReader(osz); - var meta = reader.ReadMetadata(); + + BeatmapMetadata meta; + 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("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 425c6cc5dc..452bd595c7 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -13,13 +13,13 @@ namespace osu.Game.Beatmaps.Formats { private static Dictionary decoders { get; } = new Dictionary(); - public static BeatmapDecoder GetDecoder(TextReader stream) + public static BeatmapDecoder GetDecoder(StreamReader stream) { - var line = stream.ReadLine()?.Trim(); + string line = stream.ReadLine()?.Trim(); if (line == null || !decoders.ContainsKey(line)) throw new IOException(@"Unknown file format"); - return (BeatmapDecoder)Activator.CreateInstance(decoders[line]); + return (BeatmapDecoder)Activator.CreateInstance(decoders[line], line); } protected static void AddDecoder(string magic) where T : BeatmapDecoder @@ -27,17 +27,17 @@ namespace osu.Game.Beatmaps.Formats decoders[magic] = typeof(T); } - public virtual Beatmap Decode(TextReader stream) + public virtual Beatmap Decode(StreamReader stream) { return ParseFile(stream); } - public virtual void Decode(TextReader stream, Beatmap beatmap) + public virtual void Decode(StreamReader stream, Beatmap beatmap) { ParseFile(stream, beatmap); } - protected virtual Beatmap ParseFile(TextReader stream) + protected virtual Beatmap ParseFile(StreamReader stream) { var beatmap = new Beatmap { @@ -48,9 +48,11 @@ namespace osu.Game.Beatmaps.Formats Difficulty = new BeatmapDifficulty(), }, }; + ParseFile(stream, beatmap); return beatmap; } - protected abstract void ParseFile(TextReader stream, Beatmap beatmap); + + protected abstract void ParseFile(StreamReader stream, Beatmap beatmap); } } diff --git a/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs deleted file mode 100644 index 3e7dbb4d1b..0000000000 --- a/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.IO; - -namespace osu.Game.Beatmaps.Formats -{ - public class ConstructableBeatmapDecoder : BeatmapDecoder - { - protected override void ParseFile(TextReader stream, Beatmap beatmap) - { - throw new NotImplementedException(); - } - } -} diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 20b977499e..6d03205ca2 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -31,6 +31,17 @@ namespace osu.Game.Beatmaps.Formats // TODO: Not sure how far back to go, or differences between versions } + private readonly int beatmapVersion; + + public OsuLegacyDecoder() + { + } + + public OsuLegacyDecoder(string header) + { + beatmapVersion = int.Parse(header.Substring(17)); + } + private enum Section { None, @@ -246,32 +257,36 @@ namespace osu.Game.Beatmaps.Formats } } - protected override Beatmap ParseFile(TextReader stream) + protected override Beatmap ParseFile(StreamReader stream) { return new LegacyBeatmap(base.ParseFile(stream)); } - public override Beatmap Decode(TextReader stream) + public override Beatmap Decode(StreamReader stream) { return new LegacyBeatmap(base.Decode(stream)); } - protected override void ParseFile(TextReader stream, Beatmap beatmap) + protected override void ParseFile(StreamReader stream, Beatmap beatmap) { + beatmap.BeatmapInfo.BeatmapVersion = beatmapVersion; + HitObjectParser parser = null; bool hasCustomColours = false; - var section = Section.None; - while (true) + Section section = Section.None; + string line = null; + while ((line = stream.ReadLine()) != null) { - var line = stream.ReadLine(); - if (line == null) - break; if (string.IsNullOrEmpty(line)) continue; + if (line.StartsWith(@"osu file format v")) + { + beatmap.BeatmapInfo.BeatmapVersion = int.Parse(line.Substring(17)); continue; + } if (line.StartsWith(@"[") && line.EndsWith(@"]")) { diff --git a/osu.Game/Beatmaps/IO/ArchiveReader.cs b/osu.Game/Beatmaps/IO/ArchiveReader.cs index bbf4de20f5..6c6b6be23c 100644 --- a/osu.Game/Beatmaps/IO/ArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/ArchiveReader.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using osu.Framework.IO.Stores; using osu.Framework.Platform; -using osu.Game.Database; namespace osu.Game.Beatmaps.IO { @@ -35,11 +34,6 @@ namespace osu.Game.Beatmaps.IO readers.Add(new Reader { Test = test, Type = typeof(T) }); } - /// - /// Reads the beatmap metadata from this archive. - /// - public abstract BeatmapMetadata ReadMetadata(); - /// /// Gets a list of beatmap file names. /// diff --git a/osu.Game/Beatmaps/IO/OszArchiveReader.cs b/osu.Game/Beatmaps/IO/OszArchiveReader.cs index 5c0f29fb86..6c550def8d 100644 --- a/osu.Game/Beatmaps/IO/OszArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/OszArchiveReader.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using Ionic.Zip; using osu.Game.Beatmaps.Formats; -using osu.Game.Database; namespace osu.Game.Beatmaps.IO { @@ -23,23 +22,18 @@ namespace osu.Game.Beatmaps.IO private readonly Stream archiveStream; private readonly ZipFile archive; - private readonly Beatmap firstMap; public OszArchiveReader(Stream archiveStream) { this.archiveStream = archiveStream; archive = ZipFile.Read(archiveStream); - BeatmapFilenames = archive.Entries.Where(e => e.FileName.EndsWith(@".osu")) - .Select(e => e.FileName).ToArray(); + + BeatmapFilenames = archive.Entries.Where(e => e.FileName.EndsWith(@".osu")).Select(e => e.FileName).ToArray(); + if (BeatmapFilenames.Length == 0) throw new FileNotFoundException(@"This directory contains no beatmaps"); - StoryboardFilename = archive.Entries.Where(e => e.FileName.EndsWith(@".osb")) - .Select(e => e.FileName).FirstOrDefault(); - using (var stream = new StreamReader(GetStream(BeatmapFilenames[0]))) - { - var decoder = BeatmapDecoder.GetDecoder(stream); - firstMap = decoder.Decode(stream); - } + + StoryboardFilename = archive.Entries.Where(e => e.FileName.EndsWith(@".osb")).Select(e => e.FileName).FirstOrDefault(); } public override Stream GetStream(string name) @@ -50,11 +44,6 @@ namespace osu.Game.Beatmaps.IO return entry.OpenReader(); } - public override BeatmapMetadata ReadMetadata() - { - return firstMap.BeatmapInfo.Metadata; - } - public override void Dispose() { archive.Dispose(); diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index dfc916a136..41ddd8df39 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -175,7 +175,10 @@ namespace osu.Game.Database BeatmapMetadata metadata; using (var reader = ArchiveReader.GetReader(storage, path)) - metadata = reader.ReadMetadata(); + { + using (var stream = new StreamReader(reader.GetStream(reader.BeatmapFilenames[0]))) + metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata; + } if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader { diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index cda9cba70c..890623091d 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -15,6 +15,8 @@ namespace osu.Game.Database [PrimaryKey, AutoIncrement] public int ID { get; set; } + public int BeatmapVersion; + public int? OnlineBeatmapID { get; set; } public int? OnlineBeatmapSetID { get; set; } diff --git a/osu.Game/Database/DatabaseWorkingBeatmap.cs b/osu.Game/Database/DatabaseWorkingBeatmap.cs index 1b37cf2fa0..9fb3bed1e7 100644 --- a/osu.Game/Database/DatabaseWorkingBeatmap.cs +++ b/osu.Game/Database/DatabaseWorkingBeatmap.cs @@ -34,12 +34,14 @@ namespace osu.Game.Database using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) { decoder = BeatmapDecoder.GetDecoder(stream); - beatmap = decoder?.Decode(stream); + beatmap = decoder.Decode(stream); } - if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null) - using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile))) - decoder.Decode(stream, beatmap); + if (beatmap == null || !WithStoryboard || BeatmapSetInfo.StoryboardFile == null) + return beatmap; + + using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile))) + decoder.Decode(stream, beatmap); } return beatmap; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ecb3f5084c..a9e8dfb5bb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -142,7 +142,6 @@ -