1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 15:53:21 +08:00

Slightly clean up archive readers + decoders. Read beatmap version into BeatmapInfo.

This commit is contained in:
smoogipooo 2017-04-03 20:26:46 +09:00
parent 91eec9e8fc
commit 19b5555ef2
11 changed files with 61 additions and 73 deletions

View File

@ -3,10 +3,8 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO; using osu.Game.Beatmaps.IO;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database;
namespace osu.Desktop.Beatmaps.IO namespace osu.Desktop.Beatmaps.IO
{ {
@ -18,20 +16,17 @@ namespace osu.Desktop.Beatmaps.IO
public static void Register() => AddReader<LegacyFilesystemReader>((storage, path) => Directory.Exists(path)); public static void Register() => AddReader<LegacyFilesystemReader>((storage, path) => Directory.Exists(path));
private string basePath { get; } private string basePath { get; }
private Beatmap firstMap { get; }
public LegacyFilesystemReader(string path) public LegacyFilesystemReader(string path)
{ {
basePath = path; basePath = path;
BeatmapFilenames = Directory.GetFiles(basePath, @"*.osu").Select(Path.GetFileName).ToArray(); BeatmapFilenames = Directory.GetFiles(basePath, @"*.osu").Select(Path.GetFileName).ToArray();
if (BeatmapFilenames.Length == 0) if (BeatmapFilenames.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps"); throw new FileNotFoundException(@"This directory contains no beatmaps");
StoryboardFilename = Directory.GetFiles(basePath, @"*.osb").Select(Path.GetFileName).FirstOrDefault(); 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) public override Stream GetStream(string name)
@ -39,14 +34,10 @@ namespace osu.Desktop.Beatmaps.IO
return File.OpenRead(Path.Combine(basePath, name)); return File.OpenRead(Path.Combine(basePath, name));
} }
public override BeatmapMetadata ReadMetadata()
{
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose() public override void Dispose()
{ {
// no-op // no-op
} }
} }
} }

View File

@ -7,6 +7,9 @@ using osu.Game.Beatmaps.IO;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Osu; using osu.Game.Modes.Osu;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps;
using osu.Game.Database;
namespace osu.Game.Tests.Beatmaps.IO 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")) using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz"))
{ {
var reader = new OszArchiveReader(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(241526, meta.OnlineBeatmapSetID);
Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("Soleily", meta.ArtistUnicode);

View File

@ -13,13 +13,13 @@ namespace osu.Game.Beatmaps.Formats
{ {
private static Dictionary<string, Type> decoders { get; } = new Dictionary<string, Type>(); private static Dictionary<string, Type> decoders { get; } = new Dictionary<string, Type>();
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)) if (line == null || !decoders.ContainsKey(line))
throw new IOException(@"Unknown file format"); throw new IOException(@"Unknown file format");
return (BeatmapDecoder)Activator.CreateInstance(decoders[line]); return (BeatmapDecoder)Activator.CreateInstance(decoders[line], line);
} }
protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder
@ -27,17 +27,17 @@ namespace osu.Game.Beatmaps.Formats
decoders[magic] = typeof(T); decoders[magic] = typeof(T);
} }
public virtual Beatmap Decode(TextReader stream) public virtual Beatmap Decode(StreamReader stream)
{ {
return ParseFile(stream); return ParseFile(stream);
} }
public virtual void Decode(TextReader stream, Beatmap beatmap) public virtual void Decode(StreamReader stream, Beatmap beatmap)
{ {
ParseFile(stream, beatmap); ParseFile(stream, beatmap);
} }
protected virtual Beatmap ParseFile(TextReader stream) protected virtual Beatmap ParseFile(StreamReader stream)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
@ -48,9 +48,11 @@ namespace osu.Game.Beatmaps.Formats
Difficulty = new BeatmapDifficulty(), Difficulty = new BeatmapDifficulty(),
}, },
}; };
ParseFile(stream, beatmap); ParseFile(stream, beatmap);
return beatmap; return beatmap;
} }
protected abstract void ParseFile(TextReader stream, Beatmap beatmap);
protected abstract void ParseFile(StreamReader stream, Beatmap beatmap);
} }
} }

View File

@ -1,16 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// 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();
}
}
}

View File

