tf2_line_parser 0.0.1
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/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +43 -0
- data/README.md +15 -0
- data/lib/tf2_line_parser/events/assist.rb +13 -0
- data/lib/tf2_line_parser/events/capture_block.rb +26 -0
- data/lib/tf2_line_parser/events/charge_deployed.rb +23 -0
- data/lib/tf2_line_parser/events/chat.rb +38 -0
- data/lib/tf2_line_parser/events/console_say.rb +24 -0
- data/lib/tf2_line_parser/events/current_score.rb +13 -0
- data/lib/tf2_line_parser/events/damage.rb +24 -0
- data/lib/tf2_line_parser/events/domination.rb +12 -0
- data/lib/tf2_line_parser/events/event.rb +70 -0
- data/lib/tf2_line_parser/events/final_score.rb +13 -0
- data/lib/tf2_line_parser/events/heal.rb +25 -0
- data/lib/tf2_line_parser/events/kill.rb +13 -0
- data/lib/tf2_line_parser/events/match_end.rb +24 -0
- data/lib/tf2_line_parser/events/medic_death.rb +12 -0
- data/lib/tf2_line_parser/events/pickup_item.rb +28 -0
- data/lib/tf2_line_parser/events/point_capture.rb +26 -0
- data/lib/tf2_line_parser/events/revenge.rb +12 -0
- data/lib/tf2_line_parser/events/role_change.rb +28 -0
- data/lib/tf2_line_parser/events/round_length.rb +24 -0
- data/lib/tf2_line_parser/events/round_stalemate.rb +23 -0
- data/lib/tf2_line_parser/events/round_start.rb +23 -0
- data/lib/tf2_line_parser/events/round_win.rb +23 -0
- data/lib/tf2_line_parser/events/score.rb +29 -0
- data/lib/tf2_line_parser/events/suicide.rb +28 -0
- data/lib/tf2_line_parser/events/unknown.rb +28 -0
- data/lib/tf2_line_parser/line.rb +25 -0
- data/lib/tf2_line_parser/parser.rb +15 -0
- data/lib/tf2_line_parser/player.rb +19 -0
- data/lib/tf2_line_parser/version.rb +3 -0
- data/lib/tf2_line_parser.rb +13 -0
- data/script/bundler +10 -0
- data/script/ci +22 -0
- data/spec/fixtures/logs/broder_vs_epsilon.log +4539 -0
- data/spec/fixtures/logs/example.log +4528 -0
- data/spec/fixtures/logs/special_characters.log +275 -0
- data/spec/lib/tf2_line_parser/parser_spec.rb +273 -0
- data/spec/lib/tf2_line_parser/player_spec.rb +15 -0
- data/spec/spec_helper.rb +2 -0
- data/tf2_line_parser.gemspec +20 -0
- metadata +144 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tf2_line_parser (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.0.8)
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
method_source (0.8.1)
|
12
|
+
multi_json (1.6.1)
|
13
|
+
pry (0.9.12)
|
14
|
+
coderay (~> 1.0.5)
|
15
|
+
method_source (~> 0.8)
|
16
|
+
slop (~> 3.4)
|
17
|
+
pry-nav (0.2.3)
|
18
|
+
pry (~> 0.9.10)
|
19
|
+
rspec (2.12.0)
|
20
|
+
rspec-core (~> 2.12.0)
|
21
|
+
rspec-expectations (~> 2.12.0)
|
22
|
+
rspec-mocks (~> 2.12.0)
|
23
|
+
rspec-core (2.12.2)
|
24
|
+
rspec-expectations (2.12.1)
|
25
|
+
diff-lcs (~> 1.1.3)
|
26
|
+
rspec-mocks (2.12.2)
|
27
|
+
simplecov (0.7.1)
|
28
|
+
multi_json (~> 1.0)
|
29
|
+
simplecov-html (~> 0.7.1)
|
30
|
+
simplecov-html (0.7.1)
|
31
|
+
slop (3.4.3)
|
32
|
+
spec_coverage (0.0.5)
|
33
|
+
rspec (~> 2.0)
|
34
|
+
simplecov
|
35
|
+
|
36
|
+
PLATFORMS
|
37
|
+
ruby
|
38
|
+
|
39
|
+
DEPENDENCIES
|
40
|
+
pry-nav (~> 0.2.3)
|
41
|
+
rspec (~> 2.12.0)
|
42
|
+
spec_coverage (~> 0.0.5)
|
43
|
+
tf2_line_parser!
|
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# TF2 line parser[](http://travis-ci.org/Arie/tf2_line_parser) [](https://codeclimate.com/github/Arie/tf2_line_parser)
|
2
|
+
|
3
|
+
A TF2 log line parser. Unlike the other log parsers I've found, this one parses the line and returns a plain old ruby object to describe the event of the line.
|
4
|
+
I plan to use this for my own stats parsing tool.
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
* Ruby
|
8
|
+
|
9
|
+
## Missing events
|
10
|
+
* Connect
|
11
|
+
* Disconnect
|
12
|
+
* Enter game
|
13
|
+
|
14
|
+
## Credits
|
15
|
+
* nTraum, I stole most of the regexes from him his [TF2Stats](https://github.com/nTraum/tf2stats/) project.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class CaptureBlock < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} triggered "captureblocked" #{regex_cap}/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :cp_number, :cp_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :player, :cap_number, :cap_name
|
15
|
+
|
16
|
+
def initialize(time, player_name, player_steam_id, player_team, cap_number, cap_name)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@plaery = Player.new(player_name, player_steam_id, player_team)
|
19
|
+
@cap_number = cap_number
|
20
|
+
@cap_name = cap_name
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class ChargeDeployed < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} triggered "chargedeployed"/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :player
|
15
|
+
|
16
|
+
def initialize(time, name, steam_id, team)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@player = Player.new(name, steam_id, team)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
|
5
|
+
class Chat < Event
|
6
|
+
|
7
|
+
attr_accessor :time, :player, :message
|
8
|
+
|
9
|
+
def initialize(time, player_name, player_steam_id, player_team, message)
|
10
|
+
@time = parse_time(time)
|
11
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
12
|
+
@message = message
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.attributes
|
16
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :message]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class Say < Chat
|
22
|
+
|
23
|
+
def self.regex
|
24
|
+
@regex ||= /#{regex_time} #{regex_player} say #{regex_message}/
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class TeamSay < Chat
|
30
|
+
|
31
|
+
def self.regex
|
32
|
+
@regex ||= /#{regex_time} #{regex_player} say_team #{regex_message}/
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class ConsoleSay < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_console} say #{regex_message}/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :message]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :message
|
15
|
+
|
16
|
+
def initialize(time, message)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@message = message
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class Damage < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} triggered "damage" \(damage "(?'value'\d+)"\)/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :value]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :player, :value
|
15
|
+
|
16
|
+
def initialize(time, player_name, player_steam_id, player_team, value)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
19
|
+
@value = value.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
|
3
|
+
module Events
|
4
|
+
|
5
|
+
class Event
|
6
|
+
|
7
|
+
def self.time_format
|
8
|
+
@time_format ||= '%m/%d/%Y - %T'
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.regex_time
|
12
|
+
@regex_time ||= 'L (?\'time\'.*):'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.regex_player
|
16
|
+
@regex_player ||= '"(?\'player_nick\'.+)<(?\'player_uid\'\d+)><(?\'player_steamid\'STEAM_\S+)><(?\'player_team\'Red|Blue)>"'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.regex_target
|
20
|
+
@regex_target ||= '"(?\'target_nick\'.+)<(?\'target_uid\'\d+)><(?\'target_steamid\'STEAM_\S+)><(?\'target_team\'Red|Blue)>"'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.regex_cap
|
24
|
+
@regex_cap ||= '\(cp "(?\'cp_number\'\d+)"\) \(cpname "(?\'cp_name\'.\w*)'
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.regex_console
|
28
|
+
@regex_console ||= '"Console<0><Console><Console>"'
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.regex_message
|
32
|
+
@regex_message ||= '"(?\'message\'.*)"'
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.types
|
36
|
+
#ordered by how common the messages are
|
37
|
+
@types ||= [Damage, Heal, PickupItem, Assist, Kill, CaptureBlock, PointCapture, ChargeDeployed,
|
38
|
+
MedicDeath, RoleChange, Suicide, Say, TeamSay, Domination, Revenge, RoundWin, CurrentScore,
|
39
|
+
RoundLength, RoundStart, ConsoleSay, MatchEnd, FinalScore,
|
40
|
+
RoundStalemate, Unknown]
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.regex_results(matched_line)
|
44
|
+
attributes.collect do |attribute|
|
45
|
+
matched_line[attribute]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_time(time_string)
|
50
|
+
Time.strptime(time_string, Event.time_format)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
class PVPEvent < Event
|
56
|
+
def self.attributes
|
57
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :target_nick, :target_steamid, :target_team]
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_accessor :time, :player, :target
|
61
|
+
|
62
|
+
def initialize(time, player_name, player_steam_id, player_team, target_name, target_steam_id, target_team)
|
63
|
+
@time = parse_time(time)
|
64
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
65
|
+
@target = Player.new(target_name, target_steam_id, target_team)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class Heal < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} triggered "healed" against #{regex_target} \(healing "(?'value'\d+)"\)/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :target_nick, :target_steamid, :target_team, :value]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :player, :target, :value
|
15
|
+
|
16
|
+
def initialize(time, player_name, player_steam_id, player_team, target_name, target_steam_id, target_team, value)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
19
|
+
@target = Player.new(target_name, target_steam_id, target_team)
|
20
|
+
@value = value.to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class MatchEnd < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} World triggered "Game_Over" reason "(?'reason'.*)"/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :reason]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :reason
|
15
|
+
|
16
|
+
def initialize(time, reason)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@reason = reason
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class PickupItem < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} picked up item #{regex_item}/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.regex_item
|
11
|
+
@regex_item ||= '\"(?\'item\'.*)\"'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.attributes
|
15
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :item]
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :time, :player, :item
|
19
|
+
|
20
|
+
def initialize(time, player_name, player_steam_id, player_team, item)
|
21
|
+
@time = parse_time(time)
|
22
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
23
|
+
@item = item
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class PointCapture < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} Team "(?'team'Red|Blue)" triggered "pointcaptured" \(cp "(?'cp_number'\d+)"\) \(cpname "(?'cp_name'.*)"\) \(numcappers/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :team, :cp_number, :cp_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :team, :cap_number, :cap_name
|
15
|
+
|
16
|
+
def initialize(time, team, cap_number, cap_name)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@team = team
|
19
|
+
@cap_number = cap_number
|
20
|
+
@cap_name = cap_name
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class RoleChange < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} #{regex_player} changed role to #{regex_role}/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.regex_role
|
11
|
+
@regex_role ||= '\"(?\'role\'.*)\"'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.attributes
|
15
|
+
@attributes ||= [:time, :player_nick, :player_steamid, :player_team, :role]
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :time, :player, :role
|
19
|
+
|
20
|
+
def initialize(time, player_name, player_steam_id, player_team, role)
|
21
|
+
@time = parse_time(time)
|
22
|
+
@player = Player.new(player_name, player_steam_id, player_team)
|
23
|
+
@role = role
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class RoundLength < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} World triggered "Round_Length" \(seconds \"(?'length'.*)"\)/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :length]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time, :length
|
15
|
+
|
16
|
+
def initialize(time, length)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@length = length
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class RoundStalemate < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} World triggered "Round_Stalemate"/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time
|
15
|
+
|
16
|
+
def initialize(time)
|
17
|
+
@time = parse_time(time)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class RoundStart < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} World triggered "Round_Start"/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :time
|
15
|
+
|
16
|
+
def initialize(time)
|
17
|
+
@time = parse_time(time)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class RoundWin < Event
|
5
|
+
|
6
|
+
def self.regex
|
7
|
+
@regex ||= /#{regex_time} World triggered "Round_Win" \(winner "(?'team'Red|Blue)"\)/
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.attributes
|
11
|
+
@attributes ||= [:time, :team]
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :winner
|
15
|
+
|
16
|
+
def initialize(time, winner)
|
17
|
+
@time = parse_time(time)
|
18
|
+
@winner = winner
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TF2LineParser
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class Score < Event
|
5
|
+
|
6
|
+
def self.regex_score
|
7
|
+
@regex_score ||= '\"(?\'score\'\d+)\"'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.regex_team
|
11
|
+
@regex_team ||= 'Team \"(?\'team\'Red|Blue)\"'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.attributes
|
15
|
+
@attributes ||= [:time, :team, :score]
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :time, :team, :score
|
19
|
+
|
20
|
+
def initialize(time, team, score)
|
21
|
+
@time = parse_time(time)
|
22
|
+
@team = team
|
23
|
+
@score = score
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|