1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
# -----------------------------------------------------------------------------
# $Id: Kick.pm 11365 2008-05-10 14:58:28Z topia $
# -----------------------------------------------------------------------------
package User::Kick;
use strict;
use warnings;
use base qw(Module);
use Mask;
use Multicast;
use Timer;
sub new {
my $class = shift;
my $this = $class->SUPER::new(@_);
$this->{queue} = {}; # network name => [IRCmessage,...]
$this->{timer} = undef; # queueが空でない時だけ必要になるTimer
$this;
}
sub destruct {
my ($this) = @_;
if (defined $this->{timer}) {
$this->{timer}->uninstall;
$this->{timer} = undef;
}
}
sub message_arrived {
my ($this, $msg, $sender) = @_;
if ($sender->server_p && $msg->command eq 'JOIN' && defined $msg->nick) {
foreach (split m/,/,$msg->param(0)) {
my ($ch_full,$mode) = (m/^(.+?)(?:\x07(.*))?$/);
my $ch_short = Multicast::detatch($ch_full);
my $ch = $sender->channel($ch_short);
my $myself = $ch->names($sender->current_nick);
if ($myself->has_o &&
Mask::match_deep_chan([$this->config->mask('all')],$msg->prefix,$ch_full)) {
# kickキューに入れる。
$this->enqueue(
$sender->network_name, $this->construct_irc_message(
Command => 'KICK',
Params => [$ch_short,
$msg->nick,
$this->config->message || 'User::Kick']));
}
}
}
$msg;
}
sub enqueue {
my ($this, $network_name, $command) = @_;
my $queue = $this->{queue}->{$network_name};
if (!defined $queue) {
$queue = $this->{queue}->{$network_name} = [];
}
push @$queue, $command;
$this->prepare_timer;
}
sub prepare_timer {
my $this = shift;
# キュー消化タイマーが存在しなければ作る。
if (!defined $this->{timer}) {
$this->{timer} = Timer->new(
Interval => 0, # 後で變へる
Repeat => 1,
Code => sub {
my $timer = shift;
$timer->interval(1);
# 鯖毎に1つづつ消化する。
my $queue_has_elem;
while (my ($network_name, $queue) = each %{$this->{queue}}) {
my $server = RunLoop->shared->network($network_name);
my $msg = shift @$queue;
$server->send_message($msg) if defined $server;
if (@$queue > 0) {
$queue_has_elem = 1;
}
}
# 全てのキューが空になつたら終了。
if (!$queue_has_elem) {
$timer->uninstall;
$this->{timer} = undef;
}
})->install;
}
}
1;
|