File Coverage

blib/lib/Protocol/IRC.pm
Criterion Covered Total %
statement 156 164 95.1
branch 88 112 78.5
condition 17 26 65.3
subroutine 23 27 85.1
pod 18 21 85.7
total 302 350 86.2


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