Module: GameServer
- Includes:
- Server
- Included in:
- GoldSrcServer, SourceServer
- Defined in:
- lib/steam/servers/game_server.rb
Constant Summary collapse
- REQUEST_CHALLENGE =
0
- REQUEST_INFO =
1
- REQUEST_PLAYER =
2
- REQUEST_RULES =
3
Class Method Summary collapse
-
.player_status_attributes(status_header) ⇒ Object
Parses the player attribute names supplied by rcon status.
-
.split_player_status(attributes, player_status) ⇒ Object
Splits the player status obtained with rcon status.
Instance Method Summary collapse
- #handle_response_for_request(request_type, repeat_on_failure = true) ⇒ Object
- #init ⇒ Object
-
#initialize(address, port = 27015) ⇒ Object
Creates a new instance of a game server object.
-
#ping ⇒ Object
Returns the last measured response time of this server.
-
#players(rcon_password = nil) ⇒ Object
Returns an array of the player’s currently playing on this server.
- #rcon_authenticated? ⇒ Boolean
-
#rules ⇒ Object
Returns a hash of the settings applied on the server.
-
#server_info ⇒ Object
Returns a hash with basic information on the server.
- #to_s ⇒ Object
- #update_challenge_number ⇒ Object
- #update_ping ⇒ Object
- #update_player_info(rcon_password = nil) ⇒ Object
- #update_rules_info ⇒ Object
- #update_server_info ⇒ Object
Methods included from Server
Class Method Details
.player_status_attributes(status_header) ⇒ Object
Parses the player attribute names supplied by rcon status
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/steam/servers/game_server.rb', line 28 def self.player_status_attributes(status_header) status_header.split.map do |attribute| case attribute when 'connected' :time when 'frag' :score else attribute.to_sym end end end |
.split_player_status(attributes, player_status) ⇒ Object
Splits the player status obtained with rcon status
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 |
# File 'lib/steam/servers/game_server.rb', line 42 def self.split_player_status(attributes, player_status) player_status.sub! /^\d+ +/, '' if attributes.first != :userid first_quote = player_status.index '"' last_quote = player_status.rindex '"' data = [ player_status[0, first_quote], player_status[first_quote + 1..last_quote - 1], player_status[last_quote + 1..-1] ] data = [ data[0].split, data[1], data[2].split ] data.flatten! if attributes.size > data.size && attributes.include?(:state) data.insert 3, nil, nil, nil elsif attributes.size < data.size data.delete_at 1 end player_data = {} data.each_index do |i| player_data[attributes[i]] = data[i] end player_data end |
Instance Method Details
#handle_response_for_request(request_type, repeat_on_failure = true) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/steam/servers/game_server.rb', line 131 def handle_response_for_request(request_type, repeat_on_failure = true) begin case request_type when GameServer::REQUEST_CHALLENGE then request_packet = A2S_SERVERQUERY_GETCHALLENGE_Packet.new expected_response = S2C_CHALLENGE_Packet when GameServer::REQUEST_INFO then request_packet = A2S_INFO_Packet.new expected_response = S2A_INFO_BasePacket when GameServer::REQUEST_PLAYER then request_packet = A2S_PLAYER_Packet.new(@challenge_number) expected_response = S2A_PLAYER_Packet when GameServer::REQUEST_RULES then request_packet = A2S_RULES_Packet.new(@challenge_number) expected_response = S2A_RULES_Packet else raise SteamCondenserException.new("Called with wrong request type.") end send_request request_packet response_packet = reply if response_packet.kind_of? S2A_INFO_BasePacket @info_hash = response_packet.info_hash elsif response_packet.kind_of? S2A_PLAYER_Packet @player_hash = response_packet.player_hash elsif response_packet.kind_of? S2A_RULES_Packet @rules_hash = response_packet.rules_hash elsif response_packet.kind_of? S2C_CHALLENGE_Packet @challenge_number = response_packet.challenge_number else raise SteamCondenserException.new("Response of type #{response_packet.class} cannot be handled by this method.") end unless response_packet.kind_of? expected_response puts "Expected #{expected_response}, got #{response_packet.class}." if $DEBUG handle_response_for_request(request_type, false) if repeat_on_failure end rescue TimeoutException puts "Expected #{expected_response}, but timed out." if $DEBUG end end |
#init ⇒ Object
174 175 176 177 178 |
# File 'lib/steam/servers/game_server.rb', line 174 def init update_ping update_server_info update_challenge_number end |
#initialize(address, port = 27015) ⇒ Object
Creates a new instance of a game server object
The port defaults to 27015 for game servers
72 73 74 |
# File 'lib/steam/servers/game_server.rb', line 72 def initialize(address, port = 27015) super end |
#ping ⇒ Object
Returns the last measured response time of this server
If there’s no data, update_ping is called to measure the current response time of the server.
Whenever you want to get a new value for the ping time call update_ping.
82 83 84 85 |
# File 'lib/steam/servers/game_server.rb', line 82 def ping update_ping if @ping.nil? @ping end |
#players(rcon_password = nil) ⇒ Object
Returns an array of the player’s currently playing on this server.
If there’s no data, update_player_info is called to get the current list of players.
As the players and their scores change quite often be sure to update this list regularly by calling update_player_info.
94 95 96 97 |
# File 'lib/steam/servers/game_server.rb', line 94 def players(rcon_password = nil) update_player_info(rcon_password) if @player_hash.nil? @player_hash end |
#rcon_authenticated? ⇒ Boolean
99 100 101 |
# File 'lib/steam/servers/game_server.rb', line 99 def rcon_authenticated? @rcon_authenticated end |
#rules ⇒ Object
Returns a hash of the settings applied on the server. These settings are also called rules. The hash has the format of rule_name
=> rule_value
If there’s no data, update_rules_info is called to get the current list of rules.
As the rules usually don’t change often, there’s almost no need to update this hash. But if you need to, you can achieve this by calling update_rules_info.
113 114 115 116 |
# File 'lib/steam/servers/game_server.rb', line 113 def rules update_rules_info if @rules_hash.nil? @rules_hash end |
#server_info ⇒ Object
Returns a hash with basic information on the server.
If there’s no data, update_server_info is called to get up-to-date information.
The server information usually only changes on map change and when players join or leave. As the latter changes can be monitored by calling update_player_info, there’s no need to call update_server_info very often.
126 127 128 129 |
# File 'lib/steam/servers/game_server.rb', line 126 def server_info update_server_info if @info_hash.nil? @info_hash end |
#to_s ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/steam/servers/game_server.rb', line 221 def to_s return_string = '' return_string << "Ping: #{@ping}\n" return_string << "Challenge number: #{@challenge_number}\n" unless @info_hash.nil? return_string << "Info:\n" @info_hash.each do |key, value| return_string << " #{key}: #{value.inspect}\n" end end unless @player_hash.nil? return_string << "Players:\n" @player_hash.each_value do |player| return_string << " #{player}\n" end end unless @rules_hash.nil? return_string << "Rules:\n" @rules_hash.each do |key, value| return_string << " #{key}: #{value}\n" end end return_string end |
#update_challenge_number ⇒ Object
209 210 211 |
# File 'lib/steam/servers/game_server.rb', line 209 def update_challenge_number handle_response_for_request GameServer::REQUEST_CHALLENGE end |
#update_ping ⇒ Object
213 214 215 216 217 218 219 |
# File 'lib/steam/servers/game_server.rb', line 213 def update_ping send_request A2S_INFO_Packet.new start_time = Time.now reply end_time = Time.now @ping = (end_time - start_time) * 1000 end |
#update_player_info(rcon_password = nil) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/steam/servers/game_server.rb', line 180 def update_player_info(rcon_password = nil) handle_response_for_request GameServer::REQUEST_PLAYER unless rcon_password.nil? || @player_hash.nil? || @player_hash.empty? rcon_auth rcon_password players = rcon_exec('status').lines.select do |line| line.start_with?('#') && line != "#end\n" end.map do |line| line[1..-1].strip end attributes = GameServer.player_status_attributes players.shift players.each do |player| player_data = GameServer.split_player_status(attributes, player) if @player_hash.key? player_data[:name] @player_hash[player_data[:name]].add_info player_data end end end end |
#update_rules_info ⇒ Object
201 202 203 |
# File 'lib/steam/servers/game_server.rb', line 201 def update_rules_info handle_response_for_request GameServer::REQUEST_RULES end |
#update_server_info ⇒ Object
205 206 207 |
# File 'lib/steam/servers/game_server.rb', line 205 def update_server_info handle_response_for_request GameServer::REQUEST_INFO end |