tf2_line_parser 0.5.2 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b29330a6fc24eb0ae42d3e5de61300fc75c892fccf9c2f9a04b8b361175c905
4
- data.tar.gz: 1f8a4bcd5452ed7ba5ae257036f9e831ee3570844a48cacd3043d00424db9023
3
+ metadata.gz: d62fb60bbb31b6578bbf54b7f5101f8f7fc93689c432494a08679f3e9d48cdca
4
+ data.tar.gz: 9a94a4deffdcda33dddffd7efdaf4c08f3b8e97a17758fd5c46c705cf67ddb77
5
5
  SHA512:
6
- metadata.gz: bf33e8f104485bbafc7cab96beabc7ddfa14979718317416563726587238e38f41bcde9cb80bc6933339e1a04065338b5796f42c0cfa92763aae9d9bce54e4d6
7
- data.tar.gz: 85cac455f1a1a66cb9c2622daaebea9bf4fcbdc35e84b3e6337f745b987bd4287e87f16afd6905eff5a9760b36012b8b08792131365a02792d55832ccee4e16d
6
+ metadata.gz: 1f4c05bec771e0abc994ae0d83f63e6ccda3bd7cf3296defe2690603c1754cbd474836714de8abf45aa368251a974431663287077033f277a1ad1abf6154bf24
7
+ data.tar.gz: 190f40d4da42c17ef659af94bcba4d890e98f5fec17ca6f1e472f3095f9058e138a22bac59a710804343a9758f7c2f9d53336bf213ca55e5e25635731da62d6c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tf2_line_parser (0.5.2)
4
+ tf2_line_parser (0.6.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -4,8 +4,8 @@ module TF2LineParser
4
4
  module Events
5
5
  class Airshot < Damage
6
6
  def self.regex
7
- # Airshot can appear after weapon, with optional height at the end
8
- @regex ||= /#{regex_time} #{regex_player} triggered "damage" #{regex_damage_against}\(damage "(?'value'\d+)"\)#{regex_realdamage}#{regex_weapon}#{regex_airshot}#{regex_height}/.freeze
7
+ # Airshot can appear after weapon, with optional crit/healing between weapon and airshot
8
+ @regex ||= /#{regex_time} #{regex_player} triggered "damage" #{regex_damage_against}\(damage "(?'value'\d+)"\)#{regex_realdamage}#{regex_weapon}#{regex_healing}#{regex_crit}#{regex_airshot}#{regex_height}/.freeze
9
9
  end
10
10
 
11
11
  def self.regex_airshot
@@ -17,7 +17,7 @@ module TF2LineParser
17
17
  end
18
18
 
19
19
  def self.attributes
20
- @attributes ||= %i[time player_section target_section weapon airshot]
20
+ @attributes ||= %i[time player_section target_section realdamage weapon healing crit airshot]
21
21
  end
22
22
 
23
23
  def self.regex_results(matched_line)
@@ -25,7 +25,10 @@ module TF2LineParser
25
25
  player_section = matched_line['player_section']
26
26
  target_section = matched_line['target_section']
27
27
  value = matched_line['value']
28
+ realdamage = matched_line['realdamage']
28
29
  weapon = matched_line['weapon']
30
+ healing = matched_line['healing']
31
+ crit = matched_line['crit']
29
32
  airshot = matched_line['airshot']
30
33
 
31
34
  # Parse player section
@@ -37,18 +40,19 @@ module TF2LineParser
37
40
  target_name, target_uid, target_steamid, target_team = parse_target_section(target_section)
38
41
  end
39
42
 
40
- [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, airshot]
43
+ [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, airshot]
41
44
  end
42
45
 
43
- def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, airshot)
46
+ def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, airshot)
44
47
  @time = parse_time(time)
45
48
  @player = Player.new(player_name, player_uid, player_steamid, player_team)
46
49
  @target = Player.new(target_name, target_uid, target_steamid, target_team) if target_name
47
50
  @value = value.to_i
48
51
  @damage = @value
52
+ @realdamage = realdamage.to_i if realdamage && !realdamage.empty?
49
53
  @weapon = weapon
50
- @healing = nil
51
- @crit = nil
54
+ @healing = healing.to_i if healing
55
+ @crit = crit
52
56
  @headshot = nil
