gamespy_query 0.2.0pre2 → 0.2.0pre3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gamespy_query +0 -0
- data/lib/gamespy_query/base.rb +11 -18
- data/lib/gamespy_query/master.rb +16 -17
- data/lib/gamespy_query/parser.rb +11 -12
- data/lib/gamespy_query/socket.rb +117 -95
- data/lib/gamespy_query/socket_master.rb +2 -20
- data/lib/gamespy_query/version.rb +1 -1
- data/lib/gamespy_query.rb +0 -16
- data/test/units/base_test.rb +2 -2
- data/test/units/parser_test.rb +6 -6
- metadata +8 -8
data/bin/gamespy_query
CHANGED
File without changes
|
data/lib/gamespy_query/base.rb
CHANGED
@@ -13,7 +13,7 @@ module GamespyQuery
|
|
13
13
|
module Tools
|
14
14
|
STR_EMPTY = ""
|
15
15
|
CHAR_N = "\n"
|
16
|
-
|
16
|
+
|
17
17
|
module_function
|
18
18
|
# Provides access to the logger object
|
19
19
|
# Will use ActionController::Base.logger if available
|
@@ -76,9 +76,9 @@ STR
|
|
76
76
|
# Integer / Float actually String Regex
|
77
77
|
RX_S = /\A\-?0[0-9]+.*\Z/
|
78
78
|
|
79
|
-
#
|
79
|
+
# Convert data type and strip tags
|
80
80
|
# @param [String] value String to convert
|
81
|
-
def
|
81
|
+
def convert_type(value) # TODO: Force String, Integer, Float etc?
|
82
82
|
case value
|
83
83
|
when STR_X0
|
84
84
|
nil
|
@@ -99,25 +99,18 @@ STR
|
|
99
99
|
number
|
100
100
|
end
|
101
101
|
|
102
|
+
STR_UTF8 = 'UTF-8'
|
103
|
+
|
102
104
|
# Convert string to UTF-8, stripping out all invalid/undefined characters
|
103
105
|
# @param [String] str String to convert
|
104
106
|
def encode_string(str)
|
105
107
|
#Tools.debug {"Getting string #{str}"}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
def _encode_string(str)
|
113
|
-
System::Text::Encoding.UTF8.GetString(System::Array.of(System::Byte).new(str.bytes.to_a)).to_s # # begin; System::Text::Encoding.USASCII.GetString(reply[0]).to_s; rescue nil, Exception => e; Tools.log_exception(e); reply[0].map {|e| e.chr}.join; end
|
114
|
-
end
|
115
|
-
else
|
116
|
-
# Get UTF-8 string from string
|
117
|
-
# @param [String] str
|
118
|
-
def _encode_string(str)
|
119
|
-
#(str + ' ').encode("US-ASCII", invalid: :replace, undef: :replace)[0..-3]
|
120
|
-
str.bytes.to_a.pack("U*")
|
108
|
+
#System::Text::Encoding.UTF8.GetString(System::Array.of(System::Byte).new(str.bytes.to_a)).to_s # # begin; System::Text::Encoding.USASCII.GetString(reply[0]).to_s; rescue nil, Exception => e; Tools.log_exception(e); reply[0].map {|e| e.chr}.join; end
|
109
|
+
begin
|
110
|
+
str.bytes.to_a.pack('C*').force_encoding(STR_UTF8)
|
111
|
+
rescue nil, Exception => e
|
112
|
+
Tools.log_exception e
|
113
|
+
str.encode("UTF-8", invalid: :replace, undef: :replace)
|
121
114
|
end
|
122
115
|
end
|
123
116
|
end
|
data/lib/gamespy_query/master.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
module GamespyQuery
|
2
2
|
# Provides access to the Gamespy Master browser
|
3
3
|
class Master < Base
|
4
|
+
# TODO: gslist.exe output encoding seems to be a problem.
|
5
|
+
# not been able to find a solution yet to get unicode instead of garbelled characters
|
6
|
+
# If impossible, perhaps should try custom implementation of master query
|
7
|
+
|
4
8
|
PARAMS = [:hostname, :gamever, :gametype, :gamemode, :numplayers, :maxplayers, :password, :equalModRequired, :mission, :mapname,
|
5
|
-
:mod, :signatures, :verifysignatures, :gamestate, :dedicated, :platform, :
|
9
|
+
:mod, :signatures, :verifysignatures, :gamestate, :dedicated, :platform, :sv_battleye, :language, :difficulty]
|
6
10
|
|
7
11
|
RX_ADDR_LINE = /^[\s\t]*([\d\.]+)[\s\t:]*(\d+)[\s\t]*(.*)$/
|
8
12
|
|
@@ -13,6 +17,14 @@ module GamespyQuery
|
|
13
17
|
"\\\\"
|
14
18
|
end
|
15
19
|
|
20
|
+
path = defined?(Rails) ? File.join(Rails.root, "config") : File.join(Dir.pwd, "config")
|
21
|
+
DEFAULT_GEOIP_PATH = case RUBY_PLATFORM
|
22
|
+
when /-mingw32$/, /-mswin32$/
|
23
|
+
path.gsub("/", "\\")
|
24
|
+
else
|
25
|
+
path
|
26
|
+
end
|
27
|
+
|
16
28
|
# Geo settings
|
17
29
|
attr_reader :geo
|
18
30
|
|
@@ -22,8 +34,8 @@ module GamespyQuery
|
|
22
34
|
# Initializes the instance
|
23
35
|
# @param [String] geo Geo string
|
24
36
|
# @param [String] game Game string
|
25
|
-
def initialize(geo = nil, game = "arma2oapc")
|
26
|
-
@geo, @game = geo, game
|
37
|
+
def initialize(geo = nil, game = "arma2oapc", geoip_path = nil)
|
38
|
+
@geo, @game, @geoip_path = geo, game, geoip_path
|
27
39
|
end
|
28
40
|
|
29
41
|
# Convert the master browser data to hash
|
@@ -118,20 +130,7 @@ module GamespyQuery
|
|
118
130
|
|
119
131
|
# Get geoip_path
|
120
132
|
def geoip_path
|
121
|
-
|
122
|
-
|
123
|
-
case RUBY_PLATFORM
|
124
|
-
when /-mingw32$/, /-mswin32$/
|
125
|
-
File.join(Rails.root, "config").gsub("/", "\\")
|
126
|
-
else
|
127
|
-
File.join(Rails.root, "config")
|
128
|
-
end
|
133
|
+
@geoip_path || DEFAULT_GEOIP_PATH
|
129
134
|
end
|
130
135
|
end
|
131
136
|
end
|
132
|
-
|
133
|
-
if $0 == __FILE__
|
134
|
-
master = GamespyQuery::Master.new
|
135
|
-
r = master.read
|
136
|
-
puts r
|
137
|
-
end
|
data/lib/gamespy_query/parser.rb
CHANGED
@@ -30,13 +30,13 @@ module GamespyQuery
|
|
30
30
|
# - Array, packetDATA ordered already by packetID
|
31
31
|
def initialize(packets)
|
32
32
|
@packets = case packets
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
when Hash
|
34
|
+
packets.keys.sort.map{|key| packets[key] }
|
35
|
+
when Array
|
36
|
+
packets
|
37
|
+
else
|
38
|
+
raise UnsupportedFormat, "Unsupported format: #{packets.class}"
|
39
|
+
end
|
40
40
|
end
|
41
41
|
|
42
42
|
# Parse game and player data to hash
|
@@ -48,7 +48,7 @@ module GamespyQuery
|
|
48
48
|
data[:game] = {} # Key: InfoKey, Value: InfoValue
|
49
49
|
data[:players] = {} # Key: InfoType, Value: Array of Values
|
50
50
|
player_info = false
|
51
|
-
player_data = ""
|
51
|
+
player_data = ""
|
52
52
|
|
53
53
|
# Parse the packets
|
54
54
|
@packets.each do |packet|
|
@@ -70,12 +70,12 @@ module GamespyQuery
|
|
70
70
|
else
|
71
71
|
# GameData-only
|
72
72
|
data[:game].merge!(parse_game_data(packet))
|
73
|
-
end
|
73
|
+
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
# Parse player_data
|
78
|
-
data[:players] = parse_player_data(player_data)
|
78
|
+
data[:players] = parse_player_data(encode_string player_data)
|
79
79
|
|
80
80
|
data
|
81
81
|
end
|
@@ -168,7 +168,7 @@ module GamespyQuery
|
|
168
168
|
player_data[player_data.keys[i]] << encode_string(entry.sub(STR_X0, STR_EMPTY))
|
169
169
|
str.sub!(entry, STR_EMPTY)
|
170
170
|
end
|
171
|
-
|
171
|
+
|
172
172
|
# Search for SIX string to overwrite last entry
|
173
173
|
new_player_data = []
|
174
174
|
overwrite = false
|
@@ -177,7 +177,6 @@ module GamespyQuery
|
|
177
177
|
overwrite = true # tag so that the next entry will overwrite the latest entry
|
178
178
|
next # ignore
|
179
179
|
else
|
180
|
-
info = clean(info) if [2,3].include?(i) # Apply data_type conversion for Score and Deaths
|
181
180
|
if overwrite
|
182
181
|
new_player_data[-1] = info # Overwrite latest entry
|
183
182
|
overwrite = false # done the overwrite
|
data/lib/gamespy_query/socket.rb
CHANGED
@@ -5,83 +5,6 @@ require 'yaml'
|
|
5
5
|
require 'socket'
|
6
6
|
|
7
7
|
module GamespyQuery
|
8
|
-
# Provides socket functionality on multiple platforms
|
9
|
-
# TODO
|
10
|
-
module MultiSocket
|
11
|
-
# Create socket
|
12
|
-
def create_socket(*params)
|
13
|
-
Tools.debug {"Creating socket #{params}"}
|
14
|
-
_create_socket(*params)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Write socket
|
18
|
-
def socket_send(*params)
|
19
|
-
Tools.debug {"Sending socket #{params}"}
|
20
|
-
_socket_send(*params)
|
21
|
-
end
|
22
|
-
|
23
|
-
# Read socket
|
24
|
-
def socket_receive(*params)
|
25
|
-
Tools.debug {"Receiving socket #{params}"}
|
26
|
-
_socket_receive(*params)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Close socket
|
30
|
-
def socket_close(*params)
|
31
|
-
Tools.debug {"Closing socket #{params}"}
|
32
|
-
@s.close
|
33
|
-
end
|
34
|
-
|
35
|
-
if RUBY_PLATFORM =~ /mswin32/
|
36
|
-
include System::Net
|
37
|
-
include System::Net::Sockets
|
38
|
-
|
39
|
-
# Create socket
|
40
|
-
def _create_socket(host, port)
|
41
|
-
@ip_end_point = IPEndPoint.new(IPAddress.Any, 0)
|
42
|
-
@s = UdpClient.new
|
43
|
-
@s.client.receive_timeout = DEFAULT_TIMEOUT * 1000
|
44
|
-
@s.connect(host, port.to_i)
|
45
|
-
end
|
46
|
-
|
47
|
-
# Write socket
|
48
|
-
def _socket_send(packet)
|
49
|
-
@s.Send(packet, packet.length)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Read socket
|
53
|
-
def _socket_receive
|
54
|
-
@s.Receive(@ip_end_point)
|
55
|
-
end
|
56
|
-
|
57
|
-
else
|
58
|
-
|
59
|
-
# Create socket
|
60
|
-
def _create_socket(host, port)
|
61
|
-
@s = UDPSocket.new
|
62
|
-
@s.connect(host, port)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Write socket
|
66
|
-
def _socket_send(packet)
|
67
|
-
@s.puts(packet)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Read socket
|
71
|
-
def _socket_receive
|
72
|
-
begin
|
73
|
-
Timeout::timeout(DEFAULT_TIMEOUT) do
|
74
|
-
@s.recvfrom(RECEIVE_SIZE)
|
75
|
-
end
|
76
|
-
rescue Timeout::Error
|
77
|
-
raise TimeoutError, "TimeOut on #{self}"
|
78
|
-
ensure
|
79
|
-
@s.close
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
8
|
# Provides direct connection functionality to gamespy enabled game servers
|
86
9
|
# This query contains up to 7x more information than the gamespy master browser query
|
87
10
|
# For example, player lists with info (teams, scores, deaths) are only available by using direct connection
|
@@ -117,6 +40,8 @@ module GamespyQuery
|
|
117
40
|
RX_CHALLENGE2 = /[^0-9\-]/si
|
118
41
|
RX_SPLITNUM = /^splitnum\x00(.)/i
|
119
42
|
|
43
|
+
PLATFORM_IR = /-mswin32/
|
44
|
+
|
120
45
|
# TODO: Support pings
|
121
46
|
# TODO: Handle .NET native sockets
|
122
47
|
STATE_INIT, STATE_SENT_CHALLENGE, STATE_RECEIVED_CHALLENGE, STATE_SENT_CHALLENGE_RESPONSE, STATE_RECEIVE_DATA, STATE_READY = 0, 1, 2, 3, 4, 5
|
@@ -170,15 +95,11 @@ module GamespyQuery
|
|
170
95
|
else
|
171
96
|
raise NotInWriteState, "NotInWriteState, #{self}"
|
172
97
|
end
|
173
|
-
rescue
|
174
|
-
r = false
|
175
|
-
self.failed = true
|
176
|
-
close unless closed?
|
177
|
-
rescue => e
|
178
|
-
Tools.log_exception e
|
98
|
+
rescue nil, Exception => e
|
179
99
|
self.failed = true
|
180
100
|
r = nil
|
181
101
|
close unless closed?
|
102
|
+
raise e
|
182
103
|
end
|
183
104
|
|
184
105
|
=begin
|
@@ -192,6 +113,31 @@ module GamespyQuery
|
|
192
113
|
r
|
193
114
|
end
|
194
115
|
|
116
|
+
# Temp Workaround for IO.select issue on IR
|
117
|
+
def _read_non_block
|
118
|
+
if RUBY_PLATFORM =~ PLATFORM_IR
|
119
|
+
time_end = Time.now + DEFAULT_TIMEOUT
|
120
|
+
success = false
|
121
|
+
until success || Time.now >= time_end
|
122
|
+
begin
|
123
|
+
d = self.recvfrom_nonblock(RECEIVE_SIZE)
|
124
|
+
success = d
|
125
|
+
rescue SocketError
|
126
|
+
|
127
|
+
rescue nil, Exception => e
|
128
|
+
Tools.log_exception(e)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
if success
|
132
|
+
success
|
133
|
+
else
|
134
|
+
raise TimeOutError, "The read operation has timedout"
|
135
|
+
end
|
136
|
+
else
|
137
|
+
self.recvfrom_nonblock(RECEIVE_SIZE)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
195
141
|
# Handle the read state
|
196
142
|
def handle_read
|
197
143
|
# Tools.debug {"Read: #{self.inspect}, #{self.state}"}
|
@@ -200,14 +146,14 @@ module GamespyQuery
|
|
200
146
|
begin
|
201
147
|
case self.state
|
202
148
|
when STATE_SENT_CHALLENGE
|
203
|
-
data =
|
149
|
+
data = _read_non_block
|
204
150
|
Tools.debug {"Read (1): #{self.inspect}: #{data}"}
|
205
151
|
|
206
152
|
handle_challenge data[0]
|
207
153
|
|
208
154
|
self.state = STATE_RECEIVED_CHALLENGE
|
209
155
|
when STATE_SENT_CHALLENGE_RESPONSE, STATE_RECEIVE_DATA
|
210
|
-
data =
|
156
|
+
data = _read_non_block
|
211
157
|
Tools.debug {"Read (3,4): #{self.inspect}: #{data}"}
|
212
158
|
self.state = STATE_RECEIVE_DATA
|
213
159
|
|
@@ -227,16 +173,11 @@ module GamespyQuery
|
|
227
173
|
else
|
228
174
|
raise NotInReadState, "NotInReadState, #{self}"
|
229
175
|
end
|
230
|
-
rescue
|
231
|
-
r = false
|
232
|
-
self.failed = true
|
233
|
-
close unless closed?
|
234
|
-
rescue => e
|
235
|
-
# TODO: Simply raise the exception?
|
236
|
-
Tools.log_exception(e)
|
176
|
+
rescue nil, Exception => e
|
237
177
|
self.failed = true
|
238
178
|
r = nil
|
239
179
|
close unless closed?
|
180
|
+
raise e
|
240
181
|
end
|
241
182
|
r
|
242
183
|
end
|
@@ -290,6 +231,7 @@ module GamespyQuery
|
|
290
231
|
# @param [String] reply Reply from server
|
291
232
|
def sync reply = self.fetch
|
292
233
|
game_data, key = {}, nil
|
234
|
+
Tools.debug {"DATA: #{reply.inspect}"}
|
293
235
|
return game_data if reply.nil? || reply.empty?
|
294
236
|
|
295
237
|
parser = Parser.new(reply)
|
@@ -305,18 +247,19 @@ module GamespyQuery
|
|
305
247
|
|
306
248
|
# Fetch all packets from socket
|
307
249
|
def fetch
|
250
|
+
Tools.debug {"FUCK ME"}
|
308
251
|
pings = []
|
309
252
|
r = self.data
|
310
253
|
begin
|
311
|
-
until valid?
|
254
|
+
until valid? || failed
|
312
255
|
if handle_state
|
313
|
-
if IO.select(nil, [self], nil, DEFAULT_TIMEOUT)
|
256
|
+
if RUBY_PLATFORM =~ PLATFORM_IR || IO.select(nil, [self], nil, DEFAULT_TIMEOUT)
|
314
257
|
handle_write
|
315
258
|
else
|
316
259
|
raise TimeOutError, "TimeOut during write, #{self}"
|
317
260
|
end
|
318
261
|
else
|
319
|
-
if IO.select([self], nil, nil, DEFAULT_TIMEOUT)
|
262
|
+
if RUBY_PLATFORM =~ PLATFORM_IR || IO.select([self], nil, nil, DEFAULT_TIMEOUT)
|
320
263
|
handle_read
|
321
264
|
else
|
322
265
|
raise TimeOutError, "TimeOut during read, #{self}"
|
@@ -341,4 +284,83 @@ module GamespyQuery
|
|
341
284
|
r
|
342
285
|
end
|
343
286
|
end
|
287
|
+
|
288
|
+
# Provides socket functionality on multiple platforms
|
289
|
+
# TODO
|
290
|
+
=begin
|
291
|
+
module MultiSocket
|
292
|
+
# Create socket
|
293
|
+
def create_socket(*params)
|
294
|
+
Tools.debug {"Creating socket #{params}"}
|
295
|
+
_create_socket(*params)
|
296
|
+
end
|
297
|
+
|
298
|
+
# Write socket
|
299
|
+
def socket_send(*params)
|
300
|
+
Tools.debug {"Sending socket #{params}"}
|
301
|
+
_socket_send(*params)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Read socket
|
305
|
+
def socket_receive(*params)
|
306
|
+
Tools.debug {"Receiving socket #{params}"}
|
307
|
+
_socket_receive(*params)
|
308
|
+
end
|
309
|
+
|
310
|
+
# Close socket
|
311
|
+
def socket_close(*params)
|
312
|
+
Tools.debug {"Closing socket #{params}"}
|
313
|
+
@s.close
|
314
|
+
end
|
315
|
+
|
316
|
+
if RUBY_PLATFORM =~ /mswin32/
|
317
|
+
include System::Net
|
318
|
+
include System::Net::Sockets
|
319
|
+
|
320
|
+
# Create socket
|
321
|
+
def _create_socket(host, port)
|
322
|
+
@ip_end_point = IPEndPoint.new(IPAddress.Any, 0)
|
323
|
+
@s = UdpClient.new
|
324
|
+
@s.client.receive_timeout = DEFAULT_TIMEOUT * 1000
|
325
|
+
@s.connect(host, port.to_i)
|
326
|
+
end
|
327
|
+
|
328
|
+
# Write socket
|
329
|
+
def _socket_send(packet)
|
330
|
+
@s.Send(packet, packet.length)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Read socket
|
334
|
+
def _socket_receive
|
335
|
+
@s.Receive(@ip_end_point)
|
336
|
+
end
|
337
|
+
|
338
|
+
else
|
339
|
+
|
340
|
+
# Create socket
|
341
|
+
def _create_socket(host, port)
|
342
|
+
@s = UDPSocket.new
|
343
|
+
@s.connect(host, port)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Write socket
|
347
|
+
def _socket_send(packet)
|
348
|
+
@s.puts(packet)
|
349
|
+
end
|
350
|
+
|
351
|
+
# Read socket
|
352
|
+
def _socket_receive
|
353
|
+
begin
|
354
|
+
Timeout::timeout(DEFAULT_TIMEOUT) do
|
355
|
+
@s.recvfrom(RECEIVE_SIZE)
|
356
|
+
end
|
357
|
+
rescue Timeout::Error
|
358
|
+
raise TimeoutError, "TimeOut on #{self}"
|
359
|
+
ensure
|
360
|
+
@s.close
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
=end
|
344
366
|
end
|
@@ -54,10 +54,10 @@ module GamespyQuery
|
|
54
54
|
Tools.debug {"Sockets: #{queue.size}, AddrsLeft: #{@addrs.size}, ReadReady: #{"#{ready[0].size} / #{read_sockets.size}, WriteReady: #{ready[1].size} / #{write_sockets.size}, ExcReady: #{ready[2].size} / #{queue.size}" unless ready.nil?}"}
|
55
55
|
|
56
56
|
# Read
|
57
|
-
ready[0].each { |s|
|
57
|
+
ready[0].each { |s| begin; s.handle_read(); rescue nil, Exception => e; queue.delete(s); end }
|
58
58
|
|
59
59
|
# Write
|
60
|
-
ready[1].each { |s|
|
60
|
+
ready[1].each { |s| begin; s.handle_write(); rescue nil, Exception => e; queue.delete(s); end }
|
61
61
|
|
62
62
|
# Exceptions
|
63
63
|
#ready[2].each { |s| queue.delete(s) unless s.handle_exc }
|
@@ -104,21 +104,3 @@ module GamespyQuery
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
108
|
-
if $0 == __FILE__
|
109
|
-
require_relative 'master'
|
110
|
-
srv = File.open(ARGV[0] || "servers.txt") { |f| f.read }
|
111
|
-
master = GamespyQuery::Master.new
|
112
|
-
addrs = master.get_server_list srv
|
113
|
-
|
114
|
-
time_start = Time.now
|
115
|
-
sm = GamespyQuery::SocketMaster.new(addrs)
|
116
|
-
sockets = sm.process!
|
117
|
-
time_taken = Time.now - time_start
|
118
|
-
|
119
|
-
cool = sockets.count {|v| v.valid? }
|
120
|
-
dude = sockets.size - cool
|
121
|
-
|
122
|
-
puts "Success: #{cool}, Failed: #{dude}"
|
123
|
-
puts "Took: #{time_taken}s"
|
124
|
-
end
|
data/lib/gamespy_query.rb
CHANGED
@@ -22,19 +22,3 @@ module GamespyQuery
|
|
22
22
|
"GamespyQuery version #{VERSION}"
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
|
-
|
27
|
-
if $0 == __FILE__
|
28
|
-
host, port = if ARGV.size > 1
|
29
|
-
ARGV
|
30
|
-
else
|
31
|
-
ARGV[0].split(":")
|
32
|
-
end
|
33
|
-
time_start = Time.now
|
34
|
-
g = GamespyQuery::Socket.new("#{host}:#{port}")
|
35
|
-
r = g.sync
|
36
|
-
time_taken = Time.now - time_start
|
37
|
-
puts "Took: #{time_taken}s"
|
38
|
-
exit unless r
|
39
|
-
puts r.to_yaml
|
40
|
-
end
|
data/test/units/base_test.rb
CHANGED
@@ -19,8 +19,8 @@ context "Funcs" do
|
|
19
19
|
# TODO: This method doesnt do anything atm
|
20
20
|
asserts("strip_tags") { topic.strip_tags "test" }.equals "test"
|
21
21
|
|
22
|
-
asserts("
|
23
|
-
asserts("
|
22
|
+
asserts("convert integer") { topic.convert_type "1" }.equals 1
|
23
|
+
asserts("convert float") { topic.convert_type "1.5" }.equals 1.5
|
24
24
|
|
25
25
|
asserts("encode_string") { topic.encode_string("test encoding").encoding }.equals Encoding.find("UTF-8")
|
26
26
|
|
data/test/units/parser_test.rb
CHANGED
@@ -16,8 +16,8 @@ context "Parser" do
|
|
16
16
|
setup { topic[:game] }
|
17
17
|
denies("Game data") { topic }.empty
|
18
18
|
|
19
|
-
asserts("gamever") { topic[
|
20
|
-
asserts("sv_battleye") { topic[
|
19
|
+
asserts("gamever") { topic[:gamever] }.equals "1.59.79548"
|
20
|
+
asserts("sv_battleye") { topic[:sv_battleye] }.equals "1"
|
21
21
|
end
|
22
22
|
|
23
23
|
context "Players data" do
|
@@ -32,15 +32,15 @@ context "Parser" do
|
|
32
32
|
context "First element" do
|
33
33
|
asserts("Name") { topic[:names][0] }.equals "Skilllos"
|
34
34
|
asserts("Team") { topic[:teams][0] }.equals ""
|
35
|
-
asserts("Score") { topic[:scores][0] }.equals 371
|
36
|
-
asserts("Deaths") { topic[:deaths][0] }.equals 24
|
35
|
+
asserts("Score") { topic[:scores][0] }.equals "371"
|
36
|
+
asserts("Deaths") { topic[:deaths][0] }.equals "24"
|
37
37
|
end
|
38
38
|
|
39
39
|
context "Tenth element" do
|
40
40
|
asserts("Name") { topic[:names][10] }.equals "DrHat"
|
41
41
|
asserts("Team") { topic[:teams][10] }.equals ""
|
42
|
-
asserts("Score") { topic[:scores][10] }.equals 37
|
43
|
-
asserts("Deaths") { topic[:deaths][10] }.equals 8
|
42
|
+
asserts("Score") { topic[:scores][10] }.equals "37"
|
43
|
+
asserts("Deaths") { topic[:deaths][10] }.equals "8"
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gamespy_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.0pre3
|
5
5
|
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cri
|
16
|
-
requirement: &
|
16
|
+
requirement: &10524320 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *10524320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: riot
|
27
|
-
requirement: &
|
27
|
+
requirement: &10523880 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *10523880
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &10523420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *10523420
|
47
47
|
description: ''
|
48
48
|
email:
|
49
49
|
- sb@dev-heaven.net
|