File Coverage

blib/lib/POE/Component/IRC/Plugin/POE/Knee.pm
Criterion Covered Total %
statement 45 100 45.0
branch 1 16 6.2
condition 2 12 16.6
subroutine 12 16 75.0
pod 1 4 25.0
total 61 148 41.2


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