Class: GoldSrcSocket

Inherits:
Object
  • Object
show all
Includes:
SteamSocket
Defined in:
lib/steam/sockets/goldsrc_socket.rb

Overview

This class represents a socket used to communicate with game servers based on the GoldSrc engine (e.g. Half-Life, Counter-Strike)

Author:

  • Sebastian Staudt

Instance Method Summary collapse

Methods included from SteamSocket

#close, #receive_packet, #send, timeout=

Constructor Details

#initialize(ipaddress, port_number = 27015, is_hltv = false) ⇒ GoldSrcSocket

Creates a new socket to communicate with the server on the given IP address and port

Parameters:

  • ipaddress (String)

    Either the IP address or the DNS name of the server

  • port_number (Fixnum) (defaults to: 27015)

    The port the server is listening on

  • is_hltv (Boolean) (defaults to: false)

    ‘true` if the target server is a HTLV instance. HLTV behaves slightly different for RCON commands, this flag increases compatibility.



31
32
33
34
35
# File 'lib/steam/sockets/goldsrc_socket.rb', line 31

def initialize(ipaddress, port_number = 27015, is_hltv = false)
  super ipaddress, port_number

  @is_hltv = is_hltv
end

Instance Method Details

#rcon_challengeObject

Requests a challenge number from the server to be used for further requests

Raises:

  • (RCONBanError)

    if the IP of the local machine has been banned on the game server

See Also:



125
126
127
128
129
130
131
132
133
134
# File 'lib/steam/sockets/goldsrc_socket.rb', line 125

def rcon_challenge
  rcon_send 'challenge rcon'
  response = reply.response.strip

  if response.strip == 'You have been banned from this server.'
    raise RCONBanError
  end

  @rcon_challenge = response[14..-1]
end

#rcon_exec(password, command) ⇒ RCONGoldSrcResponse

Executes the given command on the server via RCON

Parameters:

  • password (String)

    The password to authenticate with the server

  • command (String)

    The command to execute on the server

Returns:

Raises:

  • (RCONBanError)

    if the IP of the local machine has been banned on the game server

  • (RCONNoAuthError)

    if the password is incorrect

See Also:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/steam/sockets/goldsrc_socket.rb', line 90

def rcon_exec(password, command)
  rcon_challenge if @rcon_challenge.nil? || @is_hltv

  rcon_send "rcon #@rcon_challenge #{password} #{command}"
  if @is_hltv
    begin
      response = reply.response
    rescue SteamCondenser::TimeoutError
      response = ''
    end
  else
    response = reply.response
  end

  if response.strip == 'Bad rcon_password.'
    raise RCONNoAuthError
  elsif response.strip == 'You have been banned from this server.'
    raise RCONBanError
  end

  rcon_send "rcon #@rcon_challenge #{password}"

  begin
    response_part = reply.response
    response << response_part
  end while response_part.size > 0

  response
end

#rcon_send(command) ⇒ Object

Wraps the given command in a RCON request packet and send it to the server

Parameters:

  • command (String)

    The RCON command to send to the server



139
140
141
# File 'lib/steam/sockets/goldsrc_socket.rb', line 139

def rcon_send(command)
  send RCONGoldSrcRequest.new(command)
end

#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.

Returns:



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
78
# File 'lib/steam/sockets/goldsrc_socket.rb', line 44

def reply
  receive_packet 1400

  if @buffer.long == 0xFFFFFFFE
    split_packets = []
    begin
      request_id = @buffer.long
      packet_number_and_count = @buffer.byte
      packet_count = packet_number_and_count & 0xF
      packet_number = (packet_number_and_count >> 4) + 1

      split_packets[packet_number - 1] = @buffer.get

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

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

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

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

  packet
end