ssc.bot 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,64 +1,54 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Bot.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Bot is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU Lesser General Public License as published by
11
- # the Free Software Foundation, either version 3 of the License, or
12
- # (at your option) any later version.
13
- #
14
- # SSC.Bot is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- # GNU Lesser General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU Lesser General Public License
20
- # along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
12
+ require 'attr_bool'
24
13
  require 'set'
25
14
 
26
-
27
15
  module SSCBot
28
16
  class ChatLog
29
17
  ###
30
18
  # The base class of all parsed messages from a chat log file.
31
- #
32
- # @author Jonathan Bradley Whited (@esotericpig)
19
+ #
20
+ # @author Jonathan Bradley Whited
33
21
  # @since 0.1.0
34
22
  ###
35
23
  class Message
24
+ extend AttrBool::Ext
25
+
36
26
  # Adds +type+ to the list of valid {TYPES}
37
27
  # and creates a boolean method for it ending with a +?+.
38
- #
28
+ #
39
29
  # @param type [Symbol,String] the new type to add
40
30
  def self.add_type(type)
41
- type = type.to_sym()
42
-
31
+ type = type.to_sym
32
+
43
33
  return if TYPES.include?(type)
44
-
34
+
45
35
  TYPES.add(type)
46
-
47
- name = type.to_s().sub('?','q_')
48
-
36
+
37
+ name = type.to_s.sub('?','q_')
38
+
49
39
  define_method(:"type_#{name}?") do
50
40
  return @type == type
51
41
  end
52
42
  end
53
-
43
+
54
44
  # Valid types of messages.
55
- #
45
+ #
56
46
  # You can add your own custom type(s) that you parse manually:
57
47
  # SSCBot::ChatLog::Message.add_type(:custom)
58
- TYPES = Set.new()
59
-
48
+ TYPES = Set.new
49
+
60
50
  # In order of F1 Help box.
61
- %i{
51
+ %i[
62
52
  pub team private remote freq chat
63
53
  ?lines ?namelen ?ignore ?nopubchat ?obscene ?away ?log ?logbuffer
64
54
  ?kill kill ?enter enter ?leave leave ?message ?messages ?chat
@@ -68,38 +58,38 @@ class ChatLog
68
58
  ?sound ?alarm ?sheep ?getnews
69
59
  ?squadowner ?squad ?squadlist ?loadmacro ?savemacro
70
60
  unknown
71
- }.each() do |type|
61
+ ].each do |type|
72
62
  add_type(type)
73
63
  end
74
-
64
+
75
65
  # @param type [Symbol] the type to check if valid
76
66
  # @return [Boolean] +true+ if +type+ is one of {TYPES}, else +false+
77
67
  def self.valid_type?(type)
78
68
  return TYPES.include?(type)
79
69
  end
80
-
70
+
81
71
  attr_reader :line # @return [String] the raw (unparsed) line from the file
82
72
  attr_reader :type # @return [Symbol] what type of message this is; one of {TYPES}
83
-
73
+
84
74
  # @param line [String] the raw (unparsed) line from the file
85
75
  # @param type [Symbol] what type of message this is; must be one of {TYPES}
86
76
  def initialize(line,type:)
87
- type = type.to_sym()
88
-
89
- raise ArgumentError,"invalid line{#{line.inspect()}}" if line.nil?()
90
- raise ArgumentError,"invalid type{#{type.inspect()}}" if !self.class.valid_type?(type)
91
-
77
+ type = type.to_sym
78
+
79
+ raise ArgumentError,"invalid line{#{line.inspect}}" if line.nil?
80
+ raise ArgumentError,"invalid type{#{type.inspect}}" if !self.class.valid_type?(type)
81
+
92
82
  @line = line
93
83
  @type = type
94
84
  end
95
-
85
+
96
86
  # A convenience method for comparing anything that responds to
97
87
  # +:to_sym():+, like +String+.
98
- #
88
+ #
99
89
  # @param type [String,Symbol] the type to convert & compare against
100
90
  # @return [Boolean] +true+ if this message is of type +type+, else +false+
101
91
  def type?(type)
102
- return @type == type.to_sym()
92
+ return @type == type.to_sym
103
93
  end
104
94
  end
105
95
  end
@@ -1,23 +1,11 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Bot.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Bot is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU Lesser General Public License as published by
11
- # the Free Software Foundation, either version 3 of the License, or
12
- # (at your option) any later version.
13
- #
14
- # SSC.Bot is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- # GNU Lesser General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU Lesser General Public License
20
- # along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
@@ -25,38 +13,26 @@ require 'forwardable'
25
13
 