53
57
  @airshot = (airshot.to_i == 1)
54
58
  end
@@ -3,7 +3,7 @@
3
3
  module TF2LineParser
4
4
  module Events
5
5
  class Damage < Event
6
- attr_reader :damage, :crit, :headshot, :healing
6
+ attr_reader :damage, :realdamage, :crit, :headshot, :healing
7
7
 
8
8
  def self.regex
9
9
  @regex ||= /#{regex_time} #{regex_player} triggered "damage" #{regex_damage_against}\(damage "(?'value'\d+)"\)#{regex_realdamage}#{regex_weapon}#{regex_healing}#{regex_crit}#{regex_headshot}/.freeze
@@ -34,7 +34,7 @@ module TF2LineParser
34
34
  end
35
35
 
36
36
  def self.attributes
37
- @attributes ||= %i[time player_section target_section value weapon healing crit headshot]
37
+ @attributes ||= %i[time player_section target_section value realdamage weapon healing crit headshot]
38
38
  end
39
39
 
40
40
  def self.regex_results(matched_line)
@@ -42,6 +42,7 @@ module TF2LineParser
42
42
  player_section = matched_line['player_section']
43
43
  target_section = matched_line['target_section']
44
44
  value = matched_line['value']
45
+ realdamage = matched_line['realdamage']
45
46
  weapon = matched_line['weapon']
46
47
  healing = matched_line['healing']
47
48
  crit = matched_line['crit']
@@ -56,15 +57,16 @@ module TF2LineParser
56
57
  target_name, target_uid, target_steamid, target_team = parse_target_section(target_section)
57
58
  end
58
59
 
59
- [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, healing, crit, headshot]
60
+ [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, headshot]
60
61
  end
61
62
 
62
- def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, healing, crit, headshot)
63
+ def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, headshot)
63
64
  @time = parse_time(time)
64
65
  @player = Player.new(player_name, player_uid, player_steamid, player_team)
65
66
  @target = Player.new(target_name, target_uid, target_steamid, target_team) if target_name
66
67
  @value = value.to_i
67
68
  @damage = @value
69
+ @realdamage = realdamage.to_i if realdamage && !realdamage.empty?
68
70
  @weapon = weapon
69
71
  @healing = healing.to_i if healing
70
72
  @crit = crit
@@ -12,7 +12,7 @@ module TF2LineParser
12
12
  end
13
13
 
14
14
  def self.attributes
15
- @attributes ||= %i[time player_section target_section value weapon healing crit headshot]
15
+ @attributes ||= %i[time player_section target_section value realdamage weapon healing crit headshot]
16
16
  end
17
17
 
18
18
  def self.regex_results(matched_line)
@@ -20,6 +20,7 @@ module TF2LineParser
20
20
  player_section = matched_line['player_section']
21
21
  target_section = matched_line['target_section']
22
22
  value = matched_line['value']
23
+ realdamage = matched_line['realdamage']
23
24
  weapon = matched_line['weapon']
24
25
  healing = matched_line['healing']
25
26
  crit = matched_line['crit']
@@ -34,15 +35,16 @@ module TF2LineParser
34
35
  target_name, target_uid, target_steamid, target_team = parse_target_section(target_section)
35
36
  end
36
37
 
37
- [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, healing, crit, headshot]
38
+ [time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, headshot]
38
39
  end
39
40
 
40
- def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, weapon, healing, crit, headshot)
41
+ def initialize(time, player_name, player_uid, player_steamid, player_team, target_name, target_uid, target_steamid, target_team, value, realdamage, weapon, healing, crit, headshot)
41
42
  @time = parse_time(time)
42
43
  @player = Player.new(player_name, player_uid, player_steamid, player_team)
43
44
  @target = Player.new(target_name, target_uid, target_steamid, target_team) if target_name
44
45
  @value = value.to_i
45
46
  @damage = @value
47
+ @realdamage = realdamage.to_i if realdamage && !realdamage.empty?
46
48
  @weapon = weapon
47
49
  @healing = healing.to_i if healing
48
50
  @crit = crit
@@ -3,19 +3,35 @@
3
3
  module TF2LineParser
4
4
  module Events
5
5
  class PointCapture < Event
