Skip to content

Commit 95f1177

Browse files
authored
Merge pull request #891 from zelgomer/zmartfilter
Update zmartfilter.pl to v1.02
2 parents 1db6800 + 1222e32 commit 95f1177

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

scripts/zmartfilter.pl

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use Irssi;
33
use vars qw($VERSION %IRSSI);
44

5-
$VERSION = "1.01";
5+
$VERSION = "1.02";
66
%IRSSI = (
77
name => "zmartfilter",
88
description => "smartfilter.pl reimagined, optimized for unusually flakey networks such as IRC over I2P",
@@ -26,7 +26,7 @@
2626

2727

2828
Irssi::theme_register([
29-
squelched => "{line_start} {channick_hilight \$0} {chanhost_hilight \$1} squelched",
29+
squelched => "{channick_hilight \$0} {chanhost_hilight \$1} squelched",
3030
]);
3131

3232

@@ -135,13 +135,29 @@ sub message_kick {
135135
activity($server, $channel, undef, $nick);
136136
}
137137

138+
sub message_nick {
139+
my ($server, $newnick, $oldnick) = @_;
140+
# if this user recently joined any channels then entries relating to
141+
# $oldnick in the tjoined table need to be copied with $newnick; no
142+
# reason to bother deleting the $oldnick entries now, they will get
143+
# collected after $join_time elapses
144+
for my $oldkey (keys %tjoined) {
145+
my ($s, $t, $n) = split(/$;/, $oldkey);
146+
if ($s eq $server->{tag} && $n eq $oldnick) {
147+
my $newkey = join($;, $s, $t, $newnick);
148+
$tjoined{$newkey} = $tjoined{$oldkey};
149+
}
150+
}
151+
}
152+
138153
sub message_server_channel_nick_address { activity(@_[0, 1, 3, 2]); }
139154

140155
Irssi::signal_add({
141156
"message public" => \&message_server_x_x_address_target,
142157
"message own_public" => \&message_own_public,
143158
"message join" => \&message_join,
144159
"message kick" => \&message_kick,
160+
"message nick" => \&message_nick,
145161
"message invite" => \&message_server_channel_nick_address,
146162
"message topic" => sub { activity(@_[0, 1, 4]); },
147163
"message irc op_public" => \&message_server_x_x_address_target,
@@ -158,20 +174,45 @@ sub message_kick {
158174
sub print_text {
159175
my ($dest, $text, $stripped) = @_;
160176

161-
# only filter text bound for channel windows
162-
my ($now, $server, $target) = ( time(), $dest->{server}, $dest->{target} );
163-
if (!$server || !$server->{connected} || !$server->ischannel($target)) {
177+
# only filter text bound for a dest with a connected server
178+
my ($now, $server) = ( time(), $dest->{server} );
179+
if (!$server || !$server->{connected}) {
164180
return;
165181
}
166182

167-
# don't filter text bound for channels in the whitelist
168-
if (grep { $_ eq $target } @whitelist_channels) {
183+
my ($level, @targets) = $dest->{level};
184+
if ($level & (MSGLEVEL_NICKS | MSGLEVEL_QUITS)) {
185+
# nick changes and quits are printed only once per window, so
186+
# $dest could reference a channel where this user is considered
187+
# inactive when there is another channel in the same window
188+
# (e.g., /JOIN -window or /QUERY -window) where the user is
189+
# considered active, in which case the text would be
190+
# erroneously suppressed; so all further processing must
191+
# consider every windowitem associated with this window and
192+
# server
193+
@targets = grep { $_->{server} && $_->{server}->{tag} eq $server->{tag} } $dest->{window}->items();
194+
} else {
195+
# other messages are printed for each windowitem, even if
196+
# they're in the same window, so @targets includes only the
197+
# single relevant windowitem
198+
@targets = ( $dest->{window}->item_find($server, $dest->{target}) );
199+
}
200+
201+
# only filter text bound only for channels
202+
if (grep { !$server->ischannel($_->{name}) } @targets) {
169203
return;
170204
}
171205

172-
my ($level, @nicks, %addresses) = $dest->{level};
206+
# don't filter text bound for channels in the whitelist
207+
for my $target (@targets) {
208+
if (grep { $_ eq $target->{name} } @whitelist_channels) {
209+
return;
210+
}
211+
}
212+
213+
my (@nicks, %addresses);
173214
if ($level & (MSGLEVEL_JOINS | MSGLEVEL_PARTS | MSGLEVEL_QUITS)) {
174-
if ($stripped =~ /([^ ]+) \[([^]]+)\] has (joined|left|quit)/) {
215+
if ($stripped =~ /([^ ]+) \[([^]]+)\] has (changed|joined|left|quit)/) {
175216
@nicks = ($1);
176217
# this nick may have just parted or quit, in which case
177218
# we can't rely on the channel->nick->address lookup,
@@ -197,48 +238,48 @@ sub print_text {
197238
my $slevel = MSGLEVEL_JOINS | MSGLEVEL_PARTS | MSGLEVEL_QUITS |
198239
MSGLEVEL_NICKS | MSGLEVEL_MODES;
199240
my ($athreshold, $jthreshold) = ( $now - $allow_time, $now - $join_time );
200-
for my $nick (@nicks) {
241+
for my $target (@targets) { for my $nick (@nicks) {
201242
if ($nick eq $server->{nick}) {
202243
# it's text that relates to me
203244
return;
204245
}
205246
my $address = $addresses{$nick};
206247
if (!$address) {
207-
$address = $server->channel_find($target);
208-
$address = $address->nick_find($nick);
248+
$address = $target->nick_find($nick);
209249
$address = $address->{host};
210250
if (!$address) {
211251
next;
212252
}
253+
$addresses{$nick} = $address; # for future iterations
213254
}
214255
if ($server->mask_match_address('*!*@services.*', "", $address)) {
215256
# relates to network services
216257
return;
217258
}
218-
my $key = join($;, $server->{tag}, $target, $address);
259+
my $key = join($;, $server->{tag}, $target->{name}, $address);
219260
my $tstamp = $tactive{$key};
220261
if ($tstamp && $athreshold < $tstamp) {
221262
if (0 < $allow_max && ++$nallowed{$key} <= $allow_max) {
222263
# relates to an active user who hasn't been
223264
# squelched by $allow_max yet
224265
return;
225266
}
226-
$server->printformat($target, $slevel, "squelched",
267+
$server->printformat($target->{name}, $slevel, "squelched",
227268
$nick, $address);
228269
delete $tactive{$key};
229270
delete $nallowed{$key};
230271
}
231272
if ($level & MSGLEVEL_MODES) {
232-
# also check whether any nicks affected a mode change
233-
# were NOT recently joined, in which case this was a
234-
# spontaneous mode change (perhaps a new operator
273+
# also check whether any nicks affected by a mode
274+
# change were NOT recently joined, in which case this
275+
# was a spontaneous mode change (perhaps a new operator
235276
# elevation) and I want to see it
236-
$tstamp = $tjoined{$server->{tag}, $target, $nick};
277+
$tstamp = $tjoined{$server->{tag}, $target->{name}, $nick};
237278
if (!$tstamp || $tstamp <= $jthreshold) {
238279
return;
239280
}
240281
}
241-
}
282+
} }
242283

243284
# if I made it this far it means this text is to be suppressed
244285
Irssi::signal_stop();

0 commit comments

Comments
 (0)