use strict; use vars qw($VERSION %IRSSI); use Irssi; use Data::Dumper; $VERSION = '0.41'; %IRSSI = ( authors => 'Remco Lanting', contact => 'remco.lanting+irssi@gmail.com', name => 'Operscript', description => 'Do some magic to unrealircd server notices', license => 'Public domain', ); # # Todo: # # - add more notice formats # - change the window title(s) for the notices to something nice if possible # - if connect rate is just slightly over the limit for a longer period, # auto-adjust the setting # + Make sure alerts have a timeout between them # - Logging of notices, with an on/off setting # # - = todo # + = implemented but pretty much untested # my $wname; my $window; my $sname; my $lastalert = 0; # %servers{'servername'} # [0] = min array # [1] = sec array # [2] = chistory # [0] = start time # [1] = total number of connects # [3] = settings # [0] = enabled (0/1) # [1] = 10 second window # [2] = 60 second window # [3] = alltime window # [4] = alerts (0/1) # [4] = kline queue my %servers = (); sub load_data { # load the settings into the hash # irc.server.com-BOOL-0.5-0.2-0.1-BOOL irc.server2.com- etc. my @d = split(/ /, Irssi::settings_get_str('operscript_servers')); %servers = (); return unless scalar @d >=1; foreach my $s(@d) { my @si = split(/\-/,$s); @servers{$si[0]} = [ [], [], [time()-1,0], [$si[1], $si[2], $si[3], $si[4], $si[5]] ]; } } sub populate_servers { # initial adding of servers so they don't have to be created manually my @serverlist = Irssi::servers(); my $count = 0; foreach my $s(@serverlist) { if ($s->{'server_operator'} || $s->{'usermode'} =~ /o/i ) { @servers{$s->{'real_address'}} = [[],[],[time()-1,0],["1", Irssi::settings_get_str('operscript_10sec'), Irssi::settings_get_str('operscript_60sec'), Irssi::settings_get_str('operscript_alltime'), "0"]]; $count++; } } Irssi::print($count." servers were added and enabled automatically because you have an o-line on those servers"); operscript_save(0); } sub alert { my ($message, $servername) = @_; if ($message && @{${$servers{$servername}}[3]}[4] && $lastalert + 120 < time()) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_HILIGHT, 'alert', $message); $lastalert = time(); } } sub connect_check { my ($servername) = @_; my $time = time(); push(@{${$servers{$servername}}[0]}, $time); push(@{${$servers{$servername}}[1]}, $time); @{${$servers{$servername}}[2]}[1]++; while ( @{${$servers{$servername}}[0]}[0] + 60 < $time) { shift(@{@{$servers{$servername}}[0]}); } while ( @{${$servers{$servername}}[1]}[0] + 10 < $time) { shift(@{@{$servers{$servername}}[1]}); } my $at = @{${$servers{$servername}}[2]}[1]/(time()-@{${$servers{$servername}}[2]}[0]); my $sec = @{@{$servers{$servername}}[1]}/10; my $min = @{@{$servers{$servername}}[0]}/60; if (Irssi::settings_get_bool('operscript_debug')) { print "10sec: $sec /s, 60sec: $min /s, alltime: $at /s"; } if ( ($sec > @{${$servers{$servername}}[3]}[1]) || ($min > @{${$servers{$servername}}[3]}[2]) || ($at > @{${$servers{$servername}}[3]}[3]) ) { return 1; } return 0; } sub event_notice { my ($server, $data, $nick, $address) = @_; my @d = split(/:/,$data); # only server notices (1) for servers that are defined (2) and enabled (3) sent to me (4) return unless $nick eq $server->{'real_address'} && defined $servers{$server->{'real_address'}} && @{${$servers{$server->{'real_address'}}}[3]}[0] && substr($d[0],0,-1) eq $server->{'nick'}; if ( Irssi::settings_get_bool('operscript_seperate_servers')) { $wname = $nick; $sname = ""; } else { $wname = "snotice"; $sname = $server->{'real_address'}." "; } $window = Irssi::window_find_name($wname); if(!defined $window) { $window = Irssi::Windowitem::window_create($wname, 1); $window->set_name($wname); # $window->change_server($server) if (Irssi::settings_get_bool('operscript_seperate_servers')); } $window->change_server($server) if (Irssi::settings_get_bool('operscript_seperate_servers')); # remove colours so hilighting lines works better $data =~ s/\x03\d?\d?(,\d?\d?)?|\x02|\x1f|\x16|\x06|\x07//g; if (index($data,"*** Notice") ne -1) { if ($data =~ /\*\*\* Notice \-\- Client connecting on port (\d+): ([^\s]+) \(([^\s]+)\) \[(.+)\] $/ ) { $window->printformat(MSGLEVEL_SNOTES, 'connect', $sname, $1, $2, $3, $4); alert("Connect flood detected", $sname) unless !connect_check($sname); } elsif($data =~ /\*\*\* Notice \-\- Client connecting on port (\d+): ([^\s]+) \(([^\s]+)\) \[([^\s]+)\] \[(.+)\]/ ) { $window->printformat(MSGLEVEL_SNOTES, 'connectssl', $sname, $1, $2, $3, $4, $5); alert("Connect flood detected", $sname) unless !connect_check($sname); } elsif($data =~ /\*\*\* Notice \-\- Client exiting: ([^\s]+) \(([^\s]+)\) \[(.+)\]/ ) { $window->printformat(MSGLEVEL_SNOTES, 'disconnect', $sname, $1, $2, $3); } elsif($data =~ /\*\*\* Notice \-\- Received KILL message for ([^\s]+) from ([^\s]+) Path: ([^\s]+) \((.+)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'kill', $sname, $1, $2, $3, $4) } elsif($data =~ /\*\*\* Notice \-\- ([^\s]+) \(([^\s]+)\) has been forced to change his\/her nickname to ([^\s]+)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'nickchangeforce', $sname, $1, $2, $3) } elsif($data =~ /\*\*\* Notice \-\- ([^\s]+) \(([^\s]+)\) has changed his\/her nickname to ([^\s]+)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'nickchange', $sname, $1, $2, $3) } elsif($data =~ /\*\*\* Notice \-\- TS Control \- U:line set time to be ([\d]+) \(timediff: ([\d]+)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'tscontrol', $sname, $1, $2, $3) } elsif($data =~ /\*\*\* Notice \-\- ([^\s]+) used ([^\s]+) to make ([^\s]+) join ([^\s]+)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'saoverride', $sname, $1, $2, $3, $4) } elsif($data =~ /\*\*\* Notice \-\- ([^\s]+) used ([^\s]+) to make ([^\s]+) part ([^\s]+)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'saoverride', $sname, $1, $2, $3, $4) } elsif($data =~ /\*\*\* Notice \-\- ([^\s]+) is rehashing server config file/ ) { $window->printformat(MSGLEVEL_SNOTES, 'rehash', $sname, $1) } elsif($data =~ /\*\*\* Notice \-\- (Loading IRCd configuration \.\.)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'rehashmessage', $sname, $1) } elsif($data =~ /\*\*\* Notice \-\- (Configuration loaded without any problems \.\.)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'rehashmessage', $sname, $1) } elsif ( Irssi::settings_get_bool('operscript_unknown')) { # so anything I missed is logged too $window->printformat(MSGLEVEL_SNOTES, 'unknown', $sname, $data); } } elsif (index($data,"*** OperOverride") ne -1) { #$window->print("[operoverride] $data"); if ($data =~ /\*\*\* OperOverride \-\- ([^\s]+) \(([^\s]+)\) invited him\/herself into ([^\s]+) \(overriding ([^\s]+)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'operinvite', $sname, $1, $2, $3, $4); } elsif ($data =~ /\*\*\* OperOverride \-\- ([^\s]+) \(([^\s]+)\) MODE ([^\s]+) ([^\s]+) ?(.+)?/ ) { $window->printformat(MSGLEVEL_SNOTES, 'opermode', $sname, $1, $2, $3, $4, $5); } elsif ($data =~ /\*\*\* OperOverride \-\- ([^\s]+) \(([^\s]+)\) TOPIC ([^\s]+) \'(.+)\'/ ) { $window->printformat(MSGLEVEL_SNOTES, 'opertopic', $sname, $1, $2, $3, $4); } elsif ($data =~ /\*\*\* OperOverride \-\- ([^\s]+) \(([^\s]+)\) KICK ([^\s]+) ([^\s]+) \((.+)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'operkick', $sname, $1, $2, $3, $4, $5); } } elsif (index($data,"[\2vhost\2]") ne -1) { #if you login yourself and fail, you get a notice too. #$window->print("[vhost notice] $data"); if ($data =~ /Failed login for vhost ([^\s]+) by ([^\s]+) \- (.+)/) { $window->printformat(MSGLEVEL_SNOTES, 'vhosterror', $sname, $1, $2, $3); } elsif ($data =~ /([^\s]+) \(([^\s]+)\) is now using vhost ([^\s]+)/) { $window->printformat(MSGLEVEL_SNOTES, 'vhost', $sname, $1, $2, $3); } elsif ($data =~ /Login for ([^\s]+) failed - password incorrect/) { # this notice is because you failed to login using /vhost # yourself, return control back to the main loop return; } } elsif (index($data,"Exiting ssl client") ne -1) { if ($data =~ /Exiting ssl client \[\@([\d]+\.[\d]+\.[\d]+\.[\d]+)\.([\d]+)\]: (.+)/) { $window->printformat(MSGLEVEL_SNOTES, 'ssl1', $sname, $1, $2, $3); } elsif ($data =~ /Exiting ssl client (.+)\[\@([\d]+\.[\d]+\.[\d]+\.[\d]+)\.([\d]+)\]: (.+)/) { $window->printformat(MSGLEVEL_SNOTES, 'ssl2', $sname, $1, $2, $3, $4); } } elsif ($data =~ /Failed OPER attempt by ([^\s]+) \(([^\s]+)\) \[(.+)\]/) { $window->printformat(MSGLEVEL_SNOTES, 'operunknown', $sname, $1, $2, $3); } elsif ($data =~ /Failed OPER attempt by ([^\s]+) \(([^\s]+)\) using UID ([^\s]+) \[(.+)\]/) { $window->printformat(MSGLEVEL_SNOTES, 'operfail', $sname, $1, $2, $3, $4); } elsif ($data =~ /Stats \'(.)\' requested by ([^\s]+) \(([^\s]+)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'stats', $sname, $1, $2, $3); } elsif ($data =~ /\*\*\* Global \-\- from ([^\s]+): (.+)$/ ) { if ($1 eq $server->{'real_address'}) { # this should be a /samode, or anything else the server is stupid enough to send over Global if ($data =~ /\*\*\* Global \-\- from ([^\s]+): ([^\s]+) used ([^\s]+) ([^\s]+) \(([^\s]+)\)/) { $window->printformat(MSGLEVEL_SNOTES, 'saoverride', $sname, $2, $3, $4, $5); } else { $window->printformat(MSGLEVEL_SNOTES, 'unknown', $sname, $data); } } else { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'globops', $sname, $1, $2); } } elsif ($data =~ /\*\*\* LocOps \-\- from ([^\s]+): (.+)$/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'locops', $sname, $1, $2); } elsif ($data =~ /\*\*\* ChatOps \-\- from ([^\s]+): (.+)$/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'chatops', $sname, $1, $2); } elsif ($data =~ /\*\*\* AdminChat \-\- from ([^\s]+): (.+)$/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'adminchat', $sname, $1, $2); } elsif ($data =~ /\*\*\* NetAdmin\.Chat \-\- from ([^\s]+): (.+)$/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'netadminchat', $sname, $1, $2); } elsif ($data =~ /\*\*\* HelpOp \-\- from ([^\s]+) \(([^\s]+)\): (.+)$/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'helpop', $sname, $1, $2, $3); } elsif ($data =~ /\*\*\* (.*) added for (.*) on (.*) \(from (.*) to expire at (.*): (.*)\)$/ ) { $window->printformat(MSGLEVEL_SNOTES, 'line', $sname, $1, $2, $3, $4, $5, $6); } elsif ($data =~ /\*\*\* Expiring (.*) \(([^\s]+)\) made by ([^\s]+) \(Reason: (.*)\) set ([^\s]+) seconds ago/) { $window->printformat(MSGLEVEL_SNOTES, 'exline', $sname, $1, $2, $3, $4, $5); } elsif ($data =~ /([^\s]+) removed (.*) ([^\s]+) \(set at (.*) - reason: (.*)\)/ ) { $window->printformat(MSGLEVEL_SNOTES, 'unline', $sname, substr($1,1), $2, $3, $4, $5); } elsif ($data =~ /([^\s:]+) changed the (.*) of ([^\s]+) \(([^\s]+)\) to be (.*)/) { $window->printformat(MSGLEVEL_SNOTES, 'chinfo', $sname, $1, $2, $3, $4, $5); } elsif ($data =~ /\*\*\* ([^\s]+) \(([^\s]+)\) did a \/whois on you/ ) { $window->printformat(MSGLEVEL_SNOTES+MSGLEVEL_PUBLIC, 'whois', $sname, $1, $2); } elsif ($data =~ /([^\s]+) \(([^\s]+)\) \[([^\s]+)\] is now (.+) \(([^\s]+)\)/) { $window->printformat(MSGLEVEL_SNOTES, 'operup', $sname, substr($1,1), $2, $3, $4, $5); } elsif ($data =~ /\*\*\* Flood \-\- ([^\s]+) \(([^\s]+)\) exceeds ([\d]+) ([^\s]+)/) { $window->printformat(MSGLEVEL_SNOTES, 'sflood', $sname, substr($1,1), $2, $3, $4); } elsif ($data =~ /Forbidding Q-lined nick ([^\s]+) from \[([^\s]+)\]/) { if (Irssi::settings_get_bool('operscript_zline_on_qline')) { $server->command("quote zline +*\@$2 7d botnet"); } $window->printformat(MSGLEVEL_SNOTES, 'qline', $sname, $1, $2); } elsif (index($data,"Spamfilter") ne -1) { if ($data =~ /\*\*\* Spamfilter added: \'(.*)\' \[target: ([^\s]+)\] \[action: ([^\s]+)\] \[reason: (.*)\] on (.*) \(from ([^\s]+)\)/) { $window->printformat(MSGLEVEL_SNOTES, 'spamadd', $sname, $1, $2, $3, $4, $5, $6); } elsif ($data =~ /([^\s]+) removed Spamfilter \'(.*)\' \(set at (.*)\)/) { $window->printformat(MSGLEVEL_SNOTES, 'spamdel', $sname, $1, $2, $3); } elsif ($data =~ /\[Spamfilter\] ([^\s]+) matches filter \'(.*)\': \[([^\s]+) ([^\s]+): \'(.*)\'\] \[(.*)\]/) { $window->printformat(MSGLEVEL_SNOTES, 'spammatch', $sname, $1, $2, $3, $4, $5, $6); } } elsif ( Irssi::settings_get_bool('operscript_unknown')) { # a lot of stuff can end up here, hence the setting $window->printformat(MSGLEVEL_SNOTES, 'unknown', $sname, $data); } else { # nothing matched and unknown lines are not captured so return before the signal is stopped return; } Irssi::signal_stop(); } sub operscript_sub { my ($cstring, $server, $item) = @_; my @mywords = split(/ /, lc($cstring)); if ($mywords[0] eq "view") { return unless operscript_checkserver($mywords[1]); my @d = @{${$servers{$mywords[1]}}[3]}; Irssi::print("Settings for ".$mywords[1]); Irssi::print("Enabled: ".$d[0]); Irssi::print("10 second window: ".$d[1]); Irssi::print("60 second window: ".$d[2]); Irssi::print("Alltime window: ".$d[3]); Irssi::print("Alerts: ".$d[4]); } elsif ($mywords[0] eq "stats") { return unless operscript_checkserver($mywords[1]); Irssi::print("Fancy stats will perhaps get to be here sometime"); } elsif ($mywords[0] eq "add") { if (defined $servers{$mywords[1]}) { Irssi::print("Server is already defined"); } else { @servers{$mywords[1]} = [[],[],[time()-1,0],["1", Irssi::settings_get_str('operscript_10sec'), Irssi::settings_get_str('operscript_60sec'), Irssi::settings_get_str('operscript_alltime'), "0"]]; Irssi::print("Server added"); operscript_save(0); } } elsif ($mywords[0] eq "del") { return unless operscript_checkserver($mywords[1]); delete $servers{$mywords[1]}; Irssi::print("Server deleted"); operscript_save(0); } elsif ($mywords[0] eq "set") { return unless operscript_checkserver($mywords[1]); if ($mywords[2] eq "enabled") { if ($mywords[3] eq "1" || $mywords[3] eq "0") { ${${$servers{$mywords[1]}}[3]}[0] = $mywords[3]; operscript_save(1); } else { Irssi::print("Unknown value '".$mywords[3]."'. Expected 0 or 1"); } } elsif ($mywords[2] eq "10sec") { if ($mywords[3] > 0) { ${${$servers{$mywords[1]}}[3]}[1] = $mywords[3]; operscript_save(1); } else { Irssi::print("Unknown value '".$mywords[3]."'. Expected a (decimal) number greater than zero"); } } elsif ($mywords[2] eq "60sec") { if ($mywords[3] > 0) { ${${$servers{$mywords[1]}}[3]}[2] = $mywords[3]; operscript_save(1); } else { Irssi::print("Unknown value '".$mywords[3]."'. Expected a (decimal) number greater than zero"); } } elsif ($mywords[2] eq "alltime") { if ($mywords[3] > 0) { ${${$servers{$mywords[1]}}[3]}[3] = $mywords[3]; operscript_save(1); } else { Irssi::print("Unknown value '".$mywords[3]."'. Expected a (decimal) number greater than zero"); } } elsif ($mywords[2] eq "alerts") { if ($mywords[3] eq "1" || $mywords[3] eq "0") { ${${$servers{$mywords[1]}}[3]}[4] = $mywords[3]; operscript_save(1); } else { Irssi::print("Unknown value '".$mywords[3]."'. Expected 0 or 1"); } } else { Irssi::print("Unknown setting '".$mywords[2]."' Expected "); } } elsif ($mywords[0] eq "save") { operscript_save(1); } elsif ($mywords[0] eq "reload") { load_data(); } else { Irssi::print("Operscript usage:"); Irssi::print("/operscript help: display this help"); Irssi::print("/operscript add : add a server"); Irssi::print("/operscript del : delete a server"); Irssi::print("/operscript view : view server settings"); Irssi::print("/operscript set : alter a setting"); Irssi::print("/operscript save: save all settings to the /set"); Irssi::print("/operscript reload: reload the settings from the /set"); Irssi::print("There are also a few global settings, do '/set operscript' to see them all"); } } sub operscript_checkserver { my ($server) = @_; if (defined $servers{$server}) { return 1; } else { Irssi::print("The server named '".$server."' doesn't exist"); return 0; } } sub operscript_save { my ($noisy) = @_; # save all settings to the /set my $savestring = ""; while (my($key, $value) = each(%servers)){ $savestring .= $key; foreach my $item (@{${$servers{$key}}[3]}) { $savestring .= "-".$item; } $savestring .= " "; } Irssi::settings_set_str("operscript_servers", $savestring); return unless $noisy; Irssi::print("Settings saved successfully"); } sub event_send_text { my ($data, $server, $witem) = @_; my $active_window = Irssi::active_win(); if ( $active_window->{'name'} ne "snotice" && $active_window->{'name'} ne $server->{'real_address'} ) { return; } if ($server eq '0') { $active_window->printformat(MSGLEVEL_SNOTES, 'message', "", "No active server, change with ^X"); return; } if (!operscript_checkoper()) { $active_window->printformat(MSGLEVEL_SNOTES, 'message', "", "You're not an oper on ".$server->{'real_address'}.", change server with ^X"); return; } if ($data =~ /^kline queue$/i) { operscript_process_queue($server, "kline", "+"); } elsif ($data =~ /^clear queue$/i) { %{${$servers{$server->{'real_address'}}}[4]} = (); $active_window->printformat(MSGLEVEL_CLIENTCRAP, 'message', "", "Queue cleared"); } elsif ($data =~ /^gline queue$/i) { operscript_process_queue($server, "gline", "+"); } elsif ($data =~ /^ungline queue$/i) { operscript_process_queue($server, "gline", "-"); } elsif ($data =~ /^shun queue$/i) { operscript_process_queue($server, "shun", "+"); } elsif ($data =~ /^unshun queue$/i) { operscript_process_queue($server, "shun", "-"); } elsif ($data =~ /^unkline queue$/i) { operscript_process_queue($server, "kline", "-"); } operscript_queue($server,$data,$active_window); Irssi::signal_stop(); } sub operscript_queue { my ($server, $line,$window) = @_; #filter out *.opera.com here if ($line =~ /\b~?([a-zA-Z0-9._-]{1,10})@([a-zA-Z0-9_.-]+)\b/) { my ($user, $host) = ($1, $2); if ($host =~ /.*\.opera\.com/) { return; } @{${$servers{$server->{'real_address'}}}[4]}{"$host"} = $user; if (Irssi::settings_get_bool('operscript_kline_queue')) { my $prefix = ""; if ( !Irssi::settings_get_bool('operscript_seperate_servers')) { $prefix = $server->{'real_address'}." "; } $window->printformat(MSGLEVEL_CLIENTCRAP, 'message', $prefix, "host added to queue"); } else { operscript_process_queue($server, "kline", "+"); } } } sub operscript_process_queue { my ($server, $action, $mod) = @_; my $time = Irssi::settings_get_int('operscript_kline_time'); my $reason = Irssi::settings_get_str('operscript_kline_reason'); my $count = 0; while (my($key, $value) = each(%{${$servers{$server->{'real_address'}}}[4]})){ $server->command("quote $action $mod*\@$key $time $reason"); $count++; } %{${$servers{$server->{'real_address'}}}[4]} = (); my $prefix = ""; if ( !Irssi::settings_get_bool('operscript_seperate_servers')) { $prefix = $server->{'real_address'}." "; } $mod = ($mod eq "+")? "added":"removed"; Irssi::active_win()->printformat(MSGLEVEL_CLIENTCRAP, 'message', $prefix, $action." ".$mod." for ".$count." hosts"); } sub operscript_checkoper { return 0 unless Irssi::active_server(); return 1 if Irssi::active_server()->{server_operator} or Irssi::active_server()->{'usermode'} =~ /o/i; return 0; } # Using {servernotice $0} would be nice but it doesn't collapse if there is no content Irssi::theme_register([ 'connect', '{server $0}[%BConnect%n] {nick $2} {nickhost $3} on port $1, type $4', 'connectssl', '{server $0}[%BConnect%n] {nick $2} {nickhost $3} on port $1, type $4 [$5]', 'disconnect', '{server $0}[%bDisconnect%n] {nick $1} {nickhost $2} {reason $3}', 'kill', '{server $0}[%mKill%n] {nickhost $1} was killed by {nickhost $2} Path: $3 {reason $4}', 'stats', '{server $0}[%YStats%n] /stats $1 reguested by {nick $2} {nickhost $3}', 'operinvite', '{server $0}[%gOperOverride%n] {nick $1} {nickhost $2} invited him/herself into $3 overriding $4', 'opermode', '{server $0}[%gOperOverride%n] {nick $1} {nickhost $2} did a /mode $3 $4 $5', 'opertopic', '{server $0}[%gOperOverride%n] {nick $1} {nickhost $2} changed the topic on $3 to \'$4\'', 'operkick', '{server $0}[%gOperOverride%n] {nick $1} {nickhost $2} kicked $4 from $3 with reason {reason $5}', 'operunknown', '{server $0}[%rFailed OPER%n] {nick $1} {nickhost $2} tried to oper up but got {reason $3}', 'operfail', '{server $0}[%rFailed OPER%n] {nick $1} {nickhost $2} tried to oper up using {nick $3} but got {reason $4}', 'nickchange', '{server $0}[%cNickChange%n] {nick $1} {nickhost $2} has changed his/her nick to {nick $3}', 'nickchangeforce', '{server $0}[%KNickChange%n] An oper forced {nick $1} {nickhost $2} to change his/her nick to {nick $3}', 'tscontrol', '{server $0}[%yTScontrol%n] U:line set time to be $1 (difference: $2)', 'vhosterror', '{server $0}[Vhost] {nickhost $2} failed login for $1 {reason $3}', 'vhost', '{server $0}[Vhost] {nick $1} {nickhost $2} is now using vhost $3', 'globops', '{server $0}[GlobOps] {msgnick $1}$2', 'locops', '{server $0}[LocOps] {msgnick $1}$2', 'chatops', '{server $0}[ChatOps] {msgnick $1}$2', 'adminchat', '{server $0}[AdminChat] {msgnick $1}$2', 'netadminchat', '{server $0}[NetAdminChat] {msgnick $1}$2', 'helpop', '{server $0}[HelpOp] ($2) {msgnick $1}$3', 'saoverride', '{server $0}[%GSAoverride%n] {nick $1} used $2 on $3 ($4)', 'line', '{server $0}[%MServerBan%n] $1 for {nickhost $2} set on $3 by {nickhost $4} expiring on $5 {reason $6}', 'exline', '{server $0}[%MServerBan%n] Expiring $1 for {nickhost $2} set by {nickhost $3} {reason $4} (was set $5 seconds ago)', 'unline', '{server $0}[%MServerBan%n] $1 removed $2 set on {nickhost $3} (set at $4 {reason $5})', 'chinfo', '{server $0}[Info] {nick $1} changed the $2 of {nick $3} {nickhost $4} to be $5', 'alert', '[%RALERT%n] $0', 'whois', '{server $0}[%CWhois%n] $1 {nickhost $2} did a /whois on you', 'message', '{server $0}[Message] $1', 'operup', '{server $0}[OperUP] $1 {nickhost $2} opered up using login [$3], making him/her $4 ($5)', 'sflood', '{server $0}[Flood] {nickhost $1} $4 $2>$3', 'ssl1', '{server $0}[%KSSLError%n] Client connecting from {nickhost $1}, port $2 had a problem: $3', 'ssl2', '{server $0}[%KSSLError%n] {nick $1} connecting from {nickhost $2}, port $3 had a problem: $4', 'qline', '{server $0}[Q:line] Forbidding Q-lined nick $1 from $2', 'spamadd', '{server $0}[Spamfilter] Added: \'$1\' [target: $2] [action: $3] [reason: $4] on $5 by {nickhost $6}', 'spamdel', '{server $0}[Spamfilter] Removed: \'$2\' on $3 by {nickhost $1}', 'spammatch', '{server $0}[Spamfilter] Match: \'$2\' by {nickhost $1} [target: $3 $4] [message: $5] [reason: $6]', 'rehash', '{server $0}[Rehash] Config file is being rehashed by $1', 'rehashmessage', '{server $0}[Rehash] $1', 'unknown', '{server $0}[Unknown] $1' ]); # global settings Irssi::settings_add_bool('operscript', 'operscript_seperate_servers', 0); Irssi::settings_add_bool('operscript', 'operscript_debug', 0); Irssi::settings_add_bool('operscript', 'operscript_unknown', 0); Irssi::settings_add_bool('operscript', 'operscript_zline_on_qline', 0); # Initial values for the per server settings Irssi::settings_add_str('operscript', 'operscript_10sec', "0.5"); Irssi::settings_add_str('operscript', 'operscript_60sec', "0.2"); Irssi::settings_add_str('operscript', 'operscript_alltime', "0.1"); # used to store all server specific settings Irssi::settings_add_str('operscript', 'operscript_servers', ""); # easy kline settings Irssi::settings_add_int('operscript', 'operscript_kline_time', 259200); # 259200 = 3 days Irssi::settings_add_bool('operscript', 'operscript_kline_queue', 1); Irssi::settings_add_str('operscript', 'operscript_kline_reason', 'botnet'); Irssi::command_bind("operscript", "operscript_sub"); Irssi::signal_add("event notice", "event_notice"); Irssi::signal_add('send text', 'event_send_text'); if (Irssi::settings_get_str('operscript_servers') eq "") { populate_servers(); } else { load_data(); } print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded successfully.';