Skip to content

Commit ae3100a

Browse files
authored
Merge pull request #33615 from bdach/slider-encode-decode-instability
Fix lack of slider encode-decode stability due to truncating control point coordinates on decode
2 parents bc07aba + eab02a2 commit ae3100a

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,31 @@ public void TestOnlyEightComboColoursEncoded()
211211
Assert.That(decodedAfterEncode.skin.Configuration.CustomComboColours, Has.Count.EqualTo(8));
212212
}
213213

214+
[Test]
215+
public void TestEncodeStabilityOfSliderWithFractionalCoordinates()
216+
{
217+
Slider originalSlider = new Slider
218+
{
219+
Position = new Vector2(0.6f),
220+
Path = new SliderPath(new[]
221+
{
222+
new PathControlPoint(Vector2.Zero, PathType.PERFECT_CURVE),
223+
new PathControlPoint(new Vector2(25.6f, 78.4f)),
224+
new PathControlPoint(new Vector2(55.8f, 34.2f)),
225+
})
226+
};
227+
var beatmap = new Beatmap
228+
{
229+
HitObjects = { originalSlider }
230+
};
231+
232+
var encoded = encodeToLegacy((beatmap, new TestLegacySkin(beatmaps_resource_store, string.Empty)));
233+
var decodedAfterEncode = decodeFromLegacy(encoded, string.Empty, version: LegacyBeatmapEncoder.FIRST_LAZER_VERSION);
234+
var decodedSlider = (Slider)decodedAfterEncode.beatmap.HitObjects[0];
235+
Assert.That(decodedSlider.Path.ControlPoints.Select(p => p.Position),
236+
Is.EquivalentTo(originalSlider.Path.ControlPoints.Select(p => p.Position)));
237+
}
238+
214239
private bool areComboColoursEqual(IHasComboColours a, IHasComboColours b)
215240
{
216241
// equal to null, no need to SequenceEqual
@@ -233,11 +258,11 @@ private void sort(IBeatmap beatmap)
233258
}
234259
}
235260

236-
private (IBeatmap beatmap, TestLegacySkin skin) decodeFromLegacy(Stream stream, string name)
261+
private (IBeatmap beatmap, TestLegacySkin skin) decodeFromLegacy(Stream stream, string name, int version = LegacyDecoder<Beatmap>.LATEST_VERSION)
237262
{
238263
using (var reader = new LineBufferedReader(stream))
239264
{
240-
var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader);
265+
var beatmap = new LegacyBeatmapDecoder(version) { ApplyOffsets = false }.Decode(reader);
241266
var beatmapSkin = new TestLegacySkin(beatmaps_resource_store, name);
242267
stream.Seek(0, SeekOrigin.Begin);
243268
beatmapSkin.Configuration = new LegacySkinDecoder().Decode(reader);

osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,14 @@ private PathControlPoint[] convertPathString(string pointString, Vector2 offset)
335335
ArrayPool<(PathType, int)>.Shared.Return(segmentsBuffer);
336336
}
337337

338-
static Vector2 readPoint(string value, Vector2 startPos)
338+
Vector2 readPoint(string value, Vector2 startPos)
339339
{
340340
string[] vertexSplit = value.Split(':');
341341

342-
Vector2 pos = new Vector2((int)Parsing.ParseDouble(vertexSplit[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(vertexSplit[1], Parsing.MAX_COORDINATE_VALUE)) - startPos;
342+
Vector2 pos = formatVersion >= LegacyBeatmapEncoder.FIRST_LAZER_VERSION
343+
? new Vector2(Parsing.ParseFloat(vertexSplit[0], Parsing.MAX_COORDINATE_VALUE), Parsing.ParseFloat(vertexSplit[1], Parsing.MAX_COORDINATE_VALUE))
344+
: new Vector2((int)Parsing.ParseFloat(vertexSplit[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(vertexSplit[1], Parsing.MAX_COORDINATE_VALUE));
345+
pos -= startPos;
343346
return pos;
344347
}
345348
}

0 commit comments

Comments
 (0)