public static UpdateConnectedPlayersMessage Send() { Logger.LogFormat("This server informing all clients of the new PlayerList state: {0}", Category.Connections, string.Join(",", PlayerList.Instance.AllPlayers)); UpdateConnectedPlayersMessage msg = new UpdateConnectedPlayersMessage(); var prepareConnectedPlayers = new List <ClientConnectedPlayer>(); bool pendingSpawn = false; foreach (ConnectedPlayer c in PlayerList.Instance.AllPlayers) { if (c.Connection == null) { continue; //offline player } if (string.IsNullOrEmpty(c.Name)) { if (c.GameObject != null) { var joinedViewer = c.GameObject.GetComponent <JoinedViewer>(); if (joinedViewer != null) { pendingSpawn = true; } else { continue; } } else { continue; } } var tag = ""; if (PlayerList.Instance.IsAdmin(c.UserId)) { tag = "<color=red>[Admin]</color>"; } else if (PlayerList.Instance.IsMentor(c.UserId)) { tag = "<color=#6400ff>[Mentor]</color>"; } prepareConnectedPlayers.Add(new ClientConnectedPlayer { UserName = c.Username, Name = c.Name, Job = c.Job, PendingSpawn = pendingSpawn, Tag = tag }); } msg.Players = prepareConnectedPlayers.ToArray(); msg.SendToAll(); return(msg); }
private static void TrySendUpdate() { if (CustomNetworkManager.Instance != null && CustomNetworkManager.Instance._isServer && PlayerList.Instance != null) { UpdateConnectedPlayersMessage.Send(); } }
private void TryRemove(ConnectedPlayer player) { Debug.Log($"Removed {player}"); values.Remove(player); NetworkServer.Destroy(player.GameObject); UpdateConnectedPlayersMessage.Send(); }
private void TryRemove(ConnectedPlayer player) { Logger.Log($"Removed {player}", Category.Connections); values.Remove(player); AddPrevious(player); NetworkServer.Destroy(player.GameObject); UpdateConnectedPlayersMessage.Send(); }
private void TryRemove(ConnectedPlayer player) { Logger.Log($"Removed {player}", Category.Connections); loggedOff.Add(player); values.Remove(player); AddPrevious(player); UpdateConnectedPlayersMessage.Send(); CheckRcon(); }
public static UpdateConnectedPlayersMessage Send() { UpdateConnectedPlayersMessage msg = new UpdateConnectedPlayersMessage(); msg.Players = PlayerList.Instance.ClientConnectedPlayerList.ToArray(); msg.SendToAll(); return(msg); }
private static void UpdatePlayerList() { Dictionary <string, GameObject> connectedPlayers = PlayerList.Instance.connectedPlayers; //Notify all clients that connected players list should be updated GameObject[] players = new GameObject[connectedPlayers.Count]; connectedPlayers.Values.CopyTo(players, 0); UpdateConnectedPlayersMessage.Send(players); }
/// <summary> /// Spawns a new player character and transfers the connection's control into the new body. /// If existingMind is null, creates the new mind and assigns it to the new body. /// /// Fires server and client side player spawn hooks. /// </summary> /// <param name="connection">connection to give control to the new player character</param> /// <param name="occupation">occupation of the new player character</param> /// <param name="characterSettings">settings of the new player character</param> /// <param name="existingMind">existing mind to transfer to the new player, if null new mind will be created /// and assigned to the new player character</param> /// <param name="spawnPos">world position to spawn at</param> /// <param name="naked">If spawning a player, should the player spawn without the defined initial equipment for their occupation?</param> /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled, /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param> /// /// <returns>the spawned object</returns> private static GameObject ServerSpawnInternal(NetworkConnection connection, Occupation occupation, CharacterSettings characterSettings, Mind existingMind, Vector3Int?spawnPos = null, bool naked = false, bool willDestroyOldBody = false) { //determine where to spawn them if (spawnPos == null) { Transform spawnTransform = GetSpawnForJob(occupation.JobType); if (spawnTransform == null) { Logger.LogErrorFormat( "Unable to determine spawn position for connection {0} occupation {1}. Cannot spawn player.", Category.ItemSpawn, connection.address, occupation.DisplayName); return(null); } spawnPos = spawnTransform.transform.position.CutToInt(); } //create the player object var newPlayer = ServerCreatePlayer(spawnPos.GetValueOrDefault()); var newPlayerScript = newPlayer.GetComponent <PlayerScript>(); //get the old body if they have one. var oldBody = existingMind?.GetCurrentMob(); //transfer control to the player object ServerTransferPlayer(connection, newPlayer, oldBody, EVENT.PlayerSpawned, characterSettings, willDestroyOldBody); if (existingMind == null) { //create the mind of the player Mind.Create(newPlayer, occupation); } else { //transfer the mind to the new body existingMind.SetNewBody(newPlayerScript); } var ps = newPlayer.GetComponent <PlayerScript>(); var connectedPlayer = PlayerList.Instance.Get(connection); connectedPlayer.Name = ps.playerName; connectedPlayer.Job = ps.mind.occupation.JobType; UpdateConnectedPlayersMessage.Send(); //fire all hooks var info = SpawnInfo.Player(occupation, characterSettings, CustomNetworkManager.Instance.humanPlayerPrefab, SpawnDestination.At(spawnPos), naked: naked); Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, newPlayer)); return(newPlayer); }
public static UpdateConnectedPlayersMessage Send(GameObject[] players) { UpdateConnectedPlayersMessage msg = new UpdateConnectedPlayersMessage(); msg.Players = players; msg.SendToAll(); return(msg); }
private async Task 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, ConnectionIP = connectionToClient.address }); // this validates Userid and Token var isValidPlayer = await PlayerList.Instance.ValidatePlayer(unverifiedClientVersion, unverifiedConnPlayer, unverifiedToken); if (isValidPlayer == false) { ClearCache(); PlayerList.Instance.Remove(unverifiedConnPlayer); Logger.LogWarning($"Set up new player: invalid player. For {unverifiedUsername}", Category.Connections); return; } //Add player to the list of current round players PlayerList.Instance.AddToRoundPlayers(unverifiedConnPlayer); //Send to client their job ban entries var jobBanEntries = PlayerList.Instance.ClientAskingAboutJobBans(unverifiedConnPlayer); PlayerList.ServerSendsJobBanDataMessage.Send(unverifiedConnPlayer.Connection, jobBanEntries); //Send to client the current crew job counts if (CrewManifestManager.Instance != null) { SetJobCountsMessage.SendToPlayer(CrewManifestManager.Instance.Jobs, unverifiedConnPlayer); } UpdateConnectedPlayersMessage.Send(); IsValidPlayerAndWaitingOnLoad = true; STUnverifiedClientId = unverifiedClientId; STVerifiedUserid = unverifiedUserid; //Is validated within PlayerList.Instance.ValidatePlayer( STVerifiedConnPlayer = unverifiedConnPlayer; }
public static void RespawnPlayer(NetworkConnection conn, short playerControllerId, JobType jobType) { GameObject player = CreatePlayer(jobType); NetworkServer.ReplacePlayerForConnection(conn, player, playerControllerId); Dictionary <string, GameObject> connectedPlayers = PlayerList.Instance.connectedPlayers; //Notify all clients that connected players list should be updated GameObject[] players = new GameObject[connectedPlayers.Count]; connectedPlayers.Values.CopyTo(players, 0); UpdateConnectedPlayersMessage.Send(players); }
private void CmdTrySetInitialName(string name) { // Logger.Log($"TrySetName {name}"); if (PlayerList.Instance != null) { var player = PlayerList.Instance.Get(connectionToClient); player.Name = name; playerName = player.Name; PlayerList.Instance.TryAddScores(player.Name); UpdateConnectedPlayersMessage.Send(); } }
private void TryMoveClientToOfflineList(ConnectedPlayer player) { if (!loggedIn.Contains(player)) { Logger.Log($"Player with name {player.Name} was not found in online player list. " + $"Verifying player lists for integrity...", Category.Connections); ValidatePlayerListRecords(); return; } Logger.Log($"Added {player.Name} to offline player list.", Category.Connections); loggedOff.Add(player); loggedIn.Remove(player); UpdateConnectedPlayersMessage.Send(); CheckRcon(); }
public override void OnServerDisconnect(NetworkConnection conn) { if (conn != null && conn.playerControllers.Count > 0) { GameObject player = conn.playerControllers[0].gameObject; PlayerList.Instance.RemovePlayer(player.name); //Notify clients that the connected players list should be updated GameObject[] players = new GameObject[PlayerList.Instance.connectedPlayers.Count]; PlayerList.Instance.connectedPlayers.Values.CopyTo(players, 0); UpdateConnectedPlayersMessage.Send(players); //TODO DROP ALL HIS OBJECTS Debug.Log("PlayerDisconnected: " + conn.playerControllers[0].gameObject.name); NetworkServer.Destroy(conn.playerControllers[0].gameObject); } }
private void CmdServerSetupPlayer(ulong steamId, string clientID, string username) { var connPlayer = new ConnectedPlayer { Connection = connectionToClient, GameObject = gameObject, Username = username, Job = JobType.NULL, SteamId = steamId, ClientId = clientID }; //Add player to player list PlayerList.Instance.Add(connPlayer); // Sync all player data and the connected player count CustomNetworkManager.Instance.SyncPlayerData(gameObject); UpdateConnectedPlayersMessage.Send(); // If they have a player to rejoin send the client the player to rejoin, otherwise send a null gameobject. var loggedOffPlayer = PlayerList.Instance.TakeLoggedOffPlayer(clientID); if (loggedOffPlayer == null) { //This is the players first time connecting to this round, assign them a Client ID; clientID = System.Guid.NewGuid().ToString(); connPlayer.ClientId = clientID; } // 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(); } } TargetLocalPlayerSetupPlayer(connectionToClient, loggedOffPlayer, clientID, GameManager.Instance.CurrentRoundState); }
public static UpdateConnectedPlayersMessage Send() { UpdateConnectedPlayersMessage msg = new UpdateConnectedPlayersMessage(); var prepareConnectedPlayers = new List <ClientConnectedPlayer>(); foreach (ConnectedPlayer c in PlayerList.Instance.AllPlayers) { prepareConnectedPlayers.Add(new ClientConnectedPlayer { Name = c.Name, Job = c.Job }); } msg.Players = prepareConnectedPlayers.ToArray(); msg.SendToAll(); return(msg); }
public static void RespawnPlayer(NetworkConnection conn, short playerControllerId, JobType jobType, CharacterSettings characterSettings, GameObject oldBody) { GameObject player = CreatePlayer(jobType); TransferPlayer(conn, playerControllerId, player, oldBody, EVENT.PlayerSpawned, characterSettings); new Mind(player, jobType); var equipment = player.GetComponent <Equipment>(); var playerScript = player.GetComponent <PlayerScript>(); var connectedPlayer = PlayerList.Instance.Get(conn); connectedPlayer.Name = playerScript.playerName; UpdateConnectedPlayersMessage.Send(); PlayerList.Instance.TryAddScores(playerScript.playerName); equipment.SetPlayerLoadOuts(); if (jobType != JobType.SYNDICATE && jobType != JobType.AI) { SecurityRecordsManager.Instance.AddRecord(playerScript, jobType); } }
public static UpdateConnectedPlayersMessage Send() { Logger.LogFormat("This server informing all clients of the new PlayerList state: {0}", Category.Connections, string.Join(",", PlayerList.Instance.AllPlayers)); UpdateConnectedPlayersMessage msg = new UpdateConnectedPlayersMessage(); var prepareConnectedPlayers = new List <ClientConnectedPlayer>(); foreach (ConnectedPlayer c in PlayerList.Instance.AllPlayers) { prepareConnectedPlayers.Add(new ClientConnectedPlayer { Name = c.Name, Job = c.Job }); } msg.Players = prepareConnectedPlayers.ToArray(); msg.SendToAll(); return(msg); }
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 }); //this validates Userid and Token var isValidPlayer = await PlayerList.Instance.ValidatePlayer(unverifiedClientId, unverifiedUsername, unverifiedUserid, unverifiedClientVersion, unverifiedConnPlayer, unverifiedToken); if (isValidPlayer == false) { Logger.LogWarning("Set up new player: invalid player."); return; } // Check if they have a player to rejoin. If not, assign them a new client ID. GameObject loggedOffPlayer = PlayerList.Instance.TakeLoggedOffPlayerbyClientId(unverifiedClientId); // If the player does not yet have an in-game object to control, they'll probably have a // JoinedViewer assigned as they were only in the lobby. If so, destroy it and use the new one. if (loggedOffPlayer != null) { var checkForViewer = loggedOffPlayer.GetComponent <JoinedViewer>(); if (checkForViewer) { Destroy(loggedOffPlayer); loggedOffPlayer = null; } } 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.CountdownEndTime); } else { GameManager.Instance.CheckPlayerCount(); } } // If there's a logged off player, we will force them to rejoin. Previous logic allowed client to re-enter // their body or not, which should not be up to the client! if (loggedOffPlayer != null) { StartCoroutine(WaitForLoggedOffObserver(loggedOffPlayer)); } else { TargetLocalPlayerSetupNewPlayer(connectionToClient, GameManager.Instance.CurrentRoundState); } PlayerList.Instance.CheckAdminState(unverifiedConnPlayer, unverifiedUserid); PlayerList.Instance.CheckMentorState(unverifiedConnPlayer, unverifiedUserid); PlayerList.ClientJobBanDataMessage.Send(unverifiedUserid); }
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); } }
/// <summary> /// Spawns a new player character and transfers the connection's control into the new body. /// If existingMind is null, creates the new mind and assigns it to the new body. /// /// Fires server and client side player spawn hooks. /// </summary> /// <param name="connection">connection to give control to the new player character</param> /// <param name="occupation">occupation of the new player character</param> /// <param name="characterSettings">settings of the new player character</param> /// <param name="existingMind">existing mind to transfer to the new player, if null new mind will be created /// and assigned to the new player character</param> /// <param name="spawnPos">world position to spawn at</param> /// <param name="spawnItems">If spawning a player, should the player spawn without the defined initial equipment for their occupation?</param> /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled, /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param> /// /// <returns>the spawned object</returns> private static GameObject ServerSpawnInternal(NetworkConnection connection, Occupation occupation, CharacterSettings characterSettings, Mind existingMind, Vector3Int?spawnPos = null, bool spawnItems = true, bool willDestroyOldBody = false) { //determine where to spawn them if (spawnPos == null) { Transform spawnTransform; //Spawn normal location for special jobs or if less than 2 minutes passed if (GameManager.Instance.stationTime < ARRIVALS_SPAWN_TIME || occupation.LateSpawnIsArrivals == false) { spawnTransform = GetSpawnForJob(occupation.JobType); } else { spawnTransform = GetSpawnForLateJoin(occupation.JobType); //Fallback to assistant spawn location if none found for late join if (spawnTransform == null && occupation.JobType != JobType.NULL) { spawnTransform = GetSpawnForJob(JobType.ASSISTANT); } } if (spawnTransform == null) { Logger.LogErrorFormat( "Unable to determine spawn position for connection {0} occupation {1}. Cannot spawn player.", Category.ItemSpawn, connection.address, occupation.DisplayName); return(null); } spawnPos = spawnTransform.transform.position.CutToInt(); } //create the player object var newPlayer = ServerCreatePlayer(spawnPos.GetValueOrDefault()); var newPlayerScript = newPlayer.GetComponent <PlayerScript>(); //get the old body if they have one. var oldBody = existingMind?.GetCurrentMob(); //transfer control to the player object ServerTransferPlayer(connection, newPlayer, oldBody, EVENT.PlayerSpawned, characterSettings, willDestroyOldBody); if (existingMind == null) { //create the mind of the player Mind.Create(newPlayer, occupation); } else { //transfer the mind to the new body existingMind.SetNewBody(newPlayerScript); } var ps = newPlayer.GetComponent <PlayerScript>(); var connectedPlayer = PlayerList.Instance.Get(connection); connectedPlayer.Name = ps.playerName; connectedPlayer.Job = ps.mind.occupation.JobType; UpdateConnectedPlayersMessage.Send(); //fire all hooks var info = SpawnInfo.Player(occupation, characterSettings, CustomNetworkManager.Instance.humanPlayerPrefab, SpawnDestination.At(spawnPos), spawnItems: spawnItems); Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, newPlayer)); return(newPlayer); }
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); }
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 }); // this validates Userid and Token var isValidPlayer = await PlayerList.Instance.ValidatePlayer(unverifiedClientId, unverifiedUsername, unverifiedUserid, unverifiedClientVersion, unverifiedConnPlayer, unverifiedToken); if (isValidPlayer == false) { Logger.LogWarning($"Set up new player: invalid player. For {unverifiedUsername}", Category.Connections); return; } //Send to client their job ban entries var jobBanEntries = PlayerList.Instance.ClientAskingAboutJobBans(unverifiedConnPlayer); PlayerList.ServerSendsJobBanDataMessage.Send(unverifiedConnPlayer.Connection, jobBanEntries); //Send to client the current crew job counts if (CrewManifestManager.Instance != null) { SetJobCountsMessage.SendToPlayer(CrewManifestManager.Instance.Jobs, unverifiedConnPlayer); } 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.CountdownEndTime); } else { GameManager.Instance.CheckPlayerCount(); } } // Check if they have a player to rejoin before creating a new ConnectedPlayer var loggedOffPlayer = PlayerList.Instance.RemovePlayerbyClientId(unverifiedClientId, unverifiedUserid, unverifiedConnPlayer); var checkForViewer = loggedOffPlayer?.GameObject.GetComponent <JoinedViewer>(); if (checkForViewer) { Destroy(loggedOffPlayer.GameObject); loggedOffPlayer = null; } // If there's a logged off player, we will force them to rejoin their body if (loggedOffPlayer == null) { TargetLocalPlayerSetupNewPlayer(connectionToClient, GameManager.Instance.CurrentRoundState); } else { StartCoroutine(WaitForLoggedOffObserver(loggedOffPlayer.GameObject)); } PlayerList.Instance.CheckAdminState(unverifiedConnPlayer, unverifiedUserid); PlayerList.Instance.CheckMentorState(unverifiedConnPlayer, unverifiedUserid); }