6
+ CAPPERS_REGEX = /\(player\d+\s+"(?<player_section>[^"]*<[^>]*><[^>]*><[^>]*>)"\)/
7
+
8
+ attr_reader :cappers
9
+
6
10
  def self.regex
7
- @regex ||= /#{regex_time} Team "(?'team'Red|Blue)" triggered "pointcaptured" \(cp "(?'cp_number'\d+)"\) \(cpname "(?'cp_name'.*)"\) \(numcappers/.freeze
11
+ @regex ||= /#{regex_time} Team "(?'team'Red|Blue)" triggered "pointcaptured" \(cp "(?'cp_number'\d+)"\) \(cpname "(?'cp_name'[^"]*)"\) \(numcappers "(?'numcappers'\d+)"\)(?'cappers_section'.*)/.freeze
8
12
  end
9
13
 
10
14
  def self.attributes
11
- @attributes ||= %i[time team cp_number cp_name]
15
+ @attributes ||= %i[time team cp_number cp_name numcappers cappers_section]
12
16
  end
13
17
 
14
- def initialize(time, team, cap_number, cap_name)
18
+ def initialize(time, team, cap_number, cap_name, _numcappers, cappers_section)
15
19
  @time = parse_time(time)
16
20
  @team = team
17
21
  @cap_number = cap_number
18
22
  @cap_name = cap_name
23
+ @cappers = parse_cappers(cappers_section)
24
+ end
25
+
26
+ private
27
+
28
+ def parse_cappers(section)
29
+ return [] unless section
30
+
31
+ section.scan(CAPPERS_REGEX).map do |match|
32
+ name, uid, steam_id, team = self.class.parse_player_section(match[0])
33
+ Player.new(name, uid, steam_id, team) if name
34
+ end.compact
19
35
  end
20
36
  end
21
37
  end
@@ -157,7 +157,7 @@ module TF2LineParser
157
157
  if suffix.include?('(headshot "')
158
158
  [Events::HeadshotDamage]
159
159
  elsif suffix.include?('(airshot "')
160
- [Events::Airshot]
160
+ [Events::Airshot, Events::Damage]
161
161
  else
162
162
  [Events::Damage]
163
163
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TF2LineParser
4
- VERSION = '0.5.2'
4
+ VERSION = '0.6.1'
5
5
  end
@@ -5,3 +5,4 @@ L 12/18/2025 - 22:10:55: "fy<14><[U:1:442791013]><Blue>" triggered "damage" agai
5
5
  L 12/18/2025 - 22:12:57: "tantwo<17><[U:1:191375689]><Blue>" triggered "damage" against "keicam<9><[U:1:163231154]><Red>" (damage "105") (weapon "quake_rl") (airshot "1") (height "318")
6
6
  L 12/18/2025 - 22:12:58: "tantwo<17><[U:1:191375689]><Blue>" triggered "damage" against "keicam<9><[U:1:163231154]><Red>" (damage "99") (realdamage "9") (weapon "quake_rl") (airshot "1") (height "427")
7
7
  L 12/18/2025 - 22:15:21: "fy<14><[U:1:442791013]><Blue>" triggered "damage" against "gibusmain<19><[U:1:258908204]><Red>" (damage "109") (realdamage "66") (weapon "tf_projectile_rocket") (airshot "1") (height "228")
8
+ L 03/21/2026 - 22:02:55: "Bass Windu<15><[U:1:156982175]><Blue>" triggered "damage" against "auto<14><[U:1:101982160]><Red>" (damage "152") (weapon "rocketlauncher_directhit") (crit "mini") (airshot "1") (height "242")
@@ -38,33 +38,29 @@ module TF2LineParser
38
38
  player_steam_id = 'STEAM_0:1:16347045'
39
39
  player_team = 'Red'
40
40
  value = '69'
41
+ realdamage = nil
41
42
  weapon = nil
42
43
  healing = nil
43
44
  crit = nil
44
45
  headshot = nil
45
46
  expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, nil, nil,
46
- nil, nil, value, weapon, healing, crit, headshot)
47
+ nil, nil, value, realdamage, weapon, healing, crit, headshot)
47
48
  parse(line)
48
49
  end
49
50
 
50
51
  it 'recognizes new steam id log lines with detailed damage' do
51
52
  line = new_log_lines[0]
