# Auto-op script for X-Chat 1.4.x # # Copyright 2000 Ethan Blanton; This file is GPL'd software. See the GNU # General Public License version 2 or later for more information. # http://www.fsf.org/copyleft/gpl.html my $configfile = "$ENV{HOME}/.xchat/auto-op.cfg"; my %opslist = undef; my $cook_patterns = 1; IRC::register "Auto-op", "2.0", "save_default", ""; IRC::add_message_handler("INBOUND", "inbound_handler"); IRC::add_command_handler("auto", "auto_handler"); sub inbound_handler { my $msg = shift; if($msg =~ /:(.+?) JOIN :(.*)/) { ($user, $chan) = ($1, $2); foreach $pattern (keys(%opslist)) { $re = $pattern; next if !$re; $re =~ s/\./\\./g; $re =~ s/\*/.*?/g; if($user =~ /$re/) { foreach $channel (@{$opslist{$pattern}}) { if($chan eq $channel) { $user =~ s/(.*?)\!.*/$1/; IRC::print "Setting mode \0038+o\0032 $user\003 in\0032 $chan\003\n"; IRC::command "/MODE $chan +o $user"; return(0); } } } } } return(0); } sub auto_handler { my @commandlist = split(/\s/, shift); my $command = shift(@commandlist); if(!$command) { IRC::print "/AUTO requires a command. Type /AUTO help for a list.\n"; return 1; } if(lc($command) eq "help") { IRC::print "Known commands for /AUTO:\n", " help Display this message\n", " load [config] Load ops list from [config]\n", " (default if unspecified)\n", " clear Dump current ops list", " save [config] Save current ops list to [config]\n", " (default if unspecified)", " add [channel] Add [channel] to the ops list\n", " for (Defaults to the\n", " current channel)\n", " remove [channel] Remove [channel] from the ops\n", " list for (defaults to\n", " the current channel)\n", " delete Removes all channels for \n", " and deletes 's entry\n", " list [pattern] List all channels for [pattern]\n", " (Defaults to all patterns)\n", " cook (on | off) Turn pattern cooking on or off\n", "\n Default config file: $configfile\n"; return 1; } if(lc($command) eq "load") { my $file = shift(@commandlist); if($file) { load_list($file); } else { load_list($configfile); } return 1; } if(lc($command) eq "clear") { %opslist = undef; IRC::print "Cleared auto-op list\n"; return 1; } if(lc($command) eq "save") { my $file = shift(@commandlist); if($file) { save_list($file); } else { save_list($configfile); } return 1; } if(lc($command) eq "add") { my $pattern = cook_pattern(shift(@commandlist)); my $channel = shift(@commandlist); if(!$pattern) { IRC::print "/AUTO add: requires an argument\n"; return 1; } $channel = IRC::get_info(2) if !$channel; $opslist{$pattern} = () if not defined $opslist{$pattern}; push @{$opslist{$pattern}}, $channel; IRC::print "Added $channel to $pattern\n"; return 1; } if(lc($command) eq "remove") { my $pattern = cook_pattern(shift(@commandlist)); my $channel = shift(@commandlist); my @list; if(!$pattern) { IRC::print "/AUTO remove: requires an argument\n"; return 1; } if(not defined $opslist{$pattern}) { IRC::print "/AUTO remove: pattern '$pattern' does not exist\n"; return 1; } $channel = IRC::get_info(2) if !$channel; foreach $chan (@{$opslist{$pattern}}) { if($chan && $chan ne $channel) { push @list, $chan; } } if(@list > 0) { $opslist{$pattern} = \@list; IRC::print "Removed $channel from $pattern\n"; } else { delete $opslist{$pattern}; IRC::print "Deleted $pattern from Auto-op list\n"; } return 1; } if(lc($command) eq "delete") { my $pattern = cook_pattern(shift(@commandlist)); if(!$pattern) { IRC::print "/AUTO delete: requires an argument\n"; return 1; } delete $opslist{$pattern}; IRC::print "Deleted $pattern from Auto-op list\n"; return 1; } if(lc($command) eq "list") { my $pattern = shift(@commandlist); my @list; if($pattern) { if(not defined $opslist{$pattern}) { IRC::print "$pattern: No list available\n"; return 1; } push @list, $pattern; } else { @list = keys(%opslist); } foreach $pat (@list) { next if !$pat; my $line = "$pat: "; foreach $chan (@{$opslist{$pat}}) { $line .= " $chan"; } IRC::print "$line\n"; } return 1; } if(lc($command) eq "cook") { $state = lc(shift(@commandlist)); if($state eq "on") { IRC::print "Pattern cooking is ON\n"; $cook_patterns = 1; return 1; } if($state eq "off") { IRC::print "Pattern cooking is OFF\n"; $cook_patterns = 0; return 1; } IRC::print "/AUTO cook: Argument must be 'on' or 'off'\n"; return 1; } IRC::print "/AUTO: Unknown command $command, type /AUTO help for more information\n"; return 1; } sub load_list { my $file = shift; if(!open(CONFIG, $file)) { IRC::print "Could not open\0034 $file\003, auto-op list unchanged.\n"; return; } while() { /\s*(\S+)\s*(.*?)\s*$/; my($pattern, $channels) = ($1, $2); $opslist{$pattern} = () if not defined $opslist{$pattern}; while($channels) { $channels =~ s/^(\S+)\s*//; push @{$opslist{$pattern}}, $1; } } close CONFIG; IRC::print "Successfully loaded\00310 $file\003.\n"; } sub save_list { my $file = shift; my @array; if(!open(CONFIG, ">$file")) { IRC::print "Could not open\0034 $file\003, save aborted.\n"; return; } foreach $pattern (keys %opslist) { next if !$pattern; my $line = "$pattern"; foreach $channel (@{$opslist{$pattern}}) { $line .= " $channel"; } push @array, $line; } @array = sort(@array); foreach $line (@array) { print CONFIG "$line\n"; } IRC::print "Successfully saved\00310 $file\003.\n"; close CONFIG; } sub cook_pattern { $pattern = shift; if($cook_patterns) { $pattern =~ s/^(.*?):$/$1/; $pattern =~ s/mailto\://; $pattern = "!" . $pattern if not $pattern =~ /!/; $pattern =~ s/^.*?!(.*?)@.*?\.(.*)$/*!$1@*.$2/; } return $pattern; } sub load_default { load_list($configfile); } sub save_default { save_list($configfile); } IRC::add_timeout_handler(10, "load_default");