fonte 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/README.md +2 -2
- data/lib/fonte.rb +0 -1
- data/lib/fonte/parsers.rb +1 -1
- data/lib/fonte/parsers/action.treetop +75 -2
- data/lib/fonte/parsers/l4d2_player.treetop +93 -0
- data/lib/fonte/parsers/log.treetop +1 -6
- data/lib/fonte/parsers/number.treetop +15 -1
- data/lib/fonte/parsers/player.treetop +3 -28
- data/lib/fonte/parsers/property.treetop +15 -1
- data/lib/fonte/parsers/rcon.treetop +10 -2
- data/lib/fonte/parsers/source_player.treetop +45 -0
- data/lib/fonte/parsers/steam_id.treetop +1 -1
- data/lib/fonte/version.rb +1 -1
- data/spec/parsers/action_parser_spec.rb +41 -0
- data/spec/parsers/l4d2_player_spec.rb +55 -0
- data/spec/parsers/log_parser_spec.rb +8 -6
- data/spec/parsers/number_parser_spec.rb +17 -0
- data/spec/parsers/player_parser_spec.rb +6 -26
- data/spec/parsers/property_parser_spec.rb +20 -0
- data/spec/parsers/rcon_parser_spec.rb +2 -0
- data/spec/parsers/source_player_parser_spec.rb +47 -0
- data/spec/parsers/steam_id_parser_spec.rb +21 -8
- data/spec/support/shared_examples/real_player.rb +5 -0
- metadata +16 -8
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -34,7 +34,7 @@ log.date_time.day # => 26
|
|
34
34
|
```
|
35
35
|
|
36
36
|
## Games it supports
|
37
|
-
In the current version it can parse all TF2, CSS and DOD files.
|
37
|
+
In the current version it can parse all TF2, L4D, CSS and DOD files.
|
38
38
|
|
39
39
|
## Disclaimer
|
40
|
-
This is a very early approach and can be a considered a proof of concept. Lots of things should (and will) be changed. For instance, I am not quite happy with the forced _".value"_ API, but for now, it was the easiest way to implement.
|
40
|
+
This is a very early approach and can be a considered a proof of concept. Lots of things should (and will) be changed. For instance, I am not quite happy with the forced _".value"_ API, but for now, it was the easiest way to implement.
|
data/lib/fonte.rb
CHANGED
data/lib/fonte/parsers.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Fonte
|
2
2
|
module Parsers
|
3
|
-
%w(number
|
3
|
+
%w(word number temporal address rcon steam_id source_player l4d2_player player property action log).each do |parser|
|
4
4
|
Treetop.load File.join(File.dirname(__FILE__), "parsers", parser)
|
5
5
|
end
|
6
6
|
end
|
@@ -5,6 +5,7 @@ module Fonte
|
|
5
5
|
include Player
|
6
6
|
include Address
|
7
7
|
include Property
|
8
|
+
include Rcon
|
8
9
|
|
9
10
|
rule action
|
10
11
|
log_started_action
|
@@ -39,6 +40,9 @@ module Fonte
|
|
39
40
|
/ score_report
|
40
41
|
/ weapon_selection_action
|
41
42
|
/ weapon_pickup_action
|
43
|
+
/ rcon_command
|
44
|
+
/ steamauth_failure_action
|
45
|
+
/ spawn_action
|
42
46
|
end
|
43
47
|
|
44
48
|
rule log_started_action
|
@@ -74,7 +78,7 @@ module Fonte
|
|
74
78
|
end
|
75
79
|
|
76
80
|
rule cvar_set_action
|
77
|
-
(
|
81
|
+
(cvar_set_complete_syntax / cvar_set_colon_sytax) {
|
78
82
|
def value
|
79
83
|
"cvar set"
|
80
84
|
end
|
@@ -85,6 +89,14 @@ module Fonte
|
|
85
89
|
}
|
86
90
|
end
|
87
91
|
|
92
|
+
rule cvar_set_complete_syntax
|
93
|
+
([Ss] "erver cvar" SPACE)? key:quoted_word SPACE "=" SPACE val:quoted_word
|
94
|
+
end
|
95
|
+
|
96
|
+
rule cvar_set_colon_sytax
|
97
|
+
"server_cvar:" SPACE key:quoted_word SPACE val:quoted_word
|
98
|
+
end
|
99
|
+
|
88
100
|
rule map_loading_action
|
89
101
|
"Loading map" SPACE name:map_name {
|
90
102
|
def value
|
@@ -206,6 +218,10 @@ module Fonte
|
|
206
218
|
end
|
207
219
|
|
208
220
|
rule kill_action
|
221
|
+
source_kill_action / l4d2_kill_action
|
222
|
+
end
|
223
|
+
|
224
|
+
rule source_kill_action
|
209
225
|
QUOTE attacker:player QUOTE SPACE "killed" SPACE QUOTE victim:player QUOTE SPACE "with" SPACE QUOTE weapon QUOTE properties:action_properties? {
|
210
226
|
def value
|
211
227
|
"kill"
|
@@ -213,6 +229,31 @@ module Fonte
|
|
213
229
|
}
|
214
230
|
end
|
215
231
|
|
232
|
+
# TODO: move this to separated grammar
|
233
|
+
rule l4d2_kill_action
|
234
|
+
"(DEATH)" source_kill_action {
|
235
|
+
def value
|
236
|
+
"kill"
|
237
|
+
end
|
238
|
+
|
239
|
+
def attacker
|
240
|
+
source_kill_action.attacker
|
241
|
+
end
|
242
|
+
|
243
|
+
def victim
|
244
|
+
source_kill_action.victim
|
245
|
+
end
|
246
|
+
|
247
|
+
def weapon
|
248
|
+
source_kill_action.weapon
|
249
|
+
end
|
250
|
+
|
251
|
+
def properties
|
252
|
+
source_kill_action.properties
|
253
|
+
end
|
254
|
+
}
|
255
|
+
end
|
256
|
+
|
216
257
|
rule injure_action
|
217
258
|
QUOTE attacker:player QUOTE SPACE "attacked" SPACE QUOTE victim:player QUOTE SPACE "with" SPACE QUOTE weapon QUOTE properties:action_properties? {
|
218
259
|
def value
|
@@ -246,13 +287,21 @@ module Fonte
|
|
246
287
|
end
|
247
288
|
|
248
289
|
rule triggered_world_action
|
249
|
-
"World triggered" SPACE action:quoted_word properties:action_properties? {
|
290
|
+
"World triggered" SPACE action:quoted_word reason:triggered_world_action_reason? properties:action_properties? {
|
250
291
|
def value
|
251
292
|
action.value
|
252
293
|
end
|
253
294
|
}
|
254
295
|
end
|
255
296
|
|
297
|
+
rule triggered_world_action_reason
|
298
|
+
SPACE "reason" SPACE reason:quoted_word {
|
299
|
+
def value
|
300
|
+
reason.value
|
301
|
+
end
|
302
|
+
}
|
303
|
+
end
|
304
|
+
|
256
305
|
rule chat_action
|
257
306
|
QUOTE player QUOTE SPACE "say" SPACE message:quoted_word {
|
258
307
|
def value
|
@@ -322,6 +371,30 @@ module Fonte
|
|
322
371
|
}
|
323
372
|
end
|
324
373
|
|
374
|
+
rule steamauth_failure_action
|
375
|
+
"STEAMAUTH: Client" SPACE client:steamauth_client SPACE "received failure code" SPACE code:integer {
|
376
|
+
def value
|
377
|
+
"authentication failure"
|
378
|
+
end
|
379
|
+
}
|
380
|
+
end
|
381
|
+
|
382
|
+
rule spawn_action
|
383
|
+
QUOTE player QUOTE SPACE "spawned" {
|
384
|
+
def value
|
385
|
+
"spawn"
|
386
|
+
end
|
387
|
+
}
|
388
|
+
end
|
389
|
+
|
390
|
+
rule steamauth_client
|
391
|
+
(!SPACE .)+ {
|
392
|
+
def value
|
393
|
+
text_value
|
394
|
+
end
|
395
|
+
}
|
396
|
+
end
|
397
|
+
|
325
398
|
rule role
|
326
399
|
word
|
327
400
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Fonte
|
2
|
+
module Parsers
|
3
|
+
grammar L4D2Player
|
4
|
+
include Word
|
5
|
+
include Number
|
6
|
+
include SourcePlayer
|
7
|
+
|
8
|
+
rule l4d2_player
|
9
|
+
source_player "<" character:l4d2_character ">" "<" status:l4d2_player_status ">" "<" l4d2_life ">" "<" l4d2_position ">" "<" area:l4d2_area ">" {
|
10
|
+
def nickname
|
11
|
+
source_player.nickname
|
12
|
+
end
|
13
|
+
|
14
|
+
def uid
|
15
|
+
source_player.uid
|
16
|
+
end
|
17
|
+
|
18
|
+
def steam_id
|
19
|
+
source_player.steam_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def team
|
23
|
+
source_player.team
|
24
|
+
end
|
25
|
+
|
26
|
+
def life
|
27
|
+
l4d2_life.value[:life]
|
28
|
+
end
|
29
|
+
|
30
|
+
def blood
|
31
|
+
l4d2_life.value[:blood]
|
32
|
+
end
|
33
|
+
|
34
|
+
def position
|
35
|
+
l4d2_position.position
|
36
|
+
end
|
37
|
+
|
38
|
+
def angle
|
39
|
+
l4d2_position.angle
|
40
|
+
end
|
41
|
+
|
42
|
+
def value
|
43
|
+
source_player.value
|
44
|
+
end
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
rule l4d2_character
|
49
|
+
(![<>] character)* {
|
50
|
+
def value
|
51
|
+
text_value
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
rule l4d2_player_status
|
57
|
+
(![<>] character)* {
|
58
|
+
def value
|
59
|
+
text_value
|
60
|
+
end
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
rule l4d2_life
|
65
|
+
l4d2_life_blood / "0" {
|
66
|
+
def value
|
67
|
+
{ :life => 0, :blood => 0 }
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
rule l4d2_life_blood
|
73
|
+
life:integer "+" blood:integer {
|
74
|
+
def value
|
75
|
+
{ :life => life.value, :blood => blood.value }
|
76
|
+
end
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
rule l4d2_position
|
81
|
+
"setpos_exact" SPACE position:coordinates ";" SPACE "setang" SPACE angle:coordinates
|
82
|
+
end
|
83
|
+
|
84
|
+
rule l4d2_area
|
85
|
+
"Area" SPACE integer {
|
86
|
+
def value
|
87
|
+
integer.value
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -3,15 +3,10 @@ module Fonte
|
|
3
3
|
grammar Log
|
4
4
|
include Word
|
5
5
|
include Temporal
|
6
|
-
include Rcon
|
7
6
|
include Action
|
8
7
|
|
9
8
|
rule entry
|
10
|
-
"L" SPACE date_time ":" SPACE command "\n"?
|
11
|
-
end
|
12
|
-
|
13
|
-
rule command
|
14
|
-
action / rcon_command
|
9
|
+
(!"L" .)* "L" SPACE date_time ":" SPACE command:action "\n"?
|
15
10
|
end
|
16
11
|
end
|
17
12
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module Fonte
|
2
2
|
module Parsers
|
3
3
|
grammar Number
|
4
|
+
include Word
|
5
|
+
|
4
6
|
rule number
|
5
|
-
float / integer
|
7
|
+
coordinates / float / integer
|
6
8
|
end
|
7
9
|
|
8
10
|
rule float
|
@@ -35,6 +37,18 @@ module Fonte
|
|
35
37
|
end
|
36
38
|
}
|
37
39
|
end
|
40
|
+
|
41
|
+
rule coordinates
|
42
|
+
x:coordinate SPACE y:coordinate SPACE z:coordinate {
|
43
|
+
def value
|
44
|
+
[x.value, y.value, z.value]
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
rule coordinate
|
50
|
+
float / integer
|
51
|
+
end
|
38
52
|
end
|
39
53
|
end
|
40
54
|
end
|
@@ -1,36 +1,11 @@
|
|
1
1
|
module Fonte
|
2
2
|
module Parsers
|
3
3
|
grammar Player
|
4
|
-
include
|
5
|
-
include
|
6
|
-
include SteamID
|
4
|
+
include SourcePlayer
|
5
|
+
include L4D2Player
|
7
6
|
|
8
7
|
rule player
|
9
|
-
|
10
|
-
def value
|
11
|
-
text_value
|
12
|
-
end
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
rule nickname
|
17
|
-
(![<>] .)* {
|
18
|
-
def value
|
19
|
-
text_value
|
20
|
-
end
|
21
|
-
}
|
22
|
-
end
|
23
|
-
|
24
|
-
rule uid
|
25
|
-
integer
|
26
|
-
end
|
27
|
-
|
28
|
-
rule team
|
29
|
-
(![<>] character)* {
|
30
|
-
def value
|
31
|
-
text_value == "Unassigned" || text_value == "Console" || text_value == "" ? nil : text_value
|
32
|
-
end
|
33
|
-
}
|
8
|
+
l4d2_player / source_player
|
34
9
|
end
|
35
10
|
end
|
36
11
|
end
|
@@ -2,6 +2,8 @@ module Fonte
|
|
2
2
|
module Parsers
|
3
3
|
grammar Property
|
4
4
|
include Word
|
5
|
+
include Number
|
6
|
+
include Player
|
5
7
|
|
6
8
|
rule properties
|
7
9
|
property+ {
|
@@ -40,7 +42,19 @@ module Fonte
|
|
40
42
|
end
|
41
43
|
|
42
44
|
rule property_value
|
43
|
-
quoted_word
|
45
|
+
number_property / player_property / quoted_word
|
46
|
+
end
|
47
|
+
|
48
|
+
rule player_property
|
49
|
+
QUOTE value:player QUOTE
|
50
|
+
end
|
51
|
+
|
52
|
+
rule number_property
|
53
|
+
QUOTE number QUOTE {
|
54
|
+
def value
|
55
|
+
number.value
|
56
|
+
end
|
57
|
+
}
|
44
58
|
end
|
45
59
|
end
|
46
60
|
end
|
@@ -9,11 +9,19 @@ module Fonte
|
|
9
9
|
end
|
10
10
|
|
11
11
|
rule rcon_success
|
12
|
-
"Rcon:" SPACE rcon_challenge <Fonte::Nodes::RconCommandNode>
|
12
|
+
"Rcon:" SPACE rcon_challenge <Fonte::Nodes::RconCommandNode> {
|
13
|
+
def value
|
14
|
+
"successfully rcon"
|
15
|
+
end
|
16
|
+
}
|
13
17
|
end
|
14
18
|
|
15
19
|
rule rcon_failure
|
16
|
-
"Bad Rcon:" SPACE rcon_challenge <Fonte::Nodes::RconCommandNode>
|
20
|
+
"Bad Rcon:" SPACE rcon_challenge <Fonte::Nodes::RconCommandNode> {
|
21
|
+
def value
|
22
|
+
"bad rcon"
|
23
|
+
end
|
24
|
+
}
|
17
25
|
end
|
18
26
|
|
19
27
|
rule rcon_challenge
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Fonte
|
2
|
+
module Parsers
|
3
|
+
grammar SourcePlayer
|
4
|
+
include Number
|
5
|
+
include Word
|
6
|
+
include SteamID
|
7
|
+
|
8
|
+
rule source_player
|
9
|
+
nickname "<" uid ">" "<" steam_id:player_steam_id ">" "<" team ">" {
|
10
|
+
def value
|
11
|
+
text_value
|
12
|
+
end
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
rule nickname
|
17
|
+
(![<>] character)* {
|
18
|
+
def value
|
19
|
+
text_value
|
20
|
+
end
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
rule uid
|
25
|
+
integer
|
26
|
+
end
|
27
|
+
|
28
|
+
rule player_steam_id
|
29
|
+
steam_id / "" {
|
30
|
+
def value
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
rule team
|
37
|
+
(![<>] character)* {
|
38
|
+
def value
|
39
|
+
text_value == "Unassigned" || text_value == "Console" || text_value == "" ? nil : text_value
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/fonte/version.rb
CHANGED
@@ -60,6 +60,12 @@ module Fonte
|
|
60
60
|
its(:value) { should == "cvar set" }
|
61
61
|
its(:"to_hash") { should == { "key" => "value"} }
|
62
62
|
end
|
63
|
+
|
64
|
+
context "when it starts with server_cvar" do
|
65
|
+
let(:action) { 'server_cvar: "key" "value"' }
|
66
|
+
its(:value) { should == "cvar set" }
|
67
|
+
its(:"to_hash") { should == { "key" => "value"} }
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
describe "sever name" do
|
@@ -175,6 +181,18 @@ module Fonte
|
|
175
181
|
let(:action) { '"Reu<2><STEAM_1:1:24968171><Blue>" killed "guimello<13><STEAM_1:1:34492580><Red>" with "minigun" (attacker_position "3354 -2485 -187") (victim_position "3410 -2518 -149")' }
|
176
182
|
it_should_behave_like "a action with properties", "attacker_position", "victim_position"
|
177
183
|
end
|
184
|
+
|
185
|
+
context "l4d2 format" do
|
186
|
+
let(:action) { '(DEATH)"Reu<2><STEAM_1:1:24968171><Survivor><Gambler><ALIVE><80+0><setpos_exact 4793.19 -3962.89 165.33; setang 18.14 -34.47 0.00><Area 70>" killed "infected<552><><Infected><infected><DEAD><0><setpos_exact 4831.17 -3989.32 104.81; setang 0.00 288.65 0.00><Area 792>" with "melee"' }
|
187
|
+
its(:value) { should == "kill" }
|
188
|
+
its(:"attacker.value") { should == "Reu<2><STEAM_1:1:24968171><Survivor>" }
|
189
|
+
its(:"victim.value") { should == "infected<552><><Infected>" }
|
190
|
+
|
191
|
+
context "with properties" do
|
192
|
+
let(:action) { '(DEATH)"Reu<2><STEAM_1:1:24968171><Survivor><Gambler><ALIVE><80+0><setpos_exact 4793.19 -3962.89 165.33; setang 18.14 -34.47 0.00><Area 70>" killed "infected<552><><Infected><infected><DEAD><0><setpos_exact 4831.17 -3989.32 104.81; setang 0.00 288.65 0.00><Area 792>" with "melee" (headshot)' }
|
193
|
+
it_should_behave_like "a action with properties", "headshot"
|
194
|
+
end
|
195
|
+
end
|
178
196
|
end
|
179
197
|
|
180
198
|
describe "injure" do
|
@@ -249,6 +267,11 @@ module Fonte
|
|
249
267
|
let(:action) { 'World triggered "Mini_Round_Selected" (round "Round_A")' }
|
250
268
|
it_should_behave_like "a action with properties", "round"
|
251
269
|
end
|
270
|
+
|
271
|
+
context "with reason" do
|
272
|
+
let(:action) { 'World triggered "Game_Over" reason "Reached Time Limit"' }
|
273
|
+
its(:value) { should == "Game_Over" }
|
274
|
+
end
|
252
275
|
end
|
253
276
|
|
254
277
|
describe "chat" do
|
@@ -317,6 +340,24 @@ module Fonte
|
|
317
340
|
its(:"player.value") { should == "Reu<2><STEAM_1:1:24968171><Blue>" }
|
318
341
|
its(:"weapon.value") { should == "Shotgun" }
|
319
342
|
end
|
343
|
+
|
344
|
+
describe "rcon command" do
|
345
|
+
let(:action) { 'Rcon: "rcon challenge "password" command" from "192.168.10.1:17015"' }
|
346
|
+
it_should_behave_like "a rcon command", :password => "password", :origin => "//192.168.10.1:17015"
|
347
|
+
end
|
348
|
+
|
349
|
+
describe "steamauth" do
|
350
|
+
let(:action) { 'STEAMAUTH: Client reu received failure code 6' }
|
351
|
+
its(:value) { should == "authentication failure" }
|
352
|
+
its(:"client.value") { should == "reu" }
|
353
|
+
its(:"code.value") { should == 6 }
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "spawn" do
|
357
|
+
let(:action) { '"Pulo_ms<8><STEAM_1:1:41920953><Survivor><Producer><ALIVE><100+0><setpos_exact 3617.36 -1739.69 294.53; setang 0.00 179.84 0.00><Area 205>" spawned' }
|
358
|
+
its(:value) { should == "spawn" }
|
359
|
+
its(:"player.value") { should == "Pulo_ms<8><STEAM_1:1:41920953><Survivor>" }
|
360
|
+
end
|
320
361
|
end
|
321
362
|
end
|
322
363
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fonte
|
4
|
+
module Parsers
|
5
|
+
describe L4D2PlayerParser do
|
6
|
+
subject { parser.parse(player) }
|
7
|
+
let(:parser) { described_class.new }
|
8
|
+
|
9
|
+
context "of a real player" do
|
10
|
+
let(:player) { "Pulo_ms<8><STEAM_1:1:41920953><Survivor><Producer><ALIVE><100+0><setpos_exact 3617.36 -1739.69 294.53; setang 0.00 179.84 0.00><Area 205>" }
|
11
|
+
|
12
|
+
it_should_behave_like "a real player"
|
13
|
+
|
14
|
+
its(:value) { should == "Pulo_ms<8><STEAM_1:1:41920953><Survivor>" }
|
15
|
+
|
16
|
+
its(:"nickname.value") { should == "Pulo_ms" }
|
17
|
+
its(:"uid.value") { should == 8 }
|
18
|
+
its(:"steam_id.value") { should == "STEAM_1:1:41920953" }
|
19
|
+
its(:"team.value") { should == "Survivor" }
|
20
|
+
its(:"character.value") { should == "Producer" }
|
21
|
+
its(:"status.value") { should == "ALIVE" }
|
22
|
+
its(:life) { should == 100 }
|
23
|
+
its(:blood) { should == 0 }
|
24
|
+
its(:"position.value") { should == [3617.36, -1739.69, 294.53] }
|
25
|
+
its(:"angle.value") { should == [0.00, 179.84, 0.00] }
|
26
|
+
its(:"area.value") { should == 205 }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "of a infected" do
|
30
|
+
let(:player) { "infected<552><><Infected><infected><DEAD><100+50><setpos_exact 4831.17 -3989.32 104.81; setang 0.00 288.65 0.00><Area 792>" }
|
31
|
+
|
32
|
+
its(:value) { should == "infected<552><><Infected>" }
|
33
|
+
|
34
|
+
its(:"nickname.value") { should == "infected" }
|
35
|
+
its(:"uid.value") { should == 552 }
|
36
|
+
its(:"steam_id.value") { should be_nil }
|
37
|
+
its(:"team.value") { should == "Infected" }
|
38
|
+
its(:"character.value") { should == "infected" }
|
39
|
+
its(:"status.value") { should == "DEAD" }
|
40
|
+
its(:life) { should == 100 }
|
41
|
+
its(:blood) { should == 50 }
|
42
|
+
its(:"position.value") { should == [4831.17, -3989.32, 104.81] }
|
43
|
+
its(:"angle.value") { should == [0.00, 288.65, 0.00] }
|
44
|
+
its(:"area.value") { should == 792 }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with zero life" do
|
48
|
+
let(:player) { "infected<552><><Infected><infected><DEAD><0><setpos_exact 4831.17 -3989.32 104.81; setang 0.00 288.65 0.00><Area 792>" }
|
49
|
+
|
50
|
+
its(:life) { should == 0 }
|
51
|
+
its(:blood) { should == 0 }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -20,13 +20,15 @@ module Fonte
|
|
20
20
|
subject { parser.parse(text).command }
|
21
21
|
it { should be }
|
22
22
|
end
|
23
|
-
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
context "when there are garbage before the log line" do
|
25
|
+
let(:text) { '????RL 12/26/2011 - 02:14:29: Loading map "c4m2_sugarmill_a"' }
|
26
|
+
it { should be }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when there is a line break after the log line" do
|
30
|
+
let(:text) { "L 12/26/2011 - 02:14:29: server cvars start\n" }
|
31
|
+
it { should be }
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -75,6 +75,23 @@ module Fonte
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
describe "coordinates" do
|
80
|
+
context "only integers" do
|
81
|
+
let(:number) { "10 10 20" }
|
82
|
+
it { should == [10, 10, 20] }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "only floats" do
|
86
|
+
let(:number) { "3617.36 -1739.69 294.53" }
|
87
|
+
it { should == [3617.36, -1739.69, 294.53] }
|
88
|
+
end
|
89
|
+
|
90
|
+
context "mixing integers and floats" do
|
91
|
+
let(:number) { "3617.36 -1739 294.53" }
|
92
|
+
it { should == [3617.36, -1739, 294.53] }
|
93
|
+
end
|
94
|
+
end
|
78
95
|
end
|
79
96
|
end
|
80
97
|
end
|
@@ -4,36 +4,16 @@ module Fonte
|
|
4
4
|
module Parsers
|
5
5
|
describe PlayerParser do
|
6
6
|
let(:parser) { described_class.new }
|
7
|
-
let(:player) { "Reu<2><STEAM_1:1:24968171><Red>" }
|
8
|
-
|
9
7
|
subject { parser.parse(player) }
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
its(:"uid.value") { should == 2 }
|
15
|
-
its(:"steam_id.value") { should == "STEAM_1:1:24968171" }
|
16
|
-
its(:"team.value") { should == "Red" }
|
17
|
-
|
18
|
-
context "when the player is a bot" do
|
19
|
-
let(:player) { "Nick<42><Bot><Red>" }
|
20
|
-
its(:"steam_id.value") { should be_nil }
|
21
|
-
end
|
22
|
-
|
23
|
-
context "when the player is the console" do
|
24
|
-
let(:player) { "Console<0><Console><Console>" }
|
25
|
-
its(:"steam_id.value") { should be_nil }
|
26
|
-
its(:"team.value") { should be_nil }
|
27
|
-
end
|
28
|
-
|
29
|
-
context "when the team is not present" do
|
30
|
-
let(:player) { "Reu<2><STEAM_1:1:24968171><>" }
|
31
|
-
its(:"team.value") { should be_nil }
|
9
|
+
context "when the player is a default source player" do
|
10
|
+
let(:player) { "Reu<2><STEAM_1:1:24968171><Red>" }
|
11
|
+
it { should be }
|
32
12
|
end
|
33
13
|
|
34
|
-
context "when the
|
35
|
-
let(:player) { "
|
36
|
-
|
14
|
+
context "when the player is a left4dead2 player" do
|
15
|
+
let(:player) { "Pulo_ms<8><STEAM_1:1:41920953><Survivor><Producer><ALIVE><100+0><setpos_exact 3617.36 -1739.69 294.53; setang 0.00 179.84 0.00><Area 205>" }
|
16
|
+
it { should be }
|
37
17
|
end
|
38
18
|
end
|
39
19
|
end
|
@@ -24,6 +24,26 @@ module Fonte
|
|
24
24
|
it { should be }
|
25
25
|
its(:value) { should == { "headshot" => true } }
|
26
26
|
end
|
27
|
+
|
28
|
+
context "player property" do
|
29
|
+
let(:properties) { '(player "Reu<2><STEAM_1:1:24968171><Red>")' }
|
30
|
+
it { should be }
|
31
|
+
|
32
|
+
describe "player" do
|
33
|
+
subject { parser.parse(properties).value["player"] }
|
34
|
+
it_should_behave_like "a real player"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "number property" do
|
39
|
+
let(:properties) { '(area "10")' }
|
40
|
+
its(:value) { should == { "area" => 10 } }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "coordinate property" do
|
44
|
+
let(:properties) { '(attacker_position "-1624 1258 617")' }
|
45
|
+
its(:value) { should == { "attacker_position" => [-1624, 1258, 617] } }
|
46
|
+
end
|
27
47
|
end
|
28
48
|
end
|
29
49
|
end
|
@@ -10,11 +10,13 @@ module Fonte
|
|
10
10
|
context "with a successfully rcon challenge" do
|
11
11
|
let(:rcon_command) { 'Rcon: "rcon challenge "password" command" from "192.168.10.1:17015"' }
|
12
12
|
it_should_behave_like "a rcon command", :password => "password", :origin => "//192.168.10.1:17015"
|
13
|
+
its(:value) { should == "successfully rcon" }
|
13
14
|
end
|
14
15
|
|
15
16
|
context "with a bad rcon challenge" do
|
16
17
|
let(:rcon_command) { 'Bad Rcon: "rcon challenge "password" command" from "192.168.10.1:17015"' }
|
17
18
|
it_should_behave_like "a rcon command", :password => "password", :origin => "//192.168.10.1:17015"
|
19
|
+
its(:value) { should == "bad rcon" }
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fonte
|
4
|
+
module Parsers
|
5
|
+
describe SourcePlayerParser do
|
6
|
+
let(:parser) { described_class.new }
|
7
|
+
let(:player) { "Reu<2><STEAM_1:1:24968171><Red>" }
|
8
|
+
|
9
|
+
subject { parser.parse(player) }
|
10
|
+
|
11
|
+
its(:value) { should == "Reu<2><STEAM_1:1:24968171><Red>" }
|
12
|
+
|
13
|
+
its(:"nickname.value") { should == "Reu" }
|
14
|
+
its(:"uid.value") { should == 2 }
|
15
|
+
its(:"steam_id.value") { should == "STEAM_1:1:24968171" }
|
16
|
+
its(:"team.value") { should == "Red" }
|
17
|
+
|
18
|
+
it_should_behave_like "a real player"
|
19
|
+
|
20
|
+
context "when the player is a bot" do
|
21
|
+
let(:player) { "Nick<42><Bot><Red>" }
|
22
|
+
its(:"steam_id.value") { should be_nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when the steam id is blank" do
|
26
|
+
let(:player) { "Reu<2><><Unassigned>" }
|
27
|
+
its(:"steam_id.value") { should be_nil }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when the player is the console" do
|
31
|
+
let(:player) { "Console<0><Console><Console>" }
|
32
|
+
its(:"steam_id.value") { should be_nil }
|
33
|
+
its(:"team.value") { should be_nil }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the team is not present" do
|
37
|
+
let(:player) { "Reu<2><STEAM_1:1:24968171><>" }
|
38
|
+
its(:"team.value") { should be_nil }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when the team is unissiged" do
|
42
|
+
let(:player) { "Reu<2><STEAM_1:1:24968171><Unassigned>" }
|
43
|
+
its(:"team.value") { should be_nil }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -33,14 +33,27 @@ module Fonte
|
|
33
33
|
end
|
34
34
|
|
35
35
|
context "of a bot" do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
context "labeled as Bot" do
|
37
|
+
let(:steam_id) { "Bot" }
|
38
|
+
its(:value) { should_not be }
|
39
|
+
|
40
|
+
it { should_not be_real_player }
|
41
|
+
it { should_not be_unknown }
|
42
|
+
it { should be_bot }
|
43
|
+
it { should_not be_pending }
|
44
|
+
it { should_not be_console }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "labeled as BOT" do
|
48
|
+
let(:steam_id) { "BOT" }
|
49
|
+
its(:value) { should_not be }
|
50
|
+
|
51
|
+
it { should_not be_real_player }
|
52
|
+
it { should_not be_unknown }
|
53
|
+
it { should be_bot }
|
54
|
+
it { should_not be_pending }
|
55
|
+
it { should_not be_console }
|
56
|
+
end
|
44
57
|
end
|
45
58
|
|
46
59
|
context "of a invalid user" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fonte
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
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-
|
12
|
+
date: 2012-02-04 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2151838740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.8.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2151838740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: treetop
|
27
|
-
requirement: &
|
27
|
+
requirement: &2151837600 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.4.8
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2151837600
|
36
36
|
description:
|
37
37
|
email:
|
38
38
|
- rnavarro1@gmail.com
|
@@ -58,28 +58,33 @@ files:
|
|
58
58
|
- lib/fonte/parsers.rb
|
59
59
|
- lib/fonte/parsers/action.treetop
|
60
60
|
- lib/fonte/parsers/address.treetop
|
61
|
+
- lib/fonte/parsers/l4d2_player.treetop
|
61
62
|
- lib/fonte/parsers/log.treetop
|
62
63
|
- lib/fonte/parsers/number.treetop
|
63
64
|
- lib/fonte/parsers/player.treetop
|
64
65
|
- lib/fonte/parsers/property.treetop
|
65
66
|
- lib/fonte/parsers/rcon.treetop
|
67
|
+
- lib/fonte/parsers/source_player.treetop
|
66
68
|
- lib/fonte/parsers/steam_id.treetop
|
67
69
|
- lib/fonte/parsers/temporal.treetop
|
68
70
|
- lib/fonte/parsers/word.treetop
|
69
71
|
- lib/fonte/version.rb
|
70
72
|
- spec/parsers/action_parser_spec.rb
|
71
73
|
- spec/parsers/address_parser_spec.rb
|
74
|
+
- spec/parsers/l4d2_player_spec.rb
|
72
75
|
- spec/parsers/log_parser_spec.rb
|
73
76
|
- spec/parsers/number_parser_spec.rb
|
74
77
|
- spec/parsers/player_parser_spec.rb
|
75
78
|
- spec/parsers/property_parser_spec.rb
|
76
79
|
- spec/parsers/rcon_parser_spec.rb
|
80
|
+
- spec/parsers/source_player_parser_spec.rb
|
77
81
|
- spec/parsers/steam_id_parser_spec.rb
|
78
82
|
- spec/parsers/temporal_parser_spec.rb
|
79
83
|
- spec/parsers/word_parser_spec.rb
|
80
84
|
- spec/spec_helper.rb
|
81
85
|
- spec/support/shared_examples/properties.rb
|
82
86
|
- spec/support/shared_examples/rcon_command.rb
|
87
|
+
- spec/support/shared_examples/real_player.rb
|
83
88
|
homepage: https://github.com/reu/fonte
|
84
89
|
licenses: []
|
85
90
|
post_install_message:
|
@@ -94,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
99
|
version: '0'
|
95
100
|
segments:
|
96
101
|
- 0
|
97
|
-
hash:
|
102
|
+
hash: -228607665135122413
|
98
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
104
|
none: false
|
100
105
|
requirements:
|
@@ -103,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
108
|
version: '0'
|
104
109
|
segments:
|
105
110
|
- 0
|
106
|
-
hash:
|
111
|
+
hash: -228607665135122413
|
107
112
|
requirements: []
|
108
113
|
rubyforge_project: fonte
|
109
114
|
rubygems_version: 1.8.10
|
@@ -113,14 +118,17 @@ summary: Valve Source Engine log parser
|
|
113
118
|
test_files:
|
114
119
|
- spec/parsers/action_parser_spec.rb
|
115
120
|
- spec/parsers/address_parser_spec.rb
|
121
|
+
- spec/parsers/l4d2_player_spec.rb
|
116
122
|
- spec/parsers/log_parser_spec.rb
|
117
123
|
- spec/parsers/number_parser_spec.rb
|
118
124
|
- spec/parsers/player_parser_spec.rb
|
119
125
|
- spec/parsers/property_parser_spec.rb
|
120
126
|
- spec/parsers/rcon_parser_spec.rb
|
127
|
+
- spec/parsers/source_player_parser_spec.rb
|
121
128
|
- spec/parsers/steam_id_parser_spec.rb
|
122
129
|
- spec/parsers/temporal_parser_spec.rb
|
123
130
|
- spec/parsers/word_parser_spec.rb
|
124
131
|
- spec/spec_helper.rb
|
125
132
|
- spec/support/shared_examples/properties.rb
|
126
133
|
- spec/support/shared_examples/rcon_command.rb
|
134
|
+
- spec/support/shared_examples/real_player.rb
|