public void Join(Player joiningPlayer, string password = "") { Logger.Log(this, "Player {0} joined room {1}", joiningPlayer.Data.Name, RoomData.ID); // Prevent join if password is incorrect if (joiningPlayer.Data.ID != Owner.Data.ID && password != RoomData.Password) { Logger.Log(this, "Player {0} provided incorrect password {1}. (Is {2})", joiningPlayer.Data.Name, password, RoomData.Password); joiningPlayer.SendRoomJoinNotice(RoomNotice.InvalidPassword); return; } // Prevent join if room is full if (Players.Count == Settings.Values.Server.MaxPlayers) { Logger.Log(this, "Player {0} attempt to join the room {1} but that room is full", joiningPlayer.Data.Name, RoomData.ID); joiningPlayer.SendRoomJoinNotice(RoomNotice.RoomFull); return; } // Prevent join if game has started if (RoomData.GameStarted) { Logger.Log(this, "Player {0} attempt to join the room {1} but the game has already started", joiningPlayer.Data.Name, RoomData.ID); joiningPlayer.SendRoomJoinNotice(RoomNotice.GameAlreadyStarted); return; } if (Players.Contains(joiningPlayer)) { // TODO: Handle player rejoining room after disconnection? Logger.Log(this, "Already contains player {0}", joiningPlayer.Data.Name); joiningPlayer.SendRoomJoinNotice(RoomNotice.AlreadyInRoom); } else { joiningPlayer.SendRoomJoinNotice(RoomNotice.None); // Assign colour var color = RoomIdPool.GetValue(); joiningPlayer.AssignRoomId(color); Players.Add(joiningPlayer); RoomData.Players.Add(joiningPlayer.Data); // Add callbacks joiningPlayer.OnConnectionClosed += OnPlayerConnectionClosed; joiningPlayer.OnAwayStatusChanged += OnPlayerAwayStatusChanged; // Send message to joining player EchoActionToAll(joiningPlayer.Data, PlayerAction.Joined); SendUpdateToAll(); } }
void OnPlayerConnectionClosed(object sender, PlayerConnectionClosed e) { // Remove callbacks e.Player.OnConnectionClosed -= OnPlayerConnectionClosed; e.Player.OnAwayStatusChanged -= OnPlayerAwayStatusChanged; // Inform players switch (e.CloseReason) { case PlayerCloseReason.Disconnected: EchoActionToAll(e.Player.Data, PlayerAction.Disconnected); break; case PlayerCloseReason.Left: EchoActionToAll(e.Player.Data, PlayerAction.Left); break; case PlayerCloseReason.Kicked: EchoActionToAll(e.Player.Data, PlayerAction.Kicked); break; default: break; } // Remove player var data = RoomData.Players.Find(x => x.ID == e.Player.Data.ID); RoomData.Players.Remove(data); Players.Remove(e.Player); // Return color to pool RoomIdPool.ReturnValue(e.Player.Data.RoomId); if (Players.Count != 0) { // Assign a new owner if (Owner != Players[0]) { Owner = Players[0]; RoomData.Owner = Owner.Data; EchoActionToAll(Owner.Data, PlayerAction.PromotedToOwner); } if (Players.Count < Settings.Values.Server.MinPlayers) { CancelCountdown(); } SendUpdateToAll(); } else { // Remove room if no players remain if (Game != null) { Game.End(); } if (CountdownTimer != null) { CountdownTimer.Stop(); } Logger.Log(this, "Closing room {0} as it is empty", RoomData.ID); ConnectionsHandler.RemoveMessageListener(this); if (OnEmpty != null) { OnEmpty(this, this); } } }