File Coverage

blib/lib/POE/Component/IRC/Plugin/POE/Knee.pm
Criterion Covered Total %
statement 48 103 46.6
branch 1 16 6.2
condition 2 12 16.6
subroutine 13 17 76.4
pod 1 4 25.0
total 65 152 42.7


line stmt bran cond sub pod time code
1             package POE::Component::IRC::Plugin::POE::Knee;
2              
3 1     1   499744 use strict;
  1         2  
  1         45  
4 1     1   6 use warnings;
  1         1  
  1         35  
5 1     1   6 use Time::HiRes qw(gettimeofday);
  1         6  
  1         11  
6 1     1   2102 use Math::Random;
  1         10869  
  1         156  
7 1     1   11 use POE;
  1         2  
  1         8  
8 1     1   329 use POE::Component::IRC::Plugin qw(:ALL);
  1         2  
  1         144  
9 1     1   944 use POE::Component::IRC::Common qw(:ALL);
  1         788  
  1         312  
10 1     1   5 use vars qw($VERSION);
  1         2  
  1         1312  
11              
12             $VERSION = '1.08';
13              
14             sub new {
15 1     1 1 7947 my $package = shift;
16 1         4 my %args = @_;
17 1         7 $args{lc $_} = delete $args{$_} for keys %args;
18 1 0 33     9 $args{stages} = 5 unless $args{stages} and $args{stages} =~ /^\d+$/ and $args{stages} <= 30;
      33        
19 1         5 bless \%args, $package;
20             }
21              
22             sub PCI_register {
23 1     1 0 466 my ($self,$irc) = @_;
24 1 50       7 die "This plugin must be used with POE::Component::IRC::State or a subclass of that\n"
25             unless $irc->isa('POE::Component::IRC::State');
26 1         6 $self->{irc} = $irc;
27 1         6 $irc->plugin_register( $self, 'SERVER', qw(public) );
28 1         56 $self->{session_id} = POE::Session->create(
29             object_states => [
30             $self => [ qw(_shutdown _start _race_on _run) ],
31             ],
32             )->ID();
33 1         137 return 1;
34             }
35              
36             sub PCI_unregister {
37 1     1 0 2432 my ($self,$irc) = splice @_, 0, 2;
38 1         11 $poe_kernel->call( $self->{session_id} => '_shutdown' );
39 1         18 delete $self->{irc};
40 1         4 return 1;
41             }
42              
43             sub S_public {
44 0     0 0 0 my ($self,$irc) = splice @_, 0, 2;
45 0         0 my ($nick,$userhost) = ( split /!/, ${ $_[0] } )[0..1];
  0         0  
46 0         0 my $channel = ${ $_[1] }->[0];
  0         0  
47 0         0 my $what = ${ $_[2] };
  0         0  
48 0         0 my $mapping = $irc->isupport('CASEMAPPING');
49 0         0 my $mynick = $irc->nick_name();
50 0         0 my ($command) = $what =~ m/^\s*\Q$mynick\E[\:\,\;\.]?\s*(.*)$/i;
51 0 0       0 return PCI_EAT_NONE unless $command;
52 0         0 my @cmd = split /\s+/, $command;
53 0 0       0 return PCI_EAT_NONE unless uc( $cmd[0] ) eq 'POEKNEE';
54 0 0       0 if ( $self->{_race_in_progress} ) {
55 0         0 $irc->yield( privmsg => $channel => "There is already a race in progress" );
56 0         0 return PCI_EAT_NONE;
57             }
58 0         0 $poe_kernel->post( $self->{session_id}, '_race_on', $channel, $cmd[1] );
59 0         0 return PCI_EAT_NONE;
60             }
61              
62             sub _start {
63 1     1   185 my ($kernel,$self) = @_[KERNEL,OBJECT];
64 1         3 $self->{_race_in_progress} = 0;
65 1         12 $self->{session_id} = $_[SESSION]->ID();
66 1         10 $kernel->refcount_increment( $self->{session_id}, __PACKAGE__ );
67 1         30 undef;
68             }
69              
70             sub _shutdown {
71 1     1   69 my ($kernel,$self) = @_[KERNEL,OBJECT];
72 1         7 $kernel->alarm_remove_all();
73 1         64 $kernel->refcount_decrement( $self->{session_id}, __PACKAGE__ );
74 1         58 undef;
75             }
76              
77             sub _race_on {
78 0     0     my ($kernel,$self,$channel,$stages) = @_[KERNEL,OBJECT,ARG0,ARG1];
79 0 0 0       $stages = $self->{stages} unless $stages and $stages =~ /^\d+$/ and $stages <= 30;
      0        
80 0           $self->{_race_in_progress} = 1;
81 0           $self->{_distance} = $stages;
82 0           $self->{_progress} = [ ];
83 0           my $irc = $self->{irc};
84 0           my @channel_list = $irc->channel_list($channel);
85 0           my $seed = 5;
86 0           my $start = 'POE::Knee Race is on! ' . scalar @channel_list . ' ponies over ' . $self->{_distance} . ' stages.';
87 0           push @{ $self->{_progress} }, join(' ', _stamp(), $start);
  0            
88 0           $irc->yield('ctcp', $channel, 'ACTION ' . $start );
89 0           foreach my $nick ( @channel_list ) {
90             #my $nick_modes = $irc->nick_channel_modes($channel,$nick);
91             #$seed += rand(3) if $nick_modes =~ /o/;
92             #$seed += rand(2) if $nick_modes =~ /h/;
93             #$seed += rand(1) if $nick_modes =~ /v/;
94 0           my $delay = random_uniform(1,0,$seed);
95 0           push @{ $self->{_progress} }, join(' ', _stamp(), $nick, "($delay)", "is off!");
  0            
96 0           $kernel->delay_add( '_run', $delay, $nick, $channel, $seed, 1 );
97             }
98 0           undef;
99             }
100              
101             sub _run {
102 0     0     my ($kernel,$self,$nick,$channel,$seed,$stage) = @_[KERNEL,OBJECT,ARG0..ARG3];
103 0           push @{ $self->{_progress} }, _stamp() . " $nick reached stage " . ++$stage;
  0            
104 0 0         if ( $stage > $self->{_distance} ) {
105             # Stop the race
106 0           $kernel->alarm_remove_all();
107 0           my $result = "$nick! Won the POE::Knee race!";
108 0           $self->{irc}->yield( 'privmsg', $channel, $result );
109 0           push @{ $self->{_progress} }, _stamp() . " " . $result;
  0            
110 0           my $race_result = delete $self->{_progress};
111 0           $self->{irc}->yield( '__send_event', 'irc_poeknee_results', $channel, $race_result );
112 0           $self->{_race_in_progress} = 0;
113 0           return;
114             }
115 0 0         if ( $stage > $self->{_race_in_progress} ) {
116 0           $self->{irc}->yield( 'ctcp', $channel, "ACTION $nick! leads at stage $stage" );
117 0           $self->{_race_in_progress}++;
118             }
119 0           $kernel->delay_add( '_run', random_uniform(1,0,$seed), $nick, $channel, $seed, $stage );
120 0           undef;
121             }
122              
123             sub _stamp {
124 0     0     return join('.', gettimeofday);
125             }
126              
127             1;
128             __END__