Пример #1
0
        /// <summary>
        /// Event called whenever raw data is received on the TCP socket.
        /// </summary>
        private void TCPPacketReceived(object sender, SocketAsyncEventArgs e)
        {
            // Parse out the actual RCON packet
            RCONPacket packet = RCONPacket.FromBytes(e.Buffer);

            if (packet.Type == PacketType.AuthResponse)
            {
                // Failed auth responses return with an ID of -1
                if (packet.Id == -1)
                {
                    throw new AuthenticationException($"Authentication failed for {_tcp.RemoteEndPoint}.");
                }

                // Tell Connect that authentication succeeded
                _authenticationTask.SetResult(true);
            }

            // Forward to handler
            RCONPacketReceived(packet);

            // Continue listening
            if (!_connected)
            {
                return;
            }
            _tcp.ReceiveAsync(e);
        }
Пример #2
0
        /// <summary>
        ///     Event called whenever raw data is received on the TCP socket.
        /// </summary>
        private void TCPPacketReceived(object sender, SocketAsyncEventArgs e)
        {
            // Parse out the actual RCON packet
            RCONPacket packet = null;

            try
            {
                packet = RCONPacket.FromBytes(e.Buffer);
            }
            catch (Exception exception)
            {
                Console.WriteLine("Unable to read packet, this has been observed when trying to communicate" +
                                  " with a server that is currently booting.\n" + exception.Message);
                Dispose();
                return;
            }

            if (packet.Type == PacketType.AuthResponse)
            {
                // Failed auth responses return with an ID of -1
                if (packet.Id == -1)
                {
                    Console.WriteLine($"Authentication failed for {_tcp.RemoteEndPoint}.");
                    Dispose();
                    return;
                }

                // Tell Connect that authentication succeeded

                try
                {
                    _authenticationTask.SetResult(true);
                }
                catch
                {
                    Console.WriteLine("Failure setting authentication task - disposing");
                    Dispose();
                    return;
                }
            }

            // Forward to handler
            RCONPacketReceived(packet);

            // Continue listening
            if (!_connected)
            {
                return;
            }
            _tcp.ReceiveAsync(e);
        }
Пример #3
0
        /// <summary>
        /// Event called whenever raw data is received on the TCP socket.
        /// </summary>
        private void TCPPacketReceived(object sender, SocketAsyncEventArgs e)
        {
            int size = BitConverter.ToInt32(e.Buffer, 0) + 4;

            if (size > e.Buffer.Length)
            {
                throw new OverflowException($"RCON message {size} bytes is larger than TCP buffer {e.Buffer.Length} bytes");
            }

            if (e.BytesTransferred + e.Offset < size)
            {
                // need more data, put e back for another go...
                e.SetBuffer(e.Offset + e.BytesTransferred, size - (e.Offset + e.BytesTransferred));

                if (!_connected)
                {
                    return;
                }
                _tcp.ReceiveAsync(e);
            }
            else
            {
                // Parse out the actual RCON packet
                RCONPacket packet = RCONPacket.FromBytes(e.Buffer);

                if (packet.Type == PacketType.AuthResponse)
                {
                    // Failed auth responses return with an ID of -1
                    if (packet.Id == -1)
                    {
                        throw new AuthenticationException($"Authentication failed for {_tcp.RemoteEndPoint}.");
                    }

                    // Tell Connect that authentication succeeded
                    _authenticationTask.SetResult(true);
                }

                // Forward to handler
                RCONPacketReceived(packet);

                // Continue listening
                if (!_connected)
                {
                    return;
                }
                e.SetBuffer(0, 4);
                _tcp.ReceiveAsync(e);
            }
        }
Пример #4
0
        /// <summary>
        /// Read data from pipeline when available, constructing new RCON packets
        /// </summary>
        /// <param name="reader"></param>
        /// <returns>Consumer Task</returns>
        async Task ReadPipeAsync(PipeReader reader)
        {
            byte[] byteArr = new byte[Constants.MAX_PACKET_SIZE];
            while (true)
            {
                ReadResult result = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer      = result.Buffer;
                SequencePosition        packetStart = buffer.Start;

                if (buffer.Length < 4)
                {
                    if (result.IsCompleted)
                    {
                        break;
                    }
                    reader.AdvanceTo(packetStart, buffer.End);
                    continue;
                    // Complete header not yet received
                }
                int size = BitConverter.ToInt32(buffer.Slice(packetStart, 4).ToArray(), 0);
                if (buffer.Length >= size + 4)
                {
                    // Get packet end positions
                    SequencePosition packetEnd = buffer.GetPosition(size + 4, packetStart);
                    byteArr = buffer.Slice(packetStart, packetEnd).ToArray();
                    RCONPacket packet = RCONPacket.FromBytes(byteArr);

                    if (packet.Type == PacketType.AuthResponse)
                    {
                        // Failed auth responses return with an ID of -1
                        if (packet.Id == -1)
                        {
                            _authenticationTask.SetException(
                                new AuthenticationException($"Authentication failed for {_tcp.RemoteEndPoint}.")
                                );
                        }
                        // Tell Connect that authentication succeeded
                        _authenticationTask.SetResult(true);
                    }

                    // Forward rcon packet to handler
                    RCONPacketReceived(packet);

                    reader.AdvanceTo(packetEnd);
                }
                else
                {
                    reader.AdvanceTo(packetStart, buffer.End);
                }

                // Tell the PipeReader how much of the buffer we have consumed

                // Stop reading if there's no more data coming
                if (buffer.IsEmpty && result.IsCompleted)
                {
                    break; // exit loop
                }
            }

            // If authentication did not complete
            _authenticationTask.TrySetException(
                new AuthenticationException($"Server did not respond to auth {_tcp.RemoteEndPoint}.")
                );

            // Mark the PipeReader as complete
            await reader.CompleteAsync();
        }