ssc.bot 0.1.1 → 0.2.0

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.
@@ -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