File Coverage

blib/lib/Games/EverQuest/LogLineParser.pm
Criterion Covered Total %
statement 43 53 81.1
branch 10 14 71.4
condition 6 6 100.0
subroutine 9 11 81.8
pod 4 6 66.6
total 72 90 80.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Games::EverQuest::LogLineParser - Perl extension for parsing lines from the
4             EverQuest log file.
5              
6             =head1 SYNOPSIS
7              
8             use Games::EverQuest::LogLineParser;
9              
10             my $eqlog_file = 'c:/everquest/eqlog_Soandso_veeshan.txt';
11              
12             open(my $eq_log_fh, $eqlog_file) || die "$eqlog_file: $!";
13              
14             while (<$eq_log_fh>)
15             {
16             my $parsed_line = parse_eq_line($_);
17             next unless $parsed_line;
18             do_something($parsed_line);
19             }
20              
21             =head1 DESCRIPTION
22              
23             C provides functions related to parsing the
24             interesting bits from an EverQuest log file.
25              
26             =head2 Functions
27              
28             =over 4
29              
30             =item C
31              
32             Returns a hash ref, containing variable keys depending on the determined line
33             type of the given log line. If the line was not recognized, then false is
34             returned.
35              
36             Two keys that will always be present, if the line was recognized, are
37             C and C. The first will contain the time string from
38             the line, while the latter will be a string indicating how the line was
39             classified. A given C hash ref, will always contain the same keys,
40             though some of the values may be C or empty.
41              
42             For a list of line types (and associated keys) see the L section
43             below.
44              
45             =item C
46              
47             If you expect a line to be of a certain type, and want to test or parse it as
48             that type, you can use this function. Call it with the expected line type
49             and the log line to test or parse.
50              
51             Returns a hash ref, containing variable keys depending on the type of line
52             that was passed. If the line could not be parsed as the given line type,
53             then false is returned.
54              
55             Two keys that will always be present, if the line was recognized, are
56             C and C. The first will contain the time string from
57             the line, while the latter will be a string indicating how the line was
58             classified. A given C hash ref, will always contain the same keys,
59             though some of the values may be C or empty.
60              
61             For a list of line types (and associated keys) see the L section
62             below.
63              
64             =item C{'time_stamp'})>
65              
66             Given the C value from a parsed line, returns a hash ref with the
67             following structure:
68              
69             ## sample input [Mon Oct 13 00:42:36 2003]
70             {
71             day => 'Mon',
72             month => 'Oct',
73             date => '13',
74             hour => '00',
75             min => '42',
76             sec => '36',
77             year => '2003',
78             }
79              
80             =item C
81              
82             Returns a list of all possible line types for the hash refs that are returned by
83             C.
84              
85             =item C
86              
87             Returns a list of all possible keys for the hash refs that are returned by
88             C.
89              
90             =back
91              
92             =head1 EXPORT
93              
94             By default the C, C, C,
95             C and C subroutines are exported.
96              
97             =head1 SCRIPTS
98              
99             Several scripts have been included as both tools and examples. All default to
100             STDOUT for output, but accept an optional file name for the second argument
101             as well.
102              
103             =over 4
104              
105             =item eqlog2csv.pl [output_file]
106              
107             Converts an EverQuest log file into a CSV file (uses '|' character rather than commas).
108              
109             =item eqlog_line_type_frequency.pl [output_file]
110              
111             Reports the frequency of all line types seen in the given EverQuest log file.
112              
113             =item eqlog_unrecognized_lines.pl [output_file]
114              
115             Prints unrecognized lines from an EverQuest log file.
116              
117             =back
118              
119             =head1 LINE TYPES
120              
121             =over 4
122              
123             =cut
124              
125             package Games::EverQuest::LogLineParser;
126              
127 1     1   22962 use 5.006;
  1         3  
  1         32  
128 1     1   4 use strict;
  1         2  
  1         35  
129 1     1   4 use warnings;
  1         6  
  1         29  
130              
131 1     1   5 use Carp;
  1         1  
  1         5646  