@ -31,6 +31,17 @@ namespace osu.Game.Beatmaps.Formats
// TODO: Not sure how far back to go, or differences between versions // 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 private enum Section
{ {
None, 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)); return new LegacyBeatmap(base.ParseFile(stream));
} }
public override Beatmap Decode(TextReader stream) public override Beatmap Decode(StreamReader stream)
{ {
return new LegacyBeatmap(base.Decode(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; HitObjectParser parser = null;
bool hasCustomColours = false; bool hasCustomColours = false;
var section = Section.None; Section section = Section.None;
while (true) string line = null;
while ((line = stream.ReadLine()) != null)
{ {
var line = stream.ReadLine();
if (line == null)
break;
if (string.IsNullOrEmpty(line)) if (string.IsNullOrEmpty(line))
continue; continue;
if (line.StartsWith(@"osu file format v")) if (line.StartsWith(@"osu file format v"))
{
beatmap.BeatmapInfo.BeatmapVersion = int.Parse(line.Substring(17));
continue; continue;
}
if (line.StartsWith(@"[") && line.EndsWith(@"]")) if (line.StartsWith(@"[") && line.EndsWith(@"]"))
{ {

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Database;
namespace osu.Game.Beatmaps.IO namespace osu.Game.Beatmaps.IO
{ {
@ -35,11 +34,6 @@ namespace osu.Game.Beatmaps.IO
readers.Add(new Reader { Test = test, Type = typeof(T) }); readers.Add(new Reader { Test = test, Type = typeof(T) });
} }
/// <summary>
/// Reads the beatmap metadata from this archive.
/// </summary>
public abstract BeatmapMetadata ReadMetadata();
/// <summary> /// <summary>
/// Gets a list of beatmap file names. /// Gets a list of beatmap file names.
/// </summary> /// </summary>

View File

@ -5,7 +5,6 @@ using System.IO;
using System.Linq; using System.Linq;
using Ionic.Zip; using Ionic.Zip;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
namespace osu.Game.Beatmaps.IO namespace osu.Game.Beatmaps.IO
{ {
@ -23,23 +22,18 @@ namespace osu.Game.Beatmaps.IO
private readonly Stream archiveStream; private readonly Stream archiveStream;
private readonly ZipFile archive; private readonly ZipFile archive;
private readonly Beatmap firstMap;
public OszArchiveReader(Stream archiveStream) public OszArchiveReader(Stream archiveStream)
{ {
this.archiveStream = archiveStream; this.archiveStream = archiveStream;
archive = ZipFile.Read(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) if (BeatmapFilenames.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps"); throw new FileNotFoundException(@"This directory contains no beatmaps");
StoryboardFilename = archive.Entries.Where(e => e.FileName.EndsWith(@".osb"))
.Select(e => e.FileName).FirstOrDefault(); 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);
}
} }
public override Stream GetStream(string name) public override Stream GetStream(string name)
@ -50,11 +44,6 @@ namespace osu.Game.Beatmaps.IO
return entry.OpenReader(); return entry.OpenReader();
} }
public override BeatmapMetadata ReadMetadata()
{
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose() public override void Dispose()
{ {
archive.Dispose(); archive.Dispose();

View File

@ -175,7 +175,10 @@ namespace osu.Game.Database
BeatmapMetadata metadata; BeatmapMetadata metadata;
using (var reader = ArchiveReader.GetReader(storage, path)) 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 if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader
{ {

View File

@ -15,6 +15,8 @@ namespace osu.Game.Database
[PrimaryKey, AutoIncrement] [PrimaryKey, AutoIncrement]
public int ID { get; set; } public int ID { get; set; }
public int BeatmapVersion;
public int? OnlineBeatmapID { get; set; } public int? OnlineBeatmapID { get; set; }
public int? OnlineBeatmapSetID { get; set; } public int? OnlineBeatmapSetID { get; set; }

View File

@ -34,12 +34,14 @@ namespace osu.Game.Database
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path)))
{ {
decoder = BeatmapDecoder.GetDecoder(stream); decoder = BeatmapDecoder.GetDecoder(stream);
beatmap = decoder?.Decode(stream); beatmap = decoder.Decode(stream);
} }
if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null) if (beatmap == null || !WithStoryboard || BeatmapSetInfo.StoryboardFile == null)
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile))) return beatmap;
decoder.Decode(stream, beatmap);
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile)))
decoder.Decode(stream, beatmap);
} }
return beatmap; return beatmap;

View File

@ -142,7 +142,6 @@
<Compile Include="Overlays\LoginOverlay.cs" /> <Compile Include="Overlays\LoginOverlay.cs" />
<Compile Include="Overlays\MusicController.cs" /> <Compile Include="Overlays\MusicController.cs" />
<Compile Include="Beatmaps\Beatmap.cs" /> <Compile Include="Beatmaps\Beatmap.cs" />
<Compile Include="Beatmaps\Formats\ConstructableBeatmapDecoder.cs" />
<Compile Include="Beatmaps\WorkingBeatmap.cs" /> <Compile Include="Beatmaps\WorkingBeatmap.cs" />
<Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" /> <Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" />
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" /> <Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />