fonte 0.1.0 → 0.2.0
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/.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
|