26
14
  require 'ssc.bot/chat_log/message_parser'
27
15
 
28
-
29
16
  module SSCBot
30
17
  class ChatLog
31
18
  ###
32
- # @author Jonathan Bradley Whited (@esotericpig)
19
+ # @author Jonathan Bradley Whited
33
20
  # @since 0.1.0
34
21
  ###
35
22
  module MessageParsable
36
23
  extend Forwardable
37
-
24
+
38
25
  MAX_NAMELEN = MessageParser::MAX_NAMELEN
39
-
40
- def_delegators(:@parser,
41
- :autoset_namelen?,:autoset_namelen=,
42
- :check_history_count,:check_history_count=,
43
- :commands,
44
- :messages,
45
- :namelen,:namelen=,
46
- :regex_cache,
47
- :store_history?,:store_history=,
48
- :strict?,:strict=,
49
-
50
- :parse,
51
-
52
- :clear_history,
53
- :reset_namelen,
54
- :store_command,
55
-
56
- :command?,
57
- )
58
-
26
+
59
27
  attr_reader :parser
28
+
29
+ (MessageParser.public_instance_methods - Class.public_instance_methods).each do |method|
30
+ name = method.to_s
31
+
32
+ next if name.start_with?('match_') || name.start_with?('parse_')
33
+
34
+ def_delegator(:@parser,method)
35
+ end
60
36
  end
61
37
  end
62
38
  end
@@ -1,23 +1,11 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Bot.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Bot is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU Lesser General Public License as published by
11
- # the Free Software Foundation, either version 3 of the License, or
12
- # (at your option) any later version.
13
- #
14
- # SSC.Bot is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- # GNU Lesser General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU Lesser General Public License
20
- # along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
@@ -30,16 +18,17 @@ require 'ssc.bot/util'
30
18
  require 'ssc.bot/chat_log/message'
31
19
  require 'ssc.bot/chat_log/messages'
32
20
 
33
-
34
21
  module SSCBot
35
22
  class ChatLog
36
23
  ###
37
- # @author Jonathan Bradley Whited (@esotericpig)
24
+ # @author Jonathan Bradley Whited
38
25
  # @since 0.1.0
39
26
  ###
40
27
  class MessageParser
28
+ extend AttrBool::Ext
29
+
41
30
  MAX_NAMELEN = 24
42
-
31
+
43
32
  attr_accessor? :autoset_namelen
44
33
  attr_accessor :check_history_count
45
34
  attr_reader :commands
@@ -48,10 +37,10 @@ class ChatLog
48
37
  attr_reader :regex_cache
49
38
  attr_accessor? :store_history
50
39
  attr_accessor? :strict
51
-
40
+
52
41
  def initialize(autoset_namelen: true,check_history_count: 5,namelen: nil,store_history: true,strict: true)
53
42
  super()
54
-
43
+
55
44
  @autoset_namelen = autoset_namelen
56
45
  @check_history_count = check_history_count
57
46
  @commands = {}
@@ -61,37 +50,37 @@ class ChatLog
61
50
  @store_history = store_history
62
51
  @strict = strict
63
52
  end
64
-
53
+
65
54
  # The Ruby interpreter should cache the args' default values,
66
55
  # so no reason to manually cache them unless a variable is involved inside.
67
- #
56
+ #
68
57
  # @example Default Format
69
58
  # 'X Name> Message'
70
- def match_player(line,type_name:,name_prefix: '',name_suffix: '> ',type_prefix: %r{..},use_namelen: true)
59
+ def match_player(line,type_name:,name_prefix: '',name_suffix: '> ',type_prefix: /../,use_namelen: true)
71
60
  cached_regex = @regex_cache[type_name]
72
-
73
- if cached_regex.nil?()
61
+
62
+ if cached_regex.nil?
74
63
  cached_regex = {}
75
64
  @regex_cache[type_name] = cached_regex
76
65
  end
77
-
78
- use_namelen &&= !@namelen.nil?()
66
+
67
+ use_namelen &&= !@namelen.nil?
79
68
  key = use_namelen ? @namelen : :no_namelen
80
69
  regex = cached_regex[key]
81
-
82
- if regex.nil?()
70
+
71
+ if regex.nil?
83
72
  name_prefix = Util.quote_str_or_regex(name_prefix)
