Save Xchat::get_info("xchatdir") in $xchatdir variable
[softsnow_xchat2_filter.git] / SoftSnow_filter.pl
bloba74aec7615926559187dc662337f1c9382cbaf12
1 #!/usr/bin/perl
3 # SoftSnow XChat2 filter script
5 ## Summary:
6 ##
7 # Filter out fileserver announcements and SPAM on IRC
9 ## Description:
11 # This script started as an upgrade to the SoftSnow filter script
12 # from http://dukelupus.pri.ee/softsnow/ircscripts/scripts.shtml
13 # or http://softsnow.griffin3.com/ircscripts/scripts.shtml
14 # (originally http://www.softsnow.biz/softsnow_filter/filter.shtml)
15 # It borrows some ideas from filter-ebooks (#ebooks Xchat2 filter
16 # script) by KiBo, and its older version by RJVJR, mainly moving
17 # from the old IRC:: interface to the new Xchat2 API.
19 # Tested on #ebooks channel on IRCHighWay (irc.irchighway.net)
21 # Use '/FILTER HELP' (or '/HELP FILTER') to list all commands.
22 # By default filter is turned off: use '/FILTER ON' to start
23 # filtering contents, use '/FILTERWINDOW ON' to log filtered
24 # lines to '(filtered)' window.
27 ## Install:
29 # Place SoftSnow_filter.pl in your ~/.xchat directory
31 ## URL (repositories):
32 # * http://github.com/jnareb/softsnow-xchat2-filter
33 # * http://gitorious.org/projects/softsnow-xchat2-filter
34 # * http://repo.or.cz/w/softsnow_xchat2_filter.git
36 ## ChangeLog (main points only):
38 # Version 1.2:
39 # * Original version of SoftSnow filter this one is based on
40 # Version 1.2.2:
41 # * Add /FILTER command, to turn filter off and on, and to limit
42 # filtering to current IRC server only
43 # Version 1.2.3:
44 # * Allow to save and load filter rules from file (UNIX only)
45 # * Add ALLOW rules, for example to show '@search' while filtering '@'
46 # Version 2.0.1:
47 # * Use new XChat2 API (Xchat:: instead of IRC::)
48 # Version 2.0.5:
49 # * More secure saving rules to a file (always save whole file)
50 # Version 2.1.0:
51 # * Allow printing (logging) filtered content to '(filtered)' window
52 # via 'Channel Message' text event, with nick of sender
53 # Version 2.1.3:
54 # * /FILTERWINDOW command to control and query of logging filtered
55 # contents to separate '(filtered)' window
56 # Version 2.2.0:
57 # * /FILTER DEBUG shows now some filter statistics
59 ## TODO:
61 # * Add GUI and MENU (would require XChat >= 2.4.5)
62 # * Change format of saved rules to 'm/.../' or 'qr{...}';
63 # see YAML (YAML::Types) and Data::Dumper code and output
64 # * Save and read config together with filter rules
65 # * Autosave (and autoread) configuration, if turned on
66 # * Read default config and rules from __DATA__, add reset
67 # * Save filter rules usage statistics
68 # * Import filter rules from filter-ebooks3.3FINAL script
69 # * Limit filter to specified channels (or all channels)
70 # * Filter private SPAM (SPAM sent to you, but not other)
71 # * ? Don't accept DCC from users not on common channel
72 # * ? Do not accept files, or dangerous files, from regular users
73 # * Color nicks in '(filtered)' window according to matched rule
74 # * Add command to clear '(filtered)' window
75 # * Add option to strip codes from logged filtered lines
76 # * Limit number of lines in '(filtered)' window
77 # * ? Perhaps something about '@find' and '!find' results?
78 # * Triggers, for example automatic /dccallow + resubmit,
79 # if request fails (due to double '.' in filename, etc.)
81 use strict;
82 use warnings;
84 use File::Temp qw(tempfile);
85 use File::Copy qw(move);
88 my $scriptName = "SoftSnow XChat2 Filter";
89 my $scriptVersion = "2.2.2";
90 my $scriptDescr = "Filter out file server announcements and IRC SPAM";
92 my $B = chr 2; # bold
93 my $U = chr 31; # underline
94 my $C = chr 3; # start of color sequence
95 my $R = chr 22; # reverse
96 my $O = chr 15; # reset
98 ### config ###
99 my $xchatdir = Xchat::get_info("xchatdir");
100 my $filter_file = "$xchatdir/SoftSnow_filter.conf";
102 # is filter is turned on on start
103 my $filter_turned_on = 1;
104 # if true limit to given server (host)
105 my $limit_to_server = 'irc.irchighway.net';
106 # use overrides (ALLOW before DENY)
107 my $use_filter_allow = 0;
109 # log (print) filtered content to separate window
110 my $filtered_to_window = 0;
111 # name of window with filtered lines
112 my $filter_window = "(filtered)";
113 ### end config ###
115 my $filter_commands = 'ON|OFF|STATUS|SERVER|SERVERON|ALL|HELP|DEBUG|CLEARSTATS|SORT|PRINT|ALLOW|ADD|DELETE|SAVE|LOAD';
117 my $filter_help = <<"EOF";
118 ${B}/FILTER $filter_commands${B}
119 /FILTER ON|OFF - turns filtering on/off
120 /FILTER HELP - prints this help message
121 /FILTER STATUS - prints if filter is turned on, and with what limits
122 /FILTER DEBUG - shows some info; used in debuggin the filter
123 /FILTER CLEARSTATS - reset filter statistics
124 /FILTER SORT - sort deny rules to have more often matched rules first
125 /FILTER PRINT - prints all the rules
126 /FILTER ALLOW - toggle use of ALLOW rules (before DENY).
127 /FILTER SERVER - limits filtering to current server (host)
128 /FILTER SERVERON - limits to server and turns filter on
129 /FILTER ALL - resumes filtering everywhere i.e. removes limits
130 /FILTER SAVE - saves the rules to the file $filter_file
131 /FILTER LOAD - loads the rules from the file, replacing existing rules
132 /FILTER ADD <rule> - add rule at the end of the DENY rules
133 /FILTER DELETE [<num>] - delete rule number <num>, or last rule
134 /FILTER SHOW [<num>] - show rule number <num>, or last rule
135 /FILTER VERSION - prints the name and version of this script
136 /FILTER WINDOW <arg>... - same as /FILTERWINDOW <arg>...
137 /FILTER without parameter is equivalent to /FILTER STATUS
140 my $filterwindow_commands = 'ON|OFF|CLOSE|HELP|STATUS|DEBUG';
142 my $filterwindow_help = <<"EOF";
143 ${B}/FILTERWINDOW $filterwindow_commands${B}
144 /FILTERWINDOW ON|OFF - turns saving filtered content to ${U}$filter_window${U}
145 /FILTERWINDOW CLOSE - close ${U}$filter_window${U} (and turn off logging)
146 /FILTERWINDOW STATUS - prints if saving to ${U}$filter_window${U} is turned on
147 /FILTERWINDOW HELP - prints this help message
148 /FILTERWINDOW DEBUG - shows some info; used in debugging this part of filter
149 /FILTERWINDOW without parameter is equivalent to /FILTERWINDOW STATUS
152 Xchat::register($scriptName, $scriptVersion, $scriptDescr);
154 Xchat::hook_command("FILTER", \&filter_command_handler,
155 { help_text => $filter_help });
156 Xchat::hook_command("FILTERWINDOW", \&filterwindow_command_handler,
157 { help_text => $filterwindow_help });
158 Xchat::hook_server("PRIVMSG", \&privmsg_handler);
160 Xchat::print("Loading ${B}$scriptName $scriptVersion${B}...\n".
161 " For help: ${B}/FILTER HELP${B}\n");
163 # GUI, windows, etc.
164 if ($filtered_to_window) {
165 Xchat::command("QUERY $filter_window");
168 # information about (default) options used
169 if ($filter_turned_on) {
170 Xchat::print("Filter turned ${B}ON${B}\n");
171 } else {
172 Xchat::print("Filter turned ${B}OFF${B}\n");
174 if ($limit_to_server) {
175 Xchat::print("Filter limited to server $limit_to_server\n")
177 if ($use_filter_allow) {
178 Xchat::print("Filter uses ALLOW rules\n");
181 # ------------------------------------------------------------
183 my @filter_allow = (
184 q/^\@search\s/,
187 my @filter_deny = (
188 q/\@/,
189 q/^\s*\!/,
190 q/slot\(s\)/,
191 #q/~&~&~/,
193 #xdcc
194 q/^\#\d+/,
196 #fserves
197 q/(?i)fserve.*trigger/,
198 q/(?i)trigger.*\!/,
199 q/(?i)trigger.*\/ctcp/,
200 q/(?i)type\:\s*\!/,
201 q/(?i)file server online/,
203 #ftps
204 q/(?i)ftp.*l\/p/,
206 #CTCPs
207 q/SLOTS/,
208 q/MP3 /,
210 #messages for when a file is received/failed to receive
211 q/(?i)DEFINITELY had the right stuff to get/,
212 q/(?i)has just received/,
213 q/(?i)I have just received/,
215 #mp3 play messages
216 q/is listening to/,
217 q/\]\-MP3INFO\-\[/,
219 #spammy scripts
220 q/\]\-SpR\-\[/,
221 q/We are BORG/,
223 #general messages
224 q/brave soldier in the war/,
227 my $nlines = 0; # how many lines we passed through filter
228 my $nfiltered = 0; # how many lines were filtered
229 my $checklensum = 0; # how many rules to check to catch filtered
230 my $nallow = 0; # how many lines matched ALLOW rule
231 my %stats = (); # histogram: how many times given rule was used
233 # return 1 (true) if text given as argument is to be filtered out
234 sub isFiltered {
235 my $text = shift;
236 my $regexp = '';
238 #strip colour, underline, bold codes, etc.
239 $text = Xchat::strip_code($text);
241 # count all filtered lines;
242 $nlines++;
244 if ($use_filter_allow) {
245 foreach $regexp (@filter_allow) {
246 if ($text =~ /$regexp/) {
247 $nallow++;
248 return 0;
253 my $nrules_checked = 0;
254 foreach $regexp (@filter_deny) {
255 $nrules_checked++;
257 if ($text =~ /$regexp/) {
258 # filter statistic
259 $nfiltered++;
260 $checklensum += $nrules_checked;
261 if (exists $stats{$regexp}) {
262 $stats{$regexp}++;
263 } else {
264 $stats{$regexp} = 1;
267 return 1;
271 return 0;
274 #called when someone says something in the channel
275 #1: address of speaker
276 #2: PRIVMSG constant
277 #3: channel
278 #4: text said (prefixed with :)
279 sub privmsg_handler {
280 # $_[0] - array reference containing the IRC message or command
281 # and arguments broken into words
282 # $_[1] - array reference containing the Nth word to the last word
283 my ($address, $msgtype, $channel) = @{$_[0]};
284 my ($nick, $user, $host) = ($address =~ /^:([^!]*)!([^@]+)@(.*)$/);
286 my $text = $_[1][3]; # Get server message
288 my $server = Xchat::get_info("host");
290 #-- EXAMPLE RAW COMMANDS: --
291 #chanmsg: [':epitaph!~epitaph@CPE00a0241892b7-CM014480119187.cpe.net.cable.rogers.com', 'PRIVMSG', '#werd', ':mah', 'script', 'is', 'doing', 'stuff.']
292 #action: [':rlz!railz@bzq-199-176.red.bezeqint.net', 'PRIVMSG', '#werd', ':\x01ACTION', 'hugs', 'elhaym', '\x01']
293 #private: [':olene!oqd@girli.sh', 'PRIVMSG', 'epinoodle', ':hey']
296 return Xchat::EAT_NONE unless $filter_turned_on;
297 if ($limit_to_server) {
298 return Xchat::EAT_NONE unless $server eq $limit_to_server;
300 # do not filter out private messages
301 return Xchat::EAT_NONE unless ($channel =~ /^#/);
303 $text =~ s/^://;
305 if (isFiltered($text)) {
306 if (defined $nick && $filtered_to_window) {
307 #Xchat::print($text, $filter_window)
309 my $ctx = Xchat::get_context();
310 Xchat::set_context($filter_window);
311 Xchat::emit_print('Channel Message', $nick, $text);
312 Xchat::set_context($ctx);
314 #return Xchat::EAT_XCHAT;
315 return Xchat::EAT_ALL;
317 return Xchat::EAT_NONE;
321 # ------------------------------------------------------------
323 sub save_filter {
324 my ($fh, $tmpfile) = tempfile($filter_file.'.XXXXXX', UNLINK=>1);
326 unless ($fh) {
327 Xchat::print("${B}FILTER:${B} ".
328 "Couldn't open temporary file $tmpfile to save filter: $!\n");
329 return;
332 Xchat::print("${B}FILTER SAVE >$filter_file${B}\n");
333 foreach my $regexp (@filter_deny) {
334 Xchat::print("/".$regexp."/ saved\n");
335 print $fh $regexp."\n";
338 unless (close $fh) {
339 Xchat::print("${B}FILTER:${B} Couldn't close file to save filter: $!\n");
340 return;
342 #move($tmpfile, $filter_file);
343 rename($tmpfile, $filter_file);
344 Xchat::print("${B}FILTER SAVED ----------${B}\n");
346 return 1;
349 sub load_filter {
350 my $fh;
352 Xchat::print("${B}FILTER:${B} ...loading filter patterns\n");
353 unless (open $fh, '<', $filter_file) {
354 Xchat::print("${B}FILTER:${B} Couldn't open file to load filter: $!\n");
355 return;
358 @filter_deny = <$fh>;
359 map (chomp, @filter_deny);
361 unless (close $fh) {
362 Xchat::print("${B}FILTER:${B} Couldn't close file to load filter: $!\n");
363 return;
366 Xchat::print("${B}FILTER DENY START ----------${B}\n");
367 for (my $i = 0; $i <= $#filter_deny; $i++) {
368 Xchat::print(" [$i]: /".$filter_deny[$i]."/\n");
370 Xchat::print("${B}FILTER DENY END ------------${B}\n");
373 sub add_rule ( $ ) {
374 my $rule = shift;
376 # always ading rules at the end
377 push @filter_deny, $rule;
380 sub delete_rule ( $ ) {
381 my $num = shift || $#filter_deny;
383 splice @filter_deny, $num, 1;
386 sub slquote {
387 my $text = shift;
389 $text =~ s!([\/])!\$1!g;
391 return $text;
394 # ============================================================
395 # ------------------------------------------------------------
396 # ............................................................
398 sub cmd_version {
399 Xchat::print("${B}$scriptName $scriptVersion${B}\n");
400 Xchat::print(" * URL: http://github.com/jnareb/softsnow-xchat2-filter\n");
401 Xchat::print(" * URL: http://gitorious.org/projects/softsnow-xchat2-filter\n");
402 Xchat::print(" * URL: http://repo.or.cz/w/softsnow_xchat2_filter.git\n");
405 sub cmd_status {
406 my $server = shift;
408 if ($filter_turned_on) {
409 Xchat::print("Filter is turned ${B}ON${B}\n");
410 } else {
411 Xchat::print("Filter is turned ${B}OFF${B}\n");
413 if ($limit_to_server) {
414 if ($server eq $limit_to_server) {
415 Xchat::print("Filter is limited to ${B}current${B} ".
416 "server $limit_to_server\n");
417 } else {
418 Xchat::print("Filter is limited to server ".
419 "$limit_to_server != $server\n");
422 if ($use_filter_allow) {
423 Xchat::print("Filter is using ALLOW rules (before DENY)\n");
427 sub cmd_debug {
428 Xchat::print("${B}FILTER DEBUG START ----------${B}\n");
429 Xchat::print("Channel: ".Xchat::get_info("channel")."\n");
430 Xchat::print("Host: ".Xchat::get_info("host")."\n");
431 Xchat::print("Server: ".Xchat::get_info("server")."\n");
432 Xchat::print("Server Id: ".Xchat::get_info("id")."\n");
433 Xchat::print("Network: ".Xchat::get_info("network")."\n");
435 Xchat::print("\n");
436 Xchat::printf("%3u %s rules\n", scalar(@filter_allow), "allow");
437 Xchat::printf("%3u %s rules\n", scalar(@filter_deny), "deny");
439 my %deny_idx = ();
440 # %deny_idx = map { $filter_deny[$_] => $_ } 0..$#filter_deny;
441 @deny_idx{ @filter_deny } = (0..$#filter_deny);
442 Xchat::print("\n");
443 Xchat::print("filtered lines = $nfiltered out of $nlines\n");
444 if ($nlines > 0) {
445 Xchat::printf("filtered ratio = %f (%5.1f%%)\n",
446 $nfiltered/$nlines, 100.0*$nfiltered/$nlines);
448 if ($nfiltered > 0) {
449 Xchat::print("average to match = ".$checklensum/$nfiltered."\n");
450 foreach my $rule (sort { $stats{$b} <=> $stats{$a} } keys %stats) {
451 Xchat::printf("%5u: %5.1f%% [%2u] /%s/\n",
452 $stats{$rule}, 100.0*$stats{$rule}/$nfiltered,
453 $deny_idx{$rule}, slquote($rule));
456 if ($use_filter_allow || $nallow > 0) {
457 Xchat::print("allow matches = $nallow\n");
459 Xchat::print("${B}FILTER DEBUG END ------------${B}\n");
462 sub cmd_clear_stats {
463 $nlines = 0;
464 $nfiltered = 0;
465 $checklensum = 0;
466 $nallow = 0;
467 %stats = ();
469 Xchat::print("${B}FILTER:${B} stats cleared\n");
472 sub cmd_sort_by_stats {
473 use sort 'stable';
475 @filter_deny =
476 sort { ($stats{$b} || 0) <=> ($stats{$a} || 0) }
477 @filter_deny;
479 Xchat::print("${B}FILTER:${B} DENY rules sorted by their use descending\n");
482 sub cmd_server_limit {
483 my $server = shift;
485 if ($server) {
486 # adding limiting to given (single) server
487 if ($limit_to_server) {
488 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
489 Xchat::print("[FILTER LIMITED TO SERVER ${B}$server${B} (WAS TO $limit_to_server)]",
490 $filter_window);
491 } else {
492 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
493 Xchat::print("[FILTER LIMITED TO SERVER ${B}$server${B} (WAS UNLIMITED)]",
494 $filter_window);
496 $limit_to_server = $server;
498 } else {
499 # removing limiting to server
500 if ($limit_to_server) {
501 Xchat::print("${B}FILTER:${B} Removing limit to server $limit_to_server\n");
502 Xchat::print("[FILTER ${B}NOT LIMITED${B} TO SERVER (WAS TO $limit_to_server)]",
503 $filter_window);
505 $limit_to_server = '';
510 sub cmd_print_rules {
511 Xchat::print("${B}FILTER PRINT START ----------${B}\n");
512 Xchat::print("${B}ALLOW${B}".($use_filter_allow ? ' (on)' : ' (off)')."\n");
514 for (my $i = 0; $i <= $#filter_allow; $i++) {
515 Xchat::print("[$i]: /".$filter_allow[$i]."/\n");
517 Xchat::print("${B}DENY${B}\n");
518 for (my $i = 0; $i <= $#filter_deny; $i++) {
519 Xchat::print("[$i]: /".$filter_deny[$i]."/\n");
521 Xchat::print("${B}FILTER PRINT END ------------${B}\n");
524 sub cmd_add_rule {
525 my $rule = shift;
527 if ($rule) {
528 add_rule($rule);
529 Xchat::print("${B}FILTER RULE [$#filter_deny]:${B} /$rule/\n");
530 } else {
531 Xchat::print("Syntax: ${B}/FILTER ADD ${U}rule${U}${B} to add\n")
535 sub cmd_delete_rule {
536 my $num = shift;
538 # strip whitespace
539 $num =~ s/^\s*(.*?)\s*$/$1/g if $num;
540 SWITCH: {
541 unless ($num) {
542 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[-1]."/\n");
543 $#filter_deny--;
544 Xchat::print("${B}FILTER:${B} deleted successfully last rule\n");
545 last SWITCH;
547 if ($num !~ /^\d+$/) {
548 Xchat::print("${B}FILTER:${B} $num is not a number\n");
549 last SWITCH;
551 if ($num < 0 || $num > $#filter_deny) {
552 Xchat::print("${B}FILTER:${B} $num outside range [0,$#filter_deny]\n");
553 last SWITCH;
555 # default
557 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[$num]."/\n");
558 delete_rule($num);
559 Xchat::print("${B}FILTER:${B} deleted successfully rule $num\n");
564 sub cmd_show_rule {
565 my $num = shift;
567 $num =~ s/^\s*(.*?)\s*$/$1/g if $num;
569 if (defined $num && $num !~ /^\d+$/) {
570 Xchat::print("${B}FILTER:${B} $num is not a number\n");
571 } elsif (defined $num && !defined $filter_deny[$num]) {
572 Xchat::print("${B}FILTER:${B} rule $num does not exist\n");
573 } else {
574 Xchat::print("${B}FILTER:${B} ".(defined $num ? "[$num]" : "last").
575 " rule /".$filter_deny[defined $num ? $num : -1]."/\n");
579 # ============================================================
580 # ============================================================
581 # ============================================================
583 sub filter_command_handler {
584 my $cmd = $_[0][1]; # 1st parameter (after FILTER)
585 my $arg = $_[1][2]; # 2nd word to the last word
586 my $server = Xchat::get_info("host");
589 if (!$cmd || $cmd =~ /^STATUS$/i) {
590 cmd_status($server);
592 } elsif ($cmd =~ /^ON$/i) {
593 $filter_turned_on = 1;
594 Xchat::print("Filter turned ${B}ON${B}\n");
595 Xchat::print("[FILTER TURNED ${B}ON${B}]",
596 $filter_window);
598 } elsif ($cmd =~ /^OFF$/i) {
599 $filter_turned_on = 0;
600 Xchat::print("Filter turned ${B}OFF${B}\n");
601 Xchat::print("[FILTER TURNED ${B}OFF${B}]",
602 $filter_window);
604 } elsif ($cmd =~ /^SERVER$/i) {
605 cmd_server_limit($server);
607 } elsif ($cmd =~ /^SERVERON$/i) {
608 cmd_server_limit($server);
610 Xchat::print("[FILTER TURNED ${B}ON${B}]",
611 $filter_window)
612 if (!$filter_turned_on);
613 $filter_turned_on = 1;
614 Xchat::print("Filter turned ${B}ON${B}\n");
616 } elsif ($cmd =~ /^ALL$/i) {
617 cmd_server_limit(undef);
619 } elsif ($cmd =~ /^HELP$/i) {
620 Xchat::print($filter_help);
621 Xchat::print($filterwindow_help);
623 } elsif ($cmd =~ /^VERSION$/i) {
624 cmd_version();
626 } elsif ($cmd =~ /^DEBUG$/i || $cmd =~ /^INFO$/i) {
627 cmd_debug();
629 } elsif ($cmd =~ /^CLEARSTAT(?:S)?$/i) {
630 cmd_clear_stats();
632 } elsif ($cmd =~ /^SORT$/i) {
633 cmd_sort_by_stats();
635 } elsif ($cmd =~ /^(?:PRINT|LIST)$/i) {
636 cmd_print_rules();
638 } elsif ($cmd =~ /^ALLOW$/i) {
639 $use_filter_allow = !$use_filter_allow;
640 Xchat::print("${B}FILTER:${B} ALLOW rules ".
641 ($use_filter_allow ? "enabled" : "disabled")."\n");
643 } elsif ($cmd =~ /^ADD$/i) {
644 cmd_add_rule($arg);
646 } elsif ($cmd =~ /^DEL(?:ETE)$/i) {
647 cmd_delete_rule($arg);
649 } elsif ($cmd =~ /^SHOW$/i) {
650 cmd_show_rule($arg);
652 } elsif ($cmd =~ /^SAVE$/i) {
653 save_filter();
654 Xchat::print("${B}FILTER:${B} saved DENY rules to $filter_file\n");
656 } elsif ($cmd =~ /^(RE)?LOAD$/i) {
657 load_filter();
658 Xchat::print("${B}FILTER:${B} loaded DENY rules from $filter_file\n");
660 } elsif ($cmd =~ /^WINDOW$/i) {
661 return filterwindow_command_handler(
662 [ 'FILTERWINDOW', @{$_[0]}[2..$#{$_[0]}] ],
663 [ "FILTERWINDOW $_[1][2]", @{$_[1]}[2..$#{$_[1]}] ],
664 $_[2]
667 } else {
668 Xchat::print("Unknown command ${B}/FILTER $_[1][1]${B}\n") if $cmd;
670 return 1;
673 sub filterwindow_command_handler {
674 my $cmd = $_[0][1]; # 1st parameter (after FILTER)
675 #my $arg = $_[1][2]; # 2nd word to the last word
676 my $ctx = Xchat::find_context($filter_window);
678 if (!$cmd || $cmd =~ /^STATUS$/i) {
679 Xchat::print(($filtered_to_window ? "Show" : "Don't show").
680 " filtered content in ".
681 (defined $ctx ? "open" : "closed").
682 " window ${B}$filter_window${B}\n");
684 } elsif ($cmd =~ /^DEBUG$/i) {
685 my $ctx_info = Xchat::context_info($ctx);
686 Xchat::print("${B}FILTERWINDOW DEBUG START ----------${B}\n");
687 Xchat::print("filtered_to_window = $filtered_to_window\n");
688 Xchat::print("filter_window = $filter_window\n");
689 if (defined $ctx) {
690 Xchat::print("$filter_window is ${B}open${B}\n");
691 Xchat::print("$filter_window: network => $ctx_info->{network}\n")
692 if defined $ctx_info->{'network'};
693 Xchat::print("$filter_window: host => $ctx_info->{host}\n")
694 if defined $ctx_info->{'host'};
695 Xchat::print("$filter_window: channel => $ctx_info->{channel}\n");
696 Xchat::print("$filter_window: server_id => $ctx_info->{id}\n")
697 if defined $ctx_info->{'id'};
698 } else {
699 Xchat::print("$filter_window is ${B}closed${B}\n");
701 # requires XChat >= 2.8.2
702 #Xchat::print("'Channel Message' format: ".
703 # Xchat::get_info("event_text Channel Message")."\n");
704 #Xchat::print("'Channel Msg Hilight' format: ".
705 # Xchat::get_info("event_text Channel Msg Hilight")."\n");
706 Xchat::print("${B}FILTERWINDOW DEBUG END ------------${B}\n");
708 } elsif ($cmd =~ /^ON$/i) {
709 Xchat::command("QUERY $filter_window");
710 Xchat::print("${B}----- START LOGGING FILTERED CONTENTS -----${B}\n",
711 $filter_window)
712 if !$filtered_to_window;
714 $filtered_to_window = 1;
715 Xchat::print("Filter shows filtered content in ${B}$filter_window${B}\n");
717 } elsif ($cmd =~ /^(?:OFF|CLOSE)$/i) {
718 Xchat::print("${B}----- STOP LOGGING FILTERED CONTENTS ------${B}\n",
719 $filter_window)
720 if $filtered_to_window;
721 Xchat::command("CLOSE", $filter_window)
722 if ($cmd =~ /^CLOSE$/i);
724 $filtered_to_window = 0;
725 Xchat::print("Filter doesn't show filtered content in ${B}$filter_window${B}\n");
726 Xchat::print("${B}FILTER:${B} ${B}$filter_window${B} closed\n")
727 if ($cmd =~ /^CLOSE$/i);
729 } elsif ($cmd =~ /^HELP$/i) {
730 Xchat::print($filterwindow_help);
732 } else {
733 Xchat::print("Unknown command ${B}/FILTERWINDOW $_[1][1]${B}\n") if $cmd;
734 Xchat::print("${B}${U}USAGE:${U} /FILTERWINDOW $filterwindow_commands${B}\n");
737 return 1;
740 # ======================================================================
741 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
742 # ----------------------------------------------------------------------
744 # somehow this isn't visible...
745 Xchat::print("${B}$scriptName $scriptVersion${B} loaded\n");