steam-condenser 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/lib/exceptions/packet_format_exception.rb +12 -5
  2. data/lib/exceptions/rcon_ban_exception.rb +11 -3
  3. data/lib/exceptions/rcon_no_auth_exception.rb +10 -3
  4. data/lib/exceptions/steam_condenser_exception.rb +8 -5
  5. data/lib/exceptions/timeout_exception.rb +13 -3
  6. data/lib/exceptions/web_api_exception.rb +31 -23
  7. data/lib/steam-condenser.rb +9 -3
  8. data/lib/steam-condenser/community.rb +8 -1
  9. data/lib/steam-condenser/servers.rb +7 -1
  10. data/lib/steam-condenser/version.rb +2 -1
  11. data/lib/steam/community/cacheable.rb +4 -4
  12. data/lib/steam/community/game_inventory.rb +119 -0
  13. data/lib/steam/community/game_item.rb +38 -0
  14. data/lib/steam/community/game_stats.rb +10 -4
  15. data/lib/steam/community/portal2/portal2_inventory.rb +21 -0
  16. data/lib/steam/community/portal2/portal2_item.rb +35 -0
  17. data/lib/steam/community/portal2/portal2_stats.rb +28 -0
  18. data/lib/steam/community/tf2/tf2_inventory.rb +7 -37
  19. data/lib/steam/community/tf2/tf2_item.rb +8 -79
  20. data/lib/steam/community/tf2/tf2_stats.rb +10 -13
  21. data/lib/steam/community/web_api.rb +1 -0
  22. data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +37 -4
  23. data/lib/steam/packets/a2s_info_packet.rb +10 -5
  24. data/lib/steam/packets/a2s_player_packet.rb +16 -6
  25. data/lib/steam/packets/a2s_rules_packet.rb +16 -4
  26. data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +11 -5
  27. data/lib/steam/packets/c2m_checkmd5_packet.rb +10 -4
  28. data/lib/steam/packets/m2a_server_batch_packet.rb +19 -3
  29. data/lib/steam/packets/m2c_isvalidmd5_packet.rb +14 -5
  30. data/lib/steam/packets/m2s_requestrestart_packet.rb +14 -4
  31. data/lib/steam/packets/rcon/rcon_auth_request.rb +15 -3
  32. data/lib/steam/packets/rcon/rcon_auth_response.rb +17 -3
  33. data/lib/steam/packets/rcon/rcon_exec_request.rb +15 -3
  34. data/lib/steam/packets/rcon/rcon_exec_response.rb +20 -3
  35. data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +18 -3
  36. data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +17 -3
  37. data/lib/steam/packets/rcon/rcon_packet.rb +31 -3
  38. data/lib/steam/packets/rcon/rcon_packet_factory.rb +15 -5
  39. data/lib/steam/packets/rcon/rcon_terminator.rb +14 -5
  40. data/lib/steam/packets/request_with_challenge.rb +10 -5
  41. data/lib/steam/packets/s2a_info2_packet.rb +14 -5
  42. data/lib/steam/packets/s2a_info_base_packet.rb +16 -6
  43. data/lib/steam/packets/s2a_info_detailed_packet.rb +15 -8
  44. data/lib/steam/packets/s2a_logstring_packet.rb +11 -5
  45. data/lib/steam/packets/s2a_player_packet.rb +14 -6
  46. data/lib/steam/packets/s2a_rules_packet.rb +15 -5
  47. data/lib/steam/packets/s2c_challenge_packet.rb +17 -6
  48. data/lib/steam/packets/s2m_heartbeat2_packet.rb +18 -4
  49. data/lib/steam/packets/steam_packet.rb +14 -5
  50. data/lib/steam/packets/steam_packet_factory.rb +25 -2
  51. data/lib/steam/servers/game_server.rb +154 -25
  52. data/lib/steam/servers/goldsrc_server.rb +35 -3
  53. data/lib/steam/servers/master_server.rb +77 -23
  54. data/lib/steam/servers/server.rb +42 -3
  55. data/lib/steam/servers/source_server.rb +35 -11
  56. data/lib/stringio_additions.rb +48 -3
  57. data/test/query_tests.rb +4 -4
  58. metadata +11 -6
@@ -5,16 +5,25 @@
5
5
 
6
6
  require 'steam/packets/rcon/rcon_packet'
7
7
 
