File Coverage

blib/lib/Protocol/IRC.pm
Criterion Covered Total %
statement 157 165 95.1
branch 88 112 78.5
condition 17 26 65.3
subroutine 23 27 85.1
pod 17 21 80.9
total 302 351 86.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2010-2017 -- leonerd@leonerd.org.uk
5              
6             package Protocol::IRC;
7              
8 12     12   94943 use strict;
  12         31  
  12         315  
9 12     12   43 use warnings;
  12         13  
  12         438  
10              
11             our $VERSION = '0.12';
12              
13 12     12   54 use Carp;
  12         19  
  12         867  
14 12     12   47 use Scalar::Util qw( blessed );
  12         17  
  12         921  
15              
16 12     12   5259 use Protocol::IRC::Message;
  12         655  
  12         24193  
17              
18             # This should be mixed in MI-style
19              
20             =head1 NAME
21              
22             C - IRC protocol handling
23              
24             =head1 DESCRIPTION
25              
26             This mix-in class provides a base layer of IRC message handling logic. It
27             allows reading of IRC messages from a string buffer and dispatching them to
28             handler methods on its instance.
29              
30             L provides an extension to this logic that may be more
31             convenient for IRC client implementations. Much of the code provided here is
32             still useful in client applications, so the reader should be familiar with
33             both modules.
34              
35             =head1 MESSAGE HANDLING
36              
37             Every incoming message causes a sequence of message handling to occur. First,
38             the message is parsed, and a hash of data about it is created; this is called
39             the hints hash. The message and this hash are then passed down a sequence of
40             potential handlers.
41              
42             Each handler indicates by return value, whether it considers the message to
43             have been handled. Processing of the message is not interrupted the first time
44             a handler declares to have handled a message. Instead, the hints hash is marked
45             to say it has been handled. Later handlers can still inspect the message or its
46             hints, using this information to decide if they wish to take further action.
47              
48             A message with a command of C will try handlers in following places:
49              
50             =over 4
51              
52             =item 1.
53              
54             A method called C
55              
56             $irc->on_message_COMMAND( $message, \%hints )
57              
58             =item 2.
59              
60             A method called C
61              
62             $irc->on_message( 'COMMAND', $message, \%hints )
63              
64             =back
65              
66             For server numeric replies, if the numeric reply has a known name, it will be
67             attempted first at its known name, before falling back to the numeric if it
68             was not handled. Unrecognised numerics will be attempted only at their numeric
69             value.
70              
71             Because of the wide variety of messages in IRC involving various types of data
72             the message handling specific cases for certain types of message, including
73             adding extra hints hash items, or invoking extra message handler stages. These
74             details are noted here.
75              
76             Many of these messages create new events; called synthesized messages. These
77             are messages created by the C object itself, to better
78             represent some of the details derived from the primary ones from the server.
79             These events all take lower-case command names, rather than capitals, and will
80             have a C key in the hints hash, set to a true value. These are
81             dispatched and handled identically to regular primary events, detailed above.
82              
83             If any handler of the synthesized message returns true, then this marks the
84             primary message handled as well.
85              
86             If a message is received that has a gating disposition, extra processing is
87             applied to it before the processing above. The effect on its gate is given as
88             a string (one of C, C, C) to handlers in the following
89             places:
90              
91             =over 4
92              
93             =item 1.
94              
95             A method called C
96              
97             $irc->on_message_gate_EFFECT_GATE( $message, \%hints )
98              
99             =item 2.
100              
101             A method called C
102              
103             $irc->on_message_gate_EFFECT( 'GATE', $message, \%hints )
104              
105             =item 3.
106              
107             A method called C
108              
109             $irc->on_message_gate( 'EFFECT', 'GATE', $message, \%hints )
110              
111             =back
112              
113             =head2 Message Hints
114              
115             When messages arrive they are passed to the appropriate message handling
116             method, which the implementation may define. As well as the message, a hash
117             of extra information derived from or relating to the message is also given.
118              
119             The following keys will be present in any message hint hash:
120              
121             =over 8
122              
123             =item handled => BOOL
124              
125             Initially false. Will be set to true the first time a handler returns a true
126             value.
127              
128             =item prefix_nick => STRING
129              
130             =item prefix_user => STRING
131              
132             =item prefix_host => STRING
133              
134             Values split from the message prefix; see the C
135             C method.
136              
137             =item prefix_name => STRING
138              
139             Usually the prefix nick, or the hostname in case the nick isn't defined
140             (usually on server messages).
141              
142             =item prefix_is_me => BOOL
143              
144             True if the nick mentioned in the prefix refers to this connection.
145              
146             =back
147              
148             Added to this set, will be all the values returned by the message's
149             C method. Some of these values may cause yet more values to be
150             generated.
151              
152             If the message type defines a C:
153              
154             =over 8
155              
156             =item * target_type => STRING
157              
158             Either C or C, as returned by C.
159              
160             =item * target_is_me => BOOL
161              
162             True if the target name is a user and refers to this connection.
163              
164             =back
165              
166             Any key whose name ends in C<_nick> or C<_name> will have a corresponding key
167             added with C<_folded> suffixed on its name, containing the value casefolded
168             using C. This is for the convenience of string comparisons,
169             hash keys, etc..
170              
171             Any of these keys that are not the C will additionally have a
172             corresponding key with C<_is_me> replacing the C<_nick> or C<_name>,
173             containing the boolean result of calling the C method on that
174             name. This makes it simpler to detect commands or results affecting the user
175             the connection represents.
176              
177             =cut
178              
179             =head1 METHODS
180              
181             =cut
182              
183             =head2 on_read
184              
185             $irc->on_read( $buffer )
186              
187             Informs the protocol implementation that more bytes have been read from the
188             peer. This method will modify the C<$buffer> directly, and remove from it the
189             prefix of bytes it has consumed. Any bytes remaining should be stored by the
190             caller for next time.
191              
192             Any messages found in the buffer will be passed, in sequence, to the
193             C method.
194              
195             =cut
196              
197             sub on_read
198             {
199 52     52 1 16252 my $self = shift;
200             # buffer in $_[0]
201              
202 52         363 while( $_[0] =~ s/^(.*)\x0d\x0a// ) {
203 53         123 my $line = $1;
204             # Ignore blank lines
205 53 100       121 next if !length $line;
206              
207 51         182 $self->incoming_message( Protocol::IRC::Message->new_from_line( $line ) );
208             }
209             }
210              
211             =head2 incoming_message
212              
213             $irc->incoming_message( $message )
214              
215             Invoked by the C method for every incoming IRC message. This method
216             implements the actual dispatch into various handler methods as described in
217             the L section above.
218              
219             This method is exposed so that subclasses can override it, primarily to wrap
220             extra logic before or after the main dispatch (e.g. for logging or other
221             processing).
222              
223             =cut
224              
225             sub incoming_message
226             {
227 51     51 1 57 my $self = shift;
228 51         59 my ( $message ) = @_;
229              
230 51         129 my $command = $message->command_name;
231              
232 51         132 my ( $prefix_nick, $prefix_user, $prefix_host ) = $message->prefix_split;
233              
234 51 100       256 my $hints = {
235             handled => 0,
236              
237             prefix_nick => $prefix_nick,
238             prefix_user => $prefix_user,
239             prefix_host => $prefix_host,
240             # Most of the time this will be "nick", except for special messages from the server
241             prefix_name => defined $prefix_nick ? $prefix_nick : $prefix_host,
242             };
243              
244 51 100       132 if( my $named_args = $message->named_args ) {
245 48         223 $hints->{$_} = $named_args->{$_} for keys %$named_args;
246             }
247              
248 51 100 100     194 if( defined $hints->{text} and my $encoder = $self->encoder ) {
249 2         22 $hints->{text} = $encoder->decode( $hints->{text} );
250             }
251              
252 51 100       131 if( defined( my $target_name = $hints->{target_name} ) ) {
253 28         68 my $target_type = $self->classify_name( $target_name );
254 28         65 $hints->{target_type} = $target_type;
255             }
256              
257 51         85 my $prepare_method = "prepare_hints_$command";
258 51 100       380 $self->$prepare_method( $message, $hints ) if $self->can( $prepare_method );
259              
260 51 100       148 foreach my $k ( grep { m/_nick$/ or m/_name$/ } keys %$hints ) {
  408         1408  
261 137         273 $hints->{"${k}_folded"} = $self->casefold_name( my $name = $hints->{$k} );
262 137 100       231 defined $name or next;
263 113 100       204 $k eq "prefix_name" and next;
264              
265 62         277 ( my $knew = $k ) =~ s/_name$|_nick$/_is_me/;
266 62         126 $hints->{$knew} = $self->is_nick_me( $name );
267             }
268              
269 51 100       142 if( my $disp = $message->gate_disposition ) {
270 17         71 my ( $type, $gate ) = $disp =~ m/^([-+!*])(.*)$/;
271             my $effect = ( $type eq "-" ? "more" :
272             $type eq "+" ? "done" :
273             $type eq "!" ? "fail" :
274 17 50       55 $type eq "*" ? ( $hints->{prefix_is_me} ? "done" : undef ) :
    50          
    100          
    100          
    100          
275             die "TODO" );
276              
277 17 50       29 if( defined $effect ) {
278 17 50       60 $self->invoke( "on_message_gate_${effect}_$gate", $message, $hints ) and $hints->{handled} = 1;
279 17 50       40 $self->invoke( "on_message_gate_$effect", $gate, $message, $hints ) and $hints->{handled} = 1;
280 17 50       32 $self->invoke( "on_message_gate", $effect, $gate, $message, $hints ) and $hints->{handled} = 1;
281             }
282             }
283              
284 51 100       170 $self->invoke( "on_message_$command", $message, $hints ) and $hints->{handled} = 1;
285 51 100       125 $self->invoke( "on_message", $command, $message, $hints ) and $hints->{handled} = 1;
286              
287 51 100 100     698 if( !$hints->{handled} and $message->command ne $command ) { # numerics
288 2         9 my $numeric = $message->command;
289 2 50       6 $self->invoke( "on_message_$numeric", $message, $hints ) and $hints->{handled} = 1;
290 2 50       5 $self->invoke( "on_message", $numeric, $message, $hints ) and $hints->{handled} = 1;
291             }
292             }
293              
294             =head2 send_message
295              
296             This method takes arguments in three different forms, depending on their
297             number and type.
298              
299             If the first argument is a reference then it must contain a
300             C instance which will be sent directly:
301              
302             $irc->send_message( $message )
303              
304             Otherwise, the first argument must be a plain string that gives the command
305             name. If the second argument is a hash, it provides named arguments in a form
306             similar to L, otherwise the
307             remaining arguments must be the prefix string and other positional arguments,
308             as plain strings:
309              
310             $irc->send_message( $command, { %args } )
311              
312             $irc->send_message( $command, $prefix, @args )
313              
314             =head3 Named Argument Mangling
315              
316             For symmetry with incoming message processing, this method applies some
317             adjustment of named arguments for convenience of callers.
318              
319             =over 4
320              
321             =item *
322              
323             Callers may define a named argument of C; it will be renamed to
324             C.
325              
326             =item *
327              
328             If a named argument of C is defined and an L exists, the
329             argument value will be encoded using this encoder.
330              
331             =back
332              
333             =cut
334              
335             sub send_message
336             {
337 14     14 1 36 my $self = shift;
338              
339 14         16 my $message;
340              
341 14 100       34 if( @_ == 1 ) {
342 1         2 $message = shift;
343 1 50 33     24 blessed $message and $message->isa( "Protocol::IRC::Message" ) or
344             croak "Expected an instance of Protocol::IRC::Message";
345             }
346             else {
347 13         15 my $command = shift;
348 13 50       30 ref $command and
349             croak "Expected \$command to be a plain string";
350              
351 13 100 100     61 if( @_ == 1 and ref $_[0] ) {
352 8         6 my %args = %{ $_[0] };
  8         29  
353              
354 8 100       22 $args{target_name} = delete $args{target} if defined $args{target};
355              
356 8 50 66     63 if( defined $args{text} and my $encoder = $self->encoder ) {
357 0         0 $args{text} = $encoder->encode( $args{text} );
358             }
359              
360 8         33 $message = Protocol::IRC::Message->new_from_named_args( $command, %args );
361             }
362             else {
363 5         47 my ( $prefix, @args ) = @_;
364              
365 5 100       24 if( my $encoder = $self->encoder ) {
366 1         4 my $argnames = Protocol::IRC::Message->arg_names( $command );
367              
368 1 50       4 if( defined( my $i = $argnames->{text} ) ) {
369 1 50       8 $args[$i] = $encoder->encode( $args[$i] ) if defined $args[$i];
370             }
371             }
372              
373 5         24 $message = Protocol::IRC::Message->new( $command, $prefix, @args );
374             }
375             }
376              
377 14         56 $self->write( $message->stream_to_line . "\x0d\x0a" );
378             }
379              
380             =head2 send_ctcp
381              
382             $irc->send_ctcp( $prefix, $target, $verb, $argstr )
383              
384             Shortcut to sending a CTCP message. Sends a PRIVMSG to the given target,
385             containing the given verb and argument string.
386              
387             =cut
388              
389             sub send_ctcp
390             {
391 1     1 1 2 my $self = shift;
392 1         1 my ( $prefix, $target, $verb, $argstr ) = @_;
393              
394 1         8 $self->send_message( "PRIVMSG", undef, $target, "\001$verb $argstr\001" );
395             }
396              
397             =head2 send_ctcprely
398              
399             $irc->send_ctcprely( $prefix, $target, $verb, $argstr )
400              
401             Shortcut to sending a CTCP reply. As C but using a NOTICE instead.
402              
403             =cut
404              
405             sub send_ctcpreply
406             {
407 1     1 0 2 my $self = shift;
408 1         2 my ( $prefix, $target, $verb, $argstr ) = @_;
409              
410 1         4 $self->send_message( "NOTICE", undef, $target, "\001$verb $argstr\001" );
411             }
412              
413             =head1 ISUPPORT-DRIVEN UTILITIES
414              
415             The following methods are controlled by the server information given in the
416             C settings. They use the C required method to query the
417             information required.
418              
419             =cut
420              
421             =head2 casefold_name
422              
423             $name_folded = $irc->casefold_name( $name )
424              
425             Returns the C<$name>, folded in case according to the server's C
426             C. Such a folded name will compare using C according to whether the
427             server would consider it the same name.
428              
429             Useful for use in hash keys or similar.
430              
431             =cut
432              
433             sub casefold_name
434             {
435 296     296 1 317 my $self = shift;
436 296         249 my ( $nick ) = @_;
437              
438 296 100       444 return undef unless defined $nick;
439              
440 272   100     425 my $mapping = lc( $self->isupport( "CASEMAPPING" ) || "" );
441              
442             # Squash the 'capital' [\] into lowercase {|}
443 272 100       793 $nick =~ tr/[\\]/{|}/ if $mapping ne "ascii";
444              
445             # Most RFC 1459 implementations also squash ^ to ~, even though the RFC
446             # didn't mention it
447 272 100       403 $nick =~ tr/^/~/ unless $mapping eq "strict-rfc1459";
448              
449 272         709 return lc $nick;
450             }
451              
452             =head2 cmp_prefix_flags
453              
454             $cmp = $irc->cmp_prefix_flags( $lhs, $rhs )
455              
456             Compares two channel occupant prefix flags, and returns a signed integer to
457             indicate which of them has higher priviledge, according to the server's
458             ISUPPORT declaration. Suitable for use in a C function or similar.
459              
460             =cut
461              
462             sub cmp_prefix_flags
463             {
464 4     4 1 356 my $self = shift;
465 4         7 my ( $lhs, $rhs ) = @_;
466              
467 4 50 33     24 return undef unless defined $lhs and defined $rhs;
468              
469             # As a special case, compare emptystring as being lower than voice
470 4 50 33     9 return 0 if $lhs eq "" and $rhs eq "";
471 4 50       7 return 1 if $rhs eq "";
472 4 50       5 return -1 if $lhs eq "";
473              
474 4         8 my $PREFIX_FLAGS = $self->isupport( 'prefix_flags' );
475              
476 4 50       18 ( my $lhs_index = index $PREFIX_FLAGS, $lhs ) > -1 or return undef;
477 4 100       12 ( my $rhs_index = index $PREFIX_FLAGS, $rhs ) > -1 or return undef;
478              
479             # IRC puts these in greatest-first, so we need to swap the ordering here
480 3         9 return $rhs_index <=> $lhs_index;
481             }
482              
483             =head2 cmp_prefix_modes
484              
485             $cmp = $irc->cmp_prefix_modes( $lhs, $rhs )
486              
487             Similar to C, but compares channel occupant C command
488             flags.
489              
490             =cut
491              
492             sub cmp_prefix_modes
493             {
494 4     4 1 5 my $self = shift;
495 4         6 my ( $lhs, $rhs ) = @_;
496              
497 4 50 33     17 return undef unless defined $lhs and defined $rhs;
498              
499 4         9 my $PREFIX_MODES = $self->isupport( "prefix_modes" );
500              
501 4 50       17 ( my $lhs_index = index $PREFIX_MODES, $lhs ) > -1 or return undef;
502 4 100       9 ( my $rhs_index = index $PREFIX_MODES, $rhs ) > -1 or return undef;
503              
504             # IRC puts these in greatest-first, so we need to swap the ordering here
505 3         10 return $rhs_index <=> $lhs_index;
506             }
507              
508             =head2 prefix_mode2flag
509              
510             $flag = $irc->prefix_mode2flag( $mode )
511              
512             Converts a channel occupant C flag (such as C) into a name prefix
513             flag (such as C<@>).
514              
515             =cut
516              
517             sub prefix_mode2flag
518             {
519 7     7 1 2486 my $self = shift;
520 7         12 my ( $mode ) = @_;
521              
522 7         13 return $self->isupport( 'prefix_map_m2f' )->{$mode};
523             }
524              
525             =head2 prefix_flag2mode
526              
527             $mode = $irc->prefix_flag2mode( $flag )
528              
529             The inverse of C.
530              
531             =cut
532              
533             sub prefix_flag2mode
534             {
535 2     2 1 349 my $self = shift;
536 2         5 my ( $flag ) = @_;
537              
538 2         5 return $self->isupport( 'prefix_map_f2m' )->{$flag};
539             }
540              
541             =head2 classify_name
542              
543             $classification = $irc->classify_name( $name )
544              
545             Returns C if the given name matches the pattern of names allowed for
546             channels according to the server's C C. Returns C
547             if not.
548              
549             =cut
550              
551             sub classify_name
552             {
553 40     40 1 44 my $self = shift;
554 40         44 my ( $name ) = @_;
555              
556 40 100       101 return "channel" if $name =~ $self->isupport( "channame_re" );
557 11         54 return "user"; # TODO: Perhaps we can be a bit stricter - only check for valid nick chars?
558             }
559              
560             =head2 is_nick_me
561              
562             $me = $irc->is_nick_me( $nick )
563              
564             Returns true if the given nick refers to that in use by the connection.
565              
566             =cut
567              
568             sub is_nick_me
569             {
570 67     67 1 52 my $self = shift;
571 67         62 my ( $nick ) = @_;
572              
573 67         93 return $self->casefold_name( $nick ) eq $self->nick_folded;
574             }
575              
576             =head1 INTERNAL MESSAGE HANDLING
577              
578             The following messages are handled internally by C.
579              
580             =cut
581              
582             =head2 PING
583              
584             C messages are automatically replied to with C.
585              
586             =cut
587              
588             sub on_message_PING
589             {
590 0     0 0 0 my $self = shift;
591 0         0 my ( $message, $hints ) = @_;
592              
593 0         0 $self->send_message( "PONG", undef, $message->named_args->{text} );
594              
595 0         0 return 1;
596             }
597              
598             =head2 NOTICE and PRIVMSG
599              
600             Because C and C are so similar, they are handled together by
601             synthesized events called C, C and C. Depending on the
602             contents of the text, and whether it was supplied in a C or a
603             C, one of these three events will be created.
604              
605             In all cases, the hints hash will contain a C key being true or
606             false, depending on whether the original messages was a C or a
607             C, a C key containing the message target name, a
608             case-folded version of the name in a C key, and a
609             classification of the target type in a C key.
610              
611             For the C target type, it will contain a boolean in C to
612             indicate if the target of the message is the user represented by this
613             connection.
614              
615             For the C target type, it will contain a C key
616             containing the channel message restriction, if present.
617              
618             For normal C messages, it will contain a key C containing the
619             actual message text.
620              
621             For either CTCP message type, it will contain keys C and
622             C with the parsed message. The C will contain the first
623             space-separated token, and C will be a string containing the rest
624             of the line, otherwise unmodified. This type of message is also subject to a
625             special stage of handler dispatch, involving the CTCP verb string. For
626             messages with C as the verb, the following are tried. C may stand
627             for either C or C.
628              
629             =over 4
630              
631             =item 1.
632              
633             A method called C
634              
635             $irc->on_message_CTCP_VERB( $message, \%hints )
636              
637             =item 2.
638              
639             A method called C
640              
641             $irc->on_message_CTCP( 'VERB', $message, \%hintss )
642              
643             =item 3.
644              
645             A method called C
646              
647             $irc->on_message( 'CTCP VERB', $message, \%hints )
648              
649             =back
650              
651             =cut
652              
653             sub on_message_NOTICE
654             {
655 3     3 0 6 my $self = shift;
656 3         3 my ( $message, $hints ) = @_;
657 3         10 return $self->_on_message_text( $message, $hints, 1 );
658             }
659              
660             sub on_message_PRIVMSG
661             {
662 7     7 0 9 my $self = shift;
663 7         10 my ( $message, $hints ) = @_;
664 7         22 return $self->_on_message_text( $message, $hints, 0 );
665             }
666              
667             sub _on_message_text
668             {
669 10     10   10 my $self = shift;
670 10         11 my ( $message, $hints, $is_notice ) = @_;
671              
672 10         73 my %hints = (
673             %$hints,
674             synthesized => 1,
675             is_notice => $is_notice,
676             );
677              
678             # TODO: In client->server messages this might be a comma-separated list
679 10         23 my $target = delete $hints{targets};
680              
681 10         21 my $prefixflag_re = $self->isupport( 'prefixflag_re' );
682              
683 10         30 my $restriction = "";
684 10         104 while( $target =~ m/^$prefixflag_re/ ) {
685 1         6 $restriction .= substr( $target, 0, 1, "" );
686             }
687              
688 10         18 $hints{target_name} = $target;
689 10         19 $hints{target_name_folded} = $self->casefold_name( $target );
690              
691 10         38 my $type = $hints{target_type} = $self->classify_name( $target );
692              
693 10 100       64 if( $type eq "channel" ) {
    50          
694 5         9 $hints{restriction} = $restriction;
695 5         14 $hints{target_is_me} = '';
696             }
697             elsif( $type eq "user" ) {
698             # TODO: user messages probably can't have restrictions. What to do
699             # if we got one?
700 5         9 $hints{target_is_me} = $self->is_nick_me( $target );
701             }
702              
703 10         15 my $text = $hints->{text};
704              
705 10 100       33 if( $text =~ m/^\x01(.*)\x01$/ ) {
706 2         8 ( my $verb, $text ) = split( m/ /, $1, 2 );
707 2         5 $hints{ctcp_verb} = $verb;
708 2         3 $hints{ctcp_args} = $text;
709              
710 2 100       4 my $ctcptype = $is_notice ? "ctcpreply" : "ctcp";
711              
712 2 50       7 $self->invoke( "on_message_${ctcptype}_$verb", $message, \%hints ) and $hints{handled} = 1;
713 2 50       5 $self->invoke( "on_message_${ctcptype}", $verb, $message, \%hints ) and $hints{handled} = 1;
714 2 50       4 $self->invoke( "on_message", "$ctcptype $verb", $message, \%hints ) and $hints{handled} = 1;
715             }
716             else {
717 8         11 $hints{text} = $text;
718              
719 8 100       22 $self->invoke( "on_message_text", $message, \%hints ) and $hints{handled} = 1;
720 8 100       23 $self->invoke( "on_message", "text", $message, \%hints ) and $hints{handled} = 1;
721             }
722              
723 10         98 return $hints{handled};
724             }
725              
726             =head1 REQUIRED METHODS
727              
728             As this class is an abstract base class, a concrete implementation must
729             provide the following methods to complete it and make it useable.
730              
731             =cut
732              
733             =head2 write
734              
735             $irc->write( $string )
736              
737             Requests the byte string to be sent to the peer
738              
739             =cut
740              
741 0     0 1 0 sub write { croak "Attemped to invoke abstract ->write on " . ref $_[0] }
742              
743             =head2 encoder
744              
745             $encoder = $irc->encoder
746              
747             Optional. If supplied, returns an L object used to encode or decode
748             the bytes appearing in a C field of a message. If set, all text strings
749             will be returned, and should be given, as Unicode strings. They will be
750             encoded or decoded using this object.
751              
752             =cut
753              
754 30     30 1 110 sub encoder { undef }
755              
756             =head2 invoke
757              
758             $result = $irc->invoke( $name, @args )
759              
760             Optional. If provided, invokes the message handling routine called C<$name>
761             with the given arguments. A default implementation is provided which simply
762             attempts to invoke a method of the given name, or return false if no method
763             of that name exists.
764              
765             If an implementation does override this method, care should be taken to ensure
766             that methods are tested for and invoked if present, in addition to any other
767             work the method wishes to perform, as this is the basis by which derived
768             message handling works.
769              
770             =cut
771              
772             sub invoke
773             {
774 214     214 1 168 my $self = shift;
775 214         305 my ( $name, @args ) = @_;
776 214 100       969 return unless $self->can( $name );
777 103         244 return $self->$name( @args );
778             }
779              
780             =head2 isupport
781              
782             $value = $irc->isupport( $field )
783              
784             Should return the value of the given C field.
785              
786             As well as the all-capitals server-supplied fields, the following fields may
787             be requested. Their names are all lowercase and contain underscores, to
788             distinguish them from server-supplied fields.
789              
790             =over 8
791              
792             =item prefix_modes => STRING
793              
794             The mode characters from C (e.g. C)
795              
796             =item prefix_flags => STRING
797              
798             The flag characters from C (e.g. C<@%+>)
799              
800             =item prefixflag_re => Regexp
801              
802             A precompiled regexp that matches any of the prefix flags
803              
804             =item prefix_map_m2f => HASH
805              
806             A map from mode characters to flag characters
807              
808             =item prefix_map_f2m => HASH
809              
810             A map from flag characters to mode characters
811              
812             =item chanmodes_list => ARRAY
813              
814             A 4-element array containing the split portions of C;
815              
816             [ $listmodes, $argmodes, $argsetmodes, $boolmodes ]
817              
818             =item channame_re => Regexp
819              
820             A precompiled regexp that matches any string beginning with a channel prefix
821             character in C.
822              
823             =back
824              
825             =cut
826              
827 0     0 1 0 sub isupport { croak "Attempted to invoke abstract ->isupport on " . ref $_[0] }
828              
829             =head2 nick
830              
831             $nick = $irc->nick
832              
833             Should return the current nick in use by the connection.
834              
835             =head2 nick_folded
836              
837             $nick_folded = $irc->nick_folded
838              
839             Optional. If supplied, should return the current nick as case-folded by the
840             C method. If not provided, this will be performed by
841             case-folding the result from C.
842              
843             =cut
844              
845 0     0 1 0 sub nick { croak "Attempted to invoke abstract ->nick on " . ref $_[0] }
846 67     67 1 136 sub nick_folded { $_[0]->casefold_name( $_[0]->nick ) }
847              
848             =head1 AUTHOR
849              
850             Paul Evans
851              
852             =cut
853              
854             0x55AA;