コード例 #1
0
        /// <summary>Sends a message of the specified type, with the specified data.</summary>
        /// <param name="type">The type of the message to send.</param>
        /// <param name="packet">The data to send.</param>
        protected override void Send(SessionMessage type, IWritablePacket packet = null)
        {
            if (ConnectionState != ClientState.Connected)
            {
                throw new InvalidOperationException("Not in a session.");
            }
            try
            {
                using (var wrapper = new Packet())
                {
                    wrapper.Write((byte)type).Write(packet);
                    var written = _stream.Write(wrapper);

                    // Statistics.
                    Info.PutOutgoingTraffic(
                        written,
                        type == SessionMessage.Data
                            ? TrafficTypes.Data
                            : TrafficTypes.Protocol);
                    Info.PutOutgoingPacketSize(written);
                    if (packet != null)
                    {
                        Info.PutOutgoingPacketCompression((packet.Length / (float)written) - 1f);
                    }
                }
            }
            catch (IOException ex)
            {
                Logger.TraceException("Socket connection died.", ex);
                Reset();
            }
        }
コード例 #2
0
        /// <summary>Join a local game.</summary>
        /// <param name="server">the local server to join.</param>
        /// <param name="playerName">the name with which to register.</param>
        /// <param name="playerData">additional data to be associated with our player.</param>
        public void Join(IServerSession server, string playerName, object playerData)
        {
            if (ConnectionState != ClientState.Unconnected)
            {
                throw new InvalidOperationException("Must leave the current session first.");
            }
            if (!(server is HybridServerSession <TPlayerData>))
            {
                throw new InvalidOperationException("Incompatible server type.");
            }
            if (!(playerData is TPlayerData))
            {
                throw new ArgumentException("Invalid type.", "playerData");
            }

            Logger.Debug("Begin connecting to local server.");
            _playerName     = playerName;
            _playerData     = (TPlayerData)playerData;
            ConnectionState = ClientState.Connecting;

            // Check if the server is already full.
            if (server.PlayerCount >= server.MaxPlayers)
            {
                Logger.Debug("Join failed, server already full.");
                Reset();
                return;
            }

            // Create the two 'pipes' we use to pass data from client to server
            // and vice versa.
            var toClient = new SlidingStream();
            var toServer = new SlidingStream();

            // Our stream is the one where the sink is the server.
            // The server gets one in the other direction (see below).
            _stream = new SlidingPacketStream(toClient, toServer);
            using (var packet = new Packet())
            {
                using (var packetInner = new Packet())
                {
                    packetInner.
                    Write(_playerName).
                    Write(_playerData);
                    packet.
                    Write((byte)SessionMessage.JoinRequest).
                    Write((IWritablePacket)packetInner);
                    var written = _stream.Write(packet);

                    // Statistics.
                    Info.PutOutgoingTraffic(written, TrafficTypes.Protocol);
                    Info.PutOutgoingPacketSize(written);
                    Info.PutOutgoingPacketCompression((packet.Length / (float)written) - 1f);
                }
            }

            // Let's try this. This can throw if the server is already
            // full, but that shouldn't happen, because we checked above.
            ((HybridServerSession <TPlayerData>)server).
            Add(new SlidingPacketStream(toServer, toClient));
        }
コード例 #3
0
 /// <summary>
 ///     Writes the specified packet to the underlying stream. It can then be read byte a <c>PacketStream</c> on the other
 ///     end of the stream.
 /// </summary>
 /// <param name="packet">The packet to write.</param>
 /// <returns>
 ///     The number of bytes actually written. This can differ from the length of the specified packet due to
 ///     transforms from wrapper streams (encryption, compression, ...)
 /// </returns>
 /// <exception cref="System.IO.IOException">If the underlying stream fails.</exception>
 public int Write(IWritablePacket packet)
 {
     using (var data = new Packet())
     {
         data.Write(Crypto.Encrypt(packet.GetBuffer(), 0, packet.Length));
         return(_stream.Write(data));
     }
 }
コード例 #4
0
        /// <summary>Connected successfully to the server, send login data.</summary>
        private void HandleConnected(IAsyncResult result)
        {
            lock (this)
            {
                if (_tcp == null)
                {
                    return;
                }
                try
                {
                    Logger.Debug("Connected to host, sending actual join request.");
                    _tcp.EndConnect(result);
                    _stream =
                        new EncryptedPacketStream(new CompressedPacketStream(new NetworkPacketStream(_tcp.GetStream())));
                    using (var packet = new Packet())
                    {
                        using (var packetInner = new Packet())
                        {
                            packetInner.
                            Write(_playerName).
                            Write(_playerData);
                            packet.
                            Write((byte)SessionMessage.JoinRequest).
                            Write((IWritablePacket)packetInner);
                            var written = _stream.Write(packet);

                            // Statistics.
                            Info.PutOutgoingTraffic(written, TrafficTypes.Protocol);
                            Info.PutOutgoingPacketSize(written);
                            Info.PutOutgoingPacketCompression((packet.Length / (float)written) - 1f);
                        }
                    }
                }
                catch (SocketException ex)
                {
                    // Connection failed.
                    Logger.DebugException("Join failed.", ex);
                    _resetRequested = true;
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Writes the specified packet to the underlying stream. It can then be read
        /// byte a <c>PacketStream</c> on the other end of the stream.
        /// </summary>
        /// <param name="packet">The packet to write.</param>
        /// <returns>The number of bytesa actually written. This can differ
        /// from the length of the specified packet due to transforms from
        /// wrapper streams (encryption, compression, ...)</returns>
        /// <exception cref="System.IO.IOException">If the underlying stream fails.</exception>
        public int Write(IWritablePacket packet)
        {
            using (var data = new Packet())
            {
                // If packets are large, try compressing them, see if it helps.
                // Only start after a certain size. General overhead for gzip
                // seems to be around 130byte, so make sure we're well beyond that.
                byte[] compressed;
                if (packet.Length > 200 && (compressed = SimpleCompression.Compress(packet.GetBuffer(), packet.Length)).Length < packet.Length)
                {
                    // OK, worth it, it's smaller than before.
                    data.Write(true);
                    data.Write(compressed);
                }
                else
                {
                    data.Write(false);
                    data.Write(packet.GetBuffer(), 0, packet.Length);
                }

                return(_stream.Write(data));
            }
        }