8
- # This class is used to determine the end of a RCON response from Source
9
- # servers. Packets of this type are sent after the actual RCON command and the
10
- # empty response packet from the server will indicate the end of the response.
8
+ # This packet class represents a special SERVERDATA_RESPONSE_VALUE packet which
9
+ # is sent to the server
10
+ #
11
+ # It is used to determine the end of a RCON response from Source servers.
12
+ # Packets of this type are sent after the actual RCON command and the empty
13
+ # response packet from the server will indicate the end of the response.
14
+ #
15
+ # @author Sebastian Staudt
16
+ # @see SourceServer#rcon_exec
11
17
  class RCONTerminator
12
18
 
13
19
  include RCONPacket
14
20
 
15
- # Creates a new RCONTerminator instance for the given request ID
21
+ # Creates a new RCON terminator packet instance for the given request ID
22
+ #
23
+ # @param [Fixnum] request_id The request ID for the current RCON
24
+ # communication
16
25
  def initialize(request_id)
17
- super request_id, RCONPacket::SERVERDATA_RESPONSE_VALUE, nil
26
+ super request_id, SERVERDATA_RESPONSE_VALUE, nil
18
27
  end
19
28
 
20
29
  end
@@ -1,12 +1,17 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
- # This module implements a to_s method for request packets which send a challenge number
6
+ # This module implements a method to generate raw packet data used by request
7
+ # packets which send a challenge number
8
+ #
9
+ # @author Sebastian Staudt
7
10
  module RequestWithChallenge
8
11
 
9
- # Returns a packed version of the request
12
+ # Returns the raw data representing this packet
13
+ #
14
+ # @return string A string containing the raw data of this request packet
10
15
  def to_s
11
16
  [0xFF, 0xFF, 0xFF, 0xFF, @header_data, @content_data.string.to_i].pack('c5l')
12
17
  end
@@ -1,17 +1,26 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/s2a_info_base_packet'
7
7
 
8
- # The S2A_INFO2_Packet class represents the response to a A2S_INFO request sent
9
- # to a Source server.
8
+ # This class represents a S2A_INFO_DETAILED response packet sent by a Source or
9
+ # GoldSrc server
10
+ #
11
+ # Out-of-date (before 10/24/2008) GoldSrc servers use an older format (see
12
+ # {S2A_INFO_DETAILED_Packet}).
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @see GameServer#update_server_info
10
16
  class S2A_INFO2_Packet
11
17
 
12
18
  include S2A_INFO_BasePacket
13
19
 
14
- # Creates a S2A_INFO2 response object based on the data received.
20
+ # Creates a new S2A_INFO2 response object based on the given data
21
+ #
22
+ # @param [String] data The raw packet data replied from the server
23
+ # @see S2A_INFO_BasePacket#generate_info_hash
15
24
  def initialize(data)
16
25
  super S2A_INFO2_HEADER, data
17
26
 
@@ -1,19 +1,29 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2A_INFO_BasePacket class represents the response to a A2S_INFO
9
- # request send to the server.
8
+ # This module implements methods to generate and access server information from
9
+ # S2A_INFO_DETAILED and S2A_INFO2 response packets
10
+ #
11
+ # @author Sebastian Staudt
12
+ # @see S2A_INFO_DETAILED_Packet
13
+ # @see S2A_INFO2_Packet
10
14
  module S2A_INFO_BasePacket
11
15
 
12
16
  include SteamPacket
13
17
 
18
+ # Returns the information provided by the server
19
+ #
20
+ # @return [Hash<String, Object>] The information provided by the server
14
21
  attr_reader :info_hash
15
22
 
16
- # Returns the hash containing information on the server
23
+ protected
24
+
25
+ # Generates a hash of server properties from the instance variables of the
26
+ # including packet object
17
27
  def generate_info_hash