132              
133             require Exporter;
134              
135             our @ISA = qw/ Exporter /;
136              
137             our @EXPORT = qw/ parse_eq_line parse_eq_line_type parse_eq_time_stamp
138             all_possible_line_types all_possible_keys /;
139              
140             our @EXPORT_OK = qw( coins_to_platinum );
141              
142             our $VERSION = '0.09';
143              
144             my (@line_types, %line_types);
145              
146              
147             # $BAZAAR_PRICE is used in many bzrlog regexps.
148             my $BAZAAR_PRICE = qr/(?: (\d+)p)?(?: (\d+)g)?(?: (\d+)s)?(?: (\d+)c)?/;
149              
150             ## returns a parsed line hash ref if the line is understood, else false
151             sub parse_eq_line
152             {
153 71     71 1 35571 my ($line) = @_;
154              
155 71 50       197 return unless length $line > 28;
156              
157 71         115 $line =~ tr/\r\n//d;
158              
159 71         170 my $time_stamp = substr($line, 0, 27, '');
160              
161 71         115 for my $line_type (@line_types)
162             {
163 2153 100       8672 if (my @parts = $line =~ $line_type->{'rx'})
164             {
165 71         215 my $parsed_line = $line_type->{'handler'}->(@parts);
166 71         143 $parsed_line->{'time_stamp'} = $time_stamp;
167 71 100       173 if(exists $parsed_line->{platinum}) {
168 9         56 $parsed_line->{value} = coins_to_platinum(%$parsed_line);
169             }
170 71         239 return $parsed_line;
171             }
172             }
173              
174 0         0 return;
175              
176             }
177              
178             ## returns a parsed line hash ref if the line is of the given type, else false
179             sub parse_eq_line_type
180             {
181 71     71 1 35709 my ($line_type_name, $line) = @_;
182              
183 71 50       200 confess "invalid line type ($line_type_name)"
184             unless exists $line_types{$line_type_name};
185              
186 71 50       167 return unless length $line > 28;
187              
188 71         114 $line =~ tr/\r\n//d;
189              
190 71         160 my $time_stamp = substr($line, 0, 27, '');
191              
192 71 50       694 if (my @parts = $line =~ $line_types{$line_type_name}->{'rx'})
193             {
194 71         197 my $parsed_line = $line_types{$line_type_name}->{'handler'}->(@parts);
195 71         141 $parsed_line->{'time_stamp'} = $time_stamp;
196 71 100       160 if(exists $parsed_line->{platinum}) {
197 9         37 $parsed_line->{value} = coins_to_platinum(%$parsed_line);
198             }
199 71         249 return $parsed_line;
200             }
201              
202 0         0 return;
203              
204             }
205              
206             ## parses the time_stamp into a hash ref
207             ## sample input [Mon Oct 13 00:42:36 2003]
208             sub parse_eq_time_stamp
209             {
210 1     1 0 439 my ($time_stamp) = @_;
211              
212 1         3 $time_stamp =~ tr/][:/ /;
213              
214 1         5 my ($day, $month, $date, $hour, $min, $sec, $year) = split ' ', $time_stamp;
215              
216             return
217             {
218 1         9 day => $day,
219             month => $month,
220             date => $date,
221             hour => $hour,
222             min => $min,
223             sec => $sec,
224             year => $year
225             };
226              
227             }
228              
229             ## returns all possible line types
230             sub all_possible_line_types
231             {
232              
233 0     0 1 0 return map { $_->{'handler'}->()->{'line_type'} } @line_types;
  0         0  
234              
235             }
236              
237             ## returns all possible keys from the set of all parsed line hash refs
238             ## 'time_stamp' and 'value' are special-cased, as they're automatically
239             ## added after the line is parsed.
240              
241             sub all_possible_keys
242             {
243              
244 0     0 1 0 my %all_keys;
245              
246 0         0 for my $line_type (@line_types)
247             {
248 0         0 for my $key (keys %{ $line_type->{'handler'}->() })
  0         0  
249             {
250 0         0 $all_keys{$key}++;
251             }
252             }
253              
254 0         0 return ( sort (keys %all_keys, 'time_stamp', 'value') );
255              
256             }
257              
258             ## Converts a list of coins into a decimalised platinum figure.
259             ## eg: 12pp 5gp 3sp 6cp = 12.536
260             sub coins_to_platinum {
261 18     18 0 87 my %coins = @_;
262              
263             return $coins{platinum} +
264             ($coins{gold } || 0)/ 10 +
265             ($coins{silver } || 0)/ 100 +
266 18   100     216 ($coins{copper } || 0)/1000;
      100        
      100        
267             }
268              
269             =item MELEE_DAMAGE
270              
271             input line:
272              
273             [Mon Oct 13 00:42:36 2003] You slash a Bloodguard crypt sentry for 88 points of damage.
274              
275             output hash ref:
276              
277             {
278             line_type => 'MELEE_DAMAGE',
279             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
280             attacker => 'You',
281             attack => 'slash',
282             attackee => 'A Bloodguard crypt sentry',
283             amount => '88',
284             };
285              
286             comments:
287              
288             none
289              
290             =cut
291              
292             push @line_types,
293             {
294             rx => qr/\A(.+?) (slash|hit|kick|pierce|bash|punch|crush|bite|maul|backstab|claw|strike)(?:s|es)? (?!by non-melee)(.+?) for (\d+) points? of damage\.\z/,
295             handler => sub
296             {
297             my ($attacker, $attack, $attackee, $amount) = @_;
298             return
299             {
300             line_type => 'MELEE_DAMAGE',
301             attacker => $attacker,
302             attack => $attack,
303             attackee => $attackee,
304             amount => $amount,
305             };
306             }
307              
308             };
309              
310             =item YOU_MISS_MOB
311              
312             input line:
313              
314             [Mon Oct 13 00:42:36 2003] You try to kick a Bloodguard crypt sentry, but miss!
315              
316             output hash ref:
317              
318             {
319             line_type => 'YOU_MISS_MOB',
320             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
321             attack => 'slash',
322             attackee => 'A Bloodguard crypt sentry',
323             };
324              
325             comments:
326              
327             none
328              
329             =cut
330              
331             push @line_types,
332             {
333             rx => qr/\AYou try to (\w+) (.+?), but miss!\z/,
334             handler => sub
335             {
336             my ($attack, $attackee) = @_;
337             return
338             {
339             line_type => 'YOU_MISS_MOB',
340             attack => $attack,
341             attackee => $attackee,
342             };
343             }
344             };
345              
346             =item OTHER_MISSES
347              
348             input line:
349              
350             [Mon Oct 13 00:42:36 2003] A Bloodguard crypt sentry tries to hit YOU, but misses!
351              
352             output hash ref:
353              
354             {
355             line_type => 'OTHER_MISSES',
356             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
357             attacker => 'A Bloodguard crypt sentry',
358             attack => 'hit',
359             attackee => 'YOU',
360             };
361              
362             input line:
363              
364             [Mon Oct 13 00:42:36 2003] Soandso tries to slash a Bloodguard crypt sentry, but misses!
365              
366             output hash ref:
367              
368             {
369             line_type => 'OTHER_MISSES',
370             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
371             attacker => 'Soandso',
372             attack => 'slash',
373             attackee => 'a Bloodguard crypt sentry',
374             };
375              
376             comments:
377              
378             none
379              
380             =cut
381              
382             push @line_types,
383             {
384             rx => qr/\A(.+?) tries to (\w+) (.+?), but misses!\z/,
385             handler => sub
386             {
387             my ($attacker, $attack, $attackee) = @_;
388             return
389             {
390             line_type => 'OTHER_MISSES',
391             attacker => $attacker,
392             attack => $attack,
393             attackee => $attackee,
394             };
395             }
396             };
397              
398             =item FACTION_HIT
399              
400             input line:
401              
402             [Mon Oct 13 00:42:36 2003] Your faction standing with Loyals got worse.
403              
404             output hash ref:
405              
406             {
407             line_type => 'FACTION_HIT',
408             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
409             faction_group => 'Loyals',
410             faction_change => 'worse',
411             };
412              
413             comments:
414              
415             none
416              
417             =cut
418              
419             push @line_types,
420             {
421             rx => qr/\AYour faction standing with (.+?) got (better|worse)\.\z/,
422             handler => sub
423             {
424             my ($faction_group, $faction_change) = @_;
425             return
426             {
427             line_type => 'FACTION_HIT',
428             faction_group => $faction_group,
429             faction_change => $faction_change,
430             };
431             }
432              
433             };
434              
435             =item YOU_REPEL_HIT
436              
437             input line:
438              
439             [Mon Oct 13 00:42:36 2003] A Bloodguard crypt sentry tries to hit YOU, but YOU parry!
440              
441             output hash ref:
442              
443             {
444             line_type => 'YOU_REPEL_HIT',
445             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
446             attacker => 'A Bloodguard crypt sentry',
447             attack => 'hit',
448             repel => 'parry',
449             };
450              
451             comments:
452              
453             none
454              
455             =cut
456              
457             push @line_types,
458             {
459             rx => qr/\A(.+?) tries to (\w+) YOU, but YOU (\w+)!\z/,
460             handler => sub
461             {
462             my ($attacker, $attack, $repel) = @_;
463             return
464             {
465             line_type => 'YOU_REPEL_HIT',
466             attacker => $attacker,
467             attack => $attack,
468             repel => $repel,
469             };
470             }
471              
472             };
473              
474             =item MOB_REPELS_HIT
475              
476             input line:
477              
478             [Mon Oct 13 00:42:36 2003] You try to slash a Bloodguard crypt sentry, but a Bloodguard crypt sentry ripostes!
479              
480             output hash ref:
481              
482             {
483             line_type => 'MOB_REPELS_HIT',
484             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
485             attack => 'slash',
486             attackee => 'A Bloodguard crypt sentry',
487             repel => 'riposte',
488             };
489              
490             comments:
491              
492             none
493              
494             =cut
495              
496             push @line_types,
497             {
498             rx => qr/\AYou try to (\w+) (.+?), but \2 (\w+)s!\z/,
499             handler => sub
500             {
501             my ($attack, $attackee, $repel) = @_;
502             $repel ||= '';
503             $repel = 'parry' if $repel eq 'parrie';
504             return
505             {
506             line_type => 'MOB_REPELS_HIT',
507             attack => $attack,
508             attackee => $attackee,
509             repel => $repel,
510             };
511             }
512              
513             };
514              
515             =item SLAIN_BY_YOU
516              
517             input line:
518              
519             [Mon Oct 13 00:42:36 2003] You have slain a Bloodguard crypt sentry!
520              
521             output hash ref:
522              
523             {
524             line_type => 'SLAIN_BY_YOU',
525             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
526             slayee => 'A Bloodguard crypt sentry',
527             };
528              
529             comments:
530              
531             none
532              
533             =cut
534              
535             push @line_types,
536             {
537             rx => qr/\AYou have slain (.+?)!\z/,
538             handler => sub
539             {
540             my ($slayee) = @_;
541             return
542             {
543             line_type => 'SLAIN_BY_YOU',
544             slayee => $slayee,
545             };
546             }
547              
548             };
549              
550             =item SKILL_UP
551              
552             input line:
553              
554             [Mon Oct 13 00:42:36 2003] You have become better at Abjuration! (222)
555              
556             output hash ref:
557              
558             {
559             line_type => 'SKILL_UP',
560             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
561             skill_upped => 'Abjuration',
562             skill_value => '222',
563             };
564              
565             comments:
566              
567             none
568              
569             =cut
570              
571             push @line_types,
572             {
573             rx => qr/\AYou have become better at (.+?)! \((\d+)\)\z/,
574             handler => sub
575             {
576             my ($skill_upped, $skill_value) = @_;
577             return
578             {
579             line_type => 'SKILL_UP',
580             skill_upped => $skill_upped,
581             skill_value => $skill_value,
582             };
583             }
584              
585             };
586              
587             =item SLAIN_BY_OTHER
588              
589             input line:
590              
591             [Mon Oct 13 00:42:36 2003] a Bloodguard crypt sentry has been slain by Soandso!
592              
593             output hash ref:
594              
595             {
596             line_type => 'SLAIN_BY_OTHER',
597             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
598             slayee => 'A Bloodguard crypt sentry',
599             slayer => 'Soandso',
600             };
601              
602             comments:
603              
604             none
605              
606             =cut
607              
608             push @line_types,
609             {
610             rx => qr/\A(.+?) has been slain by (.+?)!\z/,
611             handler => sub
612             {
613             my ($slayee, $slayer) = @_;
614             return
615             {
616             line_type => 'SLAIN_BY_OTHER',
617             slayee => $slayee,
618             slayer => $slayer,
619             };
620             }
621              
622             };
623              
624             =item CORPSE_MONEY
625              
626             input line:
627              
628             [Mon Oct 13 00:42:36 2003] You receive 67 platinum, 16 gold, 20 silver and 36 copper from the corpse.
629              
630             output hash ref:
631              
632             {
633             line_type => 'CORPSE_MONEY',
634             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
635             platinum => '67',
636             gold => '16',
637             silver => '20',
638             copper => '36',
639             value => 68.8360,
640             };
641              
642             comments:
643              
644             none
645              
646             =cut
647              
648             push @line_types,
649             {
650             rx => qr/\AYou receive (.+?)from the corpse\.\z/,
651             handler => sub
652             {
653             my ($money) = @_;
654             $money ||= '';
655             $money =~ s/and//;
656             my %moneys = reverse split '[ ,]+', $money;
657             return
658             {
659             line_type => 'CORPSE_MONEY',
660             platinum => $moneys{'platinum'} || 0,
661             gold => $moneys{'gold'} || 0,
662             silver => $moneys{'silver'} || 0,
663             copper => $moneys{'copper'} || 0,
664             };
665             }
666              
667             };
668              
669             =item DAMAGE_SHIELD
670              
671             input line:
672              
673             [Mon Oct 13 00:42:36 2003] a Bloodguard crypt sentry was hit by non-melee for 8 points of damage.
674              
675             output hash ref:
676              
677             {
678             line_type => 'DAMAGE_SHIELD',
679             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
680             attacker => 'A Bloodguard crypt sentry',
681             amount => '8',
682             };
683              
684             comments:
685              
686             none
687              
688             =cut
689              
690             push @line_types,
691             {
692             rx => qr/\A(.+?) was hit by non-melee for (\d+) points? of damage\.\z/,
693             handler => sub
694             {
695             my ($attacker, $amount) = @_;
696             return
697             {
698             line_type => 'DAMAGE_SHIELD',
699             attacker => $attacker,
700             amount => $amount,
701             };
702             }
703              
704             };
705              
706             =item DIRECT_DAMAGE
707              
708             input line:
709              
710             [Mon Oct 13 00:42:36 2003] Soandso hit a Bloodguard crypt sentry for 300 points of non-melee damage.
711              
712             output hash ref:
713              
714             {
715             line_type => 'DIRECT_DAMAGE',
716             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
717             attacker => 'Soandso',
718             attackee => 'A Bloodguard crypt sentry',
719             amount => '300',
720             };
721              
722             comments:
723              
724             none
725              
726             =cut
727              
728             push @line_types,
729             {
730             rx => qr/\A(.+?) hit (.+?) for (\d+) points? of non-melee damage\.\z/,
731             handler => sub
732             {
733             my ($attacker, $attackee, $amount) = @_;
734             return
735             {
736             line_type => 'DIRECT_DAMAGE',
737             attacker => $attacker,
738             attackee => $attackee,
739             amount => $amount,
740             };
741             }
742              
743             };
744              
745             =item DAMAGE_OVER_TIME
746              
747             input line:
748              
749             [Mon Oct 13 00:42:36 2003] A Bloodguard crypt sentry has taken 3 damage from your Flame Lick.
750              
751             output hash ref:
752              
753             {
754             line_type => 'DAMAGE_OVER_TIME',
755             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
756             attackee => 'A Bloodguard crypt sentry',
757             amount => '3',
758             spell => 'Flame Lick',
759             };
760              
761             comments:
762              
763             none
764              
765             =cut
766              
767             push @line_types,
768             {
769             rx => qr/\A(.+?) has taken (\d+) damage from your (.+?)\.\z/,
770             handler => sub
771             {
772             my ($attackee, $amount, $spell) = @_;
773             return
774             {
775             line_type => 'DAMAGE_OVER_TIME',
776             attackee => $attackee,
777             amount => $amount,
778             spell => $spell,
779             };
780             }
781              
782             };
783              
784             =item LOOT_ITEM
785              
786             input line:
787              
788             [Mon Oct 13 00:42:36 2003] --You have looted a Flawed Green Shard of Might.--
789              
790             output hash ref:
791              
792             {
793             line_type => 'LOOT_ITEM',
794             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
795             looter => 'You',
796             item => 'Flawed Green Shard of Might',
797             };
798              
799             input line:
800              
801             [Mon Oct 13 00:42:36 2003] --Soandso has looted a Tears of Prexus.--
802              
803             output hash ref:
804              
805             {
806             line_type => 'LOOT_ITEM',
807             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
808             looter => 'Soandso',
809             item => 'Tears of Prexus',
810             };
811              
812             comments:
813              
814             none
815              
816             =cut
817              
818             push @line_types,
819             {
820             rx => qr/\A--(\S+) (?:has|have) looted a (.+?)\.--\z/,
821             handler => sub
822             {
823             my ($looter, $item) = @_;
824             return
825             {
826             line_type => 'LOOT_ITEM',
827             looter => $looter,
828             item => $item,
829             };
830             }
831              
832             };
833              
834             =item BUY_ITEM
835              
836             input line:
837              
838             [Mon Oct 13 00:42:36 2003] You give 1 gold 2 silver 5 copper to Cavalier Aodus.
839              
840             output hash ref:
841              
842             {
843             line_type => 'BUY_ITEM',
844             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
845             platinum => 0,
846             gold => '1',
847             silver => '2',
848             copper => '4',
849             value => 0.124,
850             merchant => 'Cavalier Aodus',
851             };
852              
853             comments:
854              
855             none
856              
857             =cut
858              
859             push @line_types,
860             {
861             rx => qr/\AYou give (.+?) to (.+?)\.\z/,
862             handler => sub
863             {
864             my ($money, $merchant) = @_;
865             $money ||= '';
866             my %moneys = reverse split ' ', $money;
867             return
868             {
869             line_type => 'BUY_ITEM',
870             platinum => $moneys{'platinum'} || 0,
871             gold => $moneys{'gold'} || 0,
872             silver => $moneys{'silver'} || 0,
873             copper => $moneys{'copper'} || 0,
874             merchant => $merchant,
875             };
876             }
877              
878             };
879              
880             =item ENTERED_ZONE
881              
882             input line:
883              
884             [Mon Oct 13 00:42:36 2003] You have entered The Greater Faydark.
885              
886             output hash ref:
887              
888             {
889             line_type => 'ENTERED_ZONE',
890             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
891             zone => 'The Greater Faydark',
892             };
893              
894             comments:
895              
896             none
897              
898             =cut
899              
900             push @line_types,
901             {
902             rx => qr/\AYou have entered (.+?)\.\z/,
903             handler => sub
904             {
905             my ($zone) = @_;
906             return
907             {
908             line_type => 'ENTERED_ZONE',
909             zone => $zone,
910             };
911             }
912              
913             };
914              
915             =item SELL_ITEM
916              
917             input line:
918              
919             [Mon Oct 13 00:42:36 2003] You receive 120 platinum from Magus Delin for the Fire Emerald Ring(s).
920              
921             output hash ref:
922              
923             {
924             line_type => 'SELL_ITEM',
925             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
926             platinum => '120',
927             gold => 0,
928             silver => 0,
929             copper => 0,
930             value => 120.000,
931             merchant => 'Magus Delin',
932             item => 'Fire Emerald Ring',
933             };
934              
935             comments:
936              
937             none
938              
939             =cut
940              
941             push @line_types,
942             {
943             rx => qr/\AYou receive (.+?) from (.+?) for the (.+?)\(s\)\.\z/,
944             handler => sub
945             {
946             my ($money, $merchant, $item) = @_;
947             $money ||= '';
948             my %moneys = reverse split ' ', $money;
949             return
950             {
951             line_type => 'SELL_ITEM',
952             platinum => $moneys{'platinum'} || 0,
953             gold => $moneys{'gold'} || 0,
954             silver => $moneys{'silver'} || 0,
955             copper => $moneys{'copper'} || 0,
956             merchant => $merchant,
957             item => $item,
958             };
959             }
960             };
961              
962             =item SPLIT_MONEY
963              
964             input line:
965              
966             [Mon Oct 13 00:42:36 2003] You receive 163 platinum, 30 gold, 25 silver and 33 copper as your split.
967              
968             output hash ref:
969              
970             {
971             line_type => 'SPLIT_MONEY',
972             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
973             platinum => '163',
974             gold => '30',
975             silver => '25',
976             copper => '33',
977             value => 166.2830,
978             };
979              
980             comments:
981              
982             none
983              
984             =cut
985              
986             push @line_types,
987             {
988             rx => qr/\AYou receive (.+?) as your split\.\z/,
989             handler => sub
990             {
991             my ($money) = @_;
992             $money ||= '';
993             $money =~ s/and//;
994             my %moneys = reverse split '[ ,]+', $money;
995             return
996             {
997             line_type => 'SPLIT_MONEY',
998             platinum => $moneys{'platinum'} || 0,
999             gold => $moneys{'gold'} || 0,
1000             silver => $moneys{'silver'} || 0,
1001             copper => $moneys{'copper'} || 0,
1002             };
1003             }
1004              
1005             };
1006              
1007             =item YOU_SLAIN
1008              
1009             input line:
1010              
1011             [Mon Oct 13 00:42:36 2003] You have been slain by a Bloodguard crypt sentry!
1012              
1013             output hash ref:
1014              
1015             {
1016             line_type => 'YOU_SLAIN',
1017             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1018             slayer => 'A Bloodguard crypt sentry',
1019             };
1020              
1021             comments:
1022              
1023             none
1024              
1025             =cut
1026              
1027             push @line_types,
1028             {
1029             rx => qr/\AYou have been slain by (.+?)!\z/,
1030             handler => sub
1031             {
1032             my ($slayer) = @_;
1033             return
1034             {
1035             line_type => 'YOU_SLAIN',
1036             slayer => $slayer,
1037             };
1038             }
1039              
1040             };
1041              
1042             =item TRACKING_MOB
1043              
1044             input line:
1045              
1046             [Mon Oct 13 00:42:36 2003] You begin tracking a Bloodguard crypt sentry.
1047              
1048             output hash ref:
1049              
1050             {
1051             line_type => 'TRACKING_MOB',
1052             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1053             trackee => 'A Bloodguard crypt sentry',
1054             };
1055              
1056             comments:
1057              
1058             none
1059              
1060             =cut
1061              
1062             push @line_types,
1063             {
1064             rx => qr/\AYou begin tracking (.+?)\.\z/,
1065             handler => sub
1066             {
1067             my ($trackee) = @_;
1068             return
1069             {
1070             line_type => 'TRACKING_MOB',
1071             trackee => $trackee,
1072             };
1073             }
1074              
1075             };
1076              
1077             =item YOU_CAST
1078              
1079             input line:
1080              
1081             [Mon Oct 13 00:42:36 2003] You begin casting Ensnaring Roots.
1082              
1083             output hash ref:
1084              
1085             {
1086             line_type => 'YOU_CAST',
1087             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1088             spell => 'Ensnaring Roots',
1089             };
1090              
1091             comments:
1092              
1093             none
1094              
1095             =cut
1096              
1097             push @line_types,
1098             {
1099             rx => qr/\AYou begin casting (.+?)\.\z/,
1100             handler => sub
1101             {
1102             my ($spell) = @_;
1103             return
1104             {
1105             line_type => 'YOU_CAST',
1106             spell => $spell,
1107             };
1108             }
1109              
1110             };
1111              
1112             =item SPELL_RESISTED
1113              
1114             input line:
1115              
1116             [Mon Oct 13 00:42:36 2003] Your target resisted the Ensnaring Roots spell.
1117              
1118             output hash ref:
1119              
1120             {
1121             line_type => 'SPELL_RESISTED',
1122             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1123             spell => 'Ensnaring Roots',
1124             };
1125              
1126             comments:
1127              
1128             none
1129              
1130             =cut
1131              
1132             push @line_types,
1133             {
1134             rx => qr/\AYour target resisted the (.+?) spell\.\z/,
1135             handler => sub
1136             {
1137             my ($spell) = @_;
1138             return
1139             {
1140             line_type => 'SPELL_RESISTED',
1141             spell => $spell,
1142             };
1143             }
1144              
1145             };
1146              
1147             =item FORGET_SPELL
1148              
1149             input line:
1150              
1151             [Mon Oct 13 00:42:36 2003] You forget Ensnaring Roots.
1152              
1153             output hash ref:
1154              
1155             {
1156             line_type => 'FORGET_SPELL',
1157             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1158             spell => 'Ensnaring Roots',
1159             };
1160              
1161             comments:
1162              
1163             none
1164              
1165             =cut
1166              
1167             push @line_types,
1168             {
1169             rx => qr/\AYou forget (.+?)\.\z/,
1170             handler => sub
1171             {
1172             my ($spell) = @_;
1173             return
1174             {
1175             line_type => 'FORGET_SPELL',
1176             spell => $spell,
1177             };
1178             }
1179              
1180             };
1181              
1182             =item MEMORIZE_SPELL
1183              
1184             input line:
1185              
1186             [Mon Oct 13 00:42:36 2003] You have finished memorizing Ensnaring Roots.
1187              
1188             output hash ref:
1189              
1190             {
1191             line_type => 'MEMORIZE_SPELL',
1192             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1193             spell => 'Ensnaring Roots',
1194             };
1195              
1196             comments:
1197              
1198             none
1199              
1200             =cut
1201              
1202             push @line_types,
1203             {
1204             rx => qr/\AYou have finished memorizing (.+?)\.\z/,
1205             handler => sub
1206             {
1207             my ($spell) = @_;
1208             return
1209             {
1210             line_type => 'MEMORIZE_SPELL',
1211             spell => $spell,
1212             };
1213             }
1214              
1215             };
1216              
1217             =item YOU_FIZZLE
1218              
1219             input line:
1220              
1221             [Mon Oct 13 00:42:36 2003] Your spell fizzles!
1222              
1223             output hash ref:
1224              
1225             {
1226             line_type => 'YOU_FIZZLE',
1227             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1228             };
1229              
1230             comments:
1231              
1232             none
1233              
1234             =cut
1235              
1236             push @line_types,
1237             {
1238             rx => qr/\AYour spell fizzles!\z/,
1239             handler => sub
1240             {
1241             return
1242             {
1243             line_type => 'YOU_FIZZLE',
1244             };
1245             }
1246              
1247             };
1248              
1249             =item LOCATION
1250              
1251             input line:
1252              
1253             [Mon Oct 13 00:42:36 2003] Your Location is -63.20, 3846.55, -42.76
1254              
1255             output hash ref:
1256              
1257             {
1258             line_type => 'LOCATION',
1259             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1260             coord_1 => '-63.20',
1261             coord_2 => '3846.55',
1262             coord_3 => '-42.76',
1263             };
1264              
1265             comments:
1266              
1267             none
1268              
1269             =cut
1270              
1271             push @line_types,
1272             {
1273             rx => qr/\AYour Location is (.+?)\z/,
1274             handler => sub
1275             {
1276             my ($location_coords) = @_;
1277             $location_coords ||= '';
1278             my @coords = split /[\s,]+/, $location_coords;
1279             return
1280             {
1281             line_type => 'LOCATION',
1282             coord_1 => $coords[0],
1283             coord_2 => $coords[1],
1284             coord_3 => $coords[2],
1285             };
1286             }
1287              
1288             };
1289              
1290             =item YOU_SAY
1291              
1292             input line:
1293              
1294             [Mon Oct 13 00:42:36 2003] You say, 'thanks!'
1295              
1296             output hash ref:
1297              
1298             {
1299             line_type => 'YOU_SAY',
1300             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1301             spoken => 'thanks!',
1302             };
1303              
1304             comments:
1305              
1306             none
1307              
1308             =cut
1309              
1310             push @line_types,
1311             {
1312             rx => qr/\AYou say, '(.+)'\z/,
1313             handler => sub
1314             {
1315             my ($spoken) = @_;
1316             return
1317             {
1318             line_type => 'YOU_SAY',
1319             spoken => $spoken,
1320             };
1321             }
1322              
1323             };
1324              
1325             =item YOU_OOC
1326              
1327             input line:
1328              
1329             [Mon Oct 13 00:42:36 2003] You say out of character, 'one potato, two potato'
1330              
1331             output hash ref:
1332              
1333             {
1334             line_type => 'YOU_OOC',
1335             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1336             spoken => 'one potato, two potato',
1337             };
1338              
1339             comments:
1340              
1341             none
1342              
1343             =cut
1344              
1345             push @line_types,
1346             {
1347             rx => qr/\AYou say out of character, '(.+)'\z/,
1348             handler => sub
1349             {
1350             my ($spoken) = @_;
1351             return
1352             {
1353             line_type => 'YOU_OOC',
1354             spoken => $spoken,
1355             };
1356             }
1357              
1358             };
1359              
1360             =item YOU_SHOUT
1361              
1362             input line:
1363              
1364             [Mon Oct 13 00:42:36 2003] You shout, 'one potato, two potato'
1365              
1366             output hash ref:
1367              
1368             {
1369             line_type => 'YOU_SHOUT',
1370             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1371             spoken => 'one potato, two potato',
1372             };
1373              
1374             comments:
1375              
1376             none
1377              
1378             =cut
1379              
1380             push @line_types,
1381             {
1382             rx => qr/\AYou shout, '(.+)'\z/,
1383             handler => sub
1384             {
1385             my ($spoken) = @_;
1386             return
1387             {
1388             line_type => 'YOU_SHOUT',
1389             spoken => $spoken,
1390             };
1391             }
1392              
1393             };
1394              
1395             =item YOU_AUCTION
1396              
1397             input line:
1398              
1399             [Mon Oct 13 00:42:36 2003] You auction, 'one potato, two potato'
1400              
1401             output hash ref:
1402              
1403             {
1404             line_type => 'YOU_AUCTION',
1405             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1406             spoken => 'one potato, two potato',
1407             };
1408              
1409             comments:
1410              
1411             none
1412              
1413             =cut
1414              
1415             push @line_types,
1416             {
1417             rx => qr/\AYou auction, '(.+)'\z/,
1418             handler => sub
1419             {
1420             my ($spoken) = @_;
1421             return
1422             {
1423             line_type => 'YOU_AUCTION',
1424             spoken => $spoken,
1425             };
1426             }
1427              
1428             };
1429              
1430             =item OTHER_SAYS
1431              
1432             input line:
1433              
1434             [Mon Oct 13 00:42:36 2003] Soandso says, 'I aim to please :)'
1435              
1436             output hash ref:
1437              
1438             {
1439             line_type => 'OTHER_SAYS',
1440             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1441             speaker => 'Soandso',
1442             spoken => 'I aim to please :)',
1443             };
1444              
1445             comments:
1446              
1447             none
1448              
1449             =cut
1450              
1451             push @line_types,
1452             {
1453             rx => qr/\A(.+?) says,? '(.+)'\z/,
1454             handler => sub
1455             {
1456             my ($speaker, $spoken) = @_;
1457             return
1458             {
1459             line_type => 'OTHER_SAYS',
1460             speaker => $speaker,
1461             spoken => $spoken,
1462             };
1463             }
1464              
1465             };
1466              
1467             =item YOU_TELL_OTHER
1468              
1469             input line:
1470              
1471             [Mon Oct 13 00:42:36 2003] You told Soandso, 'lol, i was waiting for that =)'
1472              
1473             output hash ref:
1474              
1475             {
1476             line_type => 'YOU_TELL_OTHER',
1477             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1478             speakee => 'Soandso',
1479             spoken => 'lol, i was waiting for that =)',
1480             };
1481              
1482             comments:
1483              
1484             none
1485              
1486             =cut
1487              
1488             push @line_types,
1489             {
1490             rx => qr/\AYou told (\w+),? '(.+)'\z/,
1491             handler => sub
1492             {
1493             my ($speakee, $spoken) = @_;
1494             return
1495             {
1496             line_type => 'YOU_TELL_OTHER',
1497             speakee => $speakee,
1498             spoken => $spoken,
1499             };
1500             }
1501              
1502             };
1503              
1504             =item MERCHANT_TELLS_YOU
1505              
1506             input line:
1507              
1508             [Mon Oct 13 00:42:36 2003] Magus Delin tells you, 'I'll give you 3 gold 6 silver per Geode'
1509              
1510             output hash ref:
1511              
1512             {
1513             line_type => 'MERCHANT_TELLS_YOU',
1514             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1515             platinum => 0,
1516             gold => '3',
1517             silver => '6',
1518             copper => 0,
1519             value => 0.360,
1520             merchant => 'Magus Delin',
1521             item => 'Geode',
1522             };
1523              
1524             comments:
1525              
1526             none
1527              
1528             =cut
1529              
1530             ## this must be before OTHER_TELLS_YOU
1531              
1532             push @line_types,
1533             {
1534             rx => qr/\A([^,]+?) tells you, 'I\'ll give you (.+?) (?:per|for the) (.+?)\.?'\z/,
1535             handler => sub
1536             {
1537             my ($merchant, $money, $item) = @_;
1538             $money ||= '';
1539             my %moneys = reverse split ' ', $money;
1540             return
1541             {
1542             line_type => 'MERCHANT_TELLS_YOU',
1543             platinum => $moneys{'platinum'} || 0,
1544             gold => $moneys{'gold'} || 0,
1545             silver => $moneys{'silver'} || 0,
1546             copper => $moneys{'copper'} || 0,
1547             merchant => $merchant,
1548             item => $item,
1549             };
1550             }
1551              
1552             };
1553              
1554             =item MERCHANT_PRICE
1555              
1556             input line:
1557              
1558             [Mon Oct 13 00:42:36 2003] Gaelsori Heriseron tells you, 'That'll be 1 platinum 2 gold 5 silver 9 copper for the Leather Wristbands.'
1559              
1560             output hash ref:
1561              
1562             {
1563             line_type => 'MERCHANT_PRICE',
1564             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1565             platinum => '1',
1566             gold => '2',
1567             silver => '5',
1568             copper => '9',
1569             value => 1.259,
1570             merchant => 'Gaelsori Heriseron',
1571             item => 'Leather Wristbands',
1572             };
1573              
1574             comments:
1575              
1576             none
1577              
1578             =cut
1579              
1580             ## this must be before OTHER_TELLS_YOU
1581              
1582             push @line_types,
1583             {
1584             rx => qr/\A([^,]+?) tells you, 'That\'ll be (.+?) (?:per|for the) (.+?)\.?'\z/,
1585             handler => sub
1586             {
1587             my ($merchant, $money, $item) = @_;
1588             $money ||= '';
1589             my %moneys = reverse split ' ', $money;
1590             return
1591             {
1592             line_type => 'MERCHANT_PRICE',
1593             platinum => $moneys{'platinum'} || 0,
1594             gold => $moneys{'gold'} || 0,
1595             silver => $moneys{'silver'} || 0,
1596             copper => $moneys{'copper'} || 0,
1597             merchant => $merchant,
1598             item => $item,
1599             };
1600             }
1601              
1602             };
1603              
1604              
1605             =item OTHER_TELLS_YOU
1606              
1607             input line:
1608              
1609             [Mon Oct 13 00:42:36 2003] Soandso tells you, 'hows the adv?'
1610              
1611             output hash ref:
1612              
1613             {
1614             line_type => 'OTHER_TELLS_YOU',
1615             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1616             speaker => 'Soandso',
1617             spoken => 'hows the adv?',
1618             };
1619              
1620             comments:
1621              
1622             none
1623              
1624             =cut
1625              
1626             push @line_types,
1627             {
1628             rx => qr/\A([^,]+?) tells you, '(.+)'\z/,
1629             handler => sub
1630             {
1631             my ($speaker, $spoken) = @_;
1632             return
1633             {
1634             line_type => 'OTHER_TELLS_YOU',
1635             speaker => $speaker,
1636             spoken => $spoken,
1637             };
1638             }
1639              
1640             };
1641              
1642             =item YOU_TELL_GROUP
1643              
1644             input line:
1645              
1646             [Mon Oct 13 00:42:36 2003] You tell your party, 'will keep an eye out'
1647              
1648             output hash ref:
1649              
1650             {
1651             line_type => 'YOU_TELL_GROUP',
1652             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1653             spoken => 'will keep an eye out',
1654             };
1655              
1656             comments:
1657              
1658             none
1659              
1660             =cut
1661              
1662             push @line_types,
1663             {
1664             rx => qr/\AYou tell your party, '(.+)'\z/,
1665             handler => sub
1666             {
1667             my ($spoken) = @_;
1668             return
1669             {
1670             line_type => 'YOU_TELL_GROUP',
1671             spoken => $spoken,
1672             };
1673             }
1674              
1675             };
1676              
1677             =item OTHER_TELLS_GROUP
1678              
1679             input line:
1680              
1681             [Mon Oct 13 00:42:36 2003] Soandso tells the group, 'Didnt know that, thanks info'
1682              
1683             output hash ref:
1684              
1685             {
1686             line_type => 'OTHER_TELLS_GROUP',
1687             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1688             speaker => 'Soandso',
1689             spoken => 'Didnt know that, thanks info',
1690             };
1691              
1692             comments:
1693              
1694             none
1695              
1696             =cut
1697              
1698             push @line_types,
1699             {
1700             rx => qr/\A(\w+) tells the group, '(.+)'\z/,
1701             handler => sub
1702             {
1703             my ($speaker, $spoken) = @_;
1704             return
1705             {
1706             line_type => 'OTHER_TELLS_GROUP',
1707             speaker => $speaker,
1708             spoken => $spoken,
1709             };
1710             }
1711              
1712             };
1713              
1714             =item OTHER_CASTS
1715              
1716             input line:
1717              
1718             [Mon Oct 13 00:42:36 2003] Soandso begins to cast a spell.
1719              
1720             output hash ref:
1721              
1722             {
1723             line_type => 'OTHER_CASTS',
1724             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1725             caster => 'Soandso',
1726             };
1727              
1728             comments:
1729              
1730             none
1731              
1732             =cut
1733              
1734             push @line_types,
1735             {
1736             rx => qr/\A(.+?) begins to cast a spell\.\z/,
1737             handler => sub
1738             {
1739             my ($caster) = @_;
1740             return
1741             {
1742             line_type => 'OTHER_CASTS',
1743             caster => $caster,
1744             };
1745             }
1746              
1747             };
1748              
1749             =item CRITICAL_DAMAGE
1750              
1751             input line:
1752              
1753             [Mon Oct 13 00:42:36 2003] Soandso scores a critical hit! (126)
1754              
1755             output hash ref:
1756              
1757             {
1758             line_type => 'CRITICAL_DAMAGE',
1759             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1760             attacker => 'Soandso',
1761             type => 'hit',
1762             amount => '126',
1763             };
1764              
1765             input line:
1766              
1767             [Mon Oct 13 00:42:36 2003] Soandso delivers a critical blast! (3526)
1768              
1769             output hash ref:
1770              
1771             {
1772             line_type => 'CRITICAL_DAMAGE',
1773             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1774             attacker => 'Soandso',
1775             type => 'blast',
1776             amount => '3526',
1777             };
1778              
1779             comments:
1780              
1781             none
1782              
1783             =cut
1784              
1785             push @line_types,
1786             {
1787             rx => qr/\A(\w+) (?:delivers|scores) a critical (hit|blast)! \((\d+)\)\z/,
1788             handler => sub
1789             {
1790             my ($attacker, $type, $amount) = @_;
1791             return
1792             {
1793             line_type => 'CRITICAL_DAMAGE',
1794             attacker => $attacker,
1795             type => $type,
1796             amount => $amount,
1797             };
1798             }
1799              
1800             };
1801              
1802             =item PLAYER_HEALED
1803              
1804             input line:
1805              
1806             [Mon Oct 13 00:42:36 2003] Soandso has healed you for 456 points of damage.
1807              
1808             output hash ref:
1809              
1810             {
1811             line_type => 'PLAYER_HEALED',
1812             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1813             healer => 'Soandso',
1814             healee => 'you',
1815             amount => '456',
1816             };
1817              
1818             comments:
1819              
1820             none
1821              
1822             =cut
1823              
1824             push @line_types,
1825             {
1826             rx => qr/\A(\w+) (?:have|has) healed (\w+) for (\d+) points of damage.\z/,
1827             handler => sub
1828             {
1829             my ($healer, $healee, $amount) = @_;
1830             return
1831             {
1832             line_type => 'PLAYER_HEALED',
1833             healer => $healer,
1834             healee => $healee,
1835             amount => $amount,
1836             };
1837             }
1838              
1839             };
1840              
1841             =item SAYS_OOC
1842              
1843             input line:
1844              
1845             [Mon Oct 13 00:42:36 2003] Soandso says out of character, 'Stop following me :oP'
1846              
1847             output hash ref:
1848              
1849             {
1850             line_type => 'SAYS_OOC',
1851             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1852             speaker => 'Soandso',
1853             spoken => 'Stop following me :oP',
1854             };
1855              
1856             comments:
1857              
1858             none
1859              
1860             =cut
1861              
1862             push @line_types,
1863             {
1864             rx => qr/\A(\w+) says out of character, '(.+)'\z/,
1865             handler => sub
1866             {
1867             my ($speaker, $spoken) = @_;
1868             return
1869             {
1870             line_type => 'SAYS_OOC',
1871             speaker => $speaker,
1872             spoken => $spoken,
1873             };
1874             }
1875              
1876             };
1877              
1878             =item OTHER_AUCTIONS
1879              
1880             input line:
1881              
1882             [Mon Oct 13 00:42:36 2003] Soandso auctions, 'WMBS - 4k OBO'
1883              
1884             output hash ref:
1885              
1886             {
1887             line_type => 'OTHER_AUCTIONS',
1888             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1889             speaker => 'Soandso',
1890             spoken => 'WMBS - 4k OBO',
1891             };
1892              
1893             comments:
1894              
1895             none
1896              
1897             =cut
1898              
1899             push @line_types,
1900             {
1901             rx => qr/\A(\w+) auctions, '(.+)'\z/,
1902             handler => sub
1903             {
1904             my ($speaker, $spoken) = @_;
1905             return
1906             {
1907             line_type => 'OTHER_AUCTIONS',
1908             speaker => $speaker,
1909             spoken => $spoken,
1910             };
1911             }
1912              
1913             };
1914              
1915             =item OTHER_SHOUTS
1916              
1917             input line:
1918              
1919             [Mon Oct 13 00:42:36 2003] Soandso shouts, 'talk to vual stoutest'
1920              
1921             output hash ref:
1922              
1923             {
1924             line_type => 'OTHER_SHOUTS',
1925             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1926             speaker => 'Soandso',
1927             spoken => 'talk to vual stoutest',
1928             };
1929              
1930             comments:
1931              
1932             none
1933              
1934             =cut
1935              
1936             push @line_types,
1937             {
1938             rx => qr/\A(\w+) shouts, '(.+)'\z/,
1939             handler => sub
1940             {
1941             my ($speaker, $spoken) = @_;
1942             return
1943             {
1944             line_type => 'OTHER_SHOUTS',
1945             speaker => $speaker,
1946             spoken => $spoken,
1947             };
1948             }
1949              
1950             };
1951              
1952             =item PLAYER_LISTING
1953              
1954             input line:
1955              
1956             [Mon Oct 13 00:42:36 2003] [56 Outrider] Soandso (Half Elf)
1957              
1958             output hash ref:
1959              
1960             {
1961             line_type => 'PLAYER_LISTING',
1962             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1963             afk => '',
1964             linkdead => '',
1965             anon => '',
1966             level => '56',
1967             class => 'Outrider',
1968             name => 'Soandso',
1969             race => 'Half Elf',
1970             guild => 'The Foobles',
1971             zone => '',
1972             lfg => '',
1973             };
1974              
1975             input line:
1976              
1977             [Mon Oct 13 00:42:36 2003] [65 Deceiver] Soandso (Barbarian) ZONE: potranquility
1978              
1979             output hash ref:
1980              
1981             {
1982             line_type => 'PLAYER_LISTING',
1983             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
1984             afk => '',
1985             linkdead => '',
1986             anon => '',
1987             level => '65',
1988             class => 'Deceiver',
1989             name => 'Soandso',
1990             race => 'Barbarian',
1991             guild => 'The Foobles',
1992             zone => 'potranquility',
1993             lfg => '',
1994             };
1995              
1996             comments:
1997              
1998             none
1999              
2000             =cut
2001              
2002             push @line_types,
2003             {
2004             rx => qr/
2005             \A ##
2006             (\ AFK\ |\ )? ## AFK or LINKDEAD
2007             \[ ##
2008             (ANONYMOUS|\d+\ [^]]+) ## ANONYMOUS or level and class
2009             \] ##
2010             \s+ ##
2011             (\w+) ## player name
2012             \s+ ##
2013             (?:\((.+?)\))? ## player race
2014             \s* ##
2015             (?:<(.+?)>)? ## guild tag
2016             \s* ##
2017             (?:ZONE:\ (\w+))? ## zone
2018             \s* ##
2019             (LFG)? ## LFG tag
2020             \z ##
2021             /x,
2022             handler => sub
2023             {
2024             my ($afk_ld, $anon_level_class, $name, $race, $guild, $zone, $lfg) = @_;
2025             my ($afk, $linkdead, $anon, $level, $class);
2026             if (! defined $afk_ld)
2027             {
2028             ($afk, $linkdead) = ('', '');
2029             }
2030             elsif ($afk_ld eq ' AFK ')
2031             {
2032             ($afk, $linkdead) = ('AFK', '');
2033             }
2034             else
2035             {
2036             ($afk, $linkdead) = ('', 'LINKDEAD');
2037             }
2038             if ($anon_level_class && $anon_level_class ne 'ANONYMOUS')
2039             {
2040             ($level, $class) = split ' ', $anon_level_class;
2041             }
2042             else { $anon = $anon_level_class; }
2043             return
2044             {
2045             line_type => 'PLAYER_LISTING',
2046             afk => ($afk || ''),
2047             linkdead => ($linkdead || ''),
2048             anon => ($anon || ''),
2049             level => ($level || ''),
2050             class => ($class || ''),
2051             name => $name,
2052             race => ($race || ''),
2053             guild => ($guild || ''),
2054             zone => ($zone || ''),
2055             lfg => ($lfg || ''),
2056             };
2057             }
2058              
2059             };
2060              
2061             =item YOUR_SPELL_WEARS_OFF
2062              
2063             input line:
2064              
2065             [Mon Oct 13 00:42:36 2003] Your Flame Lick spell has worn off.
2066              
2067             output hash ref:
2068              
2069             {
2070             line_type => 'YOUR_SPELL_WEARS_OFF',
2071             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2072             spell => 'Flame Lick',
2073             };
2074              
2075             comments:
2076              
2077             none
2078              
2079             =cut
2080              
2081             push @line_types,
2082             {
2083             rx => qr/\AYour (.+?) spell has worn off\.\z/,
2084             handler => sub
2085             {
2086             my ($spell) = @_;
2087             return
2088             {
2089             line_type => 'YOUR_SPELL_WEARS_OFF',
2090             spell => $spell,
2091             };
2092             }
2093              
2094             };
2095              
2096             =item WIN_ADVENTURE
2097              
2098             input line:
2099              
2100             [Mon Oct 13 00:42:36 2003] You have successfully completed your adventure. You received 22 adventure points. You have 30 minutes to exit this zone.
2101              
2102             output hash ref:
2103              
2104             {
2105             line_type => 'WIN_ADVENTURE',
2106             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2107             amount => '22',
2108             };
2109              
2110             comments:
2111              
2112             none
2113              
2114             =cut
2115              
2116             push @line_types,
2117             {
2118             rx => qr/\AYou have successfully completed your adventure. You received (\d+) adventure points. You have 30 minutes to exit this zone\.\z/,
2119             handler => sub
2120             {
2121             my ($amount) = @_;
2122             return
2123             {
2124             line_type => 'WIN_ADVENTURE',
2125             amount => $amount,
2126             };
2127             }
2128              
2129             };
2130              
2131             =item SPEND_ADVENTURE_POINTS
2132              
2133             input line:
2134              
2135             [Mon Oct 13 00:42:36 2003] You have spent 40 adventure points.
2136              
2137             output hash ref:
2138              
2139             {
2140             line_type => 'SPEND_ADVENTURE_POINTS',
2141             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2142             amount => '40',
2143             };
2144              
2145             comments:
2146              
2147             none
2148              
2149             =cut
2150              
2151             push @line_types,
2152             {
2153             rx => qr/\AYou have spent (\d+) adventure points\.\z/,
2154             handler => sub
2155             {
2156             my ($amount) = @_;
2157             return
2158             {
2159             line_type => 'SPEND_ADVENTURE_POINTS',
2160             amount => $amount,
2161             };
2162             }
2163              
2164             };
2165              
2166             =item GAIN_EXPERIENCE
2167              
2168             input line:
2169              
2170             [Mon Oct 13 00:42:36 2003] You gain party experience!!
2171              
2172             output hash ref:
2173              
2174             {
2175             line_type => 'GAIN_EXPERIENCE',
2176             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2177             gainer => 'party',
2178             };
2179              
2180             input line:
2181              
2182             [Mon Oct 13 00:42:36 2003] You gain experience!!
2183              
2184             output hash ref:
2185              
2186             {
2187             line_type => 'GAIN_EXPERIENCE',
2188             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2189             gainer => '',
2190             };
2191              
2192             comments:
2193              
2194             none
2195              
2196             =cut
2197              
2198             push @line_types,
2199             {
2200             rx => qr/\AYou gain (?:(party) )?experience!!\z/,
2201             handler => sub
2202             {
2203             my ($gainer) = @_;
2204             return
2205             {
2206             line_type => 'GAIN_EXPERIENCE',
2207             gainer => ($gainer || ''),
2208             };
2209             }
2210              
2211             };
2212              
2213             =item GAME_TIME
2214              
2215             input line:
2216              
2217             [Mon Oct 13 00:42:36 2003] Game Time: Thursday, April 05, 3176 - 6 PM
2218              
2219             output hash ref:
2220              
2221             {
2222             line_type => 'GAME_TIME',
2223             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2224             time => 'Game Time: Thursday, April 05, 3176 - 6 PM',
2225             };
2226              
2227             comments:
2228              
2229             none
2230              
2231             =cut
2232              
2233             push @line_types,
2234             {
2235             rx => qr/\AGame Time: (.+)\z/,
2236             handler => sub
2237             {
2238             my ($time) = @_;
2239             return
2240             {
2241             line_type => 'GAME_TIME',
2242             time => $time,
2243             };
2244             }
2245              
2246             };
2247              
2248             =item EARTH_TIME
2249              
2250             input line:
2251              
2252             [Mon Oct 13 00:42:36 2003] Earth Time: Thursday, April 05, 2003 19:25:47
2253              
2254             output hash ref:
2255              
2256             {
2257             line_type => 'EARTH_TIME',
2258             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2259             time => 'Earth Time: Thursday, April 05, 2003 19:25:47',
2260             };
2261              
2262             comments:
2263              
2264             none
2265              
2266             =cut
2267              
2268             push @line_types,
2269             {
2270             rx => qr/\AEarth Time: (.+)\z/,
2271             handler => sub
2272             {
2273             my ($time) = @_;
2274             return
2275             {
2276             line_type => 'EARTH_TIME',
2277             time => $time,
2278             };
2279             }
2280              
2281             };
2282              
2283             =item MAGIC_DIE
2284              
2285             input line:
2286              
2287             [Mon Oct 13 00:42:36 2003] **A Magic Die is rolled by Soandso.
2288              
2289             output hash ref:
2290              
2291             {
2292             line_type => 'MAGIC_DIE',
2293             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2294             roller => 'Soandso',
2295             };
2296              
2297             comments:
2298              
2299             none
2300              
2301             =cut
2302              
2303             push @line_types,
2304             {
2305             rx => qr/\A\*\*A Magic Die is rolled by (.+?)\.\z/,
2306             handler => sub
2307             {
2308             my ($roller) = @_;
2309             return
2310             {
2311             line_type => 'MAGIC_DIE',
2312             roller => $roller,
2313             };
2314             }
2315              
2316             };
2317              
2318             =item ROLL_RESULT
2319              
2320             input line:
2321              
2322             [Mon Oct 13 00:42:36 2003] **It could have been any number from 0 to 550, but this time it turned up a 492.
2323              
2324             output hash ref:
2325              
2326             {
2327             line_type => 'ROLL_RESULT',
2328             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2329             min => '0',
2330             max => '550',
2331             amount => '492',
2332             };
2333              
2334             comments:
2335              
2336             none
2337              
2338             =cut
2339              
2340             push @line_types,
2341             {
2342             rx => qr/\A\*\*It could have been any number from (\d+) to (\d+), but this time it turned up a (\d+)\.\z/,
2343             handler => sub
2344             {
2345             my ($min, $max, $amount) = @_;
2346             return
2347             {
2348             line_type => 'ROLL_RESULT',
2349             min => $min,
2350             max => $max,
2351             amount => $amount,
2352             };
2353             }
2354              
2355             };
2356              
2357             =item BEGIN_MEMORIZE_SPELL
2358              
2359             input line:
2360              
2361             [Mon Oct 13 00:42:36 2003] Beginning to memorize Call of Sky...
2362              
2363             output hash ref:
2364              
2365             {
2366             line_type => 'BEGIN_MEMORIZE_SPELL',
2367             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2368             min => '0',
2369             max => '550',
2370             amount => '492',
2371             };
2372              
2373             comments:
2374              
2375             none
2376              
2377             =cut
2378              
2379             push @line_types,
2380             {
2381             rx => qr/\ABeginning to memorize (.+?)\.\.\.\z/,
2382             handler => sub
2383             {
2384             my ($spell) = @_;
2385             return
2386             {
2387             line_type => 'BEGIN_MEMORIZE_SPELL',
2388             spell => $spell,
2389             };
2390             }
2391              
2392             };
2393              
2394             =item SPELL_INTERRUPTED
2395              
2396             input line:
2397              
2398             [Mon Oct 13 00:42:36 2003] a Bloodguard caretaker's casting is interrupted!
2399              
2400             output hash ref:
2401              
2402             {
2403             line_type => 'SPELL_INTERRUPTED',
2404             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2405             caster => 'a Bloodguard caretaker',
2406             };
2407              
2408             input line:
2409              
2410             [Mon Oct 13 00:42:36 2003] Your spell is interrupted.
2411              
2412             output hash ref:
2413              
2414             {
2415             line_type => 'SPELL_INTERRUPTED',
2416             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2417             caster => 'You',
2418             };
2419              
2420             comments:
2421              
2422             none
2423              
2424             =cut
2425              
2426             push @line_types,
2427             {
2428             rx => qr/\A(.+?) (?:spell|casting) is interrupted(?:\.|!)\z/,
2429             handler => sub
2430             {
2431             my ($caster) = @_;
2432             $caster =~ s/(?:\'s|r)\z// if defined $caster;
2433             return
2434             {
2435             line_type => 'SPELL_INTERRUPTED',
2436             caster => $caster,
2437             };
2438             }
2439              
2440             };
2441              
2442             =item SPELL_NO_HOLD
2443              
2444             input line:
2445              
2446             [Mon Oct 13 00:42:36 2003] Your spell would not have taken hold on your target.
2447              
2448             output hash ref:
2449              
2450             {
2451             line_type => 'SPELL_NO_HOLD',
2452             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2453             };
2454              
2455             comments:
2456              
2457             none
2458              
2459             =cut
2460              
2461             push @line_types,
2462             {
2463             rx => qr/\AYour spell would not have taken hold on your target\.\z/,
2464             handler => sub
2465             {
2466             return
2467             {
2468             line_type => 'SPELL_NO_HOLD',
2469             };
2470             }
2471              
2472             };
2473              
2474             =item LEVEL_GAIN
2475              
2476             input line:
2477              
2478             [Mon Oct 13 00:42:36 2003] You have gained a level! Welcome to level 42!
2479              
2480             output hash ref:
2481              
2482             {
2483             line_type => 'LEVEL_GAIN',
2484             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2485             level => '42',
2486             };
2487              
2488             comments:
2489              
2490             none
2491              
2492             =cut
2493              
2494             push @line_types,
2495             {
2496             rx => qr/\AYou have gained a level! Welcome to level (\d+)!\z/,
2497             handler => sub
2498             {
2499             my ($level) = @_;
2500             return
2501             {
2502             line_type => 'LEVEL_GAIN',
2503             level => $level,
2504             };
2505             }
2506              
2507             };
2508              
2509             =item BAZAAR_TRADER_MODE
2510              
2511             input line:
2512              
2513             [Mon Oct 13 00:42:36 2003] Bazaar Trader Mode *ON*
2514              
2515             output hash ref:
2516              
2517             {
2518             line_type => 'BAZAAR_TRADER_MODE',
2519             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2520             status => 1,
2521             };
2522              
2523             comments:
2524              
2525             status will be '0' for OFF, and '1' for ON.
2526              
2527             =cut
2528              
2529             push @line_types,
2530             {
2531             rx => qr/\ABazaar Trader Mode \*(ON|OFF)\*\z/,
2532             handler => sub
2533             {
2534             # This gets called during module load with no arguments,
2535             # but we'd rather the undefined $mode not to cause a warning.
2536 1     1   11 no warnings 'uninitialized';
  1         2  
  1         330  
2537             my ($mode) = @_;
2538             return
2539             {
2540             line_type => 'BAZAAR_TRADER_MODE',
2541             status => ($mode eq "ON" ? 1 : 0),
2542             };
2543             }
2544             };
2545              
2546              
2547             =item BAZAAR_TRADER_PRICE
2548              
2549             input line:
2550              
2551             [Mon Oct 13 00:42:36 2003] 18.) Bone Chips (Price 2g 5s).
2552              
2553             output hash ref:
2554              
2555             {
2556             line_type => 'BAZAAR_TRADER_PRICE',
2557             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2558             item => 'Bone Chips',
2559             platinum => '0',
2560             gold => '2',
2561             silver => '5',
2562             copper => '0',
2563             value => 0.250,
2564             };
2565              
2566             comments:
2567              
2568             none
2569              
2570             =cut
2571              
2572             push @line_types,
2573             {
2574             rx => qr/\A \d+\.\) (.+?) \(Price $BAZAAR_PRICE\)\.\z/,
2575             handler => sub
2576             {
2577             my ($item, $pp, $gp, $sp, $cp) = @_;
2578             return
2579             {
2580             line_type => 'BAZAAR_TRADER_PRICE',
2581             item => $item,
2582             platinum => $pp || 0,
2583             gold => $gp || 0,
2584             silver => $sp || 0,
2585             copper => $cp || 0,
2586             };
2587             }
2588             };
2589              
2590             =item BAZAAR_SALE
2591              
2592             input line:
2593              
2594             [Mon Oct 13 00:42:36 2003] Letsmekkadyl purchased 17 Bone Chips for ( 3p 2g 3s).
2595              
2596             output hash ref:
2597              
2598             {
2599             line_type => 'BAZAAR_SALE',
2600             time_stamp => '[Mon Oct 13 00:42:36 2003] ',
2601             buyer => 'Letsmekkadyl',
2602             item => 'Leather Wristbands',
2603             quantity => 17,
2604             platinum => '3',
2605             gold => '2',
2606             silver => '3',
2607             copper => '0',
2608             value => 3.230,
2609             };
2610              
2611             comments:
2612              
2613             none
2614              
2615             =cut
2616              
2617             push @line_types,
2618             {
2619             rx => qr/\A(.+?) purchased (\d+) (.+?) for \($BAZAAR_PRICE\)\.\z/,
2620             handler => sub
2621             {
2622             my ($buyer, $qty, $item, $pp, $gp, $sp, $cp) = @_;
2623             return
2624             {
2625             line_type => 'BAZAAR_SALE',
2626             platinum => $pp || 0,
2627             gold => $gp || 0,
2628             silver => $sp || 0,
2629             copper => $cp || 0,
2630             buyer => $buyer,
2631             item => $item,
2632             quantity => $qty,
2633             };
2634             }
2635              
2636             };
2637              
2638             # Finally, we process every line in @line_types, ready to start.
2639             for my $line_type (@line_types)
2640             {
2641             my $line_type_name = $line_type->{'handler'}->()->{'line_type'};
2642             $line_types{$line_type_name} = $line_type;
2643             }
2644              
2645             1;
2646             __END__