private void OnJoinRequested(JoinRequestEventArgs e) { if (JoinRequested != null) { JoinRequested(this, e); } }
/// <summary>Got data from a pending connection.</summary> /// <param name="pendingIndex">the index of the pending connection data.</param> /// <param name="type">the type of message we got.</param> /// <param name="packet">the data we got with it.</param> private void HandlePendingData(int pendingIndex, SessionMessage type, IReadablePacket packet) { switch (type) { case SessionMessage.JoinRequest: // Player wants to join. { // First, get the name he wishes to use. var playerName = packet.ReadString().Trim(); // Valid name? if (String.IsNullOrWhiteSpace(playerName)) { throw new ArgumentException("Invalid name."); } // Get custom player data. var playerData = packet.ReadPacketizable <TPlayerData>(); // OK so far, get a number for our player. var playerNumber = FindFreePlayerNumber(); // Create the player instance for the player. var player = new Player(playerNumber, playerName, playerData); // Request additional info first, as this also triggers // validation / prepping of the joining player's player // info, or allow manual override -- disallowing the // player to join. using (var requestArgs = new JoinRequestEventArgs(player)) { try { OnJoinRequested(requestArgs); } catch (Exception ex) { // Something went wrong, possible wrong data provided by the client. // In any case, block him. Logger.ErrorException("Failed getting join response data.", ex); requestArgs.ShouldBlock = true; } // Should we block the player? if (requestArgs.ShouldBlock) { throw new PacketException("Invalid data or actively blocked."); } // After getting here it's official! We have a new player. // Store the player's info. Players[playerNumber] = player; _slots[playerNumber] = true; _clients[playerNumber] = _pending[pendingIndex].Client; _streams[playerNumber] = _pending[pendingIndex].Stream; _pending.RemoveAt(pendingIndex); if (++PlayerCount == MaxPlayers) { // Ignore connection requests, we're full. _tcp.Stop(); // Also kill all other pending connections. foreach (var pending in _pending) { pending.Stream.Dispose(); } _pending.Clear(); } // Build the response. using (var response = new Packet()) { response .Write(playerNumber) .Write(PlayerCount) .Write(MaxPlayers) .Write(requestArgs.Data); // Send info about all players in the game (including himself). foreach (var p in AllPlayers) { response .Write(p.Number) .Write(p.Name) .Write((TPlayerData)p.Data); } // Send the response! SendTo(player, SessionMessage.JoinResponse, response); } } // Tell the other players. using (var joined = new Packet()) { joined .Write(playerNumber) .Write(playerName) .Write(playerData); foreach (var p in AllPlayers) { if (!p.Equals(player)) { SendTo(p, SessionMessage.PlayerJoined, joined); } } } // Tell the local program the player has joined. OnPlayerJoined(new PlayerEventArgs(Players[playerNumber])); } break; // Ignore the rest. default: Logger.Trace("Unknown SessionMessage via TCP: {0}.", type); break; } }