Class: SourceSocket

Inherits:
Object
  • Object
show all
Includes:
SteamSocket
Defined in:
lib/steam/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 SteamSocket

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

Instance Method Details

#replySteamPacket

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:



26
27
28
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
# File 'lib/steam/sockets/source_socket.rb', line 26

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.byte
      packet_number = @buffer.byte + 1

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

      split_packets[packet_number - 1] = @buffer.get

      puts "Received packet #{packet_number} of #{packet_count} for request ##{request_id}" if $DEBUG

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

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

  if is_compressed
    puts "Got compressed reply of type \"#{packet.class.to_s}\"." if $DEBUG
  else
    puts "Got reply of type \"#{packet.class.to_s}\"." if $DEBUG
  end

  packet
end