diff options
| author | Tom Wesley | 2015-09-11 22:33:24 +0100 |
|---|---|---|
| committer | Tom Wesley | 2015-09-11 22:33:24 +0100 |
| commit | 5a2e186f0fadf7f279c1cbe9afd9be3a37a6fddd (patch) | |
| tree | e7c2ed7ec1b26df0a020f74a3fc8c32b2d25b758 | |
| parent | 49c12f0ea4a8668ebc3e12b125736b1e89b5c3a5 (diff) | |
| parent | 8906a88963bae67d81aa3325fddc48962a8dd358 (diff) | |
| download | scripts.irssi.org-5a2e186f0fadf7f279c1cbe9afd9be3a37a6fddd.tar.bz2 | |
Merge pull request #155 from nhandler/add-bansearch
Add bansearch.pl
| -rw-r--r-- | scripts/bansearch.pl | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/scripts/bansearch.pl b/scripts/bansearch.pl new file mode 100644 index 0000000..b41475f --- /dev/null +++ b/scripts/bansearch.pl @@ -0,0 +1,381 @@ +#!/usr/bin/perl + +use strict; +use Irssi; +use Irssi::Irc; +use vars qw($VERSION %IRSSI); + +$VERSION = "1.1"; +%IRSSI = ( + authors => ['Nathan Handler', 'Joseph Price'], + contact => ['nathan.handler@gmail.com', 'pricechild@ubuntu.com'], + name => 'bansearch', + description => 'Searches for bans, quiets, and channel modes affecting a user', + license => 'GPLv3+', +); + +my($channel,$person,$nick,$user,$host,$real,$account,$string,$issues,$running,@jchannels,@jchannelstocheck); + +$running=0; + +sub bansearch { + my($data,$server,$witem) = @_; + + if($running) { + Irssi::print("bansearch is already running."); + } + + $running=1; + @jchannels=(); + @jchannelstocheck=(); + + #Clear variables and register redirects + &reset(); + + #Split command arguments into a nick and a channel separated by a space + ($person,$channel)=split(/ /, $data, 2); + + #If no channel is specified, use the current window if it is a channel + if($channel!~m/^#/ && $person!~m/^\s*$/ && $witem->{type} eq "CHANNEL") { + $channel=$witem->{name}; + } + + #Stop the script and display usage information if they did not specify a person or if we can't find a channel to use + if($channel!~m/^#/ || $person=~m/^\s*$/) { + Irssi::active_win()->print("\x02Usage\x02: /bansearch nick [#channel]"); + $running=0; + return; + } + + #Print the name of the channel we are running on + Irssi::active_win()->print("\x02Channel\x02: $channel"); + + #Perform a /who <user> %uhnar + $server->redirect_event('who',1, $person, 0, undef, + { + 'event 352' => 'redir rpl_whoreply', + 'event 354' => 'redir rpl_whospcrpl', + 'event 315' => 'redir rpl_endofwho', + 'event 401' => 'redir err_nosuchnick', + '' => 'event empty', + } + ); + $server->send_raw("WHO $person %uhnar"); +} +#Irssi::signal_add('event empty', 'EMPTY'); +Irssi::signal_add('redir rpl_whoreply', 'RPL_WHOREPLY'); +Irssi::signal_add('redir rpl_whospcrpl', 'RPL_WHOREPLY'); +Irssi::signal_add('redir rpl_endofwho', 'RPL_ENDOFWHO'); +Irssi::signal_add('redir err_nosuchnick', 'ERR_NOSUCHNICK'); +Irssi::signal_add('redir err_nosuchchannel', 'ERR_NOSUCHCHANNEL'); +Irssi::signal_add('redir rpl_banlist', sub { my($server,$data) = @_; RPL_BANLIST($server, "Ban $data"); }); +Irssi::signal_add('redir rpl_endofbanlist', sub { my($server,$data) = @_; RPL_ENDOFBANLIST($server, "Ban $data"); }); +Irssi::signal_add('redir rpl_quietlist', sub { my($server,$data) = @_; RPL_BANLIST($server, "Quiet $data"); }); +Irssi::signal_add('redir rpl_endofquietlist', sub { my($server,$data) = @_; RPL_ENDOFBANLIST($server, "Quiet $data"); }); +Irssi::signal_add('redir rpl_channelmodeis', 'RPL_CHANNELMODEIS'); + +sub EMPTY { + my($server, $data) = @_; + + return if(!$running); + + Irssi::print("\x02EMPTY\x02: $data"); +} + +sub RPL_BANLIST { + my($server, $data) = @_; + + return if(!$running); + + my($type, $mask, $setby, $banchannel, $jchannel); + if($data=~m/^Ban/) { + ($type, undef, $banchannel, $mask, $setby, undef) = split(/ /, $data, 6); + } + elsif($data=~m/^Quiet/) { + ($type, undef, $banchannel, undef, $mask, $setby, undef) = split(/ /, $data, 7); + } + my $maskreg = $mask; + $maskreg=~s/\$\#.*$//; #Support matching ban-forwards + $maskreg=~s/\./\\./g; + $maskreg=~s/\//\\\//g; + $maskreg=~s/\@/\\@/g; + $maskreg=~s/\[/\\[/g; + $maskreg=~s/\]/\\]/g; + $maskreg=~s/\|/\\|/g; + $maskreg=~s/\?/\./g; + $maskreg=~s/\*/\.\*\?/g; + + #We only want to display who set the ban/quiet if it is listed as a person + if($setby=~m/^.*?\.freenode\.net$/i) { + $setby=''; + } + else { + $setby=" (Set by $setby)"; + } + + if($maskreg=~m/^\$/) { #extban + if($maskreg=~m/^\$a:(.*?)$/i) { + if($account=~m/^$1$/i && $account!~m/^0$/) { + Irssi::active_win()->print("$type against \x02$mask\x02 in $banchannel matches $account" . $setby); + $issues++; + } + else { +# Irssi::active_win()->print("$type against \x02$mask\x02 does NOT match $account" . $setby); + } + } + if($channel == $banchannel) { + if($maskreg=~m/^\$j:(.*?)$/i) { + $jchannel = $1; + if(!($jchannel ~~ @jchannels)) { + push(@jchannels, $jchannel); + push(@jchannelstocheck, $jchannel); + Irssi::active_win()->print("Following bans in " . $jchannel . " will " . $type . " " . $person . " in " . $channel . $setby); + } + } + } + if($maskreg=~m/^\$~a$/i) { + if($account=~m/^0$/) { + Irssi::active_win()->print("$type against \x02$mask\x02 in $banchannel matches unidentified user." . $setby); + $issues++; + } + else { +# Irssi::active_win()->print("$type against \x02$mask\x02 does NOT match $account" . $setby); + } + } + if($maskreg=~m/^\$r:(.*?)$/i) { + if($real=~m/^$1$/i) { + Irssi::active_win()->print("$type against \x02$mask\x02 in $banchannel matches real name of $real" . $setby); + $issues++; + } + else { +# Irssi::active_win()->print("$type against \x02$mask\x02 does NOT match real name of $real" . $setby); + } + } + if($maskreg=~m/^\$x:(.*?)$/i) { + my $full = "$nick!user\@host\#$real"; + if($full=~m/^$1$/i) { + Irssi::active_win()->print("$type against \x02$mask\x02 in $banchannel matches $full" . $setby); + $issues++; + } + else { +# Irssi::active_win()->print("$type against \x02$mask\x02 does NOT match $full" . $setby); + } + } + } + else { #Normal Ban + if($string=~m/^$maskreg$/i) { + Irssi::active_win()->print("$type against \x02$mask\x02 in $banchannel matches $string" . $setby); + $issues++; + } + else { +# Irssi::active_win()->print("$type against \x02$mask\x02 does NOT match $string" . $setby); + } + } +} + +sub RPL_ENDOFBANLIST { + my($server, $data) = @_; + + return if(!$running); + +# Irssi::active_win()->print("End of Ban List"); + if($data=~m/^Ban/) { + $server->redirect_event('mode q',1, $channel, 0, undef, + { + 'event 728' => 'redir rpl_quietlist', + 'event 729' => 'redir rpl_endofquietlist', + '' => 'event empty', + } + ); + $server->send_raw("MODE $channel q"); + } + elsif($data=~m/^Quiet/) { + $server->redirect_event('mode channel',1, $channel, 0, undef, + { + 'event 324' => 'redir rpl_channelmodeis', + '' => 'event empty', + } + ); + if (@jchannelstocheck) { + my $nextchannel = pop(@jchannelstocheck); + $server->redirect_event('mode b',1, $nextchannel, 0, undef, + { + 'event 367' => 'redir rpl_banlist', + 'event 368' => 'redir rpl_endofbanlist', + 'event 403' => 'redir err_nosuchchannel', + '' => 'event empty', + } + ); + $server->send_raw("MODE $nextchannel b"); + } else { + $server->send_raw("MODE $channel"); + } + } +} + +sub RPL_WHOREPLY { + my($server, $data) = @_; + + return if(!$running); + + (undef, $user, $host, $nick, $account, $real) = split(/ /, $data, 6); + $real=~s/^://; + Irssi::active_win()->print("\x02User\x02: $nick [$account] ($real) $user\@$host"); +} + +sub RPL_ENDOFWHO { + my($server, $data) = @_; + + return if(!$running); + + if($nick=~m/^$/ && $user=~m/^$/ && $host=~m/^$/) { + Irssi::active_win()->print("$person is currently offline."); + return; + } + $string="$nick!$user\@$host"; + $server->redirect_event('mode b',1, $channel, 0, undef, + { + 'event 367' => 'redir rpl_banlist', + 'event 368' => 'redir rpl_endofbanlist', + 'event 403' => 'redir err_nosuchchannel', + '' => 'event empty', + } + ); + $server->send_raw("MODE $channel b"); +} + +sub ERR_NOSUCHNICK { + my($server, $data) = @_; + + return if(!$running); + + Irssi::active_win()->print("$person is currently offline."); + $running=0; +} + +sub ERR_NOSUCHCHANNEL { + my($server, $data) = @_; + + return if(!$running); + + Irssi::active_win()->print("$channel does not exist."); + $running=0; +} + +sub RPL_CHANNELMODEIS { + my($server, $data) = @_; + + return if(!$running); + + my(undef, undef, $modes, $args) = split(/ /, $data, 4); + Irssi::active_win()->print("\x02Channel Modes\x02: $modes"); + if($modes=~m/i/) { + Irssi::active_win()->print("Channel is \x02invite-only\x02 (+i)"); + $issues++; + } + if($modes=~m/k/) { + Irssi::active_win()->print("Channel has a \x02password\x02 (+k)"); + $issues++; + } + if($modes=~m/r/) { + if($account=~m/^0$/) { + Irssi::active_win()->print("Channel is \x02blocking unidentified users\x02 (+r) and user is not identified"); + $issues++; + } + } + if($modes=~m/m/) { + if($server->channel_find("$channel")) { + my $n = $server->channel_find("$channel")->nick_find("$nick"); + if($n->{voice} == 0 && $n->{op} == 0) { + Irssi::active_win()->print("Channel is \x02moderated\x02 (+m) and user is not voiced or oped"); + $issues++; + } + } + else { + Irssi::active_win()->print("Channel is \x02moderated\x02 (+m) and user might not be voiced or oped"); + $issues++; + } + } + + if($issues == 0) { + Irssi::active_win()->print("There does not appear to be anything preventing $person from joining/talking in $channel"); + } + elsif ($issues == 1) { + Irssi::active_win()->print("There is \x02$issues issue\x02 that might be preventing $person from joining/talking in $channel"); + } + else { + Irssi::active_win()->print("There are \x02$issues issues\x02 that might be preventing $person from joining/talking in $channel"); + } + $running=0; +} + +sub reset { + + return if(!$running); + + $channel=''; + $person=''; + $nick=''; + $user=''; + $host=''; + $real=''; + $account=''; + $string=''; + $issues=0; + + ®ister_redirects(); +} + +sub register_redirects { + + return if(!$running); + + #who + Irssi::Irc::Server::redirect_register('who', 0, 0, + { "event 352" => 1, # start events + "event 354" => -1, + }, + { # stop events + "event 315" => 1, # End of Who List + "event 401" => 1, # No Such Nick + }, + undef, # optional events + ); + + #mode b + Irssi::Irc::Server::redirect_register('mode b', 0, 0, + { "event 367" => 1 }, # start events + { # stop events + "event 368" => 1, # End of channel ban list + "event 403" => 1, # no such channel + "event 442" => 1, # "you're not on that channel" + "event 479" => 1 # "Cannot join channel (illegal name)" + }, + undef, # optional events + ); + + #mode q + Irssi::Irc::Server::redirect_register('mode q', 0, 0, + { "event 728" => 1 }, # start events + { # stop events + "event 729" => 1, # End of channel quiet list + "event 403" => 1, # no such channel + "event 442" => 1, # "you're not on that channel" + "event 479" => 1, # "Cannot join channel (illegal name)" + }, + undef, # optional events + ); + + #mode channel + Irssi::Irc::Server::redirect_register('mode channel', 0, 0, undef, + { # stop events + "event 324" => 1, # MODE-reply + "event 403" => 1, # no such channel + "event 442" => 1, # "you're not on that channel" + "event 479" => 1 # "Cannot join channel (illegal name)" + }, + { "event 329" => 1 } # Channel create time + ); +} + +Irssi::command_bind('bansearch', 'bansearch'); |
