public bool Join(IClient client, bool asSpectator) { if (client == null) throw new ArgumentNullException("client"); if (State == GameStates.Created || State == GameStates.Stopping) { Log.Default.WriteLine(LogLevels.Warning, "Cannot join, game {0} is not started(or stopping)", Name); return false; } if (!asSpectator && PlayerCount >= MaxPlayers) { Log.Default.WriteLine(LogLevels.Warning, "Too many players in game {0}", Name); return false; } if (asSpectator && SpectatorCount >= MaxSpectators) { Log.Default.WriteLine(LogLevels.Warning, "Too many spectators in game {0}", Name); return false; } if (Clients.Any(x => x == client)) { Log.Default.WriteLine(LogLevels.Warning, "Client already in game {0}", Name); return false; } IClient previousMaster = Players.FirstOrDefault(); // _clients.Add(client); // Change role, state and game client.Roles &= ~(ClientRoles.Player | ClientRoles.Spectator); // remove player+spectator if (asSpectator) client.Roles |= ClientRoles.Spectator; else client.Roles |= ClientRoles.Player; client.State = ClientStates.WaitInGame; client.Game = this; client.LastVoteKickAnswer = null; IClient newMaster = Players.FirstOrDefault(); if (client.IsPlayer && client == newMaster) // set game master { // Clear previous game master if (previousMaster != null) previousMaster.Roles &= ~ClientRoles.GameMaster; // Set game master client.Roles |= ClientRoles.GameMaster; } // Inform client GameData gameData = new GameData { Id = Id, Name = Name, Rule = Rule, Options = Options, Clients = Clients.Select(x => new ClientData { Id = x.Id, Name = x.Name, GameId = Id, Team = x.Team, IsGameMaster = x.IsGameMaster, IsPlayer = x.IsPlayer, IsSpectator = x.IsSpectator }).ToList() }; client.OnGameJoined(GameJoinResults.Successfull, gameData, client.IsGameMaster); // Inform other clients in game foreach (IClient target in Clients.Where(c => c != client)) target.OnClientGameJoined(client.Id, asSpectator); // Inform other clients about game master modification if (client.IsGameMaster) { foreach (IClient target in Clients.Where(c => c != client)) target.OnGameMasterModified(client.Id); Log.Default.WriteLine(LogLevels.Info, "Game {0}: Game master modified: {1}", Name, client.Id); } Log.Default.WriteLine(LogLevels.Info, "Game {0}: client {1} joined", Name, client.Name); return true; }