From f776a54b9a9a2cd5ebf697caac06bd4ac3213a1e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 7 Oct 2016 15:36:20 -0400 Subject: [PATCH] Add more decoding (including full BeatmapMetadata) --- .../Beatmaps/IO/OszArchiveReaderTest.cs | 22 ++ osu.Game/Beatmaps/Beatmap.cs | 2 + osu.Game/Beatmaps/BeatmapMetadata.cs | 1 - osu.Game/Beatmaps/Events/EventType.cs | 14 + osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 271 +++++++++++------- osu.Game/osu.Game.csproj | 2 + 6 files changed, 206 insertions(+), 106 deletions(-) create mode 100644 osu.Game/Beatmaps/Events/EventType.cs diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 275de8121f..502f410951 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -2,6 +2,7 @@ using System.IO; using NUnit.Framework; using osu.Game.Beatmaps.IO; +using osu.Game.GameModes.Play; using osu.Game.Tests.Resources; namespace osu.Game.Tests.Beatmaps.IO @@ -40,6 +41,27 @@ namespace osu.Game.Tests.Beatmaps.IO foreach (var map in expected) Assert.Contains(map, maps); } + } + + [Test] + public void TestReadMetadata() + { + using (var osz = File.OpenRead(Resource.GetPath("241526 Soleily - Renatus.osz"))) + { + var reader = new OszArchiveReader(osz); + var meta = reader.ReadMetadata(); + Assert.AreEqual(241526, meta.BeatmapSetID); + Assert.AreEqual("Soleily", meta.Artist); + Assert.AreEqual("Soleily", meta.ArtistUnicode); + Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); + Assert.AreEqual("Deif", meta.Author); + Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile); + Assert.AreEqual(164471, meta.PreviewTime); + Assert.AreEqual(string.Empty, meta.Source); + Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags); + Assert.AreEqual("Renatus", meta.Title); + Assert.AreEqual("Renatus", meta.TitleUnicode); + } } } } diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index b6ec2855ba..2c96f62988 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Timing; +using osu.Game.GameModes.Play; using osu.Game.Users; using SQLite; @@ -26,6 +27,7 @@ namespace osu.Game.Beatmaps public BeatmapMetadata Metadata { get; set; } [Ignore] public BaseDifficulty BaseDifficulty { get; set; } + public PlayMode Mode { get; set; } public string Version { get; set; } } } \ No newline at end of file diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index a1808a80e6..1499dde323 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -19,7 +19,6 @@ namespace osu.Game.Beatmaps public string Author { get; set; } public string Source { get; set; } public string Tags { get; set; } - public PlayMode Mode { get; set; } public int PreviewTime { get; set; } public string AudioFile { get; set; } public string BackgroundFile { get; set; } diff --git a/osu.Game/Beatmaps/Events/EventType.cs b/osu.Game/Beatmaps/Events/EventType.cs new file mode 100644 index 0000000000..cb66a42f2d --- /dev/null +++ b/osu.Game/Beatmaps/Events/EventType.cs @@ -0,0 +1,14 @@ +using System; +namespace osu.Game.Beatmaps.Events +{ + public enum EventType + { + Background = 0, + Video = 1, + Break = 2, + Colour = 3, + Sprite = 4, + Sample = 5, + Animation = 6 + } +} \ No newline at end of file diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 879a6b0c34..cf01b751a9 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -1,131 +1,192 @@ -using System; +using System; using System.Collections.Generic; using System.IO; +using osu.Game.Beatmaps.Events; using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Timing; using osu.Game.GameModes.Play; -namespace osu.Game.Beatmaps.Formats -{ - public class OsuLegacyDecoder : BeatmapDecoder - { - public static void Register() - { - AddDecoder("osu file format v14"); - AddDecoder("osu file format v13"); - AddDecoder("osu file format v12"); - AddDecoder("osu file format v11"); - AddDecoder("osu file format v10"); - // TODO: Not sure how far back to go, or differences between versions +namespace osu.Game.Beatmaps.Formats +{ + public class OsuLegacyDecoder : BeatmapDecoder + { + public static void Register() + { + AddDecoder("osu file format v14"); + AddDecoder("osu file format v13"); + AddDecoder("osu file format v12"); + AddDecoder("osu file format v11"); + AddDecoder("osu file format v10"); + // TODO: Not sure how far back to go, or differences between versions } - private enum Section - { - None, - General, - Editor, - Metadata, - Difficulty, - Events, - TimingPoints, - Colours, - HitObjects, + + private enum Section + { + None, + General, + Editor, + Metadata, + Difficulty, + Events, + TimingPoints, + Colours, + HitObjects, } - private void HandleGeneral(Beatmap beatmap, string key, string val) - { - switch (key) - { - case "AudioFilename": + + private void HandleGeneral(Beatmap beatmap, string key, string val) + { + switch (key) + { + case "AudioFilename": beatmap.Metadata.AudioFile = val; - break; - case "AudioLeadIn": + break; + case "AudioLeadIn": // TODO - break; - case "PreviewTime": - beatmap.Metadata.PreviewTime = int.Parse(val); - break; - case "Countdown": - // TODO - break; - case "SampleSet": + break; + case "PreviewTime": + beatmap.Metadata.PreviewTime = int.Parse(val); + break; + case "Countdown": // TODO - break; - case "StackLeniency": + break; + case "SampleSet": // TODO - break; - case "Mode": - beatmap.Metadata.Mode = (PlayMode)int.Parse(val); - break; - case "LetterboxInBreaks": + break; + case "StackLeniency": // TODO - break; - case "SpecialStyle": + break; + case "Mode": + beatmap.Mode = (PlayMode)int.Parse(val); + break; + case "LetterboxInBreaks": // TODO - break; - case "WidescreenStoryboard": - // TODO - break; - } + break; + case "SpecialStyle": + // TODO + break; + case "WidescreenStoryboard": + // TODO + break; + } + } + + private void HandleMetadata(Beatmap beatmap, string key, string val) + { + switch (key) + { + case "Title": + beatmap.Metadata.Title = val; + break; + case "TitleUnicode": + beatmap.Metadata.TitleUnicode = val; + break; + case "Artist": + beatmap.Metadata.Artist = val; + break; + case "ArtistUnicode": + beatmap.Metadata.ArtistUnicode = val; + break; + case "Creator": + beatmap.Metadata.Author = val; + break; + case "Version": + beatmap.Version = val; + break; + case "Source": + beatmap.Metadata.Source = val; + break; + case "Tags": + beatmap.Metadata.Tags = val; + break; + case "BeatmapID": + beatmap.BeatmapID = int.Parse(val); + break; + case "BeatmapSetID": + beatmap.BeatmapSetID = int.Parse(val); + beatmap.Metadata.BeatmapSetID = int.Parse(val); + break; + } + } + + private void HandleEvents(Beatmap beatmap, string val) + { + if (val.StartsWith("//")) + return; + string[] split = val.Split(','); + EventType type; + int _type; + if (!int.TryParse(split[0], out _type)) + { + if (!Enum.TryParse(split[0], out type)) + throw new InvalidDataException($@"Unknown event type {split[0]}"); + } + else + type = (EventType)_type; + // TODO: Parse and store the rest of the event + if (type == EventType.Background) + beatmap.Metadata.BackgroundFile = split[2].Trim('"'); } public override Beatmap Decode(TextReader stream) - { - var beatmap = new Beatmap - { - Metadata = new BeatmapMetadata(), - HitObjects = new List(), - ControlPoints = new List(), - }; - var section = Section.None; - string line; + { + var beatmap = new Beatmap + { + Metadata = new BeatmapMetadata(), + BaseDifficulty = new BaseDifficulty(), + HitObjects = new List(), + ControlPoints = new List(), + }; + var section = Section.None; + string line; while (true) - { - line = stream.ReadLine(); + { + line = stream.ReadLine(); if (line == null) - break; - line = line.Trim(); - if (string.IsNullOrEmpty(line)) - continue; - - if (line.StartsWith("[") && line.EndsWith("]")) - { - if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section)) - throw new InvalidOperationException($@"Unknown osu section {line}"); - continue; - } - - string val = line, key = null; - if (section != Section.Events && section != Section.TimingPoints + break; + line = line.Trim(); + if (string.IsNullOrEmpty(line)) + continue; + + if (line.StartsWith("[") && line.EndsWith("]")) + { + if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section)) + throw new InvalidDataException($@"Unknown osu section {line}"); + continue; + } + + string val = line, key = null; + if (section != Section.Events && section != Section.TimingPoints && section != Section.HitObjects) - { - key = val.Remove(val.IndexOf(':')).Trim(); + { + key = val.Remove(val.IndexOf(':')).Trim(); val = val.Substring(val.IndexOf(':') + 1).Trim(); - } - switch (section) - { - case Section.General: - HandleGeneral(beatmap, key, val); - break; - case Section.Editor: - // TODO - break; - case Section.Metadata: + } + switch (section) + { + case Section.General: + HandleGeneral(beatmap, key, val); + break; + case Section.Editor: // TODO - break; - case Section.Difficulty: - // TODO - break; - case Section.Events: + break; + case Section.Metadata: + HandleMetadata(beatmap, key, val); + break; + case Section.Difficulty: // TODO - break; - case Section.TimingPoints: + break; + case Section.Events: + HandleEvents(beatmap, val); + break; + case Section.TimingPoints: // TODO - break; - case Section.HitObjects: + break; + case Section.HitObjects: // TODO - break; - } - } - return beatmap; - } - } + break; + } + } + return beatmap; + } + } } \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8775034271..48cd2da02d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -154,6 +154,7 @@ + @@ -176,6 +177,7 @@ +