Ejemplo n.º 1
0
        public void Depacketize(IReadablePacket packet)
        {
            _cellInfo.Clear();
            var cellCount = packet.ReadInt32();

            for (var i = 0; i < cellCount; i++)
            {
                var key   = packet.ReadUInt64();
                var value = packet.ReadPacketizable <CellInfo>();
                _cellInfo.Add(key, value);
            }
        }
Ejemplo n.º 2
0
        public void Depacketize(IReadablePacket packet)
        {
            _newCollisions.Clear();
            var newCollisionCount = packet.ReadInt32();

            for (var i = 0; i < newCollisionCount; ++i)
            {
                var key   = packet.ReadUInt64();
                var value = packet.ReadPacketizable <NewCollisionInfo>();
                _newCollisions.Add(key, value);
            }

            _activeCollisions.Clear();
            var activeCollisionCount = packet.ReadInt32();

            for (var i = 0; i < activeCollisionCount; ++i)
            {
                var key   = packet.ReadUInt64();
                var value = packet.ReadPacketizable <ActiveCollisionInfo>();
                _activeCollisions.Add(key, value);
            }
        }
Ejemplo n.º 3
0
        /// <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;
            }
        }
Ejemplo n.º 4
0
        /// <summary>Got some data via our TCP connection, so it's from the server.</summary>
        private void HandleTcpData(SessionMessage type, IReadablePacket packet)
        {
            switch (type)
            {
            case SessionMessage.JoinResponse:
                // Got a reply from a server for a join response.
                if (ConnectionState == ClientState.Connecting)
                {
                    // Get our number.
                    _localPlayerNumber = packet.ReadInt32();

                    // Get info about other players in the session.
                    PlayerCount = packet.ReadInt32();

                    // Maximum number of players in the session?
                    MaxPlayers = packet.ReadInt32();

                    // Sanity checks.
                    if (_localPlayerNumber < 0 || PlayerCount < 0 || MaxPlayers < 0 || MaxPlayers < PlayerCount ||
                        _localPlayerNumber >= MaxPlayers)
                    {
                        throw new PacketException("Inconsistent session info.");
                    }

                    // Allocate array for the players in the session.
                    Players = new Player[MaxPlayers];

                    // Get other game relevant data.
                    using (var joinData = packet.ReadPacketizable <Packet>())
                    {
                        // Get info on players already in the session, including us.
                        for (var i = 0; i < PlayerCount; i++)
                        {
                            // Get player number.
                            var playerNumber = packet.ReadInt32();

                            // Sanity checks.
                            if (playerNumber < 0 || playerNumber >= MaxPlayers || Players[playerNumber] != null)
                            {
                                throw new PacketException("Invalid player number.");
                            }

                            // Get player name.
                            var playerName = packet.ReadString();

                            // Get additional player data.
                            var playerData = packet.ReadPacketizable <TPlayerData>();

                            // All OK, add the player.
                            Players[playerNumber] = new Player(playerNumber, playerName, playerData);
                        }

                        // New state :)
                        ConnectionState = ClientState.Connected;

                        if (_tcp != null)
                        {
                            Logger.Debug(
                                "Successfully joined game at '{0}'.",
                                (IPEndPoint)_tcp.Client.RemoteEndPoint);
                        }
                        else
                        {
                            Logger.Debug("Successfully joined local game.");
                        }

                        // OK, let the program know.
                        OnJoinResponse(new JoinResponseEventArgs(joinData));
                    }

                    // Also, fire one join event for each player in the game. Except for
                    // the local player, because that'll likely need special treatment anyway.
                    foreach (var player in AllPlayers)
                    {
                        if (!player.Equals(LocalPlayer))
                        {
                            OnPlayerJoined(new PlayerEventArgs(player));
                        }
                    }
                }
                break;

            case SessionMessage.PlayerJoined:
                // Some player joined the session.
                if (ConnectionState == ClientState.Connected)
                {
                    // Get player number.
                    var playerNumber = packet.ReadInt32();

                    // Sanity checks.
                    if (playerNumber < 0 || playerNumber >= MaxPlayers || Players[playerNumber] != null)
                    {
                        throw new PacketException("Invalid player number.");
                    }

                    // Get player name.
                    var playerName = packet.ReadString();

                    // Get additional player data.
                    var playerData = packet.ReadPacketizable <TPlayerData>();

                    // All OK, add the player.
                    Players[playerNumber] = new Player(playerNumber, playerName, playerData);

                    // The the local program about it.
                    OnPlayerJoined(new PlayerEventArgs(Players[playerNumber]));
                }
                break;

            case SessionMessage.PlayerLeft:
                // Some player left the session.
                if (ConnectionState == ClientState.Connected)
                {
                    // Get player number.
                    var playerNumber = packet.ReadInt32();

                    // Sanity checks.
                    if (!HasPlayer(playerNumber))
                    {
                        throw new PacketException("Invalid player number.");
                    }

                    if (playerNumber == _localPlayerNumber)
                    {
                        // We were removed from the game.
                        Reset();
                    }
                    else
                    {
                        // OK, remove the player.
                        var player = Players[playerNumber];
                        Players[playerNumber] = null;

                        // Tell the local program about it.
                        OnPlayerLeft(new PlayerEventArgs(player));
                    }
                }
                break;

            case SessionMessage.Data:
                // Custom data, just forward it if we're in a session.
                if (ConnectionState == ClientState.Connected)
                {
                    OnData(new ClientDataEventArgs(packet, true));
                }
                break;

            default:
                // Ignore everything else.
                Logger.Trace("Unknown SessionMessage via TCP: {0}.", type);
                break;
            }
        }
Ejemplo n.º 5
0
 public static IReadablePacket Read <T>([NotNull] this IReadablePacket packet, [CanBeNull] out T data)
     where T : class, new()
 {
     data = packet.ReadPacketizable <T>();
     return(packet);
 }