Currently, there's a period where the API is `Offline` even though it is
about to connect (as soon as the `run` thread starts up).
This can cause any `Queue`d requests to fail if they arrive too early.
To avoid this, let's ensure the `Connecting` state is set as early as
possible.
I noticed in passing that in a very edge case scenario where the API's
`run` thread doesn't run before it is loaded into the game, something
could access it and get a guest `LocalUser` when the local user actually
has a valid login.
Put another way, the `protected HasLogin` could be `true` while
`LocalUser` is `Guest`.
I think we want to avoid this, so I've moved the initial set of the
local user earlier in the initialisation process.
If this is controversial in any way, the PR can be closed and we can
assume no one is ever going to run into this scenario (or that it
doesn't matter enough even if they did).
It proved to be too difficult to deal with the flow that clears user
states on stopping the watching of global presence updates. It's not
helped in the least that friends are updated via the API, so there's a
third flow to consider (and the timings therein - both server-spectator
and friends are updated concurrently).
Simplest is to separate the friends flow, though this does mean some
logic and state duplication.
This also throws away the logic of updating
`API.LocalUser.Value.Statistics`. Components should rely on
`LocalUserStatisticsProvider` instead for proper behaviour and ability
to update on statistics updates.
Both online and offline using the cache.
The rationale behind this change is that in the current state of
affairs, `TestPartiallyMaliciousSet()` fails in a way that cannot be
reconciled without this sort of change.
The test exercises a scenario where the beatmap being imported has an
online ID in the `.osu` file, but its hash does not match the online
hash of the beatmap. This turns out to be a more frequent scenario than
envisioned because of users doing stupid things with manual file editing
rather than reporting issues properly.
The scenario is realistic only because the behaviour of the endpoint
responsible for looking up beatmaps is such that if multiple parameters
are given (e.g. all three of beatmap MD5, online ID, and filename), it
will try the three in succession:
f6b341813b/app/Http/Controllers/BeatmapsController.php (L260-L266)
and the local metadata cache implementation reflected this
implementation.
Because online ID and filename are inherently unreliable in this
scenario due to being directly manipulable by clueless or malicious
users, neither should not be used as a fallback.
Regressed at some point.
I don't see much reason not to link the bindable directly with config.
It seems to work as you'd expect. Tested with logout (resets to
"Online") and connection failure (persists).
Closes https://github.com/ppy/osu/issues/29173.