6 use vars qw($VERSION %IRSSI $DEBUG);
8 # 0.05 -- Add IPv6 support
10 $VERSION = q$Revision: 1.1 $;
11 %IRSSI = (authors => 'Don Armstrong',
13 description => 'Provides /ak /aq /ab /abr /abrn /arn /amb /amr /at',
15 changed => q$Id: auto_bleh.pl,v 1.1 2005/03/17 08:19:53 don Exp $,
18 $DEBUG = 1 unless defined $DEBUG;
20 my ($actions, %defaults);
22 %defaults = (GET_OP => 1, # Should we try to get opped when we auto_bleh?
23 USE_CHANSERV => 1, # Should we use chanserv to get opped?
24 EXPIRE => 6000, # Do not try to do anything if the action is more than 6000 seconds old.
25 DEOP => 1, # Automatically deop after we've done whatever we were supposed to do.
26 TIMEOUT => 10, # Timeout /at bans after 10 minutes
29 my %command_bindings = (ak => 'cmd_ak',
47 my ($data, $server, $witem) = @_;
48 return do_auto_bleh('timeout',$data,$server,$witem);
52 my ($data, $server, $witem) = @_;
53 return do_auto_bleh('kick',$data,$server,$witem);
57 my ($data, $server, $witem) = @_;
58 return do_auto_bleh('kick,ban',$data,$server,$witem);
61 my ($data, $server, $witem) = @_;
62 return do_auto_bleh('kick,ban,notice',$data,$server,$witem);
66 my ($data, $server, $witem) = @_;
67 my @nicks = split /\s+/, $data;
70 do_auto_bleh('ban',$_,$server,$witem);
75 my ($data, $server, $witem) = @_;
76 return do_auto_bleh('ban',$data,$server,$witem);
80 my ($data, $server, $witem) = @_;
81 return do_auto_bleh('quiet',$data,$server,$witem);
86 my ($data, $server, $witem) = @_;
87 my @nicks = split /\s+/, $data;
90 do_auto_bleh('remove',$_,$server,$witem);
95 my ($data, $server, $witem) = @_;
96 return do_auto_bleh('remove',$data,$server,$witem);
99 my ($data, $server, $witem) =@_;
100 return do_auto_bleh('remove,ban',$data,$server,$witem);
103 my ($data, $server, $witem) =@_;
104 return do_auto_bleh('remove,ban,notice',$data,$server,$witem);
107 my ($data, $server, $witem) =@_;
108 return do_auto_bleh('remove,notice',$data,$server,$witem);
113 my ($cmd, $data, $server, $witem, $duration) = @_;
115 if (!$server || !$server->{connected}) {
116 Irssi::print("Not connected to server");
120 if ($witem->{type} ne 'CHANNEL') {
121 Irssi::print("Can't autokick on a non-channel. [$witem->{type}]");
126 # Irssi::print(Dumper($data,$server,$witem));
127 # set the network that we're on, the channel and the nick to kick
128 # once we've been opped
130 # Heh. Looks like $data needs to be sanitized a bit.
131 $data =~ /^\s*([^\s]+)\s*(\d+)?\s*(.+?|)\s*$/;
135 $timeout = $defaults{TIMEOUT} if not defined $timeout or $timeout eq '';
136 $reason = 'you should know better' if not defined $reason or $reason eq '';
138 my $nick_rec = $witem->nick_find($nick);
139 if (not defined $nick_rec) {
140 Irssi::print("Unable to find nick: $nick");
143 my $hostname = $nick_rec->{host} if defined $nick_rec;
144 Irssi::print("Unable to find hostname for $nick") if not defined $hostname or $hostname eq '';
145 $hostname =~ s/.+\@//;
147 Irssi::print("Nick set to '$nick' from '$data', reason set to '$reason'.") if $DEBUG;
148 my $action = {type => $cmd,
150 nick_rec => $nick_rec,
151 network => $witem->{server}->{chatnet},
152 server => $witem->{server},
155 channel => $witem->{name},
157 hostname => $hostname,
160 Irssi::print(i_want($action)) if $DEBUG;
161 if ($witem->{chanop}) { # we seem to be opped.
162 take_action($action,$server,$witem);
165 $actions->{$data.$action->{inserted}}=$action;
166 get_op($server, $action->{channel}) if $defaults{GET_OP};
172 my ($server,$channel) = @_;
174 Irssi::print("MSG chanserv op $channel");
175 $server->command("MSG chanserv op $channel") if $defaults{USE_CHANSERV};
181 return "I've wanted to $action->{type} $action->{nick} off $action->{channel} on $action->{network} since $action->{inserted}";
185 my ($action,$server,$channel) = @_;
187 local $_ = $action->{type};
188 # Now support multiple actions against a single nick (to FE, kick
189 # ban, or remove ban). See /abr foo
191 Irssi::print("Quieting $action->{nick} on $action->{channel} with hostname $action->{hostname} for $action->{timeout} minutes");
192 $server->send_raw("MODE $action->{channel} +q *!*@".$action->{hostname}) if $action->{hostname} ne ''; #quiet hostname
193 $bans_to_remove{"$action->{nick}$action->{inserted}"} = $action;
196 Irssi::print("Quieting $action->{nick} on $action->{channel} with hostname $action->{hostname}") if $DEBUG;
198 if ($action->{hostname}) {
199 $server->send_raw("MODE $action->{channel} +b %*!*@".$action->{hostname}) if $action->{hostname} ne ''; #quiet hostname
204 Irssi::print("Banning $action->{nick} from $action->{channel} with hostname $action->{hostname}") if $DEBUG;
205 $server->send_raw("MODE $action->{channel} +b *!*@".$action->{hostname}) if $action->{hostname} ne ''; # ban hostname
208 Irssi::print("Kicking $action->{nick} from $action->{channel}") if $DEBUG;
209 if ($action->{reason} =~ /\s/) {
210 $server->send_raw("KICK $action->{channel} $action->{nick} :$action->{reason}");
213 $server->send_raw("KICK $action->{channel} $action->{nick} $action->{reason}");
217 Irssi::print("Removing $action->{nick} from $action->{channel}") if $DEBUG;
218 if ($action->{reason} =~ /\s/) {
219 $server->send_raw("REMOVE $action->{channel} $action->{nick} :$action->{reason}");
222 $server->send_raw("REMOVE $action->{channel} $action->{nick} $action->{reason}");
226 Irssi::print("Noticing $action->{nick} with $action->{reason}") if $DEBUG;
227 $server->command("NOTICE $action->{nick} $action->{reason}");
229 # unquiet. This is crap, and needs to be changed to something sane.
231 Irssi::print("Unquieting $action->{nick} on $action->{channel} with hostname $action->{hostname}") if $DEBUG;
232 $server->command("MODE $action->{channel} -q *!*@".$action->{hostname});
239 my $channel = $rec->{channel};
240 my $server = $rec->{server};
242 #$server->command("MODE $channel->{name} -o $channel->{ownick}->{nick}");
243 if ($channel->{chanop}) {
244 Irssi::print("MODE $channel->{name} -o $channel->{ownnick}->{nick}");
245 $channel->command("/deop $channel->{ownnick}->{nick}");
249 sub sig_mode_change {
250 my ($channel,$nick) = @_;
252 #Irssi::print(Dumper($nick));
253 #Irssi::print(Dumper($channel));
255 # Are there any actions to process?
256 # See if we got opped.
257 return if scalar(keys %$actions) eq 0;
259 if ($channel->{server}->{nick} eq $nick->{nick} and $nick->{op}) {
260 # Ok, we've been opped, or we are opped now, so do whatever we're supposed to do.
261 Irssi::print("We've been opped") if $DEBUG;
262 # We seem to need some sort of delay here for the chanop stuff to catch up
263 Irssi::timeout_add_once(250,'attempt_actions',undef);
266 Irssi::print("Fooey. Not opped.") if $DEBUG;
270 sub attempt_actions {
274 foreach (keys %$actions) {
275 #Irssi::print(Dumper($actions->{$_}));
276 # See if this action is too old
277 if (time - $actions->{$_}->{inserted} > $defaults{EXPIRE}) {
278 Irssi::print("Expiring action: \"".i_want($actions->{$_})."\" because of time");
279 delete $actions->{$_};
282 Irssi::print(i_want($actions->{$_})) if $DEBUG;
283 # Find the server to take action on
284 my $server = Irssi::server_find_chatnet($actions->{$_}->{network});
285 Irssi::print("Unable to find server for chatnet: $actions->{$_}->{network}") and return if not defined $server;
286 Irssi::print("Found server for chatnet: $actions->{$_}->{network}") if $DEBUG;
287 # Find the channel to take action on
288 my $s_channel = $server->channel_find($actions->{$_}->{channel});
289 Irssi::print("Unable to find channel for channel: $actions->{$_}->{channel}") and return if not defined $s_channel;
290 Irssi::print("Found channel for channel: $actions->{$_}->{channel}") if $DEBUG;
291 # Are we opped on that channel?
292 if ($s_channel->{chanop}) { # Yes? Take the action against the user.
293 Irssi::print("We are opped on the channel!") if $DEBUG;
294 take_action($actions->{$_},$server,$s_channel);
295 push @deop_array,{server=>$server,channel=>$s_channel} if $defaults{DEOP};
296 delete $actions->{$_}; # Do not repeat this action.
299 Irssi::print("We are not opped on the channel.") if $DEBUG;
302 foreach (@deop_array) {
308 sub try_to_remove_bans {
309 return unless keys %bans_to_remove;
310 for my $key (keys %bans_to_remove) {
311 if (($bans_to_remove{$key}{inserted} + $bans_to_remove{$key}{timeout}*60) < time) {
312 $bans_to_remove{$key}{type} = 'teiuq'; #unquiet
313 $actions->{$key} = $bans_to_remove{$key};
314 delete $bans_to_remove{$key};
315 get_op($actions->{$key}{server}, $actions->{$key}{channel}) if $defaults{GET_OP};
320 # call the try to remove bans function every minute
321 Irssi::timeout_add(1000*60,'try_to_remove_bans',undef);
322 Irssi::signal_add_last('nick mode changed','sig_mode_change');
323 my ($command,$function);
325 while (($command,$function) = each %command_bindings) {
326 Irssi::command_bind($command,$function);