fonte 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,10 @@
1
1
  language: ruby
2
2
  script: bundle exec rspec -bfd spec
3
3
  rvm:
4
+ - 1.8.7
4
5
  - 1.9.2
5
6
  - 1.9.3
6
7
  - jruby
8
+ - ree
9
+ - rbx-18mode
10
+ - rbx-19mode
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. Left4Dead is not supported yet due LOTS of "custom" events.
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. Also, it doesn't support real games log yet, so, there should be a way to easily "plug" specific game "log commands".
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.
@@ -1,6 +1,5 @@
1
1
  require "fonte/version"
2
2
  require "treetop"
3
- require "polyglot"
4
3
  require "fonte/nodes"
5
4
  require "fonte/parsers"
6
5
 
@@ -1,6 +1,6 @@
1
1
  module Fonte
2
2
  module Parsers
3
- %w(number word temporal address rcon steam_id property player action log).each do |parser|
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
- ([Ss] "erver cvar" SPACE)? key:quoted_word SPACE "=" SPACE val:quoted_word {
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 Number
5
- include Word
6
- include SteamID
4
+ include SourcePlayer
5
+ include L4D2Player
7
6
 
8
7
  rule player
9
- nickname "<" uid ">" "<" steam_id ">" "<" team ">" {
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
@@ -24,7 +24,7 @@ module Fonte
24
24
  end
25
25
 
26
26
  rule steam_id_bot
27
- "Bot" <Fonte::Nodes::SteamIDNode> {
27
+ "B" ("ot" / "OT") <Fonte::Nodes::SteamIDNode> {
28
28
  def bot?
29
29
  true
30
30
  end
@@ -1,3 +1,3 @@
1
1
  module Fonte
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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
- describe "commands" do
26
- describe "rcon command" do
27
- let(:text) { 'L 12/26/2011 - 02:14:33: Rcon: "rcon challenge "password" command" from "192.168.10.1:17015"' }
28
- subject { parser.parse(text).command }
29
- it_should_behave_like "a rcon command", :password => "password", :origin => "//192.168.10.1:17015"
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
- 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
- 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 team is unissiged" do
35
- let(:player) { "Reu<2><STEAM_1:1:24968171><Unassigned>" }
36
- its(:"team.value") { should be_nil }
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
- let(:steam_id) { "Bot" }
37
- its(:value) { should_not be }
38
-
39
- it { should_not be_real_player }
40
- it { should_not be_unknown }
41
- it { should be_bot }
42
- it { should_not be_pending }
43
- it { should_not be_console }
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
@@ -0,0 +1,5 @@
1
+ shared_examples "a real player" do
2
+ its(:"nickname.value") { should be }
3
+ its(:"uid.value") { should be }
4
+ its(:"steam_id.value") { should be }
5
+ end
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.1.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-01-16 00:00:00.000000000Z
12
+ date: 2012-02-04 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2151839440 !ruby/object:Gem::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: *2151839440
24
+ version_requirements: *2151838740
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: treetop
27
- requirement: &2151837980 !ruby/object:Gem::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: *2151837980
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: 3614551501371426417
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: 3614551501371426417
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