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

ServerChangeScene sends NotReadyMessage to non-authenticated-yet connections #3784

Closed
purepelmen opened this issue Mar 18, 2024 · 2 comments
Closed

Comments

@purepelmen
Copy link

Describe the bug
If you call ServerChangeScene(), it'll call NetworkServer.SetAllClientsNotReady() which sends NotReadyMessage to all clients:

foreach (NetworkConnectionToClient conn in connections.Values)
{
    SetClientNotReady(conn);
}

Even for those who hasn't authenticated yet! That's kind of strange. Because NotReadyMessage is a message for authenticated clients only, calling ServerChangeScene() when there're non-authenticated clients on the server would disconnect them:

Disconnecting connection: connection(0). Received message Mirror.NotReadyMessage that required authentication, but the user has not authenticated yet
UnityEngine.Debug:LogWarning (object)

I'm rewriting the way my game loads and connects to servers, but this problem has appeared. I was wondering why when the online scene is set and there's definitely a ServerChangeScene() call, everything works good and even when the host player isn't authenticated yet. Now, as I understand, it's because of the order in StartHost():

if (IsServerOnlineSceneChangeNeeded())
{
    // call FinishStartHost after changing scene.
    finishStartHostPending = true;
    ServerChangeScene(onlineScene);
}
// otherwise call FinishStartHost directly
else
{
    FinishStartHost();
}

FinishStartHost() will add the host player to the list, which will be called much more later (after the scene is loaded). So ServerChangeScene() will not send the message to the host player. But when there's no online scene, FInishStartHost() will immediately add the host player, even before StartHost() stops executing.

And now after StartHost() when there's no online scene, I try to change scene with ServerChangeScene() and... there's already added host player, it's not authenticated yet... and the host client is disconnected. 👍

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

  1. You need a network manager with an authenticator set, so the host won't be authenticated immediately.
  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. Then, maybe after some time the exception will be thrown, that will disconnect the host player.
    image

Expected behavior
SetAllClientsNotReady() shouldn't set non-authenticated players not ready.

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 (but it seems like the code works the same like in the master branch now))
@purepelmen
Copy link
Author

purepelmen commented Mar 18, 2024

Idk maybe it should be something like this:

public static void SetAllClientsNotReady()
{
    foreach (NetworkConnectionToClient conn in connections.Values)
    {
        if (!conn.isAuthenticated)
            continue;

        SetClientNotReady(conn);
    }
}

EDIT: Or like this:

public static void SetClientNotReady(NetworkConnectionToClient conn)
{
    if (!conn.isAuthenticated)
        return;

    conn.isReady = false;
    conn.RemoveFromObservingsObservers();
    conn.Send(new NotReadyMessage());
}

@MrGadget1024
Copy link
Collaborator

This was already fixed in Mirror 89.0.0.
See ChangeLog.

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

2 participants