/// <summary>
    /// Waits for the client to be an observer of the player before continuing
    /// </summary>
    private IEnumerator WaitForLoggedOffObserver(GameObject loggedOffPlayer)
    {
        TargetLocalPlayerRejoinUI(connectionToClient);
        // TODO: When we have scene network culling we will need to allow observers
        // for the whole specific scene and the body before doing the logic below:
        var netIdentity = loggedOffPlayer.GetComponent <NetworkIdentity>();

        if (netIdentity == null)
        {
            Logger.LogError($"No {nameof(NetworkIdentity)} component on {loggedOffPlayer}! " +
                            "Cannot rejoin that player. Was original player object improperly created? " +
                            "Did we get runtime error while creating it?", Category.Connections);
            // TODO: if this issue persists, should probably send the poor player a message about failing to rejoin.
            yield break;
        }

        while (!netIdentity.observers.ContainsKey(connectionToClient.connectionId))
        {
            yield return(WaitFor.EndOfFrame);

            if (connectionToClient == null)
            {
                //disconnected while we were waiting
                yield break;
            }
        }

        TargetLocalPlayerRejoinUI(connectionToClient);
        PlayerSpawn.ServerRejoinPlayer(this, loggedOffPlayer);
    }
Beispiel #2
0
    /// <summary>
    /// Waits for the client to be an observer of the player before continuing
    /// </summary>
    IEnumerator WaitForLoggedOffObserver(GameObject loggedOffPlayer)
    {
        TargetLocalPlayerRejoinUI(connectionToClient);
        //TODO When we have scene network culling we will need to allow observers
        // for the whole specific scene and the body before doing the logic below:
        var netIdentity = loggedOffPlayer.GetComponent <NetworkIdentity>();

        while (!netIdentity.observers.ContainsKey(this.connectionToClient.connectionId))
        {
            yield return(WaitFor.EndOfFrame);
        }
        yield return(WaitFor.EndOfFrame);

        TargetLocalPlayerRejoinUI(connectionToClient);
        PlayerSpawn.ServerRejoinPlayer(this, loggedOffPlayer);
    }
    private void CmdServerSetupPlayer(string clientID, string username, string userid, int clientVersion)
    {
        Logger.LogFormat("A joinedviewer called CmdServerSetupPlayer on this server, clientID: {0} username: {1}", Category.Connections,
                         clientID, username);

        //Register player to player list (logging code exists in PlayerList so no need for extra logging here)
        var connPlayer = PlayerList.Instance.AddOrUpdate(new ConnectedPlayer
        {
            Connection = connectionToClient,
            GameObject = gameObject,
            Username   = username,
            Job        = JobType.NULL,
            ClientId   = clientID
        });

        if (!PlayerList.Instance.ValidatePlayer(clientID, username, userid, clientVersion, connPlayer))
        {
            return;
        }

        // Check if they have a player to rejoin. If not, assign them a new client ID
        var loggedOffPlayer = PlayerList.Instance.TakeLoggedOffPlayer(clientID);

        if (loggedOffPlayer == null)
        {
            //This is the players first time connecting to this round, assign them a Client ID;
            var oldID = clientID;
            clientID = System.Guid.NewGuid().ToString();
            Logger.LogFormat("This server did not find a logged off player with clientID {0}, assigning" +
                             " joined viewer a new ID {1}", Category.Connections, oldID, clientID);
        }

        // Sync all player data and the connected player count
        CustomNetworkManager.Instance.SyncPlayerData(gameObject);
        UpdateConnectedPlayersMessage.Send();



        // Only sync the pre-round countdown if it's already started
        if (GameManager.Instance.CurrentRoundState == RoundState.PreRound)
        {
            if (GameManager.Instance.waitForStart)
            {
                TargetSyncCountdown(connectionToClient, GameManager.Instance.waitForStart, GameManager.Instance.startTime);
            }
            else
            {
                GameManager.Instance.CheckPlayerCount();
            }
        }

        //if there's a logged off player, we will force them to rejoin. Previous logic allowed client to reenter
        //their body or not, which should not be up to the client!
        if (loggedOffPlayer != null)
        {
            PlayerSpawn.ServerRejoinPlayer(this, loggedOffPlayer);
        }
        else
        {
            TargetLocalPlayerSetupNewPlayer(connectionToClient, connPlayer.ClientId, GameManager.Instance.CurrentRoundState);
        }
    }
    private async void ServerSetUpPlayer(
        string unverifiedClientId,
        string unverifiedUsername,
        string unverifiedUserid,
        int unverifiedClientVersion,
        string unverifiedToken)
    {
        Logger.LogFormat("A joinedviewer called CmdServerSetupPlayer on this server, Unverified ClientId: {0} Unverified Username: {1}",
                         Category.Connections,
                         unverifiedClientId, unverifiedUsername);

        //Register player to player list (logging code exists in PlayerList so no need for extra logging here)
        var unverifiedConnPlayer = PlayerList.Instance.AddOrUpdate(new ConnectedPlayer
        {
            Connection = connectionToClient,
            GameObject = gameObject,
            Username   = unverifiedUsername,
            Job        = JobType.NULL,
            ClientId   = unverifiedClientId,
            UserId     = unverifiedUserid
        });

        var isValidPlayer = await PlayerList.Instance.ValidatePlayer(unverifiedClientId, unverifiedUsername,
                                                                     unverifiedUserid, unverifiedClientVersion, unverifiedConnPlayer, unverifiedToken);

        if (!isValidPlayer)
        {
            return;                         //this validates Userid and Token
        }
        // Check if they have a player to rejoin. If not, assign them a new client ID
        var loggedOffPlayer = PlayerList.Instance.TakeLoggedOffPlayerbyClientId(unverifiedClientId);

        if (loggedOffPlayer != null)
        {
            var checkForViewer = loggedOffPlayer.GetComponent <JoinedViewer>();
            if (checkForViewer)
            {
                Destroy(loggedOffPlayer);
                loggedOffPlayer = null;
            }
        }

        // Sync all player data and the connected player count
        CustomNetworkManager.Instance.SyncPlayerData(gameObject);
        UpdateConnectedPlayersMessage.Send();

        // Only sync the pre-round countdown if it's already started
        if (GameManager.Instance.CurrentRoundState == RoundState.PreRound)
        {
            if (GameManager.Instance.waitForStart)
            {
                // Calculate when the countdown will end relative to the NetworkTime
                double endTime = NetworkTime.time + GameManager.Instance.CountdownTime;
                TargetSyncCountdown(connectionToClient, GameManager.Instance.waitForStart, endTime);
            }
            else
            {
                GameManager.Instance.CheckPlayerCount();
            }
        }

        //if there's a logged off player, we will force them to rejoin. Previous logic allowed client to reenter
        //their body or not, which should not be up to the client!
        if (loggedOffPlayer != null)
        {
            PlayerSpawn.ServerRejoinPlayer(this, loggedOffPlayer);
        }
        else
        {
            TargetLocalPlayerSetupNewPlayer(connectionToClient,
                                            GameManager.Instance.CurrentRoundState);
        }

        PlayerList.Instance.CheckAdminState(unverifiedConnPlayer, unverifiedUserid);
    }
 public void CmdRejoin(GameObject loggedOffPlayer)
 {
     PlayerSpawn.ServerRejoinPlayer(this, loggedOffPlayer);
 }