52
- player_name = 'iM yUKi intel @i52'
53
- player_uid = '6'
54
- player_steam_id = '[U:1:3825470]'
55
- player_team = 'Blue'
56
- target_name = 'mix^ enigma @ i52'
57
- target_uid = '8'
58
- target_steam_id = '[U:1:33652944]'
59
- target_team = 'Red'
60
- value = '78'
61
- weapon = 'tf_projectile_rocket'
62
- healing = nil
63
- crit = nil
64
- headshot = nil
65
- expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, target_name,
66
- target_uid, target_steam_id, target_team, value, weapon, healing, crit, headshot)
67
- parse(line)
53
+ result = parse(line)
54
+ expect(result).to be_a(Events::Damage)
55
+ expect(result.player.name).to eq('iM yUKi intel @i52')
56
+ expect(result.player.steam_id).to eq('[U:1:3825470]')
57
+ expect(result.player.team).to eq('Blue')
58
+ expect(result.target.name).to eq('mix^ enigma @ i52')
59
+ expect(result.target.steam_id).to eq('[U:1:33652944]')
60
+ expect(result.target.team).to eq('Red')
61
+ expect(result.damage).to eq(78)
62
+ expect(result.realdamage).to eq(67)
63
+ expect(result.weapon).to eq('tf_projectile_rocket')
68
64
  end
69
65
 
70
66
  it 'recognizes detailed damage' do
@@ -78,12 +74,13 @@ module TF2LineParser
78
74
  target_steam_id = 'STEAM_0:0:43087158'
79
75
  target_team = 'Red'
80
76
  value = '102'
77
+ realdamage = nil
81
78
  weapon = 'tf_projectile_pipe'
82
79
  healing = nil
83
80
  crit = nil
84
81
  headshot = nil
85
82
  expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, target_name,
86
- target_uid, target_steam_id, target_team, value, weapon, healing, crit, headshot)
83
+ target_uid, target_steam_id, target_team, value, realdamage, weapon, healing, crit, headshot)
87
84
  parse(line)
88
85
  end
89
86
 
@@ -92,7 +89,7 @@ module TF2LineParser
92
89
  weapon = 'tf_projectile_rocket'
93
90
  airshot = '1'
94
91
  expect(Events::Airshot).to receive(:new).with(anything, anything, anything, anything, anything, anything, anything,
95
- anything, anything, anything, weapon, airshot)
92
+ anything, anything, anything, nil, weapon, nil, nil, airshot)
96
93
  parse(line).inspect
97
94
  end
98
95
 
@@ -107,6 +104,7 @@ module TF2LineParser
107
104
  expect(result.target.steam_id).to eq('[U:1:468872526]')
108
105
  expect(result.target.team).to eq('Red')
109
106
  expect(result.damage).to eq(105)
107
+ expect(result.realdamage).to eq(88)
110
108
  expect(result.weapon).to eq('quake_rl')
111
109
  expect(result.airshot).to eq(true)
112
110
  end
@@ -117,10 +115,28 @@ module TF2LineParser
117
115
  expect(result).to be_a(Events::Airshot)
118
116
  expect(result.player.name).to eq('tantwo')
119
117
  expect(result.damage).to eq(105)
118
+ expect(result.realdamage).to be_nil
120
119
  expect(result.weapon).to eq('quake_rl')
121
120
  expect(result.airshot).to eq(true)
122
121
  end
123
122
 
123
+ it 'recognizes airshots with crit' do
124
+ line = airshot_log_lines[7]
125
+ result = parse(line)
126
+ expect(result).to be_a(Events::Airshot)
127
+ expect(result.player.name).to eq('Bass Windu')
128
+ expect(result.player.steam_id).to eq('[U:1:156982175]')
129
+ expect(result.player.team).to eq('Blue')
130
+ expect(result.target.name).to eq('auto')
131
+ expect(result.target.steam_id).to eq('[U:1:101982160]')
132
+ expect(result.target.team).to eq('Red')
133
+ expect(result.damage).to eq(152)
134
+ expect(result.realdamage).to be_nil
135
+ expect(result.weapon).to eq('rocketlauncher_directhit')
136
+ expect(result.crit).to eq('mini')
137
+ expect(result.airshot).to eq(true)
138
+ end
139
+
124
140
  it 'recognizes airshot heals (Crusader Crossbow mid-air)' do
