gamespy_query 0.2.0pre → 0.2.0pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/gamespy_query/base.rb +2 -1
- data/lib/gamespy_query/master.rb +10 -6
- data/lib/gamespy_query/parser.rb +5 -2
- data/lib/gamespy_query/socket.rb +7 -19
- data/lib/gamespy_query/version.rb +1 -1
- data/test/units/socket_test.rb +4 -4
- metadata +8 -8
data/lib/gamespy_query/base.rb
CHANGED
@@ -116,7 +116,8 @@ STR
|
|
116
116
|
# Get UTF-8 string from string
|
117
117
|
# @param [String] str
|
118
118
|
def _encode_string(str)
|
119
|
-
(str + ' ').encode("
|
119
|
+
#(str + ' ').encode("US-ASCII", invalid: :replace, undef: :replace)[0..-3]
|
120
|
+
str.bytes.to_a.pack("U*")
|
120
121
|
end
|
121
122
|
end
|
122
123
|
end
|
data/lib/gamespy_query/master.rb
CHANGED
@@ -87,10 +87,14 @@ module GamespyQuery
|
|
87
87
|
ip, port, content = $1, $2, $3
|
88
88
|
content = content.split(STR_SPLIT)
|
89
89
|
content << "" unless (content.size % 2 == 0)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
i % 2 == 0
|
90
|
+
game_data = {}
|
91
|
+
key = nil
|
92
|
+
content.each_with_index do |data, i|
|
93
|
+
if i % 2 == 0
|
94
|
+
key = data.to_sym
|
95
|
+
else
|
96
|
+
game_data[key] = data.is_a?(String) ? encode_string(data) : data
|
97
|
+
end
|
94
98
|
end
|
95
99
|
addr = "#{ip}:#{port}"
|
96
100
|
if list.has_key?(addr)
|
@@ -103,9 +107,9 @@ module GamespyQuery
|
|
103
107
|
list[addr] = e
|
104
108
|
end
|
105
109
|
if e[:gamedata]
|
106
|
-
e[:gamedata].merge!(
|
110
|
+
e[:gamedata].merge!(game_data)
|
107
111
|
else
|
108
|
-
e[:gamedata] =
|
112
|
+
e[:gamedata] = game_data
|
109
113
|
end
|
110
114
|
end
|
111
115
|
list
|
data/lib/gamespy_query/parser.rb
CHANGED
@@ -17,6 +17,9 @@ module GamespyQuery
|
|
17
17
|
RX_PLAYER_HEADER = /\x01/
|
18
18
|
RX_END = /\x00\x02$/
|
19
19
|
|
20
|
+
class UnsupportedFormat < StandardError
|
21
|
+
end
|
22
|
+
|
20
23
|
# Packets to process
|
21
24
|
attr_reader :packets
|
22
25
|
|
@@ -32,7 +35,7 @@ module GamespyQuery
|
|
32
35
|
when Array
|
33
36
|
packets
|
34
37
|
else
|
35
|
-
raise "Unsupported format"
|
38
|
+
raise UnsupportedFormat, "Unsupported format: #{packets.class}"
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
@@ -100,7 +103,7 @@ module GamespyQuery
|
|
100
103
|
|
101
104
|
packet.split(STR_SPLIT).each_with_index do |data, index|
|
102
105
|
if (index % 2) == 0
|
103
|
-
key =
|
106
|
+
key = data.to_sym
|
104
107
|
else
|
105
108
|
game_data[key] = data.is_a?(String) ? encode_string(data) : data
|
106
109
|
end
|
data/lib/gamespy_query/socket.rb
CHANGED
@@ -74,7 +74,7 @@ module GamespyQuery
|
|
74
74
|
@s.recvfrom(RECEIVE_SIZE)
|
75
75
|
end
|
76
76
|
rescue Timeout::Error
|
77
|
-
raise TimeoutError
|
77
|
+
raise TimeoutError, "TimeOut on #{self}"
|
78
78
|
ensure
|
79
79
|
@s.close
|
80
80
|
end
|
@@ -108,22 +108,10 @@ module GamespyQuery
|
|
108
108
|
# Maximum receive size
|
109
109
|
RECEIVE_SIZE = 1500
|
110
110
|
|
111
|
-
STR_HOSTNAME = "hostname"
|
112
|
-
STR_PLAYERS = "players"
|
113
|
-
STR_DEATHS = "deaths_\x00\x00"
|
114
|
-
STR_PLAYER = "player_\x00\x00"
|
115
|
-
STR_TEAM = "team_\x00\x00"
|
116
|
-
STR_SCORE = "score_\x00\x00"
|
117
|
-
|
118
|
-
SPLIT = STR_X0
|
119
|
-
STR_END = "\x00\x02"
|
120
111
|
STR_EMPTY = Tools::STR_EMPTY
|
121
112
|
STR_BLA = "%c%c%c%c".encode("ASCII-8BIT")
|
122
113
|
STR_GARBAGE = "\x00\x04\x05\x06\a"
|
123
114
|
|
124
|
-
RX_PLAYER_EMPTY = /^player_\x00\x00\x00/
|
125
|
-
RX_PLAYER_INFO = /\x01(team|player|score|deaths)_.(.)/ # \x00 from previous packet, \x01 from continueing player info, (.) - should it overwrite previous value?
|
126
|
-
|
127
115
|
RX_NO_CHALLENGE = /0@0$/
|
128
116
|
RX_CHALLENGE = /0@/
|
129
117
|
RX_CHALLENGE2 = /[^0-9\-]/si
|
@@ -180,7 +168,7 @@ module GamespyQuery
|
|
180
168
|
self.puts self.needs_challenge ? BASE_PACKET + @id_packet + self.needs_challenge + FULL_INFO_PACKET_MP : BASE_PACKET + @id_packet + FULL_INFO_PACKET_MP
|
181
169
|
self.state = STATE_SENT_CHALLENGE_RESPONSE
|
182
170
|
else
|
183
|
-
raise NotInWriteState, "NotInWriteState"
|
171
|
+
raise NotInWriteState, "NotInWriteState, #{self}"
|
184
172
|
end
|
185
173
|
rescue NotInWriteState => e
|
186
174
|
r = false
|
@@ -237,7 +225,7 @@ module GamespyQuery
|
|
237
225
|
close unless closed?
|
238
226
|
end
|
239
227
|
else
|
240
|
-
raise NotInReadState, "NotInReadState"
|
228
|
+
raise NotInReadState, "NotInReadState, #{self}"
|
241
229
|
end
|
242
230
|
rescue NotInReadState => e
|
243
231
|
r = false
|
@@ -308,9 +296,9 @@ module GamespyQuery
|
|
308
296
|
data = parser.parse
|
309
297
|
|
310
298
|
game_data.merge!(data[:game])
|
311
|
-
game_data[
|
299
|
+
game_data[:players] = Parser.pretty_player_data2(data[:players]).sort {|a, b| a[:name].downcase <=> b[:name].downcase }
|
312
300
|
|
313
|
-
game_data[
|
301
|
+
game_data[:ping] = @ping unless @ping.nil?
|
314
302
|
|
315
303
|
game_data
|
316
304
|
end
|
@@ -325,13 +313,13 @@ module GamespyQuery
|
|
325
313
|
if IO.select(nil, [self], nil, DEFAULT_TIMEOUT)
|
326
314
|
handle_write
|
327
315
|
else
|
328
|
-
raise TimeOutError, "TimeOut"
|
316
|
+
raise TimeOutError, "TimeOut during write, #{self}"
|
329
317
|
end
|
330
318
|
else
|
331
319
|
if IO.select([self], nil, nil, DEFAULT_TIMEOUT)
|
332
320
|
handle_read
|
333
321
|
else
|
334
|
-
raise TimeOutError, "TimeOut"
|
322
|
+
raise TimeOutError, "TimeOut during read, #{self}"
|
335
323
|
end
|
336
324
|
end
|
337
325
|
end
|
data/test/units/socket_test.rb
CHANGED
@@ -38,7 +38,7 @@ context "Socket" do
|
|
38
38
|
asserts("Is a hash") { topic }.is_a?(Hash)
|
39
39
|
|
40
40
|
context "Players" do
|
41
|
-
setup { topic[
|
41
|
+
setup { topic[:players] }
|
42
42
|
asserts("Players defined") { topic }.is_a?(Hash)
|
43
43
|
|
44
44
|
context "Player 0" do
|
@@ -60,9 +60,9 @@ context "Socket" do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
63
|
-
asserts("Hostname defined") { topic[
|
64
|
-
asserts("Hostname") { topic[
|
65
|
-
asserts("Modhash") { topic[
|
63
|
+
asserts("Hostname defined") { topic[:hostname] }.is_a?(String)
|
64
|
+
asserts("Hostname") { topic[:hostname] }.equals "-=WASP=- Warfare CO (Prime)"
|
65
|
+
asserts("Modhash") { topic[:modhash] }.equals "PMC v. 1.01;BAF v. 1.02;da39a3ee5e6b4b0d3255bfef95601890afd80709;"
|
66
66
|
end
|
67
67
|
|
68
68
|
# TODO
|
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.0pre2
|
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-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cri
|
16
|
-
requirement: &
|
16
|
+
requirement: &15149120 !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: *15149120
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: riot
|
27
|
-
requirement: &
|
27
|
+
requirement: &15148220 !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: *15148220
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &15147420 !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: *15147420
|
47
47
|
description: ''
|
48
48
|
email:
|
49
49
|
- sb@dev-heaven.net
|