Network Manager - Joining a match after finishing one

I have a custom Network Manager which identifies when a connection and disconnection occurs.

The flow is:

  1. Choose Online
  2. Choose public or private match
  3. Join/Create match (if you quit and rejoin here theres no issue)
  4. Start Match (scene change occurs using MyNetManager.singleton.ServerChangeScene)
  5. Finish Match
  6. Rematch/Change Characters/Quit

Rematch and Changing Characters works fine but if you quit and rejoin one of the following errors will occur:

  • A connection has already been set as ready. There can only be one.
  • There is already a player at that playerControllerId for this connections.

The behaviour is that the last player to join the room is thrown into a blank version of the scene that is loaded in step 4 while the one who created the room seems to have a correctly loaded character select scene.

The network manager code is as follows. I have been trying a lot of things to try and get it to clean up the match correctly so it might look a mess to you.:

public class MyNetManager : NetworkManager {

    bool shuttingDown = false;
    loadingScreen ld;

    void Start()
    {
        ld = GameObject.FindGameObjectWithTag("loading").GetComponent<loadingScreen>();
        if (PlayerPrefs.GetInt("GameType", 0) < 2)
            loading(false);
    }
    public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (success)
            loading(false);
        else
            message("Please check your internet connection . . .");

        base.OnMatchCreate(success, extendedInfo, matchInfo);
    }
    public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (success)
            loading(false);
        else
            message("Please check your internet connection . . .");

        base.OnMatchJoined(success, extendedInfo, matchInfo);
    }

    public override void OnStartClient(NetworkClient client)
    {
        loading(false);
        base.OnStartClient(client);
    }

    // This is called when quit is selected in step 6
    public void disconnectPlayer()
    {
        if (matchInfo != null)
        {
            matchMaker.SetMatchAttributes(matchInfo.networkId,false, matchInfo.domain, OnSetMatchAttributes);
            Network.RemoveRPCs(Network.player);
            Network.DestroyPlayerObjects(Network.player);
            matchMaker.DropConnection(matchInfo.networkId, matchInfo.nodeId, matchInfo.domain, OnDropConnection);
        }
        else
            returnToHome();
    }

    public override void OnClientDisconnect(NetworkConnection conn)
    {
        NetworkServer.DestroyPlayersForConnection(conn);
        loading(true);
        message("Player left the game");
    }

    public override void OnServerDisconnect(NetworkConnection conn)
    {
        NetworkServer.DestroyPlayersForConnection(conn);
        loading(true);
        message("Player left the game");
    }

    public override void OnDropConnection(bool success, string extendedInfo)
    {
        base.OnDropConnection(success, extendedInfo);
        if (!shuttingDown)
            returnToHome();
    }
  
    private void returnToHome()
    {
        shuttingDown = true;
        Network.Disconnect();
        StopHost();
        SceneManager.LoadScene(0);
        Destroy(gameObject);
    }

    void loading(bool show)
    {
        if (ld != null)
            ld.gameObject.SetActive(show);
    }

    void message(string message) {
  
        if(ld !=null){
            ld.setAnimation(1);
            ld.quit(message); // disconnectPlayer is called from here
        }
    }

}

The disconnect overrides do not call the super because it ends up giving a server timeout error.

Thank you for any explanations of what I have done terribly wrong, help or suggestions in advance

The rubberband answer is

    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    {
          //Instantiate your player here
         if (!NetworkServer.AddPlayerForConnection(conn, player, playerControllerId))
         {
             Debug.Log("caught");
             ServerChangeScene("lobby");
         }
    }

It forces the player back to the same scene as the host and everything works fine from there on