SoftSnow XChat2 Filter 2.2.0
[softsnow_xchat2_filter.git] / SoftSnow_filter.pl
blobf56b3aff92e0cf5f210eab94fc40ddca3bbfbf3d
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 ## Install:
23 # Place SoftSnow_filter.pl in your ~/.xchat directory
25 ## URL (repositories):
26 # * http://github.com/jnareb/softsnow-xchat2-filter
27 # * http://gitorious.org/projects/softsnow-xchat2-filter
28 # * http://repo.or.cz/w/softsnow_xchat2_filter.git
30 ## ChangeLog (main points only):
32 # Version 1.2:
33 # * Original version of SoftSnow filter this one is based on
34 # Version 1.2.2:
35 # * Add /FILTER command, to turn filter off and on, and to limit
36 # filtering to current IRC server only
37 # Version 1.2.3:
38 # * Allow to save and load filter rules from file (UNIX only)
39 # * Add ALLOW rules, for example to show '@search' while filtering '@'
40 # Version 2.0.1:
41 # * Use new XChat2 API (Xchat:: instead of IRC::)
42 # Version 2.0.5:
43 # * More secure saving rules to a file (always save whole file)
44 # Version 2.1.0:
45 # * Allow printing (logging) filtered content to '(filtered)' window
46 # via 'Channel Message' text event, with nick of sender
47 # Version 2.1.3:
48 # * /FILTERWINDOW command to control and query of logging filtered
49 # contents to separate '(filtered)' window
51 ## TODO:
53 # * Add GUI and MENU (would require XChat >= 2.4.5)
54 # * Change format of saved rules to 'm/.../' or 'qr{...}';
55 # see YAML (YAML::Types) and Data::Dumper code and output
56 # * Save and read config together with filter rules
57 # * Read default config and rules from __DATA__, add reset
58 # * Save filter rules usage statistics
59 # * Import filter rules from filter-ebooks3.3FINAL script
60 # * Limit filter to specified channels (or all channels)
61 # * Filter private SPAM (SPAM sent to you, but not other)
62 # * ? Don't accept DCC from users not on common channel
63 # * ? Do not accept files, or dangerous files, from regular users
64 # * Color nicks in '(filtered)' window according to matched rule
65 # * Add command to clear '(filtered)' window
66 # * Add option to strip codes from logged filtered lines
67 # * Limit number of lines in '(filtered)' window
68 # * ? Perhaps something about '@find' and '!find' results?
70 use strict;
71 use warnings;
73 use File::Temp qw(tempfile);
74 use File::Copy qw(move);
77 my $scriptName = "SoftSnow XChat2 Filter";
78 my $scriptVersion = "2.2.0";
79 my $scriptDescr = "Filter out file server announcements and IRC SPAM";
81 my $B = chr 2; # bold
82 my $U = chr 31; # underline
83 my $C = chr 3; # start of color sequence
84 my $R = chr 22; # reverse
85 my $O = chr 15; # reset
87 ### config ###
88 my $filter_file = Xchat::get_info("xchatdir") . "/SoftSnow_filter.conf";
90 my $filter_turned_on = 0; # is filter is turned on
91 my $limit_to_server = ''; # if true limit to given server (host)
92 my $use_filter_allow = 0; # use overrides (ALLOW before DENY)
94 my $filtered_to_window = 0;
95 my $filter_window = "(filtered)";
96 ### end config ###
98 my $filter_commands = 'ON|OFF|STATUS|SERVER|SERVERON|ALL|HELP|DEBUG|CLEARSTATS|SORT|PRINT|ALLOW|ADD|DELETE|SAVE|LOAD';
100 my $filter_help = <<"EOF";
101 ${B}/FILTER $filter_commands${B}
102 /FILTER ON|OFF - turns filtering on/off
103 /FILTER HELP - prints this help message
104 /FILTER STATUS - prints if filter is turned on, and with what limits
105 /FILTER DEBUG - shows some info; used in debuggin the filter
106 /FILTER CLEARSTATS - reset filter statistics
107 /FILTER SORT - sort deny rules to have more often matched rules first
108 /FILTER PRINT - prints all the rules
109 /FILTER ALLOW - toggle use of ALLOW rules (before DENY).
110 /FILTER SERVER - limits filtering to current server (host)
111 /FILTER SERVERON - limits to server and turns filter on
112 /FILTER ALL - resumes filtering everywhere i.e. removes limits
113 /FILTER SAVE - saves the rules to the file $filter_file
114 /FILTER LOAD - loads the rules from the file, replacing existing rules
115 /FILTER ADD <rule> - add rule at the end of the DENY rules
116 /FILTER DELETE [<num>] - delete rule number <num>, or last rule
117 /FILTER SHOW [<num>] - show rule number <num>, or last rule
118 /FILTER VERSION - prints the name and version of this script
119 /FILTER WINDOW <arg>... - same as /FILTERWINDOW <arg>...
120 /FILTER without parameter is equivalent to /FILTER STATUS
123 my $filterwindow_commands = 'ON|OFF|CLOSE|HELP|STATUS|DEBUG';
125 my $filterwindow_help = <<"EOF";
126 ${B}/FILTERWINDOW $filterwindow_commands${B}
127 /FILTERWINDOW ON|OFF - turns saving filtered content to ${U}$filter_window${U}
128 /FILTERWINDOW CLOSE - close ${U}$filter_window${U} (and turn off logging)
129 /FILTERWINDOW STATUS - prints if saving to ${U}$filter_window${U} is turned on
130 /FILTERWINDOW HELP - prints this help message
131 /FILTERWINDOW DEBUG - shows some info; used in debugging this part of filter
132 /FILTERWINDOW without parameter is equivalent to /FILTERWINDOW STATUS
135 Xchat::register($scriptName, $scriptVersion, $scriptDescr);
137 Xchat::hook_command("FILTER", \&filter_command_handler,
138 { help_text => $filter_help });
139 Xchat::hook_command("FILTERWINDOW", \&filterwindow_command_handler,
140 { help_text => $filterwindow_help });
141 Xchat::hook_server("PRIVMSG", \&privmsg_handler);
143 Xchat::print("Loading ${B}$scriptName $scriptVersion${B}...\n");
146 # GUI, windows, etc.
147 if ($filtered_to_window) {
148 Xchat::command("QUERY $filter_window");
151 # information about (default) options used
152 if ($filter_turned_on) {
153 Xchat::print("Filter turned ${B}ON${B}\n");
154 } else {
155 Xchat::print("Filter turned ${B}OFF${B}\n");
157 if ($limit_to_server) {
158 Xchat::print("Filter limited to server $limit_to_server\n")
160 if ($use_filter_allow) {
161 Xchat::print("Filter uses ALLOW rules\n");
164 # ------------------------------------------------------------
166 my @filter_allow = (
167 q/^\@search\s/,
170 my @filter_deny = (
171 q/\@/,
172 q/^\s*\!/,
173 q/slot\(s\)/,
174 #q/~&~&~/,
176 #xdcc
177 q/^\#\d+/,
179 #fserves
180 q/(?i)fserve.*trigger/,
181 q/(?i)trigger.*\!/,
182 q/(?i)trigger.*\/ctcp/,
183 q/(?i)type\:\s*\!/,
184 q/(?i)file server online/,
186 #ftps
187 q/(?i)ftp.*l\/p/,
189 #CTCPs
190 q/SLOTS/,
191 q/MP3 /,
193 #messages for when a file is received/failed to receive
194 q/(?i)DEFINITELY had the right stuff to get/,
195 q/(?i)has just received/,
196 q/(?i)I have just received/,
198 #mp3 play messages
199 q/is listening to/,
200 q/\]\-MP3INFO\-\[/,
202 #spammy scripts
203 q/\]\-SpR\-\[/,
204 q/We are BORG/,
206 #general messages
207 q/brave soldier in the war/,
210 my $nfiltered = 0; # how many lines were filtered
211 my $checklensum = 0; # how many rules to check to catch filtered
212 my $nallow = 0; # how many lines matched ALLOW rule
213 my %stats = (); # histogram: how many times given rule was used
215 # return 1 (true) if text given as argument is to be filtered out
216 sub isFiltered {
217 my $text = shift;
218 my $regexp = '';
220 #strip colour, underline, bold codes, etc.
221 $text = Xchat::strip_code($text);
223 if ($use_filter_allow) {
224 foreach $regexp (@filter_allow) {
225 if ($text =~ /$regexp/) {
226 $nallow++;
227 return 0;
232 my $nrules_checked = 0;
233 foreach $regexp (@filter_deny) {
234 $nrules_checked++;
236 if ($text =~ /$regexp/) {
237 # filter statistic
238 $nfiltered++;
239 $checklensum += $nrules_checked;
240 if (exists $stats{$regexp}) {
241 $stats{$regexp}++;
242 } else {
243 $stats{$regexp} = 1;
246 return 1;
250 return 0;
253 #called when someone says something in the channel
254 #1: address of speaker
255 #2: PRIVMSG constant
256 #3: channel
257 #4: text said (prefixed with :)
258 sub privmsg_handler {
259 # $_[0] - array reference containing the IRC message or command
260 # and arguments broken into words
261 # $_[1] - array reference containing the Nth word to the last word
262 my ($address, $msgtype, $channel) = @{$_[0]};
263 my ($nick, $user, $host) = ($address =~ /^:([^!]*)!([^@]+)@(.*)$/);
265 my $text = $_[1][3]; # Get server message
267 my $server = Xchat::get_info("host");
269 #-- EXAMPLE RAW COMMANDS: --
270 #chanmsg: [':epitaph!~epitaph@CPE00a0241892b7-CM014480119187.cpe.net.cable.rogers.com', 'PRIVMSG', '#werd', ':mah', 'script', 'is', 'doing', 'stuff.']
271 #action: [':rlz!railz@bzq-199-176.red.bezeqint.net', 'PRIVMSG', '#werd', ':\x01ACTION', 'hugs', 'elhaym', '\x01']
272 #private: [':olene!oqd@girli.sh', 'PRIVMSG', 'epinoodle', ':hey']
275 return Xchat::EAT_NONE unless $filter_turned_on;
276 if ($limit_to_server) {
277 return Xchat::EAT_NONE unless $server eq $limit_to_server;
279 # do not filter out private messages
280 return Xchat::EAT_NONE unless ($channel =~ /^#/);
282 $text =~ s/^://;
284 if (isFiltered($text)) {
285 if (defined $nick && $filtered_to_window) {
286 #Xchat::print($text, $filter_window)
288 my $ctx = Xchat::get_context();
289 Xchat::set_context($filter_window);
290 Xchat::emit_print('Channel Message', $nick, $text);
291 Xchat::set_context($ctx);
293 #return Xchat::EAT_XCHAT;
294 return Xchat::EAT_ALL;
296 return Xchat::EAT_NONE;
300 # ------------------------------------------------------------
302 sub save_filter {
303 my ($fh, $tmpfile) = tempfile($filter_file.'.XXXXXX', UNLINK=>1);
305 unless ($fh) {
306 Xchat::print("${B}FILTER:${B} ".
307 "Couldn't open temporary file $tmpfile to save filter: $!\n");
308 return;
311 Xchat::print("${B}FILTER SAVE >$filter_file${B}\n");
312 foreach my $regexp (@filter_deny) {
313 Xchat::print("/".$regexp."/ saved\n");
314 print $fh $regexp."\n";
317 unless (close $fh) {
318 Xchat::print("${B}FILTER:${B} Couldn't close file to save filter: $!\n");
319 return;
321 #move($tmpfile, $filter_file);
322 rename($tmpfile, $filter_file);
323 Xchat::print("${B}FILTER SAVED ----------${B}\n");
325 return 1;
328 sub load_filter {
329 my $fh;
331 Xchat::print("${B}FILTER:${B} ...loading filter patterns\n");
332 unless (open $fh, '<', $filter_file) {
333 Xchat::print("${B}FILTER:${B} Couldn't open file to load filter: $!\n");
334 return;
337 @filter_deny = <$fh>;
338 map (chomp, @filter_deny);
340 unless (close $fh) {
341 Xchat::print("${B}FILTER:${B} Couldn't close file to load filter: $!\n");
342 return;
345 Xchat::print("${B}FILTER DENY ----------${B}\n");
346 for (my $i = 0; $i <= $#filter_deny; $i++) {
347 Xchat::print(" [$i]: /".$filter_deny[$i]."/\n");
349 Xchat::print("${B}FILTER DENY ----------${B}\n");
352 sub add_rule ( $ ) {
353 my $rule = shift;
355 # always ading rules at the end
356 push @filter_deny, $rule;
359 sub delete_rule ( $ ) {
360 my $num = shift || $#filter_deny;
362 splice @filter_deny, $num, 1;
365 sub slquote {
366 my $text = shift;
368 $text =~ s!([\/])!\$1!g;
370 return $text;
373 # ============================================================
374 # ------------------------------------------------------------
375 # ............................................................
377 sub cmd_version {
378 Xchat::print("${B}$scriptName $scriptVersion${B}\n");
379 Xchat::print(" * URL: http://github.com/jnareb/softsnow-xchat2-filter\n");
380 Xchat::print(" * URL: http://gitorious.org/projects/softsnow-xchat2-filter\n");
381 Xchat::print(" * URL: http://repo.or.cz/w/softsnow_xchat2_filter.git\n");
384 sub cmd_status {
385 my $server = shift;
387 if ($filter_turned_on) {
388 Xchat::print("Filter is turned ${B}ON${B}\n");
389 } else {
390 Xchat::print("Filter is turned ${B}OFF${B}\n");
392 if ($limit_to_server) {
393 if ($server eq $limit_to_server) {
394 Xchat::print("Filter is limited to ${B}current${B} ".
395 "server $limit_to_server\n");
396 } else {
397 Xchat::print("Filter is limited to server ".
398 "$limit_to_server != $server\n");
401 if ($use_filter_allow) {
402 Xchat::print("Filter is using ALLOW rules (before DENY)\n");
406 sub cmd_debug {
407 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
408 Xchat::print("Channel: ".Xchat::get_info("channel")."\n");
409 Xchat::print("Host: ".Xchat::get_info("host")."\n");
410 Xchat::print("Server: ".Xchat::get_info("server")."\n");
411 Xchat::print("Server Id: ".Xchat::get_info("id")."\n");
412 Xchat::print("Network: ".Xchat::get_info("network")."\n");
414 Xchat::print("\n");
415 Xchat::printf("%3u %s rules\n", scalar(@filter_allow), "allow");
416 Xchat::printf("%3u %s rules\n", scalar(@filter_deny), "deny");
418 my %deny_idx = ();
419 # %deny_idx = map { $filter_deny[$_] => $_ } 0..$#filter_deny;
420 @deny_idx{ @filter_deny } = (0..$#filter_deny);
421 Xchat::print("\n");
422 Xchat::print("filtered lines = $nfiltered\n");
423 Xchat::print("average to match = ".$checklensum/$nfiltered."\n");
424 foreach my $rule (sort { $stats{$b} <=> $stats{$a} } keys %stats) {
425 Xchat::printf("%5u: %5.1f%% [%2u] /%s/\n",
426 $stats{$rule}, 100.0*$stats{$rule}/$nfiltered,
427 $deny_idx{$rule}, slquote($rule));
429 if ($use_filter_allow) {
430 Xchat::print("allow matches = $nallow\n");
432 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
435 sub cmd_clear_stats {
436 $nfiltered = 0;
437 $checklensum = 0;
438 $nallow = 0;
439 %stats = ();
441 Xchat::print("${B}FILTER:${B} stats cleared\n");
444 sub cmd_sort_by_stats {
445 use sort 'stable';
447 @filter_deny =
448 sort { ($stats{$b} || 0) <=> ($stats{$a} || 0) }
449 @filter_deny;
452 sub cmd_server_limit {
453 my $server = shift;
455 if ($server) {
456 # adding limiting to given (single) server
457 if ($limit_to_server) {
458 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
459 Xchat::print("[FILTER LIMITED TO SERVER ${B}$server${B} (WAS TO $limit_to_server)]",
460 $filter_window);
461 } else {
462 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
463 Xchat::print("[FILTER LIMITED TO SERVER ${B}$server${B} (WAS UNLIMITED)]",
464 $filter_window);
466 $limit_to_server = $server;
468 } else {
469 # removing limiting to server
470 if ($limit_to_server) {
471 Xchat::print("${B}FILTER:${B} Removing limit to server $limit_to_server\n");
472 Xchat::print("[FILTER ${B}NOT LIMITED${B} TO SERVER (WAS TO $limit_to_server)]",
473 $filter_window);
475 $limit_to_server = '';
480 sub cmd_print_rules {
481 Xchat::print("${B}FILTER PRINT ----------${B}\n");
482 Xchat::print("${B}ALLOW${B}".($use_filter_allow ? ' (on)' : ' (off)')."\n");
484 for (my $i = 0; $i <= $#filter_allow; $i++) {
485 Xchat::print("[$i]: /".$filter_allow[$i]."/\n");
487 Xchat::print("${B}DENY${B}\n");
488 for (my $i = 0; $i <= $#filter_deny; $i++) {
489 Xchat::print("[$i]: /".$filter_deny[$i]."/\n");
491 Xchat::print("${B}FILTER PRINT ----------${B}\n");
494 sub cmd_add_rule {
495 my $rule = shift;
497 if ($rule) {
498 add_rule($rule);
499 Xchat::print("${B}FILTER RULE [$#filter_deny]:${B} /$rule/\n");
500 } else {
501 Xchat::print("Syntax: ${B}/FILTER ADD ${U}rule${U}${B} to add\n")
505 sub cmd_delete_rule {
506 my $num = shift;
508 # strip whitespace
509 $num =~ s/^\s*(.*?)\s*$/$1/g if $num;
510 SWITCH: {
511 unless ($num) {
512 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[-1]."/\n");
513 $#filter_deny--;
514 Xchat::print("${B}FILTER:${B} deleted successfully last rule\n");
515 last SWITCH;
517 if ($num !~ /^\d+$/) {
518 Xchat::print("${B}FILTER:${B} $num is not a number\n");
519 last SWITCH;
521 if ($num < 0 || $num > $#filter_deny) {
522 Xchat::print("${B}FILTER:${B} $num outside range [0,$#filter_deny]\n");
523 last SWITCH;
525 # default
527 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[$num]."/\n");
528 delete_rule($num);
529 Xchat::print("${B}FILTER:${B} deleted successfully rule $num\n");
534 sub cmd_show_rule {
535 my $num = shift;
537 $num =~ s/^\s*(.*?)\s*$/$1/g if $num;
539 if (defined $num && $num !~ /^\d+$/) {
540 Xchat::print("${B}FILTER:${B} $num is not a number\n");
541 } elsif (defined $num && !defined $filter_deny[$num]) {
542 Xchat::print("${B}FILTER:${B} rule $num does not exist\n");
543 } else {
544 Xchat::print("${B}FILTER:${B} ".(defined $num ? "[$num]" : "last").
545 " rule /".$filter_deny[defined $num ? $num : -1]."/\n");
549 # ============================================================
550 # ============================================================
551 # ============================================================
553 sub filter_command_handler {
554 my $cmd = $_[0][1]; # 1st parameter (after FILTER)
555 my $arg = $_[1][2]; # 2nd word to the last word
556 my $server = Xchat::get_info("host");
559 if (!$cmd || $cmd =~ /^STATUS$/i) {
560 cmd_status($server);
562 } elsif ($cmd =~ /^ON$/i) {
563 $filter_turned_on = 1;
564 Xchat::print("Filter turned ${B}ON${B}\n");
565 Xchat::print("[FILTER TURNED ${B}ON${B}]",
566 $filter_window);
568 } elsif ($cmd =~ /^OFF$/i) {
569 $filter_turned_on = 0;
570 Xchat::print("Filter turned ${B}OFF${B}\n");
571 Xchat::print("[FILTER TURNED ${B}OFF${B}]",
572 $filter_window);
574 } elsif ($cmd =~ /^SERVER$/i) {
575 cmd_server_limit($server);
577 } elsif ($cmd =~ /^SERVERON$/i) {
578 cmd_server_limit($server);
580 Xchat::print("[FILTER TURNED ${B}ON${B}]",
581 $filter_window)
582 if (!$filter_turned_on);
583 $filter_turned_on = 1;
584 Xchat::print("Filter turned ${B}ON${B}\n");
586 } elsif ($cmd =~ /^ALL$/i) {
587 cmd_server_limit(undef);
589 } elsif ($cmd =~ /^HELP$/i) {
590 Xchat::print($filter_help);
591 Xchat::print($filterwindow_help);
593 } elsif ($cmd =~ /^VERSION$/i) {
594 cmd_version();
596 } elsif ($cmd =~ /^DEBUG$/i || $cmd =~ /^INFO$/i) {
597 cmd_debug();
599 } elsif ($cmd =~ /^CLEARSTAT(?:S)?$/i) {
600 cmd_clear_stats();
602 } elsif ($cmd =~ /^SORT$/i) {
603 cmd_sort_by_stats();
605 } elsif ($cmd =~ /^(?:PRINT|LIST)$/i) {
606 cmd_print_rules();
608 } elsif ($cmd =~ /^ALLOW$/i) {
609 $use_filter_allow = !$use_filter_allow;
610 Xchat::print("${B}FILTER:${B} ALLOW rules ".
611 ($use_filter_allow ? "enabled" : "disabled")."\n");
613 } elsif ($cmd =~ /^ADD$/i) {
614 cmd_add_rule($arg);
616 } elsif ($cmd =~ /^DEL(?:ETE)$/i) {
617 cmd_delete_rule($arg);
619 } elsif ($cmd =~ /^SHOW$/i) {
620 cmd_show_rule($arg);
622 } elsif ($cmd =~ /^SAVE$/i) {
623 save_filter();
624 Xchat::print("${B}FILTER:${B} saved DENY rules to $filter_file\n");
626 } elsif ($cmd =~ /^(RE)?LOAD$/i) {
627 load_filter();
628 Xchat::print("${B}FILTER:${B} loaded DENY rules from $filter_file\n");
630 } elsif ($cmd =~ /^WINDOW$/i) {
631 return filterwindow_command_handler(
632 [ 'FILTERWINDOW', @{$_[0]}[2..$#{$_[0]}] ],
633 [ "FILTERWINDOW $_[1][2]", @{$_[1]}[2..$#{$_[1]}] ],
634 $_[2]
637 } else {
638 Xchat::print("Unknown command ${B}/FILTER $_[1][1]${B}\n") if $cmd;
640 return 1;
643 sub filterwindow_command_handler {
644 my $cmd = $_[0][1]; # 1st parameter (after FILTER)
645 #my $arg = $_[1][2]; # 2nd word to the last word
646 my $ctx = Xchat::find_context($filter_window);
648 if (!$cmd || $cmd =~ /^STATUS$/i) {
649 Xchat::print(($filtered_to_window ? "Show" : "Don't show").
650 " filtered content in ".
651 (defined $ctx ? "open" : "closed").
652 " window ${B}$filter_window${B}\n");
654 } elsif ($cmd =~ /^DEBUG$/i) {
655 my $ctx_info = Xchat::context_info($ctx);
656 Xchat::print("${B}FILTERWINDOW DEBUG ----------${B}\n");
657 Xchat::print("filtered_to_window = $filtered_to_window\n");
658 Xchat::print("filter_window = $filter_window\n");
659 if (defined $ctx) {
660 Xchat::print("$filter_window is ${B}open${B}\n");
661 Xchat::print("$filter_window: network => $ctx_info->{network}\n")
662 if defined $ctx_info->{'network'};
663 Xchat::print("$filter_window: host => $ctx_info->{host}\n")
664 if defined $ctx_info->{'host'};
665 Xchat::print("$filter_window: channel => $ctx_info->{channel}\n");
666 Xchat::print("$filter_window: server_id => $ctx_info->{id}\n")
667 if defined $ctx_info->{'id'};
668 } else {
669 Xchat::print("$filter_window is ${B}closed${B}\n");
671 # requires XChat >= 2.8.2
672 #Xchat::print("'Channel Message' format: ".
673 # Xchat::get_info("event_text Channel Message")."\n");
674 #Xchat::print("'Channel Msg Hilight' format: ".
675 # Xchat::get_info("event_text Channel Msg Hilight")."\n");
676 Xchat::print("${B}FILTERWINDOW DEBUG ----------${B}\n");
678 } elsif ($cmd =~ /^ON$/i) {
679 Xchat::command("QUERY $filter_window");
680 Xchat::print("${B}----- START LOGGING FILTERED CONTENTS -----${B}\n",
681 $filter_window)
682 if !$filtered_to_window;
684 $filtered_to_window = 1;
685 Xchat::print("Filter shows filtered content in ${B}$filter_window${B}\n");
687 } elsif ($cmd =~ /^(?:OFF|CLOSE)$/i) {
688 Xchat::print("${B}----- STOP LOGGING FILTERED CONTENTS -----${B}\n",
689 $filter_window)
690 if $filtered_to_window;
691 Xchat::command("CLOSE", $filter_window)
692 if ($cmd =~ /^CLOSE$/i);
694 $filtered_to_window = 0;
695 Xchat::print("Filter doesn't show filtered content in ${B}$filter_window${B}\n");
696 Xchat::print("${B}FILTER:${B} ${B}$filter_window${B} closed\n")
697 if ($cmd =~ /^CLOSE$/i);
699 } elsif ($cmd =~ /^HELP$/i) {
700 Xchat::print($filterwindow_help);
702 } else {
703 Xchat::print("Unknown command ${B}/FILTERWINDOW $_[1][1]${B}\n") if $cmd;
704 Xchat::print("${B}${U}USAGE:${U} /FILTERWINDOW $filterwindow_commands${B}\n");
707 return 1;
710 # ======================================================================
711 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
712 # ----------------------------------------------------------------------
714 Xchat::print("${B}$scriptName $scriptVersion${B} loaded\n",
715 " For help: ${B}/FILTER HELP${B}\n");