If a user leave and then rejoins a multiplayer match while another user
is not at the lobby screen, there is a potential the `ParticipantPanel`
tracking the user will not correctly be recreated to reference the new
instance of the `MultiplayerUser`.
This happens because the `OnRoomUpdated` call is scheduled, which means
it is not running in the background, coupled with the local logic that
relies on `IEquatable(MultiplayerRoomUser)` (which in turn falls back to
a UserID comparison).
Changing this to a reference comparison is the easiest way to resolve
this. Whether we change the `IEquatable` implementation is up for
discussion.
Closes https://github.com/ppy/osu/issues/15970.
The reason this was happening was an unfortunate oversight in the
migration logic. The code that was attempting to parse the skin settings
as `int` was firing regardless of whether a skin migration from EF to
realm had already occurred. If it had occurred, the skin setting would
contain a GUID rather than an integer, and therefore fail to parse, and
therefore implicitly fallback to a EF skin ID of 0 which would be the
default skin.
Fix by not running the setting migrating logic at all when there are no
EF skins to migrate.
Optimally, I would like to remove the `Schedule` in `EndPlaying`, but it
turns out quite a few test are relying on this at very least. Adding a
paired schedule ensure that order of operations is correct, at least.
This covers the scenario where a user may be at the song select screen
while another user (the room host) starts the match. This was only made
possible with the new queue modes, so is quite a recent regression.
This avoids accidental usage which could result in data being lost or
ignored (as only the last `user` in a single frame would arrive).
This was added specifically to debounce sample playback, but given that
it's only debouncing on a single frame (hardly noticeable) I'm not going
to add back support for that yet. It should be handled by sample
playback concurrency or something more local to the usage.
As it turns out, on some cultures, the "negative integer" sign is not
encoded using the U+002D HYPHEN-MINUS codepoint. For instance, Swedish
uses U+2212 MINUS SIGN instead. This was confusing the legacy decoder,
since it is correctly depending on the serialisation being
culture-independent.
To fix, ensure that the special "end replay" frame, as well as the
replay MD5 hash, are generated in a culture-invariant manner.
Thankfully the replay MD5 hash is currently being discarded in
`LegacyScoreDecoder`, so it changing in future scores should not have
any negative effect on lazer operation.