Class: SteamCondenser::Servers::Sockets::SourceSocket

Inherits:
Object
  • Object
show all
Includes:
Logging, BaseSocket
Defined in:
lib/steam-condenser/servers/sockets/source_socket.rb

Overview

This class represents a socket used to communicate with game servers based on the Source engine (e.g. Team Fortress 2, Counter-Strike: Source)

Author:

  • Sebastian Staudt

Instance Method Summary collapse

Methods included from Logging

formatter=, included, level=, #log, logdev=

Methods included from BaseSocket

#close, #initialize, #receive_packet, #send, timeout=

Instance Method Details

#replyBasePacket

Reads a packet from the socket

The Source query protocol specifies a maximum packet size of 1,400 bytes. Bigger packets will be split over several UDP packets. This method reassembles split packets into single packet objects. Additionally Source may compress big packets using bzip2. Those packets will be compressed.

Returns:

  • (BasePacket)

    The packet replied from the server


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/steam-condenser/servers/sockets/source_socket.rb', line 29

def reply
  receive_packet 1400
  is_compressed = false
  packet_checksum = 0

  if @buffer.long == 0xFFFFFFFE
    split_packets = []
    begin
      request_id = @buffer.long
      is_compressed = ((request_id & 0x80000000) != 0)
      packet_count = @buffer.getbyte
      packet_number = @buffer.getbyte + 1

      if is_compressed
        @buffer.long
        packet_checksum = @buffer.long
      else
        @buffer.short
      end

      split_packets[packet_number - 1] = @buffer.get

      log.debug "Received packet #{packet_number} of #{packet_count} for request ##{request_id}"

      bytes_read = 0
      if split_packets.size < packet_count
        begin
          bytes_read = receive_packet
        rescue SteamCondenser::Error::Timeout
        end
      end
    end while bytes_read > 0 && @buffer.long == 0xFFFFFFFE

    packet = SteamCondenser::Servers::Packets::SteamPacketFactory.reassemble_packet(split_packets, is_compressed, packet_checksum)
  else
    packet = SteamCondenser::Servers::Packets::SteamPacketFactory.packet_from_data(@buffer.get)
  end

  if log.debug?
    packet_class = packet.class.name[/[^:]*\z/]
    if is_compressed
      log.debug "Got compressed reply of type \"#{packet_class}\"."
    else
      log.debug "Got reply of type \"#{packet_class}\"."
    end
  end

  packet
end