gamespy_query 0.2.0pre2 → 0.2.0pre3
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.
- 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
|