public GamePlayer AddPlayer <GamePlayer>(GamePlayer player) where GamePlayer : Engine.GamePlayer { if (!_playerIds.Contains(player.Id)) { _playerIds.Add(player.Id); player.IsSpectator = false; //Default them to being in game except in exigent circumstances (e.g. they chose to spectate) player.Game = this; player.AllowedTankTypes = Gamemode.GetPlayerAllowedTankTypes(player); _playersById.Add(player.Id, player); } if (Authoritative) { if (Running && !Gamemode.HotJoinEnabled) { player.IsSpectator = true; //Force spectator } else if (Running && Gamemode.HotJoinCanPlayerJoin(player)) { player.IsSpectator = false; //Let them join - first find the team and size the player list correctly player.Team = Gamemode.HotJoinGetPlayerTeam(player); var newPlayerArray = new Engine.GamePlayer[player.Team.Players.Length + 1]; Array.Copy(player.Team.Players, newPlayerArray, player.Team.Players.Length); newPlayerArray[newPlayerArray.Length - 1] = player; player.Team.Players = newPlayerArray; //Then tanks player.AllowedTankTypes = Gamemode.HotJoinGetAllowedTankTypes(player); //And add a timeout for them TimerFactory.CreateTimer(a => { if (player.HasTank || player.HasSelectedTankYet) { return; } _hotJoinPlayersWaitingForTankSelection.Remove(player); SetupPlayer(player); }, Settings.HotJoinTankSelectionTime); _hotJoinPlayersWaitingForTankSelection.Add(player); } } return(player); }