18
28
  @info_hash = Hash[
19
29
  *instance_variables.map { |var|
@@ -1,19 +1,26 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011 Sebastian Staudt
5
5
 
6
6
  require "steam/packets/s2a_info_base_packet"
7
7
 
8
- # The S2A_INFO_DETAILED_Packet class represents the response to a A2S_INFO
9
- # request send to a GoldSrc server.
10
- # This is deprecated by 10/24/2008 for GoldSrc servers. They use the same
11
- # format as Source servers (S2A_INFO2) now.
8
+ # This class represents a S2A_INFO_DETAILED response packet sent by a GoldSrc
9
+ # server
10
+ #
11
+ # This is deprecated by 10/24/2008. GoldSrc servers use the same format as
12
+ # Source servers now (see {S2A_INFO2_Packet}).
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @see GameServer#update_server_info
12
16
  class S2A_INFO_DETAILED_Packet
13
17
 
14
18
  include S2A_INFO_BasePacket
15
19
 
16
- # Creates a S2A_INFO_DETAILED response object based on the data received.
20
+ # Creates a new S2A_INFO_DETAILED response object based on the given data
21
+ #
22
+ # @param [String] data The raw packet data replied from the server
23
+ # @see S2A_INFO_BasePacket#generate_info_hash
17
24
  def initialize(data)
18
25
  super S2A_INFO_DETAILED_HEADER, data
19
26
 
@@ -1,19 +1,25 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2A_LOGSTRING packet type is used to transfer log messages.
8
+ # This class represents a S2A_LOGSTRING packet used to transfer log messages
9
+ #
10
+ # @author Sebastian Staudt
9
11
  class S2A_LOGSTRING_Packet
10
12
 
11
13
  include SteamPacket
12
14
 
13
- # The log message contained in this packet
15
+ # Returns the log message contained in this packet
16
+ #
17
+ # @return [String] The log message
14
18
  attr_reader :message
15
19
 
16
- # Creates a new log message packet
20
+ # Creates a new S2A_LOGSTRING object based on the given data
21
+ #
22
+ # @param [String] data The raw packet data sent by the server
17
23
  def initialize(data)
18
24
  super S2A_LOGSTRING_HEADER, data
19
25
 
@@ -1,25 +1,33 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2A_PLAYER_Packet class represents the response to a A2S_PLAYER
9
- # request send to the server.
8
+ # This class represents a S2A_PLAYER response sent by a game server
9
+ #
10
+ # It is used to transfer a list of players currently playing on the server.
11
+ #
12
+ # @author Sebastian Staudt
13
+ # @see GameServer#update_player_info
10
14
  class S2A_PLAYER_Packet
11
15
 
12
16
  include SteamPacket
13
17
 
18
+ # Returns the list of active players provided by the server
19
+ #
20
+ # @return [Hash<String, SteamPlayer>] All active players on the server
14
21
  attr_reader :player_hash
15
22
 
16
- # Creates a S2A_PLAYER response object based on the data received.
23
+ # Creates a new S2A_PLAYER response object based on the given data
24
+ #
25
+ # @param [String] content_data The raw packet data sent by the server
17
26
  def initialize(content_data)
18
27
  raise Exception.new('Wrong formatted S2A_PLAYER packet.') if content_data.nil?
19
28
 
20
29
  super S2A_PLAYER_HEADER, content_data
21
30
 
22
- # Ignore player count
23
31
  @content_data.byte
24
32
  @player_hash = {}
25
33
 
@@ -1,19 +1,29 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2A_RULES_Packet class represents the response to a A2S_RULES
9
- # request send to the server.
8
+ # This class represents a S2A_RULES response sent by a game server
9
+ #
10
+ # It is used to transfer a list of server rules (a.k.a. CVARs) with their
11
+ # active values.
12
+ #
13
+ # @author Sebastian Staudt
14
+ # @see GameServer#update_rules_info
10
15
  class S2A_RULES_Packet
11
16
 
12
17
  include SteamPacket
13
18
 
19
+ # Returns the list of server rules (a.k.a. CVars) with the current values
20
+ #
21
+ # @return [Hash<String, String>] A list of server rules
14
22
  attr_reader :rules_hash
15
23
 
16
- # Creates a S2A_RULES response object based on the data received.
24
+ # Creates a new S2A_RULES response object based on the given data
25
+ #
26
+ # @param [String] content_data The raw packet data sent by the server
17
27
  def initialize(content_data)
18
28
  raise Exception.new('Wrong formatted S2A_RULES response packet.') if content_data.nil?
19
29
 
@@ -1,22 +1,33 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2C_CHALLENGE_Packet class represents the response
9
- # to a A2S_SERVERQUERY_GETCHALLENGE request send to the server.
8
+ # This packet class represents a S2C_CHALLENGE response replied by a game
9
+ # server
10
+ #
11
+ # It is used to provide a challenge number to a client requesting information
12
+ # from the game server.
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @see GameServer#update_challenge_number
10
16
  class S2C_CHALLENGE_Packet
11
17
 
12
18
  include SteamPacket
13
19
 
14
- # Creates a S2C_CHALLENGE response object based on the data received.
20
+ # Creates a new S2C_CHALLENGE response object based on the given data
21
+ #
22
+ # @param [String] challenge_number The raw packet data replied from the
23
+ # server
15
24
  def initialize(challenge_number)
16
25
  super S2C_CHALLENGE_HEADER, challenge_number
17
26
  end
18
27
 
19
- # Returns the challenge number received from the server
28
+ # Returns the challenge number received from the game server
29
+ #
30
+ # @return [Fixnum] The challenge number provided by the game server
20
31
  def challenge_number
21
32
  @content_data.rewind
22
33
  @content_data.long
@@ -5,12 +5,19 @@
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The S2M_HEARTBEAT2 packet type is used to signal a game servers availability
9
- # and status to the master servers.
8
+ # This class represents a S2M_HEARTBEAT2 packet sent by game servers to master
9
+ # servers
10
+ #
11
+ # It is used to signal the game server's availability and status to the master
12
+ # servers.
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @see MasterServer#send_heartbeat
10
16
  class S2M_HEARTBEAT2_Packet
11
17
 
12
18
  include SteamPacket
13
19
 
20
+ # Default data to send with a S2M_HEARTBEAT2 packet
14
21
  DEFAULT_DATA = {
15
22
  :appid => 320,
16
23
  :bots => 0,
@@ -34,7 +41,12 @@ class S2M_HEARTBEAT2_Packet
34
41
  :version => '1.0.0.0'
35
42
  }
36
43
 
37
- # Creates a new heartbeat packet to send to a master server
44
+ # Creates a new S2M_HEARTBEAT2 packet object based on the given data
45
+ #
46
+ # @param [Hash<Symbol, Object>] data The data to send with the heartbeat. The
47
+ # data contents are merge with the values from {DEFAULT_DATA}.
48
+ # @raise [SteamCondenserException] when the required challenge number is
49
+ # missing
38
50
  def initialize(data = {})
39
51
  data = DEFAULT_DATA.merge data
40
52
 
@@ -49,7 +61,9 @@ class S2M_HEARTBEAT2_Packet
49
61
  super S2M_HEARTBEAT2_HEADER, bytes
50
62
  end
51
63
 
52
- # Returns a byte array representation of the packet data
64
+ # Returns the raw data representing this packet
65
+ #
66
+ # @return [String] A string containing the raw data of this request packet
53
67
  def to_s
54
68
  [@header_data, @content_data.string].pack('ca*')
55
69
  end
@@ -1,11 +1,15 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'stringio_additions'
7
7
 
8
- # This class represents a packet used by the Source query protocol
8
+ # This module implements the basic functionality used by most of the packets
9
+ # used in communication with master, Source or GoldSrc servers.
10
+ #
11
+ # @author Sebastian Staudt
12
+ # @see SteamPacketFactory
9
13
  module SteamPacket
10
14
 
11
15
  A2M_GET_SERVERS_BATCH2_HEADER = 0x31
@@ -29,13 +33,18 @@ module SteamPacket
29
33
  S2C_CHALLENGE_HEADER = 0x41
30
34
  S2M_HEARTBEAT2_HEADER = 0x30
31
35
 
32
- # Creates a new SteamPacket object with given header and content data
36
+ # Creates a new packet object based on the given data
37
+ #
38
+ # @param [Fixnum] header_data The packet header
39
+ # @param [String] content_data The raw data of the packet
33
40
  def initialize(header_data, content_data = '')
34
41
  @content_data = StringIO.new content_data.to_s
35
42
  @header_data = header_data
36
43
  end
37
44
 
38
- # Returns a packed string representing the packet's data
45
+ # Returns the raw data representing this packet
46
+ #
47
+ # @return [String] A string containing the raw data of this request packet
39
48
  def to_s
40
49
  [0xFF, 0xFF, 0xFF, 0xFF, @header_data, @content_data.string].pack('c5a*')
41
50
  end
@@ -1,5 +1,5 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
@@ -20,9 +20,19 @@ require 'steam/packets/m2s_requestrestart_packet'
20
20
  require 'steam/packets/s2a_logstring_packet'
21
21
  require 'steam/packets/rcon/rcon_goldsrc_response'
22
22
 
23
+ # This module provides functionality to handle raw packet data, including
24
+ # data split into several UDP / TCP packets and BZIP2 compressed data. It's the
25
+ # main utility to transform data bytes into packet objects.
26
+ #
27
+ # @author Sebastian Staudt
28
+ # @see SteamPacket
23
29
  module SteamPacketFactory
24
30
 
25
31
  # Creates a new packet object based on the header byte of the given raw data
32
+ #
33
+ # @param [String] raw_data The raw data of the packet
34
+ # @raise [SteamCondenserException] if the packet header is not recognized
35
+ # @return [SteamPacket] The packet object generated from the packet data
26
36
  def self.packet_from_data(raw_data)
27
37
  header = raw_data[0].ord
28
38
  data = raw_data[1..-1]
@@ -65,6 +75,19 @@ module SteamPacketFactory
65
75
  end
66
76
  end
67
77
 
78
+ # Reassembles the data of a split and/or compressed packet into a single
79
+ # packet object
80
+ #
81
+ # @param [Array<String>] split_packets An array of packet data
82
+ # @param [true, false] is_compressed whether the data of this packet is
83
+ # compressed
84
+ # @param [Fixnum] packet_checksum The CRC32 checksum of the decompressed
85
+ # packet data
86
+ # @raise [SteamCondenserException] if the bz2 gem is not installed
87
+ # @raise [PacketFormatException] if the calculated CRC32 checksum does not
88
+ # match the expected value
89
+ # @return [SteamPacket] The reassembled packet
90
+ # @see packet_from_data
68
91
  def self.reassemble_packet(split_packets, is_compressed = false, packet_checksum = 0)
69
92
  packet_data = split_packets.join ''
70
93
 
@@ -1,5 +1,5 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
@@ -15,6 +15,11 @@ require 'steam/packets/s2a_rules_packet'
15
15
  require 'steam/packets/s2c_challenge_packet'
16
16
  require 'steam/servers/server'
17
17
 
18
+ # This module is included by classes representing different game server
19
+ # implementations and provides the basic functionality to communicate with
20
+ # them using the common query protocol
21
+ #
22
+ # @author Sebastian Staudt
18
23
  module GameServer
19
24
 
20
25
  include Server
@@ -24,7 +29,11 @@ module GameServer
24
29
  REQUEST_PLAYER = 2
25
30
  REQUEST_RULES = 3
26
31
 
27
- # Parses the player attribute names supplied by +rcon status+
32
+ # Parses the player attribute names supplied by `rcon status`
33
+ #
34
+ # @param [String] status_header The header line provided by `rcon status`
35
+ # @return [Array<Symbol>] Split player attribute names
36
+ # @see .split_player_status
28
37
  def self.player_status_attributes(status_header)
29
38
  status_header.split.map do |attribute|
30
39
  case attribute
@@ -38,7 +47,13 @@ module GameServer
38
47
  end
39
48
  end
40
49
 
41
- # Splits the player status obtained with +rcon status+
50
+ # Splits the player status obtained with `rcon status`
51
+ #
52
+ # @param [Array<Symbol>] attributes The attribute names
53
+ # @param [String] player_status The status line of a single player
54
+ # @return [Hash<Symbol, String>] The attributes with the corresponding values
55
+ # for this player
56
+ # @see .player_status_attributes
42
57
  def self.split_player_status(attributes, player_status)
43
58
  player_status.sub! /^\d+ +/, '' if attributes.first != :userid
44
59
 
@@ -68,66 +83,119 @@ module GameServer
68
83
 
69
84
  # Creates a new instance of a game server object
70
85
  #
71
- # The port defaults to 27015 for game servers
86
+ # @param [String] address Either an IP address, a DNS name or one of them
87
+ # combined with the port number. If a port number is given, e.g.
88
+ # 'server.example.com:27016' it will override the second argument.
89
+ # @param [Fixnum] port The port the server is listening on
90
+ # @raise [SteamCondenserException] if an host name cannot be resolved
72
91
  def initialize(address, port = 27015)
73
92
  super
74
93
  end
75
94
 
76
95
  # Returns the last measured response time of this server
77
96
  #
78
- # If there's no data, update_ping is called to measure the current response
79
- # time of the server.
97
+ # If the latency hasn't been measured yet, it is done when calling this
98
+ # method for the first time.
80
99
  #
81
- # Whenever you want to get a new value for the ping time call update_ping.
100
+ # If this information is vital to you, be sure to call {#update_ping}
101
+ # regularly to stay up-to-date.
102
+ #
103
+ # @return [Fixnum] The latency of this server in milliseconds
104
+ # @see #update_ping
82
105
  def ping
83
106
  update_ping if @ping.nil?
84
107
  @ping
85
108
  end
86
109
 
87
- # Returns an array of the player's currently playing on this server.
110
+ # Returns a list of players currently playing on this server
88
111
  #
89
- # If there's no data, update_player_info is called to get the current list of
90
- # players.
112
+ # If the players haven't been fetched yet, it is done when calling this
113
+ # method for the first time.
91
114
  #
92
115
  # As the players and their scores change quite often be sure to update this
93
- # list regularly by calling update_player_info.
116
+ # list regularly by calling {#update_players} if you rely on this
117
+ # information.
118
+ #
119
+ # @param [String] rcon_password The RCON password of this server may be
120
+ # provided to gather more detailed information on the players, like
121
+ # STEAM_IDs.
122
+ # @return [Hash] The players on this server
123
+ # @see update_players
94
124
  def players(rcon_password = nil)
95
- update_player_info(rcon_password) if @player_hash.nil?
125
+ update_players(rcon_password) if @player_hash.nil?
96
126
  @player_hash
97
127
  end
98
128
 
129
+ # Authenticates the connection for RCON communication with the server
130
+ #
131
+ # @abstract Must be be implemented by including classes to handle the
132
+ # authentication
133
+ # @param [String] password The RCON password of the server
134
+ # @return [Boolean] whether the authentication was successful
135
+ # @see #rcon_exec
136
+ def rcon_auth(password)
137
+ end
138
+
99
139
  def rcon_authenticated?
100
140
  @rcon_authenticated
101
141
  end
102
142
 
103
- # Returns a hash of the settings applied on the server. These settings are
104
- # also called rules.
105
- # The hash has the format of +rule_name+ => +rule_value+
143
+ # Remotely executes a command on the server via RCON
106
144
  #
107
- # If there's no data, update_rules_info is called to get the current list of
145
+ # @abstract Must be be implemented by including classes to handle the command
146
+ # execution
147
+ # @param [String] command The command to execute on the server
148
+ # @return [String] The output of the executed command
149
+ # @see #rcon_auth
150
+ def rcon_exec(command)
151
+ end
152
+
153
+ # Returns the settings applied on the server. These settings are also called
108
154
  # rules.
109
155
  #
156
+ # If the rules haven't been fetched yet, it is done when calling this method
157
+ # for the first time.
158
+ #
110
159
  # As the rules usually don't change often, there's almost no need to update
111
160
  # this hash. But if you need to, you can achieve this by calling
112
- # update_rules_info.
161
+ # {#update_rules}.
162
+ #
163
+ # @return [Hash<String, String>] The currently active server rules
164
+ # @see #update_rules
113
165
  def rules
114
- update_rules_info if @rules_hash.nil?
166
+ update_rules if @rules_hash.nil?
115
167
  @rules_hash
116
168
  end
117
169
 
118
170
  # Returns a hash with basic information on the server.
119
171
  #
120
- # If there's no data, update_server_info is called to get up-to-date
121
- # information.
172
+ # If the server information haven't been fetched yet, it is done when
173
+ # calling this method for the first time.
122
174
  #
123
175
  # The server information usually only changes on map change and when players
124
176
  # join or leave. As the latter changes can be monitored by calling
125
- # update_player_info, there's no need to call update_server_info very often.
177
+ # {#update_players}, there's no need to call {#update_server_info} very
178
+ # often.
179
+ #
180
+ # @return [Hash] Server attributes with their values
181
+ # @see #update_server_info
126
182
  def server_info
127
183
  update_server_info if @info_hash.nil?
128
184
  @info_hash
129
185
  end
130
186
 
187
+ # Sends the specified request to the server and handles the returned response
188
+ #
189
+ # Depending on the given request type this will fill the various data
190
+ # attributes of the server object.
191
+ #
192
+ # @param [Fixnum] request_type The type of request to send to the server
193
+ # @param [Boolean] repeat_on_failure Whether the request should be repeated,
194
+ # if the replied packet isn't expected. This is useful to handle
195
+ # missing challenge numbers, which will be automatically filled in,
196
+ # although not requested explicitly.
197
+ # @raise [SteamCondenserException] if either the request type or the response
198
+ # packet is not known
131
199
  def handle_response_for_request(request_type, repeat_on_failure = true)
132
200
  begin
133
201
  case request_type
@@ -171,13 +239,30 @@ module GameServer
171
239
  end
172
240
  end
173
241
 
242
+ # Initializes this server object with basic information
243
+ #
244
+ # @see #update_challenge_number
245
+ # @see #update_ping
246
+ # @see #update_server_info
174
247
  def init
175
248
  update_ping
176
249
  update_server_info
177
250
  update_challenge_number
178
251
  end
179
252
 
180
- def update_player_info(rcon_password = nil)
253
+ # Sends a A2S_PLAYERS request to the server and updates the players' data for
254
+ # this server
255
+ #
256
+ # As the players and their scores change quite often be sure to update this
257
+ # list regularly by calling this method if you rely on this
258
+ # information.
259
+ #
260
+ # @param [String] rcon_password The RCON password of this server may be
261
+ # provided to gather more detailed information on the players, like
262
+ # STEAM_IDs.
263
+ # @see #handle_response_for_request
264
+ # @see #players
265
+ def update_players(rcon_password = nil)
181
266
  handle_response_for_request GameServer::REQUEST_PLAYER
182
267
 
183
268
  unless rcon_password.nil? || @player_hash.nil? || @player_hash.empty?
@@ -198,18 +283,52 @@ module GameServer
198
283
  end
199
284
  end
200
285
 
201
- def update_rules_info
286
+ # Sends a A2S_RULES request to the server and updates the rules of this
287
+ # server
288
+ #
289
+ # As the rules usually don't change often, there's almost no need to update
290
+ # this hash. But if you need to, you can achieve this by calling this method.
291
+ #
292
+ # @see #handle_response_for_request
293
+ # @see #rules
294
+ def update_rules
202
295
  handle_response_for_request GameServer::REQUEST_RULES
203
296
  end
204
297
 
298
+ # Sends a A2S_INFO request to the server and updates this server's basic
299
+ # information
300
+ #
301
+ # The server information usually only changes on map change and when players
302
+ # join or leave. As the latter changes can be monitored by calling
303
+ # {#update_players}, there's no need to call this method very often.
304
+ #
305
+ # @see #handle_response_for_request
306
+ # @see #server_info
205
307
  def update_server_info
206
308
  handle_response_for_request GameServer::REQUEST_INFO
207
309
  end
208
310
 
311
+ # Sends a A2S_SERVERQUERY_GETCHALLENGE request to the server and updates the
312
+ # challenge number used to communicate with this server
313
+ #
314
+ # There's usually no need to call this method explicitly, because
315
+ # {#handle_response_for_request} will automatically get the challenge number
316
+ # when the server assigns a new one.
317
+ #
318
+ # @see #handle_response_for_request
319
+ # @see #init
209
320
  def update_challenge_number
210
321
  handle_response_for_request GameServer::REQUEST_CHALLENGE
211
322
  end
212
323
 
324
+ # Sends a A2S_INFO request to the server and measures the time needed for the
325
+ # reply
326
+ #
327
+ # If this information is vital to you, be sure to call this method regularly
328
+ # to stay up-to-date.
329
+ #
330
+ # @return [Fixnum] The latency of this server in milliseconds
331
+ # @see #ping
213
332
  def update_ping
214
333
  send_request A2S_INFO_Packet.new
215
334
  start_time = Time.now
@@ -218,6 +337,10 @@ module GameServer
218
337
  @ping = (end_time - start_time) * 1000
219
338
  end
220
339
 
340
+ # Returns a human-readable text representation of the server
341
+ #
342
+ # @return [String] Available information about the server in a human-readable
343
+ # format
221
344
  def to_s
222
345
  return_string = ''
223
346
 
@@ -250,11 +373,17 @@ module GameServer
250
373
 
251
374
  protected
252
375
 
376
+ # Receives a response from the server
377
+ #
378
+ # @return [SteamPacket] The response packet replied by the server
253
379
  def reply
254
380
  @socket.reply
255
381
  end
256
382
 
257
- def send_request packet
383
+ # Sends a request packet to the server
384
+ #
385
+ # @param [SteamPacket] packet The request packet to send to the server
386
+ def send_request(packet)
258
387
  @socket.send packet
259
388
  end
260
389