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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
# -----------------------------------------------------------------------------
# $Id: Ignore.pm 15771 2008-07-13 23:55:21Z drry $
# -----------------------------------------------------------------------------
# copyright (C) 2005 Topia <topia@clovery.jp>. all rights reserved.
package Channel::Ignore;
use strict;
use warnings;
use base qw(Module);
use Mask;
use Multicast;
use NumericReply;
sub message_io_hook {
my ($this,$msg,$io,$type) = @_;
if ($io->isa('IrcIO::Server')) {
if ($type eq 'in') {
my $numeric = NumericReply::fetch_name($msg->command);
my $method = 'cmd_'.($numeric || $msg->command);
if ($this->can($method)) {
return $this->$method($msg, $io);
}
}
}
$msg;
}
*cmd_NOTICE = \&cmd_PRIVMSG;
*cmd_PART = \&cmd_PRIVMSG;
*cmd_INVITE = \&cmd_PRIVMSG;
*cmd_TOPIC = \&cmd_PRIVMSG;
*cmd_MODE = \&cmd_PRIVMSG;
*cmd_KICK = \&cmd_PRIVMSG;
sub cmd_PRIVMSG {
my ($this,$msg,$io) = @_;
my $ch_short = $msg->param(0);
my $ch_long = Multicast::attach($ch_short, $io->network_name);
if (!Multicast::channel_p($ch_short)) {
$ch_long = 'priv@'.$io->network_name;
}
if ($this->ignore_channel_p($ch_long)) {
undef;
}
else {
$msg;
}
}
sub cmd_JOIN {
my ($this,$msg,$io) = @_;
my @channels; # チャンネルリストを再構成する。
foreach my $channel (split m/,/,$msg->param(0)) {
my ($ch_short,$mode) = ($channel =~ m/^([^\x07]+)(?:\x07(.*))?/);
my $ch_long = Multicast::attach($ch_short, $io->network_name);
if (!$this->ignore_channel_p($ch_long)) {
push @channels,$channel;
}
}
if (@channels > 0) {
# 再構成の結果、チャンネルがまだ残ってた。
$msg->param(0,join(',',@channels));
}
else {
$msg = undef;
}
$msg;
}
sub cmd_NJOIN {
my ($this,$msg,$io) = @_;
my $ch_short = $msg->param(0);
my $ch_long = Multicast::attach($ch_short, $io->network_name);
if ($this->ignore_channel_p($ch_long)) {
$msg = undef;
}
$msg;
}
*cmd_QUIT = \&cmd_NICK;
sub cmd_NICK {
my ($this,$msg,$io) = @_;
# 影響を及ぼした全チャンネル名のリストを得る。このリストにはネットワーク名が付いていない。
my $no_ignore;
my $nick = $msg->nick;
foreach (grep { defined $_->names($nick) } $io->channels_list) {
my $ch_long = Multicast::attach($_,$io->network_name);
if (!$this->ignore_channel_p($ch_long)) {
$no_ignore = 1;
last;
}
}
if ($no_ignore) {
$msg;
}
else {
undef;
}
}
sub cmd_RPL_NAMREPLY {
my ($this,$msg,$io) = @_;
my $ch_short = $msg->param(2);
my $ch_long = Multicast::attach($ch_short, $io->network_name);
if ($this->ignore_channel_p($ch_long)) {
$msg = undef;
}
$msg;
}
*cmd_RPL_CHANNELMODEIS = \&cmd_RPL_ENDOFNAMES;
*cmd_RPL_TOPIC_WHO_TIME = \&cmd_RPL_ENDOFNAMES;
*cmd_RPL_TOPIC = \&cmd_RPL_ENDOFNAMES;
sub cmd_RPL_ENDOFNAMES {
my ($this,$msg,$io) = @_;
my $ch_short = $msg->param(1);
my $ch_long = Multicast::attach($ch_short, $io->network_name);
if ($this->ignore_channel_p($ch_long)) {
$msg = undef;
}
$msg;
}
sub ignore_channel_p {
my ($this,$ch_long) = @_;
Mask::match_deep([$this->config->mask('all')],$ch_long);
}
1;
=pod
info: 指定されたチャンネルの存在を、様々なメッセージから消去する。
default: off
# 対象となったチャンネルのJOIN、PART、INVITE、QUIT、NICK、NAMES、NJOINは消去される。
# 注意点
# - この機能はまだ実装途中です。いろいろな不具合があるかもしれません。むしろきっとあります。
# - サーバがわとの通信に割り込みますのでログにもとられません。
# - この機能を使っている Tiarra より上流に multi-server-mode な Tiarra を置かないでください。
# チャンネルの定義。
# また、privの場合は「priv@ネットワーク名」という文字列をチャンネル名の代わりとしてマッチングを行なう。
# 書式: mask: <チャンネルのマスク>
mask: #example@example
=cut
1;
|