antifuck.pl: add option & fix memleak. also, cocks

This commit is contained in:
wowaname 2017-03-31 03:34:08 +00:00
parent 300b8c1b26
commit 6506f323ae

View File

@ -7,7 +7,7 @@ no strict 'subs';
my $SCRIPT_NAME = 'antifuck';
my $SCRIPT_AUTHOR = 'The Krusty Krab <wowaname@volatile.ch>';
my $SCRIPT_VERSION = '1.0';
my $SCRIPT_VERSION = '1.1';
my $SCRIPT_LICENCE = 'Public domain';
my $SCRIPT_DESC = 'Defend against forcejoins (e.g. from fuckyou.pl) and '.
'forceparts (e.g. from /remove)';
@ -18,9 +18,18 @@ my %OPTIONS = (
delay => ['Delay in milliseconds to wait before autoparting', '5000'],
forward => ['Whether to allow channel forwards (+f on freenode)', '1'],
ignore => ['Servers to ignore (e.g. for bouncers), separated by comma', ''],
nobufs => ['If 1, do not create buffers for forcejoined channels', '0'],
timeout =>
['Delay in milliseconds to wait for server to send JOIN after join',
'60000'],
);
my (%channels, %part, %partbuf, $fuckbuf, $timeout_cb);
# %channels: channels we joined and received JOIN / NAMES for
# %zombie: channels we joined but aren't yet in
# %part: channels we were forced into and will part soon
# %partbuf: buffers belonging to parted channels, we'll close these on
# /antifuck part
our (%channels, %zombie, %part, %partbuf, $fuckbuf, $timeout_cb, $gc_cb);
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
@ -44,6 +53,7 @@ HELP
weechat::hook_signal('*,irc_raw_in_001', 'irc_001', '');
weechat::hook_signal('*,irc_raw_in_470', 'irc_470', '');
weechat::hook_modifier('irc_in_366', 'irc_366', '');
weechat::hook_modifier('irc_in_join', 'irc_join', '');
weechat::hook_modifier('irc_in_part', 'irc_part', '');
for my $option (keys %OPTIONS) {
@ -79,6 +89,12 @@ sub ignored
return $ignore_conf =~ /(^|,)$server($|,)/;
}
sub nobufs { weechat::config_get_plugin('nobufs') }
sub ircbuf { weechat::buffer_search('irc', "(?i)".(join '.', @_)) }
sub ircparse { weechat::info_get_hashtable(irc_message_parse =>
{ message => shift }) }
sub servchan
{
my $buf = shift;
@ -87,6 +103,13 @@ sub servchan
lc weechat::buffer_get_string($buf, 'localvar_channel'));
}
sub reset_gc
{
weechat::unhook($gc_cb) if $gc_cb;
$gc_cb = weechat::hook_timer(weechat::config_get_plugin('nobufs'), 0, 1,
'run_gc', '');
}
sub cmd_antifuck
{
my (undef, $buffer, $args) = @_;
@ -100,10 +123,7 @@ sub cmd_antifuck
return weechat::WEECHAT_RC_OK;
}
sub fuckbuf_input
{
return weechat::WEECHAT_RC_OK;
}
sub fuckbuf_input { return weechat::WEECHAT_RC_OK; }
sub fuckbuf_close
{
@ -120,7 +140,7 @@ sub irc_connect
my ($autojoin) = (weechat::config_string(weechat::config_get(
"irc.server.$server.autojoin")) =~ /^([^ ]*)/);
$channels{$server}{$_} = 1 for (split ',', lc($autojoin));
$zombie{$server}{$_} = 1 for (split ',', lc($autojoin));
return weechat::WEECHAT_RC_OK;
}
@ -131,6 +151,7 @@ sub irc_disconnect
$server = lc $server;
delete $channels{$server};
delete $zombie{$server};
delete $part{$server};
return weechat::WEECHAT_RC_OK;
@ -139,7 +160,6 @@ sub irc_disconnect
sub buffer_opened {
my $buffer = pop;
my ($server, $channel) = servchan($buffer);
return weechat::WEECHAT_RC_OK if exists $channels{$server}{$channel};
return weechat::WEECHAT_RC_OK if ignored($server);
@ -172,7 +192,9 @@ sub client_join
shift =~ /^join :?([^ ]*)/i);
($server, $channel) = (lc $server, lc $channel);
($_ eq '0' ? %{$channels{$server}} = () : $channels{$server}{$_} = 1)
reset_gc();
($_ eq '0' ? %{$channels{$server}} = () : $zombie{$server}{$_} = 1)
for (split ',', $channel);
return weechat::WEECHAT_RC_OK;
}
@ -188,6 +210,7 @@ sub client_part
return weechat::WEECHAT_RC_OK;
}
# RPL_WELCOME
sub irc_001
{
my (undef, $server, $message) = (shift,
@ -204,30 +227,61 @@ sub irc_001
return weechat::WEECHAT_RC_OK;
}
sub irc_366
sub irc_join
{
my ($server, $message) = ($_[2], $_[3]);
my ($nick, $channel) = $message =~ /^:[^ ]* 366 ([^ ]*) ([^ ]*)/i;
my $buffer = weechat::buffer_search('irc', "$server.$channel");
($server, $channel) = (lc $server, lc $channel);
my ($server, $message, $msghash) = (lc $_[2], $_[3], ircparse($_[3]));
my ($nick, $channel) = ($msghash->{nick}, $msghash->{channel});
my $buffer = ircbuf("$server.$channel");
return $message unless mynick($buffer, $nick);
if (exists $zombie{$server}{$channel} || ignored($server)) {
delete $zombie{$server}{$channel};
$channels{$server}{$channel} = 1;
return $message;
}
# XXX return $message unless mynick($buffer, $nick);
return $message if exists $channels{$server}{$channel};
return $message if ignored($server);
weechat::print($buffer, weechat::prefix('network').
'Forcejoined, not syncing modes');
return '' unless weechat::config_get_plugin('autopart');
$part{$server}{$channel} = 1;
$timeout_cb = weechat::hook_timer(
weechat::config_get_plugin('delay'), 0, 1, 'irc_join_delay', $buffer)
unless $timeout_cb;
unless $timeout_cb || !weechat::config_get_plugin('autopart');
return $message unless nobufs();
$fuckbuf = weechat::buffer_new(
'antifuck',
'fuckbuf_input',
'',
'fuckbuf_close',
''
) unless $fuckbuf;
weechat::print($fuckbuf, weechat::prefix('join').
weechat::color('irc.color.message_join').
'You were forced to join '.weechat::color('chat_channel').$channel.
weechat::color('reset').weechat::color('irc.color.message_join').
', leaving');
return '';
}
# RPL_ENDOFNAMES
sub irc_366
{
my ($server, $message) = ($_[2], $_[3]);
my ($nick, $channel) = $message =~ /^:[^ ]* 366 ([^ ]*) ([^ ]*)/i;
my $buffer = ircbuf("$server.$channel");
($server, $channel) = (lc $server, lc $channel);
return $message if exists $channels{$server}{$channel};
return '' if nobufs();
weechat::print($buffer, weechat::prefix('network').
'Forcejoined, not syncing modes');
return '';
}
# ERR_LINKCHANNEL
sub irc_470
{
my (undef, $server, $oldchan, $newchan) = (shift,
@ -267,6 +321,12 @@ sub irc_join_delay
return weechat::WEECHAT_RC_OK;
}
sub run_gc
{
%zombie = ();
return weechat::WEECHAT_RC_OK;
}
sub irc_part
{
my ($server, $message) = ($_[2], $_[3]);
@ -283,7 +343,7 @@ sub irc_part
);
my ($nick, $channel) = ($message =~ /^:([^!]*)[^ ]* part ([^ ]*)/i);
my $buffer = weechat::buffer_search('irc', "$server.$channel");
my $buffer = ircbuf("$server.$channel");
my ($lserver, $lchannel) = (lc $server, lc $channel);
return $message unless mynick($buffer, $nick);