Fix some mania replays failing to import #9993
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Found during testing of #9988.
Summary
At the start of each replay, stable adds two special replay frames: one at time 0, and one at the boundary of the skip to gameplay (minus one millisecond). The first frame was handled already:
osu/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
Lines 247 to 250 in 93a9994
but the second wasn't. That same frame also happens to specify a position of (256, -500), which the mania decoder interpreted as belonging to the 9th column (as
256 == 1 << 8
, and the shifts are zero-based).Not all maps were affected by this, however; if a map doesn't have a skip at the start, the second frame has a time of -1, which would end up being caught by the second guard right underneath the first. In short, all replays that:
would fail to import, catching this exception.
Resolve by replacing the existing check by a more directly targeted one.
Remarks
A rudimentary smoke test case is attached, to demonstrate that importing no longer crashes. I manually created this replay on stable, using a simple custom 7K beatmap. I actually found another bug during writing the test case, which will be addressed in a PR coming up ahead.
The check is quite ugly and brittle, but I'm not seeing another way of scoping this better. It shouldn't swallow frames it shouldn't, I think (stable replays are protected by the
i < 2
index check, and lazer replays are protected by theY
check - there's nothing that has the right to return a meaningful frame with negativeY
).I'm not even sure if lazer has the same notion of a skip boundary that stable does, and even if it does, I'm not sure relying on that is any better than this.