Fixes this happening on staging:
[network] 2024-01-29 17:48:24 [verbose]: WebSocketNotificationsClientConnector connected!
[network] 2024-01-29 17:48:24 [verbose]: WebSocketNotificationsClientConnector connect attempt failed: Can't use WaitSafely from inside an async operation.
I'm not sure how I ever allowed that `.WaitSafely()` to be there. It
did feel rather dangerous but then I must have forgotten and never
noticed it failing. Which is weird because you'd think that would be
caught by testing that chat isn't working but I'm pretty sure that I
tested that chat *was* indeed working.
Anyway now that entire flow is replaced by something that should
hopefully be somewhat more sane? It has a whole retry flow with logging
now which should be more robust than what was there previously (failing
to start to listen to chat events killing the entire websocket
connection for very little good reason).
This is a prerequisite for https://github.com/ppy/osu/pull/25480.
The `WebSocketNotificationsClient` was tightly coupled to chat specifics
making it difficult to use in the second factor verification flow.
This commit's goal is to separate the websocket connection and message
handling concerns from specific chat logic concerns.
Them being together always bothered me and led to the abject failure
that is `APIUser` and its sprawl. Now that I'm about to add a flag that
is unique to `/me` for verification purposes, I'm not repeating the
errors of the past by adding yet another flag to `APIUser` that is never
present outside of a single usage context.
Up until now, the `UserActivity` class hierarchy contained things like
beatmap info, room info, full replay info, etc. While this was
convenient, it is soon going to be less so, as the data is sent over the
wire to the spectator server so that the user's activity can be
broadcast to other clients.
To counteract this without creating a second separate and slimmed-down
class hierarchy, slim down the `UserActivity` structure to contain the
bare minimum amounts of data such that the structures aren't overly
large and complex to serialise, but also contain enough data that they
can be used by receiving clients directly without having to do beatmap
or score lookups.