125
141
  line = airshot_log_lines[2]
126
142
  result = parse(line)
@@ -160,28 +176,24 @@ module TF2LineParser
160
176
  crit = nil
161
177
  headshot = '1'
162
178
  expect(Events::HeadshotDamage).to receive(:new).with(anything, anything, anything, anything, anything, anything,
163
- anything, anything, anything, anything, weapon, healing, crit, headshot)
179
+ anything, anything, anything, anything, anything, weapon, healing, crit, headshot)
164
180
  parse(line).inspect
165
181
  end
166
182
 
167
- it 'ignores realdamage' do
183
+ it 'parses realdamage' do
168
184
  line = detailed_log_lines[65]
169
- player_name = 'LittleLies'
170
- player_uid = '16'
171
- player_steam_id = 'STEAM_0:0:55031498'
172
- player_team = 'Blue'
173
- target_name = 'Aquila'
174
- target_uid = '15'
175
- target_steam_id = 'STEAM_0:0:43087158'
176
- target_team = 'Red'
177
- value = '98'
178
- weapon = 'tf_projectile_pipe'
179
- healing = nil
180
- crit = nil
181
- headshot = nil
182
- expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, target_name,
183
- target_uid, target_steam_id, target_team, value, weapon, healing, crit, headshot)
184
- parse(line)
185
+ result = parse(line)
186
+ expect(result).to be_a(Events::Damage)
187
+ expect(result.damage).to eq(98)
188
+ expect(result.realdamage).to be_a(Integer)
189
+ end
190
+
191
+ it 'returns nil realdamage when not present' do
192
+ line = log_lines[1001]
193
+ result = parse(line)
194
+ expect(result).to be_a(Events::Damage)
195
+ expect(result.damage).to eq(69)
196
+ expect(result.realdamage).to be_nil
185
197
  end
186
198
 
187
199
  it 'recognizes damage with multiple optional fields' do
@@ -195,12 +207,13 @@ module TF2LineParser
195
207
  target_steam_id = 'STEAM_0:0:29650428'
196
208
  target_team = 'Blue'
197
209
  value = '150'
210
+ realdamage = '100'
198
211
  weapon = 'sniperrifle'
199
212
  healing = '25'
200
213
  crit = nil
201
214
  headshot = nil
202
215
  expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, target_name,
203
- target_uid, target_steam_id, target_team, value, weapon, healing, crit, headshot)
216
+ target_uid, target_steam_id, target_team, value, realdamage, weapon, healing, crit, headshot)
204
217
  parse(line)
205
218
  end
206
219
 
@@ -220,7 +233,7 @@ module TF2LineParser
220
233
  crit = 'crit'
221
234
  headshot = nil
222
235
  expect(Events::Damage).to receive(:new).with(anything, player_name, player_uid, player_steam_id, player_team, target_name,
223
- target_uid, target_steam_id, target_team, value, weapon, healing, crit, headshot)
236
+ target_uid, target_steam_id, target_team, value, nil, weapon, healing, crit, headshot)
224
237
  parse(line)
225
238
  end
226
239
 
@@ -232,11 +245,16 @@ module TF2LineParser
232
245
 
233
246
  it 'recognizes a point capture' do
234
247
  line = log_lines[1360]
235
- team = 'Blue'
236
- cap_number = '2'
237
- cap_name = '#Badlands_cap_cp3'
238
- expect(Events::PointCapture).to receive(:new).with(anything, team, cap_number, cap_name)
239
- parse(line)
248
+ result = parse(line)
249
+ expect(result).to be_a(Events::PointCapture)
250
+ expect(result.team).to eq('Blue')
251
+ expect(result.cap_number).to eq('2')
252
+ expect(result.cap_name).to eq('#Badlands_cap_cp3')
253
+ expect(result.cappers).to be_an(Array)
254
+ expect(result.cappers.length).to eq(4)
255
+ expect(result.cappers.first.name).to eq('broder Zebbosai')
256
+ expect(result.cappers.first.steam_id).to eq('STEAM_0:0:20805809')
257
+ expect(result.cappers.first.team).to eq('Blue')
240
258
  end
241
259
 
242
260
  it 'recognizes a round win' do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tf2_line_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arie
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-19 00:00:00.000000000 Z
10
+ date: 2026-03-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: coveralls_reborn