mirror of
https://github.com/ppy/osu.git
synced 2026-06-03 15:04:26 +08:00
Disallow zero-length sliders from specifying a non-zero number of repeats (#35220)
This commit is contained in:
committed by
GitHub
Unverified
parent
a08f7327b1
commit
1a522a19f1
@@ -476,12 +476,30 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
private ConvertHitObject createSlider(Vector2 position, bool newCombo, int comboOffset, PathControlPoint[] controlPoints, double? length, int repeatCount,
|
||||
IList<IList<HitSampleInfo>> nodeSamples)
|
||||
{
|
||||
var path = new SliderPath(controlPoints, length);
|
||||
|
||||
// there are known instances of beatmaps (https://osu.ppy.sh/beatmapsets/594828#osu/1258033) which contain zero-length sliders with non-zero numbers of repeats.
|
||||
// this was exploiting a bug in stable in which the slider repeats would be generated as objects but never actually judged as a hit *or* miss during gameplay,
|
||||
// therefore increasing the theoretical possible max combo to be gained from a slider while in practice never giving that extra combo.
|
||||
// due to lazer ensuring that an object has its nested part fully judged, this would result in broken behaviours
|
||||
// (either the zero-length slider giving hundreds of combo for nothing if the repeats are judged as hit, or insta-failing the player due to HP if judged as miss).
|
||||
// to remedy this in a way that seems least damaging, detect this situation via a heuristic and reset the number of repeats to zero.
|
||||
// this technically *does not* match stable beatmap parsing or conversion, *does not* match in-gameplay behaviour of such broken sliders,
|
||||
// and *will* fail conversion mapping tests, but again, this is supposed to be a least-worst measure to prevent exploits.
|
||||
// it is also applied centrally to all rulesets rather than in specific ruleset converters because this failure scenario
|
||||
// translates across rulesets (osu! and catch are both affected).
|
||||
if (Precision.AlmostEquals(path.Distance, 0))
|
||||
{
|
||||
repeatCount = 0;
|
||||
nodeSamples = [nodeSamples[0], nodeSamples[^1]];
|
||||
}
|
||||
|
||||
return lastObject = new ConvertSlider
|
||||
{
|
||||
Position = position,
|
||||
NewCombo = firstObject || lastObject is ConvertSpinner || newCombo,
|
||||
ComboOffset = newCombo ? comboOffset : 0,
|
||||
Path = new SliderPath(controlPoints, length),
|
||||
Path = path,
|
||||
NodeSamples = nodeSamples,
|
||||
RepeatCount = repeatCount
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user