84
73
  name_suffix = Util.quote_str_or_regex(name_suffix)
85
74
  type_prefix = Util.quote_str_or_regex(type_prefix)
86
-
75
+
87
76
  if use_namelen
88
77
  name = /.{#{@namelen}}/
89
78
  else
90
79
  name = /.*?\S/
91
80
  end
92
-
81
+
93
82
  name = Util.quote_str_or_regex(name)
94
-
83
+
95
84
  # Be careful to not use spaces ' ', but to use '\\ ' (or '\s') instead
96
85
  # because of the '/x' option.
97
86
  regex = /
@@ -99,25 +88,25 @@ class ChatLog
99
88
  #{name_prefix}(?<name>#{name})#{name_suffix}
100
89
  (?<message>.*)\z
101
90
  /x
102
-
91
+
103
92
  cached_regex[key] = regex
104
93
  end
105
-
94
+
106
95
  return regex.match(line)
107
96
  end
108
-
97
+
109
98
  def parse(line)
110
- if line.nil?()
99
+ if line.nil?
111
100
  if @strict
112
- raise ArgumentError,"invalid line{#{line.inspect()}}"
101
+ raise ArgumentError,"invalid line{#{line.inspect}}"
113
102
  else
114
103
  line = ''
115
104
  end
116
105
  end
117
-
106
+
118
107
  message = nil
119
-
120
- if !line.empty?()
108
+
109
+ if !line.empty?
121
110
  case line[0]
122
111
  when 'C'
123
112
  message = parse_chat(line)
@@ -151,64 +140,64 @@ class ChatLog
151
140
  end
152
141
  end
153
142
  end
154
-
155
- if message.nil?()
143
+
144
+ if message.nil?
156
145
  message = Message.new(line,type: :unknown)
157
146
  end
158
-
147
+
159
148
  if @store_history
160
149
  @messages << message
161
150
  end
162
-
151
+
163
152
  return message
164
153
  end
165
-
154
+
166
155
  # @example Format
167
156
  # # NOT affected by namelen.
168
157
  # 'C 1:Name> Message'
169
158
  def parse_chat(line)
170
- match = match_player(line,type_name: :chat,name_prefix: %r{(?<channel>\d+)\:},use_namelen: false)
159
+ match = match_player(line,type_name: :chat,name_prefix: /(?<channel>\d+)\:/,use_namelen: false)
171
160
  player = parse_player(line,type_name: :chat,match: match)
172
-
173
- return nil if player.nil?()
174
-
175
- channel = match[:channel].to_i()
176
-
161
+
162
+ return nil if player.nil?
163
+
164
+ channel = match[:channel].to_i
165
+
177
166
  return ChatMessage.new(line,channel: channel,name: player.name,message: player.message)
178
167
  end
179
-
168
+
180
169
  # @example Format
181
170
  # 'E Name> Message'
182
171
  def parse_freq(line)
183
172
  player = parse_player(line,type_name: :freq)
184
-
185
- return nil if player.nil?()
186
-
173
+
174
+ return nil if player.nil?
175
+
187
176
  return FreqMessage.new(line,name: player.name,message: player.message)
188
177
  end
189
-
178
+
190
179
  # @example Format
191
180
  # ' Killed.Name(100) killed by: Killer.Name'
192
181
  def parse_kill(line,match:)
193
- if match.nil?()
182
+ if match.nil?
194
183
  if @strict
195
184
  raise ParseError,"invalid kill message{#{line}}"
196
185
  else
197
186
  return nil
198
187
  end
199
188
  end
200
-
189
+
201
190
  killed = match[:killed]
202
- bounty = match[:bounty].to_i()
191
+ bounty = match[:bounty].to_i
203
192
  killer = match[:killer]
204
-
193
+
205
194
  return KillMessage.new(line,killed: killed,bounty: bounty,killer: killer)
206
195
  end
207
-
196
+
208
197
  # @example Default Format
209
198
  # 'X Name> Message'
210
199
  def parse_player(line,type_name:,match: :default)
211
- if match.nil?()
200
+ if match.nil?
212
201
  if @strict
213
202
  raise ParseError,"invalid #{type_name} message{#{line}}"
214
203
  else
@@ -218,47 +207,47 @@ class ChatLog
218
207
  # Use type_name of :player (not passed in param) for regex_cache.
219
208
  match = match_player(line,type_name: :player)
220
209
  end
221
-
210
+
222
211
  name = Util.u_lstrip(match[:name])
223
212
  message = match[:message]
224
-
225
- if name.empty?() || name.length > MAX_NAMELEN
213
+
214
+ if name.empty? || name.length > MAX_NAMELEN
226
215
  if @strict
227
216
  raise ParseError,"invalid player name for #{type_name} message{#{line}}"
228
217
  else
229
218
  return nil
230
219
  end
231
220
  end
232
-
221
+
233
222
  return PlayerMessage.new(line,type: :unknown,name: name,message: message)
234
223
  end
235
-
224
+
236
225
  # @example Format
237
226
  # 'P Name> Message'
238
227
  def parse_private(line)
239
228
  player = parse_player(line,type_name: :private)
240
-
241
- return nil if player.nil?()
242
-
229
+
230
+ return nil if player.nil?
231
+
243
232
  return PrivateMessage.new(line,name: player.name,message: player.message)
244
233
  end
245
-
234
+
246
235
  # @example Format
247
236
  # ' Name> Message'
248
237
  def parse_pub(line,match:)
249
238
  player = parse_player(line,type_name: :pub,match: match)
250
-
251
- return nil if player.nil?()
252
-
253
- cmd = Util.u_strip(player.message).downcase()
254
-
239
+
240
+ return nil if player.nil?
241
+
242
+ cmd = Util.u_strip(player.message).downcase
243
+
255
244
  if cmd.start_with?('?find')
256
- store_command(:pub,%s{?find}) # See: match_q_find?()
245
+ store_command(:pub,%s(?find)) # See: match_q_find?()
257
246
  end
258
-
247
+
259
248
  return PubMessage.new(line,name: player.name,message: player.message)
260
249
  end
261
-
250
+
262
251
  # @example Format
263
252
  # ' Not online, last seen more than 10 days ago'
264
253
  # ' Not online, last seen 9 days ago'
@@ -269,74 +258,74 @@ class ChatLog
269
258
  # ' Name is in SSCJ Devastation'
270
259
  # ' Name is in SSCC Metal Gear CTF'
271
260
  def parse_q_find(line,match:)
272
- if match.nil?()
261
+ if match.nil?
273
262
  if @strict
274
263
  raise ParseError,"invalid ?find message{#{line}}"
275
264
  else
276
265
  return nil
277
266
  end
278
267
  end
279
-
268
+
280
269
  caps = match.named_captures
281
270
  q_find = nil
282
-
271
+
283
272
  if (days = caps['days'])
284
273
  more = caps.key?('more')
285
- days = days.to_i()
286
-
274
+ days = days.to_i
275
+
287
276
  q_find = QFindMessage.new(line,find_type: :days,more: more,days: days)
288
277
  elsif (hours = caps['hours'])
289
- hours = hours.to_i()
290
-
278
+ hours = hours.to_i
279
+
291
280
  q_find = QFindMessage.new(line,find_type: :hours,hours: hours)
292
281
  elsif (player = caps['player'])
293
282
  if (arena = caps['arena'])
294
283
  private = (arena == '(Private arena)')
295
-
284
+
296
285
  q_find = QFindMessage.new(line,find_type: :arena,player: player,arena: arena,private: private)
297
286
  elsif (zone = caps['zone'])
298
287
  q_find = QFindMessage.new(line,find_type: :zone,player: player,zone: zone)
299
288
  end
300
289
  end
301
-
302
- if q_find.nil?() && @strict
290
+
291
+ if q_find.nil? && @strict
303
292
  raise ParseError,"invalid ?find message{#{line}}"
304
293
  end
305
-
294
+
306
295
  return q_find
307
296
  end
308
-
297
+
309
298
  # @example Format
310
299
  # ' Log file open: session.log'
311
300
  # ' Log file closed'
312
301
  def parse_q_log(line,match:)
313
- if match.nil?()
302
+ if match.nil?
314
303
  if @strict
315
304
  raise ParseError,"invalid ?log message{#{line}}"
316
305
  else
317
306
  return nil
318
307
  end
319
308
  end
320
-
309
+
321
310
  filename = match.named_captures['filename']
322
- log_type = filename.nil?() ? :close : :open
323
-
311
+ log_type = filename.nil? ? :close : :open
312
+
324
313
  return QLogMessage.new(line,log_type: log_type,filename: filename)
325
314
  end
326
-
315
+
327
316
  # @example Format
328
317
  # ' Message Name Length: 24'
329
318
  def parse_q_namelen(line,match:)
330
- if match.nil?()
319
+ if match.nil?
331
320
  if @strict
332
321
  raise ParseError,"invalid ?namelen message{#{line}}"
333
322
  else
334
323
  return nil
335
324
  end
336
325
  end
337
-
338
- namelen = match[:namelen].to_i()
339
-
326
+
327
+ namelen = match[:namelen].to_i
328
+
340
329
  if namelen < 1
341
330
  if @strict
342
331
  raise ParseError,"invalid namelen for ?namelen message{#{line}}"
@@ -346,105 +335,105 @@ class ChatLog
346
335
  elsif namelen > MAX_NAMELEN
347
336
  warn("namelen{#{namelen}} > max{#{MAX_NAMELEN}} for ?namelen message{#{line}}",uplevel: 0)
348
337
  end
349
-
338
+
350
339
  if @autoset_namelen
351
340
  @namelen = namelen
352
341
  end
353
-
342
+
354
343
  return QNamelenMessage.new(line,namelen: namelen)
355
344
  end
356
-
345
+
357
346
  # @example Format
358
347
  # # NOT affected by namelen.
359
348
  # 'P :Self.Name:Message'
360
349
  # 'P (Name)>Message'
361
350
  def parse_remote(line,match:)
362
- player = parse_player(line,type_name: %s{remote.private},match: match)
363
-
364
- return nil if player.nil?()
365
-
351
+ player = parse_player(line,type_name: %s(remote.private),match: match)
352
+
353
+ return nil if player.nil?
354
+
366
355
  own = (line[2] == ':')
367
356
  squad = (player.name[0] == '#')
368
-
357
+
369
358
  return RemoteMessage.new(line,
370
359
  own: own,squad: squad,
371
360
  name: player.name,message: player.message,
372
361
  )
373
362
  end
374
-
363
+
375
364
  # @example Format
376
365
  # 'T Name> Message'
377
366
  def parse_team(line)
378
367
  player = parse_player(line,type_name: :team)
379
-
380
- return nil if player.nil?()
381
-
368
+
369
+ return nil if player.nil?
370
+
382
371
  return TeamMessage.new(line,name: player.name,message: player.message)
383
372
  end
384
-
385
- def clear_history()
386
- @messages.clear()
373
+
374
+ def clear_history
375
+ @messages.clear
387
376
  end
388
-
389
- def reset_namelen()
377
+
378
+ def reset_namelen
390
379
  @namelen = nil
391
380
  end
392
-
381
+
393
382
  def store_command(type,name)
394
383
  type_hash = @commands[type]
395
-
396
- if type_hash.nil?()
384
+
385
+ if type_hash.nil?
397
386
  type_hash = {}
398
387
  @commands[type] = type_hash
399
388
  end
400
-
389
+
401
390
  type_hash[name] = @messages.length # Index of when command was found/stored
402
391
  end
403
-
392
+
404
393
  def command?(type,name,delete: true)
405
394
  return true if @check_history_count < 1
406
-
395
+
407
396
  type_hash = @commands[type]
408
-
409
- if !type_hash.nil?()
397
+
398
+ if !type_hash.nil?
410
399
  index = type_hash[name]
411
-
412
- if !index.nil?() && (@messages.length - index) <= @check_history_count
400
+
401
+ if !index.nil? && (@messages.length - index) <= @check_history_count
413
402
  type_hash.delete(name) if delete
414
-
403
+
415
404
  return true
416
405
  end
417
406
  end
418
-
407
+
419
408
  return false
420
409
  end
421
-
410
+
422
411
  # @example Format
423
412
  # ' Killed.Name(100) killed by: Killer.Name'
424
413
  def match_kill?(line)
425
414
  return false if line.length < 19 # ' N(0) killed by: N'
426
-
415
+
427
416
  return /\A (?<killed>.*?\S)\((?<bounty>\d+)\) killed by: (?<killer>.*?\S)\z/.match(line)
428
417
  end
429
-
418
+
430
419
  # @example Format
431
420
  # ' Name> Message'
432
421
  def match_pub?(line)
433
422
  return false if line.length < 5 # ' N> '
434
-
423
+
435
424
  match = match_player(line,type_name: :pub,type_prefix: ' ')
436
-
437
- if !match.nil?()
425
+
426
+ if !match.nil?
438
427
  name = Util.u_lstrip(match[:name])
439
-
440
- if name.empty?() || name.length > MAX_NAMELEN
428
+
429
+ if name.empty? || name.length > MAX_NAMELEN
441
430
  return false
442
431
  end
443
432
  end
444
-
433
+
445
434
  return match
446
435
  end
447
-
436
+
448
437
  # @example Format
449
438
  # ' Not online, last seen more than 10 days ago'
450
439
  # ' Not online, last seen 9 days ago'
@@ -456,25 +445,25 @@ class ChatLog
456
445
  # ' Name is in SSCC Metal Gear CTF'
457
446
  def match_q_find?(line)
458
447
  return false if line.length < 7 # ' N - A'
459
- return false unless command?(:pub,%s{?find})
460
-
448
+ return false unless command?(:pub,%s(?find))
449
+
461
450
  if line.start_with?(' Not online, last seen ')
462
451
  match = line.match(/(?<more>more) than (?<days>\d+) days ago\z/)
463
- match = line.match(/(?<days>\d+) days? ago\z/) if match.nil?()
464
- match = line.match(/(?<hours>\d+) hours? ago\z/) if match.nil?()
465
-
452
+ match = line.match(/(?<days>\d+) days? ago\z/) if match.nil?
453
+ match = line.match(/(?<hours>\d+) hours? ago\z/) if match.nil?
454
+
466
455
  return match
467
456
  else
468
457
  match = line.match(/\A (?<player>.+) is in (?<zone>.+)\z/)
469
- match = line.match(/\A (?<player>.+) - (?<arena>.+)\z/) if match.nil?()
470
-
458
+ match = line.match(/\A (?<player>.+) - (?<arena>.+)\z/) if match.nil?
459
+
471
460
  if match
472
461
  caps = match.named_captures
473
-
462
+
474
463
  player = caps['player']
475
-
464
+
476
465
  return false if player.length > MAX_NAMELEN
477
-
466
+
478
467
  if caps.key?('arena')
479
468
  area = caps['arena']
480
469
  elsif caps.key?('zone')
@@ -482,59 +471,59 @@ class ChatLog
482
471
  else
483
472
  return false
484
473
  end
485
-
474
+
486
475
  # If do /\A (?<player>[^[[:space:]]].+[^[[:space:]])/, then it won't
487
476
  # capture names/zones/arenas that are only 1 char long, so do this.
488
- [player[0],player[-1],area[0],area[-1]].each() do |c|
477
+ [player[0],player[-1],area[0],area[-1]].each do |c|
489
478
  if c =~ /[[:space:]]/
490
479
  return false
491
480
  end
492
481
  end
493
-
482
+
494
483
  return match
495
484
  end
496
485
  end
497
-
486
+
498
487
  return false
499
488
  end
500
-
489
+
501
490
  # @example Format
502
491
  # ' Log file open: session.log'
503
492
  # ' Log file closed'
504
493
  def match_q_log?(line)
505
494
  return false if line.length < 17
506
-
495
+
507
496
  match = /\A Log file open: (?<filename>.+)\z/.match(line)
508
- match = /\A Log file closed\z/.match(line) if match.nil?()
509
-
497
+ match = /\A Log file closed\z/.match(line) if match.nil?
498
+
510
499
  return match
511
500
  end
512
-
501
+
513
502
  # @example Format
514
503
  # ' Message Name Length: 24'
515
504
  def match_q_namelen?(line)
516
505
  return false if line.length < 24 # '...: 0'
517
506
  return false if line[21] != ':'
518
-
507
+
519
508
  return /\A Message Name Length: (?<namelen>\d+)\z/.match(line)
520
509
  end
521
-
510
+
522
511
  # @example Format
523
512
  # # NOT affected by namelen.
524
513
  # 'P :Self.Name:Message'
525
514
  # 'P (Name)>Message'
526
515
  def match_remote?(line)
527
516
  return false if line.length < 5 # 'P :N:'
528
-
517
+
529
518
  case line[2]
530
519
  when ':'
531
- return match_player(line,type_name: %s{remote.out},
520
+ return match_player(line,type_name: %s(remote.out),
532
521
  name_prefix: ':',name_suffix: ':',use_namelen: false)
533
522
  when '('
534
- return match_player(line,type_name: %s{remote.in},
523
+ return match_player(line,type_name: %s(remote.in),
535
524
  name_prefix: '(',name_suffix: ')>',use_namelen: false)
536
525
  end
537
-
526
+
538
527
  return false
539
528
  end
540
529
  end