mirror of
https://github.com/ppy/osu.git
synced 2024-12-30 12:42:56 +08:00
779 lines
38 KiB
C#
779 lines
38 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using NUnit.Framework;
|
|
using osu.Game.Audio;
|
|
using osu.Game.Beatmaps;
|
|
using osu.Game.Beatmaps.Formats;
|
|
using osu.Game.Beatmaps.Legacy;
|
|
using osu.Game.Beatmaps.Timing;
|
|
using osu.Game.IO;
|
|
using osu.Game.Rulesets.Catch;
|
|
using osu.Game.Rulesets.Catch.Beatmaps;
|
|
using osu.Game.Rulesets.Mods;
|
|
using osu.Game.Rulesets.Objects;
|
|
using osu.Game.Rulesets.Objects.Legacy;
|
|
using osu.Game.Rulesets.Objects.Types;
|
|
using osu.Game.Rulesets.Osu;
|
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
|
using osu.Game.Skinning;
|
|
using osu.Game.Tests.Resources;
|
|
using osuTK;
|
|
using osuTK.Graphics;
|
|
|
|
namespace osu.Game.Tests.Beatmaps.Formats
|
|
{
|
|
[TestFixture]
|
|
public class LegacyBeatmapDecoderTest
|
|
{
|
|
[Test]
|
|
public void TestDecodeBeatmapVersion()
|
|
{
|
|
using (var resStream = TestResources.OpenResource("beatmap-version.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var decoder = Decoder.GetDecoder<Beatmap>(stream);
|
|
var working = new TestWorkingBeatmap(decoder.Decode(stream));
|
|
|
|
Assert.AreEqual(6, working.BeatmapInfo.BeatmapVersion);
|
|
Assert.AreEqual(6, working.Beatmap.BeatmapInfo.BeatmapVersion);
|
|
Assert.AreEqual(6, working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>()).BeatmapInfo.BeatmapVersion);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapGeneral()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
var beatmapInfo = beatmap.BeatmapInfo;
|
|
var metadata = beatmap.Metadata;
|
|
|
|
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", metadata.AudioFile);
|
|
Assert.AreEqual(0, beatmapInfo.AudioLeadIn);
|
|
Assert.AreEqual(164471, metadata.PreviewTime);
|
|
Assert.AreEqual(0.7f, beatmapInfo.StackLeniency);
|
|
Assert.IsTrue(beatmapInfo.RulesetID == 0);
|
|
Assert.IsFalse(beatmapInfo.LetterboxInBreaks);
|
|
Assert.IsFalse(beatmapInfo.SpecialStyle);
|
|
Assert.IsFalse(beatmapInfo.WidescreenStoryboard);
|
|
Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown);
|
|
Assert.AreEqual(0, beatmapInfo.CountdownOffset);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapEditor()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmapInfo = decoder.Decode(stream).BeatmapInfo;
|
|
|
|
int[] expectedBookmarks =
|
|
{
|
|
11505, 22054, 32604, 43153, 53703, 64252, 74802, 85351,
|
|
95901, 106450, 116999, 119637, 130186, 140735, 151285,
|
|
161834, 164471, 175020, 185570, 196119, 206669, 209306
|
|
};
|
|
Assert.AreEqual(expectedBookmarks.Length, beatmapInfo.Bookmarks.Length);
|
|
for (int i = 0; i < expectedBookmarks.Length; i++)
|
|
Assert.AreEqual(expectedBookmarks[i], beatmapInfo.Bookmarks[i]);
|
|
Assert.AreEqual(1.8, beatmapInfo.DistanceSpacing);
|
|
Assert.AreEqual(4, beatmapInfo.BeatDivisor);
|
|
Assert.AreEqual(4, beatmapInfo.GridSize);
|
|
Assert.AreEqual(2, beatmapInfo.TimelineZoom);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapMetadata()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
var beatmapInfo = beatmap.BeatmapInfo;
|
|
var metadata = beatmap.Metadata;
|
|
|
|
Assert.AreEqual("Renatus", metadata.Title);
|
|
Assert.AreEqual("Renatus", metadata.TitleUnicode);
|
|
Assert.AreEqual("Soleily", metadata.Artist);
|
|
Assert.AreEqual("Soleily", metadata.ArtistUnicode);
|
|
Assert.AreEqual("Gamu", metadata.AuthorString);
|
|
Assert.AreEqual("Insane", beatmapInfo.Version);
|
|
Assert.AreEqual(string.Empty, metadata.Source);
|
|
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", metadata.Tags);
|
|
Assert.AreEqual(557821, beatmapInfo.OnlineBeatmapID);
|
|
Assert.AreEqual(241526, beatmapInfo.BeatmapSet.OnlineBeatmapSetID);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapDifficulty()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var difficulty = decoder.Decode(stream).BeatmapInfo.BaseDifficulty;
|
|
|
|
Assert.AreEqual(6.5f, difficulty.DrainRate);
|
|
Assert.AreEqual(4, difficulty.CircleSize);
|
|
Assert.AreEqual(8, difficulty.OverallDifficulty);
|
|
Assert.AreEqual(9, difficulty.ApproachRate);
|
|
Assert.AreEqual(1.8, difficulty.SliderMultiplier);
|
|
Assert.AreEqual(2, difficulty.SliderTickRate);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapEvents()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
var metadata = beatmap.Metadata;
|
|
var breakPoint = beatmap.Breaks[0];
|
|
|
|
Assert.AreEqual("machinetop_background.jpg", metadata.BackgroundFile);
|
|
Assert.AreEqual(122474, breakPoint.StartTime);
|
|
Assert.AreEqual(140135, breakPoint.EndTime);
|
|
Assert.IsTrue(breakPoint.HasEffect);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapTimingPoints()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
var controlPoints = (LegacyControlPointInfo)beatmap.ControlPointInfo;
|
|
|
|
Assert.AreEqual(4, controlPoints.TimingPoints.Count);
|
|
Assert.AreEqual(5, controlPoints.DifficultyPoints.Count);
|
|
Assert.AreEqual(34, controlPoints.SamplePoints.Count);
|
|
Assert.AreEqual(8, controlPoints.EffectPoints.Count);
|
|
|
|
var timingPoint = controlPoints.TimingPointAt(0);
|
|
Assert.AreEqual(956, timingPoint.Time);
|
|
Assert.AreEqual(329.67032967033, timingPoint.BeatLength);
|
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
|
|
|
timingPoint = controlPoints.TimingPointAt(48428);
|
|
Assert.AreEqual(956, timingPoint.Time);
|
|
Assert.AreEqual(329.67032967033d, timingPoint.BeatLength);
|
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
|
|
|
timingPoint = controlPoints.TimingPointAt(119637);
|
|
Assert.AreEqual(119637, timingPoint.Time);
|
|
Assert.AreEqual(659.340659340659, timingPoint.BeatLength);
|
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
|
|
|
var difficultyPoint = controlPoints.DifficultyPointAt(0);
|
|
Assert.AreEqual(0, difficultyPoint.Time);
|
|
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
|
|
|
|
difficultyPoint = controlPoints.DifficultyPointAt(48428);
|
|
Assert.AreEqual(0, difficultyPoint.Time);
|
|
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
|
|
|
|
difficultyPoint = controlPoints.DifficultyPointAt(116999);
|
|
Assert.AreEqual(116999, difficultyPoint.Time);
|
|
Assert.AreEqual(0.75, difficultyPoint.SpeedMultiplier, 0.1);
|
|
|
|
var soundPoint = controlPoints.SamplePointAt(0);
|
|
Assert.AreEqual(956, soundPoint.Time);
|
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
|
Assert.AreEqual(60, soundPoint.SampleVolume);
|
|
|
|
soundPoint = controlPoints.SamplePointAt(53373);
|
|
Assert.AreEqual(53373, soundPoint.Time);
|
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
|
Assert.AreEqual(60, soundPoint.SampleVolume);
|
|
|
|
soundPoint = controlPoints.SamplePointAt(119637);
|
|
Assert.AreEqual(119637, soundPoint.Time);
|
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
|
Assert.AreEqual(80, soundPoint.SampleVolume);
|
|
|
|
var effectPoint = controlPoints.EffectPointAt(0);
|
|
Assert.AreEqual(0, effectPoint.Time);
|
|
Assert.IsFalse(effectPoint.KiaiMode);
|
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
|
|
|
effectPoint = controlPoints.EffectPointAt(53703);
|
|
Assert.AreEqual(53703, effectPoint.Time);
|
|
Assert.IsTrue(effectPoint.KiaiMode);
|
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
|
|
|
effectPoint = controlPoints.EffectPointAt(119637);
|
|
Assert.AreEqual(95901, effectPoint.Time);
|
|
Assert.IsFalse(effectPoint.KiaiMode);
|
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeOverlappingTimingPoints()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("overlapping-control-points.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var controlPoints = (LegacyControlPointInfo)decoder.Decode(stream).ControlPointInfo;
|
|
|
|
Assert.That(controlPoints.TimingPoints.Count, Is.EqualTo(4));
|
|
Assert.That(controlPoints.DifficultyPoints.Count, Is.EqualTo(3));
|
|
Assert.That(controlPoints.EffectPoints.Count, Is.EqualTo(3));
|
|
Assert.That(controlPoints.SamplePoints.Count, Is.EqualTo(3));
|
|
|
|
Assert.That(controlPoints.DifficultyPointAt(500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
|
Assert.That(controlPoints.DifficultyPointAt(1500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
|
Assert.That(controlPoints.DifficultyPointAt(2500).SpeedMultiplier, Is.EqualTo(0.75).Within(0.1));
|
|
Assert.That(controlPoints.DifficultyPointAt(3500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
|
|
|
Assert.That(controlPoints.EffectPointAt(500).KiaiMode, Is.True);
|
|
Assert.That(controlPoints.EffectPointAt(1500).KiaiMode, Is.True);
|
|
Assert.That(controlPoints.EffectPointAt(2500).KiaiMode, Is.False);
|
|
Assert.That(controlPoints.EffectPointAt(3500).KiaiMode, Is.True);
|
|
|
|
Assert.That(controlPoints.SamplePointAt(500).SampleBank, Is.EqualTo("drum"));
|
|
Assert.That(controlPoints.SamplePointAt(1500).SampleBank, Is.EqualTo("drum"));
|
|
Assert.That(controlPoints.SamplePointAt(2500).SampleBank, Is.EqualTo("normal"));
|
|
Assert.That(controlPoints.SamplePointAt(3500).SampleBank, Is.EqualTo("drum"));
|
|
|
|
Assert.That(controlPoints.TimingPointAt(500).BeatLength, Is.EqualTo(500).Within(0.1));
|
|
Assert.That(controlPoints.TimingPointAt(1500).BeatLength, Is.EqualTo(500).Within(0.1));
|
|
Assert.That(controlPoints.TimingPointAt(2500).BeatLength, Is.EqualTo(250).Within(0.1));
|
|
Assert.That(controlPoints.TimingPointAt(3500).BeatLength, Is.EqualTo(500).Within(0.1));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestTimingPointResetsSpeedMultiplier()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("timingpoint-speedmultiplier-reset.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var controlPoints = decoder.Decode(stream).ControlPointInfo;
|
|
|
|
Assert.That(controlPoints.DifficultyPointAt(0).SpeedMultiplier, Is.EqualTo(0.5).Within(0.1));
|
|
Assert.That(controlPoints.DifficultyPointAt(2000).SpeedMultiplier, Is.EqualTo(1).Within(0.1));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapColours()
|
|
{
|
|
var decoder = new LegacySkinDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var comboColors = decoder.Decode(stream).ComboColours;
|
|
|
|
Color4[] expectedColors =
|
|
{
|
|
new Color4(142, 199, 255, 255),
|
|
new Color4(255, 128, 128, 255),
|
|
new Color4(128, 255, 255, 255),
|
|
new Color4(128, 255, 128, 255),
|
|
new Color4(255, 187, 255, 255),
|
|
new Color4(255, 177, 140, 255),
|
|
new Color4(100, 100, 100, 100),
|
|
};
|
|
Assert.AreEqual(expectedColors.Length, comboColors.Count);
|
|
for (int i = 0; i < expectedColors.Length; i++)
|
|
Assert.AreEqual(expectedColors[i], comboColors[i]);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapComboOffsetsOsu()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("hitobject-combo-offset.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
|
|
var converted = new OsuBeatmapConverter(beatmap, new OsuRuleset()).Convert();
|
|
new OsuBeatmapProcessor(converted).PreProcess();
|
|
new OsuBeatmapProcessor(converted).PostProcess();
|
|
|
|
Assert.AreEqual(4, ((IHasComboInformation)converted.HitObjects.ElementAt(0)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(5, ((IHasComboInformation)converted.HitObjects.ElementAt(2)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(5, ((IHasComboInformation)converted.HitObjects.ElementAt(4)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(6, ((IHasComboInformation)converted.HitObjects.ElementAt(6)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(11, ((IHasComboInformation)converted.HitObjects.ElementAt(8)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(14, ((IHasComboInformation)converted.HitObjects.ElementAt(11)).ComboIndexWithOffsets);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapComboOffsetsCatch()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder();
|
|
|
|
using (var resStream = TestResources.OpenResource("hitobject-combo-offset.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var beatmap = decoder.Decode(stream);
|
|
|
|
var converted = new CatchBeatmapConverter(beatmap, new CatchRuleset()).Convert();
|
|
new CatchBeatmapProcessor(converted).PreProcess();
|
|
new CatchBeatmapProcessor(converted).PostProcess();
|
|
|
|
Assert.AreEqual(4, ((IHasComboInformation)converted.HitObjects.ElementAt(0)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(5, ((IHasComboInformation)converted.HitObjects.ElementAt(2)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(5, ((IHasComboInformation)converted.HitObjects.ElementAt(4)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(6, ((IHasComboInformation)converted.HitObjects.ElementAt(6)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(11, ((IHasComboInformation)converted.HitObjects.ElementAt(8)).ComboIndexWithOffsets);
|
|
Assert.AreEqual(14, ((IHasComboInformation)converted.HitObjects.ElementAt(11)).ComboIndexWithOffsets);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeBeatmapHitObjects()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
var curveData = hitObjects[0] as IHasPathWithRepeats;
|
|
var positionData = hitObjects[0] as IHasPosition;
|
|
|
|
Assert.IsNotNull(positionData);
|
|
Assert.IsNotNull(curveData);
|
|
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
|
Assert.AreEqual(956, hitObjects[0].StartTime);
|
|
Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL));
|
|
|
|
positionData = hitObjects[1] as IHasPosition;
|
|
|
|
Assert.IsNotNull(positionData);
|
|
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
|
Assert.AreEqual(1285, hitObjects[1].StartTime);
|
|
Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeControlPointDifficultyChange()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("controlpoint-difficulty-multiplier.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var controlPointInfo = decoder.Decode(stream).ControlPointInfo;
|
|
|
|
Assert.That(controlPointInfo.DifficultyPointAt(5).SpeedMultiplier, Is.EqualTo(1));
|
|
Assert.That(controlPointInfo.DifficultyPointAt(1000).SpeedMultiplier, Is.EqualTo(10));
|
|
Assert.That(controlPointInfo.DifficultyPointAt(2000).SpeedMultiplier, Is.EqualTo(1.8518518518518519d));
|
|
Assert.That(controlPointInfo.DifficultyPointAt(3000).SpeedMultiplier, Is.EqualTo(0.5));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeControlPointCustomSampleBank()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("controlpoint-custom-samplebank.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
Assert.AreEqual("Gameplay/normal-hitnormal", getTestableSampleInfo(hitObjects[0]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal", getTestableSampleInfo(hitObjects[1]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal", getTestableSampleInfo(hitObjects[3]).LookupNames.First());
|
|
|
|
// The control point at the end time of the slider should be applied
|
|
Assert.AreEqual("Gameplay/soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First());
|
|
}
|
|
|
|
static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeHitObjectCustomSampleBank()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("hitobject-custom-samplebank.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
Assert.AreEqual("Gameplay/normal-hitnormal", getTestableSampleInfo(hitObjects[0]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal2", getTestableSampleInfo(hitObjects[1]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
|
}
|
|
|
|
static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeHitObjectFileSamples()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("hitobject-file-samples.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
Assert.AreEqual("hit_1.wav", getTestableSampleInfo(hitObjects[0]).LookupNames.First());
|
|
Assert.AreEqual("hit_2.wav", getTestableSampleInfo(hitObjects[1]).LookupNames.First());
|
|
Assert.AreEqual("Gameplay/normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
|
Assert.AreEqual("hit_1.wav", getTestableSampleInfo(hitObjects[3]).LookupNames.First());
|
|
Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume);
|
|
}
|
|
|
|
static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeSliderSamples()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("slider-samples.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
var slider1 = (ConvertSlider)hitObjects[0];
|
|
|
|
Assert.AreEqual(1, slider1.NodeSamples[0].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name);
|
|
Assert.AreEqual(1, slider1.NodeSamples[1].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name);
|
|
Assert.AreEqual(1, slider1.NodeSamples[2].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name);
|
|
|
|
var slider2 = (ConvertSlider)hitObjects[1];
|
|
|
|
Assert.AreEqual(2, slider2.NodeSamples[0].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name);
|
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name);
|
|
Assert.AreEqual(2, slider2.NodeSamples[1].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name);
|
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name);
|
|
Assert.AreEqual(2, slider2.NodeSamples[2].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name);
|
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name);
|
|
|
|
var slider3 = (ConvertSlider)hitObjects[2];
|
|
|
|
Assert.AreEqual(2, slider3.NodeSamples[0].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name);
|
|
Assert.AreEqual(HitSampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name);
|
|
Assert.AreEqual(1, slider3.NodeSamples[1].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name);
|
|
Assert.AreEqual(2, slider3.NodeSamples[2].Count);
|
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name);
|
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeHitObjectNullAdditionBank()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("hitobject-no-addition-bank.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
|
|
|
Assert.AreEqual(hitObjects[0].Samples[0].Bank, hitObjects[0].Samples[1].Bank);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestInvalidEventStillPasses()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var badResStream = TestResources.OpenResource("invalid-events.osu"))
|
|
using (var badStream = new LineBufferedReader(badResStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder.Decode(badStream));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestFallbackDecoderForCorruptedHeader()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
Beatmap beatmap = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("corrupted-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
|
|
Assert.IsNotNull(beatmap);
|
|
Assert.AreEqual("Beatmap with corrupted header", beatmap.Metadata.Title);
|
|
Assert.AreEqual("Evil Hacker", beatmap.Metadata.AuthorString);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestFallbackDecoderForMissingHeader()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
Beatmap beatmap = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("missing-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
|
|
Assert.IsNotNull(beatmap);
|
|
Assert.AreEqual("Beatmap with no header", beatmap.Metadata.Title);
|
|
Assert.AreEqual("Incredibly Evil Hacker", beatmap.Metadata.AuthorString);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeFileWithEmptyLinesAtStart()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
Beatmap beatmap = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("empty-lines-at-start.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
|
|
Assert.IsNotNull(beatmap);
|
|
Assert.AreEqual("Empty lines at start", beatmap.Metadata.Title);
|
|
Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.AuthorString);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeFileWithEmptyLinesAndNoHeader()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
Beatmap beatmap = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("empty-line-instead-of-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
|
|
Assert.IsNotNull(beatmap);
|
|
Assert.AreEqual("The dog ate the file header", beatmap.Metadata.Title);
|
|
Assert.AreEqual("Why does this keep happening", beatmap.Metadata.AuthorString);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeFileWithContentImmediatelyAfterHeader()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
Beatmap beatmap = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("no-empty-line-after-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
|
|
Assert.IsNotNull(beatmap);
|
|
Assert.AreEqual("No empty line delimiting header from contents", beatmap.Metadata.Title);
|
|
Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.AuthorString);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDecodeEmptyFile()
|
|
{
|
|
using (var resStream = new MemoryStream())
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.Throws<IOException>(() => Decoder.GetDecoder<Beatmap>(stream));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestAllowFallbackDecoderOverwrite()
|
|
{
|
|
Decoder<Beatmap> decoder = null;
|
|
|
|
using (var resStream = TestResources.OpenResource("corrupted-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyBeatmapDecoder>(decoder);
|
|
}
|
|
|
|
Assert.DoesNotThrow(LegacyDifficultyCalculatorBeatmapDecoder.Register);
|
|
|
|
using (var resStream = TestResources.OpenResource("corrupted-header.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
Assert.DoesNotThrow(() => decoder = Decoder.GetDecoder<Beatmap>(stream));
|
|
Assert.IsInstanceOf<LegacyDifficultyCalculatorBeatmapDecoder>(decoder);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestMultiSegmentSliders()
|
|
{
|
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
|
|
|
using (var resStream = TestResources.OpenResource("multi-segment-slider.osu"))
|
|
using (var stream = new LineBufferedReader(resStream))
|
|
{
|
|
var decoded = decoder.Decode(stream);
|
|
|
|
// Multi-segment
|
|
var first = ((IHasPath)decoded.HitObjects[0]).Path;
|
|
|
|
Assert.That(first.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(first.ControlPoints[0].Type, Is.EqualTo(PathType.PerfectCurve));
|
|
Assert.That(first.ControlPoints[1].Position, Is.EqualTo(new Vector2(161, -244)));
|
|
Assert.That(first.ControlPoints[1].Type, Is.EqualTo(null));
|
|
|
|
Assert.That(first.ControlPoints[2].Position, Is.EqualTo(new Vector2(376, -3)));
|
|
Assert.That(first.ControlPoints[2].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(first.ControlPoints[3].Position, Is.EqualTo(new Vector2(68, 15)));
|
|
Assert.That(first.ControlPoints[3].Type, Is.EqualTo(null));
|
|
Assert.That(first.ControlPoints[4].Position, Is.EqualTo(new Vector2(259, -132)));
|
|
Assert.That(first.ControlPoints[4].Type, Is.EqualTo(null));
|
|
Assert.That(first.ControlPoints[5].Position, Is.EqualTo(new Vector2(92, -107)));
|
|
Assert.That(first.ControlPoints[5].Type, Is.EqualTo(null));
|
|
|
|
// Single-segment
|
|
var second = ((IHasPath)decoded.HitObjects[1]).Path;
|
|
|
|
Assert.That(second.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(second.ControlPoints[0].Type, Is.EqualTo(PathType.PerfectCurve));
|
|
Assert.That(second.ControlPoints[1].Position, Is.EqualTo(new Vector2(161, -244)));
|
|
Assert.That(second.ControlPoints[1].Type, Is.EqualTo(null));
|
|
Assert.That(second.ControlPoints[2].Position, Is.EqualTo(new Vector2(376, -3)));
|
|
Assert.That(second.ControlPoints[2].Type, Is.EqualTo(null));
|
|
|
|
// Implicit multi-segment
|
|
var third = ((IHasPath)decoded.HitObjects[2]).Path;
|
|
|
|
Assert.That(third.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(third.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(third.ControlPoints[1].Position, Is.EqualTo(new Vector2(0, 192)));
|
|
Assert.That(third.ControlPoints[1].Type, Is.EqualTo(null));
|
|
Assert.That(third.ControlPoints[2].Position, Is.EqualTo(new Vector2(224, 192)));
|
|
Assert.That(third.ControlPoints[2].Type, Is.EqualTo(null));
|
|
|
|
Assert.That(third.ControlPoints[3].Position, Is.EqualTo(new Vector2(224, 0)));
|
|
Assert.That(third.ControlPoints[3].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(third.ControlPoints[4].Position, Is.EqualTo(new Vector2(224, -192)));
|
|
Assert.That(third.ControlPoints[4].Type, Is.EqualTo(null));
|
|
Assert.That(third.ControlPoints[5].Position, Is.EqualTo(new Vector2(480, -192)));
|
|
Assert.That(third.ControlPoints[5].Type, Is.EqualTo(null));
|
|
Assert.That(third.ControlPoints[6].Position, Is.EqualTo(new Vector2(480, 0)));
|
|
Assert.That(third.ControlPoints[6].Type, Is.EqualTo(null));
|
|
|
|
// Last control point duplicated
|
|
var fourth = ((IHasPath)decoded.HitObjects[3]).Path;
|
|
|
|
Assert.That(fourth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(fourth.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(fourth.ControlPoints[1].Position, Is.EqualTo(new Vector2(1, 1)));
|
|
Assert.That(fourth.ControlPoints[1].Type, Is.EqualTo(null));
|
|
Assert.That(fourth.ControlPoints[2].Position, Is.EqualTo(new Vector2(2, 2)));
|
|
Assert.That(fourth.ControlPoints[2].Type, Is.EqualTo(null));
|
|
Assert.That(fourth.ControlPoints[3].Position, Is.EqualTo(new Vector2(3, 3)));
|
|
Assert.That(fourth.ControlPoints[3].Type, Is.EqualTo(null));
|
|
Assert.That(fourth.ControlPoints[4].Position, Is.EqualTo(new Vector2(3, 3)));
|
|
Assert.That(fourth.ControlPoints[4].Type, Is.EqualTo(null));
|
|
|
|
// Last control point in segment duplicated
|
|
var fifth = ((IHasPath)decoded.HitObjects[4]).Path;
|
|
|
|
Assert.That(fifth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(fifth.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(fifth.ControlPoints[1].Position, Is.EqualTo(new Vector2(1, 1)));
|
|
Assert.That(fifth.ControlPoints[1].Type, Is.EqualTo(null));
|
|
Assert.That(fifth.ControlPoints[2].Position, Is.EqualTo(new Vector2(2, 2)));
|
|
Assert.That(fifth.ControlPoints[2].Type, Is.EqualTo(null));
|
|
Assert.That(fifth.ControlPoints[3].Position, Is.EqualTo(new Vector2(3, 3)));
|
|
Assert.That(fifth.ControlPoints[3].Type, Is.EqualTo(null));
|
|
Assert.That(fifth.ControlPoints[4].Position, Is.EqualTo(new Vector2(3, 3)));
|
|
Assert.That(fifth.ControlPoints[4].Type, Is.EqualTo(null));
|
|
|
|
Assert.That(fifth.ControlPoints[5].Position, Is.EqualTo(new Vector2(4, 4)));
|
|
Assert.That(fifth.ControlPoints[5].Type, Is.EqualTo(PathType.Bezier));
|
|
Assert.That(fifth.ControlPoints[6].Position, Is.EqualTo(new Vector2(5, 5)));
|
|
Assert.That(fifth.ControlPoints[6].Type, Is.EqualTo(null));
|
|
|
|
// Implicit perfect-curve multi-segment(Should convert to bezier to match stable)
|
|
var sixth = ((IHasPath)decoded.HitObjects[5]).Path;
|
|
|
|
Assert.That(sixth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(sixth.ControlPoints[0].Type == PathType.Bezier);
|
|
Assert.That(sixth.ControlPoints[1].Position, Is.EqualTo(new Vector2(75, 145)));
|
|
Assert.That(sixth.ControlPoints[1].Type == null);
|
|
Assert.That(sixth.ControlPoints[2].Position, Is.EqualTo(new Vector2(170, 75)));
|
|
|
|
Assert.That(sixth.ControlPoints[2].Type == PathType.Bezier);
|
|
Assert.That(sixth.ControlPoints[3].Position, Is.EqualTo(new Vector2(300, 145)));
|
|
Assert.That(sixth.ControlPoints[3].Type == null);
|
|
Assert.That(sixth.ControlPoints[4].Position, Is.EqualTo(new Vector2(410, 20)));
|
|
Assert.That(sixth.ControlPoints[4].Type == null);
|
|
|
|
// Explicit perfect-curve multi-segment(Should not convert to bezier)
|
|
var seventh = ((IHasPath)decoded.HitObjects[6]).Path;
|
|
|
|
Assert.That(seventh.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero));
|
|
Assert.That(seventh.ControlPoints[0].Type == PathType.PerfectCurve);
|
|
Assert.That(seventh.ControlPoints[1].Position, Is.EqualTo(new Vector2(75, 145)));
|
|
Assert.That(seventh.ControlPoints[1].Type == null);
|
|
Assert.That(seventh.ControlPoints[2].Position, Is.EqualTo(new Vector2(170, 75)));
|
|
|
|
Assert.That(seventh.ControlPoints[2].Type == PathType.PerfectCurve);
|
|
Assert.That(seventh.ControlPoints[3].Position, Is.EqualTo(new Vector2(300, 145)));
|
|
Assert.That(seventh.ControlPoints[3].Type == null);
|
|
Assert.That(seventh.ControlPoints[4].Position, Is.EqualTo(new Vector2(410, 20)));
|
|
Assert.That(seventh.ControlPoints[4].Type == null);
|
|
}
|
|
}
|
|
}
|
|
}
|