といあえず、お下品さを取り除いた,POE::Component::Server::IRC::WhoIsTagged
クライアントを複数起動しての動作確認が辛いので、もうこれはだめです。
お下品な人は、sample.yamlの値を変更すれば良いと思います。
package POE::Component::Server::IRC::WhoIsTagged; our $VERSION = '0.01_01'; use strict; use warnings; use Data::Dumper; use List::MoreUtils; use List::Util; use base qw/POE::Component::Server::IRC/; my $wit_user = {}; my %WIT_STATUS_DEFAULT = ( status => 'stop' , channel => '' , looser => [] ); my $wit_status ; %{ $wit_status } = %WIT_STATUS_DEFAULT; my $wit_config = {}; sub init_who_is_tagged{ my $self = shift; $wit_config = shift; $wit_status->{status} = 'stop'; } sub _daemon_cmd_message { my $self = shift; my $nick = shift || return; my $type = shift || return; my @args = @_ ; if( $type eq 'PRIVMSG' ){ my $channel = $args[0]; my $message = $args[1]; my $cmd = $self->WIT_get_cmd( $message ); # cmd_terminate : force to stop. all use can run this. if( $channel eq $wit_status->{channel} && $cmd eq 'cmd_terminate' ) { $self->WIT_terminate(); } # cmd_stop if( $channel eq $wit_status->{channel} && $cmd eq 'cmd_stop' && $wit_status->{status} eq 'king_mode' && $nick eq $wit_status->{jorker} ) { %{ $wit_status } = %WIT_STATUS_DEFAULT; } # king mode if( $channel eq $wit_status->{channel} && $wit_status->{status} eq 'king_mode' && $nick ne $wit_status->{jorker} ) { $args[1] = $self->WIT_looser_message(); } if( $channel eq $wit_status->{channel} && $wit_status->{status} eq 'playing' && $nick eq $wit_status->{jorker} ) { $args[1] = $self->WIT_jorker_message( $message ); } if( $channel eq $wit_status->{channel} && $wit_status->{status} eq 'playing' && $nick ne $wit_status->{jorker} && $self->WIT_is_looser( $nick ) ) { $args[1] = $self->WIT_looser_message(); } # cmd_start : no game yet and cmd_start command in message. if( $wit_status->{status} eq 'stop' && $cmd eq 'cmd_start') { $self->WIT_start( $channel , $self->{state}{chans}{ uc $channel }{users} ); } # cmd_doubt if( $channel eq $wit_status->{channel} && $wit_status->{status} eq 'playing' && $cmd eq 'cmd_doubt') { $args[1] .= $self->WIT_doubt( $nick , $message ); } # cmd_confess if( $channel eq $wit_status->{channel} && $wit_status->{status} eq 'playing' && $cmd eq 'cmd_confess') { $args[1] .= $self->WIT_confess( $nick , $message ); } } $self->SUPER::_daemon_cmd_message( $nick , $type , @args ); } sub WIT_is_looser{ my $self = shift; my $nick = shift; return List::MoreUtils::any { $nick eq $_ } @{ $self->{looser} } ; } sub WIT_doubt { my $self = shift; my $my_nick = shift; my $message = shift; my ( undef, $nick ) = split( qq{ } , $message ); # myself return ' error:myself' if $my_nick eq $nick ; if ( defined $wit_status->{user}{ $nick } ) { if( $wit_status->{user}{ $nick } ) { if( $nick eq $wit_status->{jorker} ) { # mach %{ $wit_status } = %WIT_STATUS_DEFAULT; # TODO : maybe use bot? return " $my_nick is WINNER!"; } else { push @{ $wit_status->{looser} } , $my_nick; return " $my_nick is LOOSER!"; } } else { return " error: $nick is already lost this game"; } } else { return " error: $nick is not playing this game"; } } ub WIT_get_cmd { my $self = shift; my $message = shift; my ( $cmd ) = split( qq{ }, $message ); my @cmds = qw(cmd_start cmd_stop cmd_doubt cmd_confess cmd_terminate); for my $key ( @cmds ) { if( $wit_config->{ $key } eq $cmd ) { return $key; } } return ''; } sub WIT_terminate { %{$wit_status} = %WIT_STATUS_DEFAULT; } sub WIT_start { my $self = shift; my $channel = shift; my $users = shift; $wit_status->{status} = 'playing'; $wit_status->{channel} = $channel; my $cnt = 1; foreach my $keys ( List::Util::shuffle( keys %{ $users } ) ) { my $user = lc $keys; $wit_status->{user}{ $user } = 1; if( $cnt == 1 ) { $wit_status->{jorker} = $user ; } $cnt++; } } sub WIT_looser_message { return $wit_config->{looser}; } sub WIT_jorker_message { my $self = shift; my $text = shift; # only replace rule for now. if( defined $wit_config->{rule}{replace} ) { my $index = rand( @{ $wit_config->{rule}{replace} } ) ; $text = $wit_config->{rule}{replace}[ $index ]; } return $text; }
cmd_start : --start cmd_stop : --stop cmd_doubt : --doubt cmd_confess : --confess cmd_terminate : --terminate rule : replace : - 'ヒデブー' - 'アベシー' - 'オッパピー' looser : 私は負け犬の、犬ちきしょうです。
use strict; use warnings; use FindBin::libs; use YAML::Syck; use File::Spec; my $file = File::Spec->catfile($FindBin::Bin,'../conf/sample.yml'); use POE qw(Component::Server::IRC::WhoIsTagged); my %conf = ( config => { servername => 'localhost', nicklen => 15, network => 'WhoIsTagged', }, ); my $ircd = POE::Component::Server::IRC::WhoIsTagged->spawn( %conf ); $ircd->init_who_is_tagged( LoadFile( $file ) ); POE::Session->create( package_states => [ main => [qw(_start)], ], heap => { ircd => $ircd }, ); $poe_kernel->run(); exit 0; sub _start { my ($kernel,$heap) = @_[KERNEL,HEAP]; $heap->{ircd}->yield( 'register' ); $heap->{ircd}->add_listener( port => 6667 ); } __END__