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

Authentication messages are skipped when using StartHost() + ServerChangeScene() #3786

Open
purepelmen opened this issue Mar 19, 2024 · 2 comments

Comments

@purepelmen
Copy link

Describe the bug
I told previously (#3784 - ServerChangeScene sends NotReadyMessage to non-authenticated-yet connections), I'm rewriting the way my game loads and connects to servers. Now I call StartHost() and immediately after it I call ServerChangeScene() (no online scene set). This should work fine, though there was a problem with NotReadyMessage in an older version of Mirror. I've made a local fix to not update Mirror now, but noticed another problem.

As the title said, any messages sent in NetworkAuthenticator.OnClientAuthenticate() are just ignored. I send a RequestMessage there to authenticate. However as I see, StartHost() doesn't immediately authenticates the local client. StartHost() calls FinishStartHost() (because there's no online scene set), then it calls HostMode.InvokeOnConnected(), and it does this: ((LocalConnectionToServer)NetworkClient.connection).QueueConnectedEvent(). That connected event would be called in the next Update of the LocalConnectionToServer():

internal override void Update()
{
    base.Update();

    // should we still process a connected event?
    if (connectedEventPending)
    {
        connectedEventPending = false;
        NetworkClient.OnConnectedEvent?.Invoke();
    }

OnConnectedEvent then calls NetworkManager.OnClientConnectInternal(), which then calls authenticator.OnClientAuthenticate() (if we have an authenticator, we do have) finally.

The problem: The update of the local client won't be called immediately, but ServerChangeScene() will be. It will set isLoadingScene to true on the server and... NetworkServer.OnTransportData() will be called:

while (!isLoadingScene &&
       connection.unbatcher.GetNextMessage(out ArraySegment<byte> message, out double remoteTimestamp))
{

Yes, this will completely ignore any authentication messages sent in NetworkAuthenticator.OnClientAuthenticate().

[IMPORTANT] How can we reproduce the issue, step by step:

  1. You need a network manager with an authenticator set. The authenticator should send a request message to the server in OnClientAuthenticate().
  2. The manager should have no online scene set.
  3. Then you call NetworkManager.StartHost();
  4. Immediately after it, you try to change scene to another one: NetworkManager.ServerChangeScene(randomScene);
  5. Even after the scene is loaded you'll notice that the message you sent previously wasn't handled by the server.

Expected behavior
Messages sent in OnClientAuthenticate() should be handled by the server.

Desktop (please complete the following information):

  • OS: Windows
  • Build target: Windows (tested in the editor though)
  • Unity version: 2022.3.20f1
  • Mirror branch: uhm.. master I think. Downloaded from asset store (81.4.0)
@purepelmen
Copy link
Author

purepelmen commented Mar 19, 2024

I've also made a simple fix for this:

// LocalConnectionToServer.cs
internal override void Update()
{
    base.Update();

    // should we still process a connected event?
    if (connectedEventPending && !NetworkServer.isLoadingScene)
    {
        connectedEventPending = false;
        NetworkClient.OnConnectedEvent?.Invoke();
    }

This solves the problem.

@purepelmen
Copy link
Author

So... ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant