People keep asking why https://github.com/ppy/osu/pull/29553 didn't fix
their databases (as stated in the PR, it didn't intend to), so this
should do it for them.
This is going to be used by server-side flows. Note that the server-side
overload of `UpdateFromLegacy()` was not calling
`LegacyScoreDecoder.PopulateTotalScoreWithoutMods()`.
Computing the score without mods inline reduces reflection overheads
from constructing mod instances, which feels pretty important for
server-side flows.
There is one weird kink in the treatment of stable scores with score V2
active - they get the *legacy* multipliers unapplied for them because
that made the most sense. For all intents and purposes this matters
mostly for client-side replays with score V2. I'm not sure whether
scores with SV2 ever make it to submission in stable.
There may be minute differences in converted score due to rounding
shenanigans but I don't think it's worth doing a reverify for this.
Closes https://github.com/ppy/osu/issues/28209.
Yes this means that such scores will have a zero total score without
mods in DB and thus might up getting their total recalculated to zero
when we try a mod multiplier rebalance (unless we skip scores with zero
completely I suppose). I also don't really care about that right now.
After way too much time investigating this, the encoding situation is
not great right now.
- Stable sets the "default code page" to be used for encoding filenames
to Shift-JIS (932):
c29ebd7fc5/osu!/GameBase.cs#L3099
- Lazer does nothing (therefore using UTF-8).
When importing to lazer, stable files are assumed to be UTF-8. This
means that the linked beatmaps don't work correctly. Forcing lazer to
decompress *and* compress using Shift-JIS will fix this.
Here's a rough idea of how things look for japanese character filenames
in current `master`:
| | stable | lazer |
|--------|--------|--------|
| export encoding | shift-jis | utf8 |
| utf8 [bit flag](https://superuser.com/a/1507988) set | ❌ | ❌ |
| import stable export osz | ✅ | ❌ |
| import lazer export osz | ❌ | ✅ |
| windows unzip | ❌ | ❌ |
| macos unzip | ✅ | ✅ |
and after this change
| | stable | lazer |
|--------|--------|--------|
| export encoding | shift-jis | shift-jis |
| utf8 [bit flag](https://superuser.com/a/1507988) set | ❌ | ❌ |
| import stable export osz | ✅ | ✅ |
| import lazer export osz | ✅ | ✅ |
| windows unzip | ❌ | ❌ |
| macos unzip | ✅ | ✅ |
A future endeavour to improve compatibility would be to look at setting
the utf8 flag in lazer, switching the default to utf8, and ensuring the
stable supports this flag (I don't believe it does right now).
Rather than creating a "corrupt" realm file in such cases, the game will
now refuse to start. This behaviour is usually what we want. In most
cases a second click on the game will start it successfully (the
previous instance's file handles are still doing stuff, or windows
defender is being silly).
Closes https://github.com/ppy/osu/issues/28018.
As it turns out, the "lower" and "upper" estimates of the combo portion
of the score being converted were misnomers. In selected cases
(scores with high accuracy but combo being lower than max by more than
a few objects) the janky score-based math could overestimate the count
of remaining objects in a map. For instance, in one case the numbers
worked out something like this:
- Accuracy: practically 100%
- Max combo on beatmap: 571x
- Max combo for score: 551x
The score-based estimation attempts to extract a "remaining object
count" from score, by doing something along of sqrt(571^2 - 551^2). That
comes out to _almost 150_. Which leads to the estimation overshooting
the total max combo count on the beatmap by some hundred objects.
To curtail this nonsense, enforce some basic invariants:
- Neither estimate is allowed to exceed maximum achievable
- Ensure that lower estimate is really lower and upper is really upper
by just looking at the values and making sure that is so rather than
just saying that it is.