Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix disparate score token types being used as one type #24697

Closed
wants to merge 6 commits into from

Conversation

bdach
Copy link
Collaborator

@bdach bdach commented Sep 1, 2023

More stuff related to #24229. I said I was gonna fix single player replays first, but on second thought I just could not look away from the magnitude of this breakage.


The replay upload flow and the user statistics update flow would rely on the score token sent by client to spectator server in BeginPlaySession(), in order to unmap the score token to a solo score ID when processing finishes.

However, spectator server thus far has not been aware that there are actually two types of token - and to be fair, client gave it no practical way to actually know this. In solo, the token ID comes from the solo_score_tokens table, and in multiplayer, the token ID comes from the multiplayer_score_links table (after ppy/osu-web#10437). Spectator server has however been treating both types as the solo score type. In particular, this could mean that the replay recording flow would royally confuse things and unmap the token to a score ID wrong due to looking for it in the wrong table, and as such, upload an entirely misattributed replay. (See also: relevant discord conversation.)

This PR aims to clean this up by passing a ScoreToken structure to spectator server rather than a plain long.

I'm not adding a dependency on ppy/osu-web#10437 here because the current token handling is wrong anyhow and would have needed to be fixed. That pull only begins to functionally matter for the upcoming osu-server-spectator-side change.

Deployment

This is a straight-up breaking change, as in:

old spectator-server new spectator-server
old client 🟢 OK 🔴 broken
new client 🔴 broken 🟢 OK

by which I mean that after the upcoming osu-spectator-server-side change is deployed, old clients will not be able to spectate.

I wanted to make this not breaking, but gave up because signalr is just not allowing that to happen because you can't overload hub methods, period. So I just did a straight-up API break. For whatever that's worth, we did that last time, too.

If you think backcompat is a blocker here, then I'll try again, but it'll 99% take at least a method rename.

It was only generally half-true that the thing was a "score ID"; in
solo, it was a score token ID all along, and in multiplayer it was
a multiplayer score ID. But that is soon to change, and it will become a
"score link ID", which is close enough to a score token to warrant
a rename.
This will allow spectator server to distinguish which type of token it
is dealing with (either solo, which means it should look up the ID in
`solo_score_tokens`, or multiplayer, which means it should look up the
ID in `multiplayer_score_links`).
Comment on lines +15 to +19
[Serializable]
[MessagePackObject]
public record ScoreToken(
[property: Key(0)] long ID,
[property: Key(1)] ScoreTokenType Type);
Copy link
Collaborator Author

@bdach bdach Sep 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure you'll like this syntax, especially the [property: ] stuff. I did it this way because it's kinda convenient for generating equality members & .ToString() which especially begins to matter on the spectator-server side. But I'll switch to standard class if this offends.

Comment on lines +181 to +185
/// <summary>
/// Constructs a <see cref="ScoreToken"/> for later use
/// from the <see cref="APIScoreToken"/> returned by web.
/// </summary>
protected abstract ScoreToken RetrieveScoreToken(APIScoreToken token);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally wanted to avoid creating this method and try to constrain this in CreateTokenRequest(), but the C# type system makes this annoying.

tl;dr: I would ideally do

protected abstract APIRequest<IAPIScoreToken> CreateTokenRequest()

with two implementations of IAPIScoreToken for solo and for multi. However the C# type system makes this extra annoying, since you can only have variance on interface generics, so that'd mean I'd have to do IAPIRequest<T> first, then probably something like IAPIScoreTokenRequest<T>, only then can it have IAPIScoreToken in the generic...... I don't think so. Unless you consider that better I guess.

Aside from more safety, also resolves "field never accessed"
inspections.
@pull-request-size pull-request-size bot added size/L and removed size/M labels Sep 1, 2023
Aside from the numerical ID of the token, it will log the type too now.
@bdach bdach self-assigned this Sep 5, 2023
bdach added a commit to bdach/osu-infrastructure that referenced this pull request Sep 5, 2023
This PR adds documentation about the multiplayer score submission flow
in the form of a sequence diagram. It was primarily created by taking
the existing solo score submission flow sequence diagram and adapting
it to the differences specific to the multi flow (different endpoints,
different tables, different ID schemes).

This diagram does not describe the current state of things. It describes
where things _should_ be after a sequence of some already-PRed changes
such as:

- ppy/osu-web#10437
- ppy/osu#24697
- ppy/osu-server-spectator#185

and some changes that are still being worked on (primarily client-side
at this point).

The main goal of the document is to inform the changes above. (And to be
something that I can easily refer to, because I keep looking up the same
information over and over right now.)
@peppy peppy self-requested a review September 12, 2023 08:18
@peppy
Copy link
Member

peppy commented Oct 12, 2023

As I mentioned in discord, sorry about this but I don't think we'll be requiring this (ignoring the wasted effort, that's probably a huge plus). I've been holding off reviewing this while I got my thoughts together and reassessed the whole structure of things, which I've documented over on ppy/osu-infrastructure#24.

Won't close just yet, but going to block until we confirm the direction in the linked issue is feasible (I believe @nanaya has already started osu-web implementation of it).

@peppy peppy added the blocked Don't merge this. label Oct 12, 2023
@peppy
Copy link
Member

peppy commented Oct 16, 2023

Closing for now to keep things clean. See ppy/osu-infrastructure#24 for rationale.

@peppy peppy closed this Oct 16, 2023
@bdach bdach deleted the fix-score-token-confusion branch January 23, 2024 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Replay Download Gives Incorrect Replay
2 participants