File Coverage

blib/lib/POE/Component/IRC/Plugin/NickReclaim.pm
Criterion Covered Total %
statement 67 68 98.5
branch 17 30 56.6
condition 7 12 58.3
subroutine 13 13 100.0
pod 1 8 12.5
total 105 131 80.1


line stmt bran cond sub pod time code
1             package POE::Component::IRC::Plugin::NickReclaim;
2             our $AUTHORITY = 'cpan:HINRIK';
3             $POE::Component::IRC::Plugin::NickReclaim::VERSION = '6.92';
4 5     5   4605 use strict;
  5         15  
  5         195  
5 5     5   30 use warnings FATAL => 'all';
  5         9  
  5         297  
6 5     5   36 use Carp;
  5         13  
  5         405  
7 5     5   37 use IRC::Utils qw(parse_user);
  5         11  
  5         451  
8 5     5   126 use POE::Component::IRC::Plugin qw(PCI_EAT_NONE);
  5         19  
  5         5048  
9              
10             sub new {
11 4     4 1 7166 my ($package) = shift;
12 4 50       24 croak "$package requires an even number of arguments" if @_ & 1;
13 4         23 my %args = @_;
14 4         31 $args{ lc $_ } = delete $args{$_} for keys %args;
15              
16 4 100 66     59 if (!defined $args{poll} || $args{poll} !~ /^\d+$/) {
17 1         8 $args{poll} = 30;
18             }
19              
20 4         40 return bless \%args, $package;
21             }
22              
23             sub PCI_register {
24 4     4 0 1024 my ($self, $irc) = @_;
25 4         36 $irc->plugin_register( $self, 'SERVER', qw(001 433 nick quit) );
26 4         226 $irc->plugin_register( $self, 'USER', qw(nick) );
27              
28 4         134 $self->{_desired_nick} = $irc->nick_name();
29 4         14 return 1;
30             }
31              
32             sub PCI_unregister {
33 4     4 0 1465 return 1;
34             }
35              
36             sub U_nick {
37 9     9 0 886 my $self = shift;
38 9         18 my ($nick) = ${ $_[1] } =~ /^NICK +(.+)/i;
  9         72  
39              
40 9 100 100     78 if (!defined $self->{_temp_nick} || $self->{_temp_nick} ne $nick) {
41 6         17 delete $self->{_temp_nick};
42 6         17 $self->{_desired_nick} = $nick;
43             }
44 9         30 return PCI_EAT_NONE;
45             }
46              
47             sub S_001 {
48 3     3 0 138 my ($self, $irc) = splice @_, 0, 2;
49 3 50       17 $self->{_reclaimed} = $irc->nick_name eq $self->{_desired_nick} ? 1 : 0;
50 3         12 return PCI_EAT_NONE;
51             }
52              
53             # ERR_NICKNAMEINUSE
54             sub S_433 {
55 3     3 0 136 my ($self, $irc) = splice @_, 0, 2;
56 3         9 my $offending = ${ $_[2] }->[0];
  3         12  
57              
58 3 50 33     18 if (!$irc->logged_in || $irc->nick_name() eq $offending) {
59 3         11 my $temp_nick = "${offending}_";
60 3         11 $self->{_temp_nick} = $temp_nick;
61              
62 3         13 $irc->yield('nick', $temp_nick);
63             }
64              
65 3 50       314 $irc->delay_remove($self->{_alarm_id}) if defined $self->{_alarm_id};
66             $self->{_alarm_id} = $irc->delay(
67             ['nick', $self->{_desired_nick} ],
68             $self->{poll}
69 3         29 );
70              
71 3         857 return PCI_EAT_NONE;
72             }
73              
74             sub S_quit {
75 1     1 0 46 my ($self, $irc) = splice @_, 0, 2;
76 1         4 my $who = parse_user(${ $_[0] });
  1         9  
77              
78 1 50 33     35 if ($who eq $irc->nick_name) {
    50          
79 0 0       0 $irc->delay_remove($self->{_alarm_id}) if defined $self->{_alarm_id};
80             }
81             elsif (!$self->{_reclaimed} && $who eq $self->{_desired_nick}) {
82 1 50       12 $irc->delay_remove($self->{_alarm_id}) if defined $self->{_alarm_id};
83 1         335 $irc->yield('nick', $self->{_desired_nick});
84             }
85              
86 1         106 return PCI_EAT_NONE;
87             }
88              
89             sub S_nick {
90 4     4 0 215 my ($self, $irc) = splice @_, 0, 2;
91 4         11 my $old_nick = parse_user(${ $_[0] });
  4         25  
92 4         68 my $new_nick = ${ $_[1] };
  4         11  
93              
94 4 100       21 if ($new_nick eq $irc->nick_name) {
    50          
95 3 50       19 if ($new_nick eq $self->{_desired_nick}) {
96 3         10 $self->{_reclaimed} = 1;
97 3 50       27 $irc->delay_remove($self->{_alarm_id}) if defined $self->{_alarm_id};
98             }
99             }
100             elsif ($old_nick eq $self->{_desired_nick}) {
101 1 50       15 $irc->delay_remove($self->{_alarm_id}) if defined $self->{_alarm_id};
102 1         424 $irc->yield('nick', $self->{_desired_nick});
103             }
104              
105 4         477 return PCI_EAT_NONE;
106             }
107              
108             1;
109              
110             =encoding utf8
111              
112             =head1 NAME
113              
114             POE::Component::IRC::Plugin::NickReclaim - A PoCo-IRC plugin for reclaiming
115             your nickname
116              
117             =head1 SYNOPSIS
118              
119             use strict;
120             use warnings;
121             use POE qw(Component::IRC Component::IRC::Plugin::NickReclaim);
122              
123             my $nickname = 'Flibble' . $$;
124             my $ircname = 'Flibble the Sailor Bot';
125             my $ircserver = 'irc.blahblahblah.irc';
126             my $port = 6667;
127              
128             my $irc = POE::Component::IRC->spawn(
129             nick => $nickname,
130             server => $ircserver,
131             port => $port,
132             ircname => $ircname,
133             ) or die "Oh noooo! $!";
134              
135             POE::Session->create(
136             package_states => [
137             main => [ qw(_start) ],
138             ],
139             );
140              
141             $poe_kernel->run();
142              
143             sub _start {
144             $irc->yield( register => 'all' );
145              
146             # Create and load our NickReclaim plugin, before we connect
147             $irc->plugin_add( 'NickReclaim' =>
148             POE::Component::IRC::Plugin::NickReclaim->new( poll => 30 ) );
149              
150             $irc->yield( connect => { } );
151             return;
152             }
153              
154             =head1 DESCRIPTION
155              
156             POE::Component::IRC::Plugin::NickReclaim - A
157             L plugin automagically deals with
158             your bot's nickname being in use and reclaims it when it becomes available
159             again.
160              
161             It registers and handles 'irc_433' events. On receiving a 433 event it will
162             reset the nickname to the 'nick' specified with C or C,
163             appendedwith an underscore, and then poll to try and change it to the
164             original nickname. If someone in your channel who has the nickname you're
165             after quits or changes nickname, the plugin will try to reclaim it
166             immediately.
167              
168             =head1 METHODS
169              
170             =head2 C
171              
172             Takes one optional argument:
173              
174             B<'poll'>, the number of seconds between nick change attempts, default is 30;
175              
176             Returns a plugin object suitable for feeding to
177             L's C method.
178              
179             =head1 AUTHOR
180              
181             Chris 'BinGOs' Williams
182              
183             With amendments applied by Zoffix Znet
184              
185             =head1 SEE ALSO
186              
187             L
188              
189             =cut