tf2_line_parser 0.5.0 → 0.5.2

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: 5c1d38c81d58d2ecb10aa612b2602de4abf47b540ec3caf003273a87cdcdb5ba
4
- data.tar.gz: 7993c5640a38063e5082780475881b1faca2898a5f6555ac4040ff612f341f2c
3
+ metadata.gz: 4b29330a6fc24eb0ae42d3e5de61300fc75c892fccf9c2f9a04b8b361175c905
4
+ data.tar.gz: 1f8a4bcd5452ed7ba5ae257036f9e831ee3570844a48cacd3043d00424db9023
5
5
  SHA512:
6
- metadata.gz: 41f0d0adece361d3e97a3ec48466dd8123fdc95d8ea26f5616f57f125426225a36f6dfc2d1a5611115993863980d2d18e08d49f46397bba71dbe8775f0c7ef65
7
- data.tar.gz: 872376b6810e9d6031cbd0d6cf38156ef99fba2dbf91174761c354a44fa040f9d7809bb5736518406bccdecbfb1f3a3f1314f6c54be14000a88af223a2287ee0
6
+ metadata.gz: bf33e8f104485bbafc7cab96beabc7ddfa14979718317416563726587238e38f41bcde9cb80bc6933339e1a04065338b5796f42c0cfa92763aae9d9bce54e4d6
7
+ data.tar.gz: 85cac455f1a1a66cb9c2622daaebea9bf4fcbdc35e84b3e6337f745b987bd4287e87f16afd6905eff5a9760b36012b8b08792131365a02792d55832ccee4e16d
data/.tool-versions ADDED
@@ -0,0 +1,2 @@
1
+ ruby 4.0.0
2
+ nodejs latest
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tf2_line_parser (0.5.0)
4
+ tf2_line_parser (0.5.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -15,7 +15,7 @@ GEM
15
15
  diff-lcs (1.6.2)
16
16
  docile (1.4.1)
17
17
  io-console (0.8.2)
18
- json (2.18.0)
18
+ json (2.18.1)
19
19
  mize (0.6.1)
20
20
  readline (0.0.4)
21
21
  reline
@@ -33,7 +33,7 @@ GEM
33
33
  rspec-mocks (3.13.7)
34
34
  diff-lcs (>= 1.2.0, < 2.0)
35
35
  rspec-support (~> 3.13.0)
36
- rspec-support (3.13.6)
36
+ rspec-support (3.13.7)
37
37
  simplecov (0.22.0)
38
38
  docile (~> 1.1)
39
39
  simplecov-html (~> 0.11)
@@ -43,8 +43,8 @@ GEM
43
43
  sync (0.5.0)
44
44
  term-ansicolor (1.11.3)
45
45
  tins (~> 1)
46
- thor (1.4.0)
47
- tins (1.51.0)
46
+ thor (1.5.0)
47
+ tins (1.51.1)
48
48
  bigdecimal
49
49
  mize (~> 0.6)
50
50
  readline
@@ -61,4 +61,4 @@ DEPENDENCIES
61
61
  tf2_line_parser!
62
62
 
63
63
  BUNDLED WITH
64
- 2.3.16
64
+ 2.5.11
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # TF2 line parser [![Build Status](https://travis-ci.org/Arie/tf2_line_parser.png?branch=master)](http://travis-ci.org/Arie/tf2_line_parser) [![Dependency Status](https://gemnasium.com/Arie/tf2_line_parser.png)](https://gemnasium.com/Arie/tf2_line_parser) [![Code Climate](https://codeclimate.com/github/Arie/tf2_line_parser.png)](https://codeclimate.com/github/Arie/tf2_line_parser) [![Coverage Status](https://coveralls.io/repos/Arie/tf2_line_parser/badge.png?branch=master)](https://coveralls.io/r/Arie/tf2_line_parser)
1
+ # TF2 line parser
2
2
 
3
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
4
  I plan to use this for my own stats parsing tool.
5
5
 
6
6
  ## Requirements
7
- * Ruby
7
+ * Ruby (no runtime dependencies)
8
8
 
9
9
  ## Credits
10
10
  * nTraum, I stole most of the regexes from his [TF2Stats](https://github.com/nTraum/tf2stats/) project.
@@ -23,7 +23,7 @@ module TF2LineParser
23
23
  end
24
24
 
25
25
  def self.regex_cap
26
- @regex_cap ||= '\(cp "(?\'cp_number\'\d+)"\) \(cpname "(?\'cp_name\'.\w*)'
26
+ @regex_cap ||= '\(cp "(?\'cp_number\'\d+)"\) \(cpname "(?\'cp_name\'[^"]*)"'
27
27
  end
28
28
 
29
29
  def self.regex_console
@@ -38,7 +38,7 @@ module TF2LineParser
38
38
  # ordered by how common the messages are
39
39
  @types ||= [ShotFired, ShotHit, PositionReport, HeadshotDamage, Airshot, Damage, AirshotHeal, Heal, PickupItem, Assist, Kill, CaptureBlock, PointCapture, ChargeDeployed,
40
40
  MedicDeath, MedicDeathEx, EmptyUber, ChargeReady, ChargeEnded, FirstHealAfterSpawn, LostUberAdvantage, BuiltObject, PlayerExtinguished, JoinedTeam, EnteredGame, RoleChange, Spawn, Suicide, KilledObject, Say, TeamSay, Domination, Revenge, RoundWin, CurrentScore,
41
- RoundLength, RoundStart, RoundSetupBegin, RoundSetupEnd, MiniRoundStart, MiniRoundSelected, IntermissionWinLimit, Connect, Disconnect, RconCommand, ConsoleSay, MatchEnd, FinalScore,
41
+ RoundLength, RoundStart, RoundSetupBegin, RoundSetupEnd, MiniRoundStart, MiniRoundSelected, WorldIntermissionWinLimit, IntermissionWinLimit, Connect, Disconnect, RconCommand, ConsoleSay, MatchEnd, FinalScore,
42
42
  RoundStalemate, Unknown].freeze
43
43
  end
44
44
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TF2LineParser
4
+ module Events
5
+ class WorldIntermissionWinLimit < RoundEventWithoutVariables
6
+ def self.round_type
7
+ @round_type ||= 'Intermission_Win_Limit'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -10,8 +10,8 @@ module TF2LineParser
10
10
  KEYWORD_DISPATCH = {
11
11
  'shot_fired' => [Events::ShotFired],
12
12
  'shot_hit' => [Events::ShotHit],
13
- 'damage' => [Events::HeadshotDamage, Events::Airshot, Events::Damage],
14
- 'healed' => [Events::AirshotHeal, Events::Heal],
13
+ 'damage' => :check_damage_subtypes,
14
+ 'healed' => :check_heal_subtypes,
15
15
  'picked up' => [Events::PickupItem],
16
16
  'kill assist' => [Events::Assist],
17
17
  'killed' => [Events::Kill],
@@ -43,7 +43,7 @@ module TF2LineParser
43
43
  'Round_Setup_End' => [Events::RoundSetupEnd],
44
44
  'Mini_Round_Start' => [Events::MiniRoundStart],
45
45
  'Mini_Round_Selected' => [Events::MiniRoundSelected],
46
- 'Intermission_Win_Limit' => [Events::IntermissionWinLimit],
46
+ 'Intermission_Win_Limit' => [Events::WorldIntermissionWinLimit, Events::IntermissionWinLimit],
47
47
  'Round_Stalemate' => [Events::RoundStalemate],
48
48
  'Game_Over' => [Events::MatchEnd],
49
49
  'connected, address' => [Events::Connect],
@@ -70,7 +70,13 @@ module TF2LineParser
70
70
  # Class method to parse without object allocation
71
71
  def self.parse(line)
72
72
  types = find_candidate_types(line)
73
- try_parse_types(line, types)
73
+ result = try_parse_types(line, types)
74
+ return result if result
75
+
76
+ # If candidate types didn't match, fall back to Unknown (unless we already tried fallbacks)
77
+ return nil if types == FALLBACK_TYPES
78
+
79
+ try_parse_types(line, [Events::Unknown])
74
80
  end
75
81
 
76
82
  class << self
@@ -84,8 +90,17 @@ module TF2LineParser
84
90
  end_idx = line.index('"', start_idx + 11)
85
91
  if end_idx
86
92
  keyword = line[start_idx + 11...end_idx]
87
- types = KEYWORD_DISPATCH[keyword]
88
- return types if types
93
+ result = KEYWORD_DISPATCH[keyword]
94
+ if result
95
+ case result
96
+ when :check_damage_subtypes
97
+ return check_damage_subtypes(line)
98
+ when :check_heal_subtypes
99
+ return check_heal_subtypes(line)
100
+ else
101
+ return result
102
+ end
103
+ end
89
104
  end
90
105
  end
91
106
  end
@@ -133,6 +148,32 @@ module TF2LineParser
133
148
  end
134
149
  nil
135
150
  end
151
+
152
+ def check_damage_subtypes(line)
153
+ damage_attr_pos = line.index('(damage "')
154
+ return [Events::Damage] unless damage_attr_pos
155
+
156
+ suffix = line[damage_attr_pos..-1]
157
+ if suffix.include?('(headshot "')
158
+ [Events::HeadshotDamage]
159
+ elsif suffix.include?('(airshot "')
160
+ [Events::Airshot]
161
+ else
162
+ [Events::Damage]
163
+ end
164
+ end
165
+
166
+ def check_heal_subtypes(line)
167
+ heal_attr_pos = line.index('(healing "')
168
+ return [Events::Heal] unless heal_attr_pos
169
+
170
+ suffix = line[heal_attr_pos..-1]
171
+ if suffix.include?('(airshot "')
172
+ [Events::AirshotHeal]
173
+ else
174
+ [Events::Heal]
175
+ end
176
+ end
136
177
  end
137
178
  end
138
179
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TF2LineParser
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.2'
5
5
  end
@@ -456,6 +456,12 @@ module TF2LineParser
456
456
  parse(line)
457
457
  end
458
458
 
459
+ it 'recognizes world intermission win limit' do
460
+ line = 'L 01/24/2026 - 15:30:45: World triggered "Intermission_Win_Limit"'
461
+ expect(Events::WorldIntermissionWinLimit).to receive(:new).with(anything)
462
+ parse(line)
463
+ end
464
+
459
465
  it 'recognizes ubercharges' do
460
466
  line = log_lines[1416]
461
467
  name = 'broder mirelin'
@@ -645,6 +651,14 @@ module TF2LineParser
645
651
  parse(line)
646
652
  end
647
653
 
654
+ it 'recognizes capture block with spaces in cpname' do
655
+ line = 'L 02/18/2026 - 23:41:55: "mein<26><[U:1:197355296]><Blue>" triggered "captureblocked" (cp "0") (cpname "the Tower") (position "611 -341 318")'
656
+ result = parse(line)
657
+ expect(result).to be_a(Events::CaptureBlock)
658
+ expect(result.player.name).to eq('mein')
659
+ expect(result.cap_name).to eq('the Tower')
660
+ end
661
+
648
662
  it 'recognizes shot_fired' do
649
663
  line = 'L 12/30/2025 - 18:34:19: "Jib<34><[U:1:367944796]><Blue>" triggered "shot_fired" (weapon "tf_projectile_rocket")'
650
664
  result = parse(line)
@@ -731,6 +745,16 @@ module TF2LineParser
731
745
  parse(line)
732
746
  end
733
747
 
748
+ it 'falls back to Unknown when keyword matches but regex does not' do
749
+ # A triggered event with a recognized keyword but unrecognized format should
750
+ # fall back to Unknown instead of returning nil
751
+ line = 'L 01/24/2026 - 15:30:45: Something triggered "Round_Win" with unexpected format'
752
+ time = '01/24/2026 - 15:30:45'
753
+ unknown = 'Something triggered "Round_Win" with unexpected format'
754
+ expect(Events::Unknown).to receive(:new).with(time, unknown)
755
+ parse(line)
756
+ end
757
+
734
758
  it 'can parse all lines in the example log files without exploding' do
735
759
  broder_vs_epsilon = File.expand_path('../../fixtures/logs/broder_vs_epsilon.log', __dir__)
736
760
  special_characters = File.expand_path('../../fixtures/logs/special_characters.log', __dir__)
metadata CHANGED
@@ -1,14 +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.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arie
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-12-31 00:00:00.000000000 Z
10
+ date: 2026-02-19 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: coveralls_reborn
@@ -75,6 +74,7 @@ files:
75
74
  - ".coverage"
76
75
  - ".gitignore"
77
76
  - ".rspec"
77
+ - ".tool-versions"
78
78
  - ".travis.yml"
79
79
  - Gemfile
80
80
  - Gemfile.lock
@@ -135,6 +135,7 @@ files:
135
135
  - lib/tf2_line_parser/events/spawn.rb
136
136
  - lib/tf2_line_parser/events/suicide.rb
137
137
  - lib/tf2_line_parser/events/unknown.rb
138
+ - lib/tf2_line_parser/events/world_intermission_win_limit.rb
138
139
  - lib/tf2_line_parser/line.rb
139
140
  - lib/tf2_line_parser/parser.rb
140
141
  - lib/tf2_line_parser/player.rb
@@ -156,7 +157,6 @@ files:
156
157
  homepage: http://github.com/Arie/tf2_line_parser
157
158
  licenses: []
158
159
  metadata: {}
159
- post_install_message:
160
160
  rdoc_options: []
161
161
  require_paths:
162
162
  - lib
@@ -171,8 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
173
  requirements: []
174
- rubygems_version: 3.5.11
175
- signing_key:
174
+ rubygems_version: 4.0.3
176
175
  specification_version: 4
177
176
  summary: TF2 log line parser
178
177
  test_files: