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