mirror of https://github.com/ppy/osu
split parsing a beatmap and parsing a storyboard
This commit is contained in:
parent
016057ab01
commit
c16925059c
|
@ -22,7 +22,7 @@ public void TestDecodeMetadata()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmap = decoder.Decode(new StreamReader(stream));
|
||||
var beatmap = decoder.DecodeBeatmap(new StreamReader(stream));
|
||||
var meta = beatmap.BeatmapInfo.Metadata;
|
||||
Assert.AreEqual(241526, meta.OnlineBeatmapSetID);
|
||||
Assert.AreEqual("Soleily", meta.Artist);
|
||||
|
@ -44,7 +44,7 @@ public void TestDecodeGeneral()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmapInfo = decoder.Decode(new StreamReader(stream)).BeatmapInfo;
|
||||
var beatmapInfo = decoder.DecodeBeatmap(new StreamReader(stream)).BeatmapInfo;
|
||||
Assert.AreEqual(0, beatmapInfo.AudioLeadIn);
|
||||
Assert.AreEqual(false, beatmapInfo.Countdown);
|
||||
Assert.AreEqual(0.7f, beatmapInfo.StackLeniency);
|
||||
|
@ -61,7 +61,7 @@ public void TestDecodeEditor()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmap = decoder.Decode(new StreamReader(stream)).BeatmapInfo;
|
||||
var beatmap = decoder.DecodeBeatmap(new StreamReader(stream)).BeatmapInfo;
|
||||
int[] expectedBookmarks =
|
||||
{
|
||||
11505, 22054, 32604, 43153, 53703, 64252, 74802, 85351,
|
||||
|
@ -84,7 +84,7 @@ public void TestDecodeDifficulty()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmap = decoder.Decode(new StreamReader(stream));
|
||||
var beatmap = decoder.DecodeBeatmap(new StreamReader(stream));
|
||||
var difficulty = beatmap.BeatmapInfo.BaseDifficulty;
|
||||
Assert.AreEqual(6.5f, difficulty.DrainRate);
|
||||
Assert.AreEqual(4, difficulty.CircleSize);
|
||||
|
@ -101,7 +101,7 @@ public void TestDecodeColors()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmap = decoder.Decode(new StreamReader(stream));
|
||||
var beatmap = decoder.DecodeBeatmap(new StreamReader(stream));
|
||||
Color4[] expected =
|
||||
{
|
||||
new Color4(142, 199, 255, 255),
|
||||
|
@ -123,7 +123,7 @@ public void TestDecodeHitObjects()
|
|||
var decoder = new OsuLegacyDecoder();
|
||||
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
{
|
||||
var beatmap = decoder.Decode(new StreamReader(stream));
|
||||
var beatmap = decoder.DecodeBeatmap(new StreamReader(stream));
|
||||
|
||||
var curveData = beatmap.HitObjects[0] as IHasCurve;
|
||||
var positionData = beatmap.HitObjects[0] as IHasPosition;
|
||||
|
|
|
@ -50,7 +50,7 @@ public void TestReadMetadata()
|
|||
|
||||
BeatmapMetadata meta;
|
||||
using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu")))
|
||||
meta = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||
meta = BeatmapDecoder.GetDecoder(stream).DecodeBeatmap(stream).Metadata;
|
||||
|
||||
Assert.AreEqual(241526, meta.OnlineBeatmapSetID);
|
||||
Assert.AreEqual("Soleily", meta.Artist);
|
||||
|
|
|
@ -79,7 +79,7 @@ private void loadStoryboard(WorkingBeatmap working)
|
|||
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
|
||||
storyboardContainer.Clock = decoupledClock;
|
||||
|
||||
storyboard = working.Beatmap.Storyboard.CreateDrawable(beatmapBacking);
|
||||
storyboard = working.Storyboard.CreateDrawable(beatmapBacking);
|
||||
storyboard.Passing = false;
|
||||
|
||||
storyboardContainer.Add(storyboard);
|
||||
|
|
|
@ -41,11 +41,6 @@ public class Beatmap<T>
|
|||
/// </summary>
|
||||
public double TotalBreakTime => Breaks.Sum(b => b.Duration);
|
||||
|
||||
/// <summary>
|
||||
/// The Beatmap's Storyboard.
|
||||
/// </summary>
|
||||
public Storyboard Storyboard = new Storyboard();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new beatmap.
|
||||
/// </summary>
|
||||
|
@ -57,7 +52,6 @@ public Beatmap(Beatmap<T> original = null)
|
|||
Breaks = original?.Breaks ?? Breaks;
|
||||
ComboColors = original?.ComboColors ?? ComboColors;
|
||||
HitObjects = original?.HitObjects ?? HitObjects;
|
||||
Storyboard = original?.Storyboard ?? Storyboard;
|
||||
|
||||
if (original == null && Metadata == null)
|
||||
{
|
||||
|
|
|
@ -495,7 +495,7 @@ private BeatmapSetInfo importToStorage(FileStore files, BeatmapStore beatmaps, A
|
|||
BeatmapMetadata metadata;
|
||||
|
||||
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
||||
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||
metadata = BeatmapDecoder.GetDecoder(stream).DecodeBeatmap(stream).Metadata;
|
||||
|
||||
// check if a set already exists with the same online id.
|
||||
beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.OnlineBeatmapSetID == metadata.OnlineBeatmapSetID) ?? new BeatmapSetInfo
|
||||
|
@ -519,7 +519,7 @@ private BeatmapSetInfo importToStorage(FileStore files, BeatmapStore beatmaps, A
|
|||
ms.Position = 0;
|
||||
|
||||
var decoder = BeatmapDecoder.GetDecoder(sr);
|
||||
Beatmap beatmap = decoder.Decode(sr);
|
||||
Beatmap beatmap = decoder.DecodeBeatmap(sr);
|
||||
|
||||
beatmap.BeatmapInfo.Path = name;
|
||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||
|
@ -572,7 +572,7 @@ protected override Beatmap GetBeatmap()
|
|||
using (var stream = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo.Path))))
|
||||
{
|
||||
BeatmapDecoder decoder = BeatmapDecoder.GetDecoder(stream);
|
||||
return decoder.Decode(stream);
|
||||
return decoder.DecodeBeatmap(stream);
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
@ -615,19 +615,17 @@ protected override Track GetTrack()
|
|||
|
||||
protected override Storyboard GetStoryboard()
|
||||
{
|
||||
if (BeatmapSetInfo?.StoryboardFile == null)
|
||||
return new Storyboard();
|
||||
|
||||
try
|
||||
{
|
||||
if (Beatmap == null || BeatmapSetInfo.StoryboardFile == null)
|
||||
return new Storyboard();
|
||||
|
||||
BeatmapDecoder decoder;
|
||||
using (var stream = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo.Path))))
|
||||
decoder = BeatmapDecoder.GetDecoder(stream);
|
||||
|
||||
using (var stream = new StreamReader(store.GetStream(getPathForFile(BeatmapSetInfo.StoryboardFile))))
|
||||
decoder.Decode(stream, Beatmap);
|
||||
|
||||
return Beatmap.Storyboard;
|
||||
return decoder.DecodeStoryboard(stream);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
|
@ -35,17 +36,12 @@ protected static void AddDecoder<T>(string magic) where T : BeatmapDecoder
|
|||
decoders[magic] = typeof(T);
|
||||
}
|
||||
|
||||
public virtual Beatmap Decode(StreamReader stream)
|
||||
public virtual Beatmap DecodeBeatmap(StreamReader stream)
|
||||
{
|
||||
return ParseFile(stream);
|
||||
return ParseBeatmap(stream);
|
||||
}
|
||||
|
||||
public virtual void Decode(StreamReader stream, Beatmap beatmap)
|
||||
{
|
||||
ParseFile(stream, beatmap);
|
||||
}
|
||||
|
||||
protected virtual Beatmap ParseFile(StreamReader stream)
|
||||
protected virtual Beatmap ParseBeatmap(StreamReader stream)
|
||||
{
|
||||
var beatmap = new Beatmap
|
||||
{
|
||||
|
@ -56,10 +52,19 @@ protected virtual Beatmap ParseFile(StreamReader stream)
|
|||
},
|
||||
};
|
||||
|
||||
ParseFile(stream, beatmap);
|
||||
ParseBeatmap(stream, beatmap);
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected abstract void ParseFile(StreamReader stream, Beatmap beatmap);
|
||||
protected abstract void ParseBeatmap(StreamReader stream, Beatmap beatmap);
|
||||
|
||||
public virtual Storyboard DecodeStoryboard(StreamReader stream)
|
||||
{
|
||||
var storyboard = new Storyboard();
|
||||
ParseStoryboard(stream, storyboard);
|
||||
return storyboard;
|
||||
}
|
||||
|
||||
protected abstract void ParseStoryboard(StreamReader stream, Storyboard storyboard);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,20 +54,135 @@ public OsuLegacyDecoder(string header)
|
|||
beatmapVersion = int.Parse(header.Substring(17));
|
||||
}
|
||||
|
||||
private enum Section
|
||||
//
|
||||
|
||||
protected override Beatmap ParseBeatmap(StreamReader stream)
|
||||
{
|
||||
None,
|
||||
General,
|
||||
Editor,
|
||||
Metadata,
|
||||
Difficulty,
|
||||
Events,
|
||||
TimingPoints,
|
||||
Colours,
|
||||
HitObjects,
|
||||
Variables,
|
||||
return new LegacyBeatmap(base.ParseBeatmap(stream));
|
||||
}
|
||||
|
||||
public override Beatmap DecodeBeatmap(StreamReader stream)
|
||||
{
|
||||
return new LegacyBeatmap(base.DecodeBeatmap(stream));
|
||||
}
|
||||
|
||||
protected override void ParseBeatmap(StreamReader stream, Beatmap beatmap)
|
||||
{
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap));
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
|
||||
beatmap.BeatmapInfo.BeatmapVersion = beatmapVersion;
|
||||
|
||||
Section section = Section.None;
|
||||
bool hasCustomColours = false;
|
||||
|
||||
string line;
|
||||
while ((line = stream.ReadLine()) != null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("//"))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith(@"osu file format v"))
|
||||
{
|
||||
beatmap.BeatmapInfo.BeatmapVersion = int.Parse(line.Substring(17));
|
||||
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;
|
||||
}
|
||||
|
||||
switch (section)
|
||||
{
|
||||
case Section.General:
|
||||
handleGeneral(beatmap, line);
|
||||
break;
|
||||
case Section.Editor:
|
||||
handleEditor(beatmap, line);
|
||||
break;
|
||||
case Section.Metadata:
|
||||
handleMetadata(beatmap, line);
|
||||
break;
|
||||
case Section.Difficulty:
|
||||
handleDifficulty(beatmap, line);
|
||||
break;
|
||||
case Section.Events:
|
||||
handleEvents(beatmap, line);
|
||||
break;
|
||||
case Section.TimingPoints:
|
||||
handleTimingPoints(beatmap, line);
|
||||
break;
|
||||
case Section.Colours:
|
||||
handleColours(beatmap, line, ref hasCustomColours);
|
||||
break;
|
||||
case Section.HitObjects:
|
||||
|
||||
// If the ruleset wasn't specified, assume the osu!standard ruleset.
|
||||
if (parser == null)
|
||||
parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser();
|
||||
|
||||
var obj = parser.Parse(line);
|
||||
|
||||
if (obj != null)
|
||||
beatmap.HitObjects.Add(obj);
|
||||
|
||||
break;
|
||||
case Section.Variables:
|
||||
handleVariables(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var hitObject in beatmap.HitObjects)
|
||||
hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
protected override void ParseStoryboard(StreamReader stream, Storyboard storyboard)
|
||||
{
|
||||
if (storyboard == null)
|
||||
throw new ArgumentNullException(nameof(storyboard));
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
|
||||
Section section = Section.None;
|
||||
StoryboardSprite storyboardSprite = null;
|
||||
CommandTimelineGroup timelineGroup = null;
|
||||
|
||||
string line;
|
||||
while ((line = stream.ReadLine()) != null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("//"))
|
||||
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;
|
||||
}
|
||||
|
||||
switch (section)
|
||||
{
|
||||
case Section.Events:
|
||||
handleEvents(storyboard, line, ref storyboardSprite, ref timelineGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
private void handleGeneral(Beatmap beatmap, string line)
|
||||
{
|
||||
if (beatmap == null)
|
||||
|
@ -240,38 +355,49 @@ private void handleDifficulty(Beatmap beatmap, string line)
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes any beatmap variables present in a line into their real values.
|
||||
/// </summary>
|
||||
/// <param name="line">The line which may contains variables.</param>
|
||||
private void decodeVariables(ref string line)
|
||||
{
|
||||
if (line == null)
|
||||
throw new ArgumentNullException(nameof(line));
|
||||
|
||||
while (line.IndexOf('$') >= 0)
|
||||
{
|
||||
string origLine = line;
|
||||
string[] split = line.Split(',');
|
||||
for (int i = 0; i < split.Length; i++)
|
||||
{
|
||||
var item = split[i];
|
||||
if (item.StartsWith("$") && variables.ContainsKey(item))
|
||||
split[i] = variables[item];
|
||||
}
|
||||
|
||||
line = string.Join(",", split);
|
||||
if (line == origLine) break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite storyboardSprite, ref CommandTimelineGroup timelineGroup)
|
||||
private void handleEvents(Beatmap beatmap, string line)
|
||||
{
|
||||
if (line == null)
|
||||
throw new ArgumentNullException(nameof(line));
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap));
|
||||
|
||||
decodeVariables(ref line);
|
||||
|
||||
string[] split = line.Split(',');
|
||||
|
||||
EventType type;
|
||||
if (!Enum.TryParse(split[0], out type))
|
||||
throw new InvalidDataException($@"Unknown event type {split[0]}");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EventType.Background:
|
||||
string filename = split[2].Trim('"');
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = filename;
|
||||
break;
|
||||
case EventType.Break:
|
||||
var breakEvent = new BreakPeriod
|
||||
{
|
||||
StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo),
|
||||
EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo)
|
||||
};
|
||||
|
||||
if (!breakEvent.HasEffect)
|
||||
return;
|
||||
|
||||
beatmap.Breaks.Add(breakEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEvents(Storyboard storyboard, string line, ref StoryboardSprite storyboardSprite, ref CommandTimelineGroup timelineGroup)
|
||||
{
|
||||
if (line == null)
|
||||
throw new ArgumentNullException(nameof(line));
|
||||
if (storyboard == null)
|
||||
throw new ArgumentNullException(nameof(storyboard));
|
||||
|
||||
var depth = 0;
|
||||
while (line.StartsWith(" ") || line.StartsWith("_"))
|
||||
{
|
||||
|
@ -293,26 +419,6 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
|
||||
switch (type)
|
||||
{
|
||||
case EventType.Video:
|
||||
case EventType.Background:
|
||||
string filename = split[2].Trim('"');
|
||||
|
||||
if (type == EventType.Background)
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = filename;
|
||||
|
||||
break;
|
||||
case EventType.Break:
|
||||
var breakEvent = new BreakPeriod
|
||||
{
|
||||
StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo),
|
||||
EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo)
|
||||
};
|
||||
|
||||
if (!breakEvent.HasEffect)
|
||||
return;
|
||||
|
||||
beatmap.Breaks.Add(breakEvent);
|
||||
break;
|
||||
case EventType.Sprite:
|
||||
{
|
||||
var layer = parseLayer(split[1]);
|
||||
|
@ -321,7 +427,7 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo);
|
||||
var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo);
|
||||
storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y));
|
||||
beatmap.Storyboard.GetLayer(layer).Add(storyboardSprite);
|
||||
storyboard.GetLayer(layer).Add(storyboardSprite);
|
||||
}
|
||||
break;
|
||||
case EventType.Animation:
|
||||
|
@ -335,7 +441,7 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo);
|
||||
var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever;
|
||||
storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType);
|
||||
beatmap.Storyboard.GetLayer(layer).Add(storyboardSprite);
|
||||
storyboard.GetLayer(layer).Add(storyboardSprite);
|
||||
}
|
||||
break;
|
||||
case EventType.Sample:
|
||||
|
@ -344,7 +450,7 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
var layer = parseLayer(split[2]);
|
||||
var path = cleanFilename(split[3]);
|
||||
var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100;
|
||||
beatmap.Storyboard.GetLayer(layer).Add(new StoryboardSample(path, time, volume));
|
||||
storyboard.GetLayer(layer).Add(new StoryboardSample(path, time, volume));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -456,9 +562,15 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
var type = split[4];
|
||||
switch (type)
|
||||
{
|
||||
case "A": timelineGroup?.BlendingMode.Add(easing, startTime, endTime, BlendingMode.Additive, startTime == endTime ? BlendingMode.Additive : BlendingMode.Inherit); break;
|
||||
case "H": timelineGroup?.FlipH.Add(easing, startTime, endTime, true, startTime == endTime); break;
|
||||
case "V": timelineGroup?.FlipV.Add(easing, startTime, endTime, true, startTime == endTime); break;
|
||||
case "A":
|
||||
timelineGroup?.BlendingMode.Add(easing, startTime, endTime, BlendingMode.Additive, startTime == endTime ? BlendingMode.Additive : BlendingMode.Inherit);
|
||||
break;
|
||||
case "H":
|
||||
timelineGroup?.FlipH.Add(easing, startTime, endTime, true, startTime == endTime);
|
||||
break;
|
||||
case "V":
|
||||
timelineGroup?.FlipV.Add(easing, startTime, endTime, true, startTime == endTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -471,30 +583,6 @@ private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite sto
|
|||
}
|
||||
}
|
||||
|
||||
private static string cleanFilename(string path)
|
||||
=> FileSafety.PathStandardise(path.Trim('\"'));
|
||||
|
||||
private static Anchor parseOrigin(string value)
|
||||
{
|
||||
var origin = (LegacyOrigins)Enum.Parse(typeof(LegacyOrigins), value);
|
||||
switch (origin)
|
||||
{
|
||||
case LegacyOrigins.TopLeft: return Anchor.TopLeft;
|
||||
case LegacyOrigins.TopCentre: return Anchor.TopCentre;
|
||||
case LegacyOrigins.TopRight: return Anchor.TopRight;
|
||||
case LegacyOrigins.CentreLeft: return Anchor.CentreLeft;
|
||||
case LegacyOrigins.Centre: return Anchor.Centre;
|
||||
case LegacyOrigins.CentreRight: return Anchor.CentreRight;
|
||||
case LegacyOrigins.BottomLeft: return Anchor.BottomLeft;
|
||||
case LegacyOrigins.BottomCentre: return Anchor.BottomCentre;
|
||||
case LegacyOrigins.BottomRight: return Anchor.BottomRight;
|
||||
}
|
||||
throw new InvalidDataException($@"Unknown origin: {value}");
|
||||
}
|
||||
|
||||
private static string parseLayer(string value)
|
||||
=> Enum.Parse(typeof(StoryLayer), value).ToString();
|
||||
|
||||
private void handleTimingPoints(Beatmap beatmap, string line)
|
||||
{
|
||||
if (beatmap == null)
|
||||
|
@ -632,97 +720,57 @@ private void handleVariables(string line)
|
|||
variables[pair.Key] = pair.Value;
|
||||
}
|
||||
|
||||
protected override Beatmap ParseFile(StreamReader stream)
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Decodes any beatmap variables present in a line into their real values.
|
||||
/// </summary>
|
||||
/// <param name="line">The line which may contains variables.</param>
|
||||
private void decodeVariables(ref string line)
|
||||
{
|
||||
return new LegacyBeatmap(base.ParseFile(stream));
|
||||
}
|
||||
if (line == null)
|
||||
throw new ArgumentNullException(nameof(line));
|
||||
|
||||
public override Beatmap Decode(StreamReader stream)
|
||||
{
|
||||
return new LegacyBeatmap(base.Decode(stream));
|
||||
}
|
||||
|
||||
protected override void ParseFile(StreamReader stream, Beatmap beatmap)
|
||||
{
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap));
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
|
||||
beatmap.BeatmapInfo.BeatmapVersion = beatmapVersion;
|
||||
|
||||
Section section = Section.None;
|
||||
bool hasCustomColours = false;
|
||||
StoryboardSprite storyboardSprite = null;
|
||||
CommandTimelineGroup timelineGroup = null;
|
||||
|
||||
string line;
|
||||
while ((line = stream.ReadLine()) != null)
|
||||
while (line.IndexOf('$') >= 0)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("//"))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith(@"osu file format v"))
|
||||
string origLine = line;
|
||||
string[] split = line.Split(',');
|
||||
for (int i = 0; i < split.Length; i++)
|
||||
{
|
||||
beatmap.BeatmapInfo.BeatmapVersion = int.Parse(line.Substring(17));
|
||||
continue;
|
||||
var item = split[i];
|
||||
if (item.StartsWith("$") && variables.ContainsKey(item))
|
||||
split[i] = variables[item];
|
||||
}
|
||||
|
||||
if (line.StartsWith(@"[") && line.EndsWith(@"]"))
|
||||
{
|
||||
if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section))
|
||||
throw new InvalidDataException($@"Unknown osu section {line}");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (section)
|
||||
{
|
||||
case Section.General:
|
||||
handleGeneral(beatmap, line);
|
||||
break;
|
||||
case Section.Editor:
|
||||
handleEditor(beatmap, line);
|
||||
break;
|
||||
case Section.Metadata:
|
||||
handleMetadata(beatmap, line);
|
||||
break;
|
||||
case Section.Difficulty:
|
||||
handleDifficulty(beatmap, line);
|
||||
break;
|
||||
case Section.Events:
|
||||
handleEvents(beatmap, line, ref storyboardSprite, ref timelineGroup);
|
||||
break;
|
||||
case Section.TimingPoints:
|
||||
handleTimingPoints(beatmap, line);
|
||||
break;
|
||||
case Section.Colours:
|
||||
handleColours(beatmap, line, ref hasCustomColours);
|
||||
break;
|
||||
case Section.HitObjects:
|
||||
|
||||
// If the ruleset wasn't specified, assume the osu!standard ruleset.
|
||||
if (parser == null)
|
||||
parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser();
|
||||
|
||||
var obj = parser.Parse(line);
|
||||
|
||||
if (obj != null)
|
||||
beatmap.HitObjects.Add(obj);
|
||||
|
||||
break;
|
||||
case Section.Variables:
|
||||
handleVariables(line);
|
||||
break;
|
||||
}
|
||||
line = string.Join(",", split);
|
||||
if (line == origLine) break;
|
||||
}
|
||||
|
||||
foreach (var hitObject in beatmap.HitObjects)
|
||||
hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
private static string cleanFilename(string path)
|
||||
=> FileSafety.PathStandardise(path.Trim('\"'));
|
||||
|
||||
private static Anchor parseOrigin(string value)
|
||||
{
|
||||
var origin = (LegacyOrigins)Enum.Parse(typeof(LegacyOrigins), value);
|
||||
switch (origin)
|
||||
{
|
||||
case LegacyOrigins.TopLeft: return Anchor.TopLeft;
|
||||
case LegacyOrigins.TopCentre: return Anchor.TopCentre;
|
||||
case LegacyOrigins.TopRight: return Anchor.TopRight;
|
||||
case LegacyOrigins.CentreLeft: return Anchor.CentreLeft;
|
||||
case LegacyOrigins.Centre: return Anchor.Centre;
|
||||
case LegacyOrigins.CentreRight: return Anchor.CentreRight;
|
||||
case LegacyOrigins.BottomLeft: return Anchor.BottomLeft;
|
||||
case LegacyOrigins.BottomCentre: return Anchor.BottomCentre;
|
||||
case LegacyOrigins.BottomRight: return Anchor.BottomRight;
|
||||
}
|
||||
throw new InvalidDataException($@"Unknown origin: {value}");
|
||||
}
|
||||
|
||||
private static string parseLayer(string value)
|
||||
=> Enum.Parse(typeof(StoryLayer), value).ToString();
|
||||
|
||||
private KeyValuePair<string, string> splitKeyVal(string line, char separator)
|
||||
{
|
||||
if (line == null)
|
||||
|
@ -737,6 +785,20 @@ private KeyValuePair<string, string> splitKeyVal(string line, char separator)
|
|||
);
|
||||
}
|
||||
|
||||
private enum Section
|
||||
{
|
||||
None,
|
||||
General,
|
||||
Editor,
|
||||
Metadata,
|
||||
Difficulty,
|
||||
Events,
|
||||
TimingPoints,
|
||||
Colours,
|
||||
HitObjects,
|
||||
Variables,
|
||||
}
|
||||
|
||||
internal enum LegacySampleBank
|
||||
{
|
||||
None = 0,
|
||||
|
|
|
@ -63,7 +63,7 @@ protected virtual Beatmap CreateBeatmap()
|
|||
|
||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(test_beatmap_data)))
|
||||
using (var reader = new StreamReader(stream))
|
||||
beatmap = BeatmapDecoder.GetDecoder(reader).Decode(reader);
|
||||
beatmap = BeatmapDecoder.GetDecoder(reader).DecodeBeatmap(reader);
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue