1# Operview - reformats some server notices, which may come i.e. from &clients 2# or &servers. Also reformat some incoming server numerics from advanced 3# commands like STATS. 4# 5# Note that whole this script is VERY ircnet-specific! 6# 7# Provided variables: 8# 9# mangle_stats_output - turn the mangling of /stats output on/off 10# mangle_server_notices - turn the mangling of server notices on/off 11# ignore_server_kills - we won't display nickname collissions 12# show_kills_path - we will display kill's path 13# 14# $Id: operview.pl,v 1.11 2002/03/30 21:16:06 pasky Exp pasky $ 15# 16 17 18use strict; 19use Irssi; 20use Irssi::Irc; 21use Irssi::TextUI; 22 23use vars qw ($VERSION %IRSSI $rcsid); 24 25$rcsid = '$Id: operview.pl,v 1.11 2002/03/30 21:16:06 pasky Exp pasky $'; 26($VERSION) = '$Revision: 1.11 $' =~ / (\d+\.\d+) /; 27%IRSSI = ( 28 name => 'operview', 29 authors => 'Petr Baudis', 30 contact => 'pasky@ji.cz', 31 url => 'http://pasky.ji.cz/~pasky/dev/irssi/', 32 license => 'GPLv2, not later', 33 description => 'Reformats some server notices, which may come i.e. from &clients or &servers at IRCnet. You can turn the script on/off bytoggling variable mangle_server_notices.', 34 sbitems => 'sclientcount kills', 35 ); 36 37my $mangle_stats_output; 38my $mangle_server_notices; 39my $ignore_server_kills; 40my $show_kills_path; 41 42my @lastkill = ('','',''); 43my @curclientcount = (0,0); 44 45Irssi::theme_register([ 46 client_connect => '{servernotice $0}Connect : {nick $[9]1} :: {nickhost $2%R@%n$3} {comment $4} :: $5-', 47 client_exit => '{servernotice $0}Disconnect : {nick $[9]1} :: {nickhost $2%R@%n$3} :: $4-', 48 client_nick => '{servernotice $0}{nick $[9]1} -> {nick $[9]2} :: {nickhost $3%R@%n$4}', 49 kills_kill => '{servernotice $0}Received %gKILL%n {nick $[9]1} ({server $2}) :: $3', # TODO: parse the path? subject to change 50 kills_operkill => '{servernotice $0}Received %gKILL%n {nick $[9]1} (%R$2%n) :: $3', 51 kills_collide => '{servernotice $0}Nick %gCOLLISION%n {nick $[9]1} :: $2', 52 servers_server => '{servernotice $0}Received %gSERVER%n {server $1} from {server $2} :: %G$3%w {comment $5} $6-', 53 servers_squit => '{servernotice $0}Received %gSQUIT %n {server $1} from {server $2} :: %R$3-%w', 54 servers_sserver=> '{servernotice $0}Sending %gSERVER%n {server $1} :: %G$2%w {comment $4} $5-', 55 servers_ssquit => '{servernotice $0}Sending %gSQUIT %n {server $1} :: %R$2-%w', 56 57# TODO: Header ? sendq smsgs skbs rmsgs rkbs age 58 stats_l => '$[!9]0 :: $[!7]3 %g<s%n $[!5]4 $[!5]5 %gr>%n $[!5]6 $[!5]7 :: $[!6]8 :: {nickhost $1%R@%n$2}', 59# TODO: Header ? pingf connf maxlinks sendq local limit global limit 60 stats_y => '$0 :: $[!4]1 :: %gpf%n $[!4]2 %gcf%n $[!4]3 %gml%n $[!4]4 %gsq%n $[!8]5 %gll%n $[!-2]6%K.%n$[!2]7 %ggl%n $[!-2]8%K.%n$[!2]9', 61# TODO: Header ? haddr hname passwd port class 62 stats_i => '$0 :: $[!20]1 $[!22]3 :: $[!6]2 :: %gp%n $4 %gc%n $5', 63# TODO: Header ? port class (N/A) host reason 64 stats_k => '$0 :: %gp%n $[!4]4 %gc%n $[!2]5 :: {nickhost $3%R@%n$1} :: $2', 65# TODO: Header ? port/masklvl class sname host passw 66 stats_c => '$0 :: %gp%n $[!4]5 %gc%n $[!2]6 :: $4 :: {nickhost $1%R@%n$2} :: $3', 67 stats_n => '$0 :: %gm%n $[!4]5 %gc%n $[!2]6 :: $4 :: {nickhost $1%R@%n$2} :: $3', 68 69# I wasn't able to discover how to get this working for statusbars. So THIS IS 70# NO-OP! Seek for its second incarnation hardcoded somewhere below. 71 72 sb_kill => '{sb $0%R@%n$1}', 73 sb_operkill => '{sb $0%R<%n$1}', 74 sb_collision => '{sb $0%R!%n}', 75 sb_sclientcount=> '{sb $0%c/%n$1%cs%n}', 76]); 77 78 79sub event_server_notice { 80 my ($server, $data, $nick, $address) = @_; 81 my ($target, $text) = $data =~ /^(\S*)\s+:(.*)$/; 82 my (@text) = split(/ /, $text); 83 84 $show_kills_path = Irssi::settings_get_bool("show_kills_path"); 85 $ignore_server_kills = Irssi::settings_get_bool("ignore_server_kills"); 86 $mangle_server_notices = Irssi::settings_get_bool("mangle_server_notices"); 87 return unless ($mangle_server_notices); 88 89 return if ($address or $nick !~ /\./); 90 91 if ($target eq '&CLIENTS') { 92 93 if ($text =~ /^Client connecting/) { 94 my (@fa) = ($text[2], $text[4], $text[6], $text[7], join(" ", splice(@text, 9))); 95 96 $fa[3] =~ s/^\[(.*)\]$/$1/; 97 98 $server->printformat($target, MSGLEVEL_SNOTES, "client_connect", 99 $nick, @fa); 100 Irssi::signal_stop(); 101 102 } elsif ($text =~ /^Client exiting/) { 103 my (@fa) = ($text[2], $text[4], $text[6], join(" ", splice(@text, 8))); 104 105 $server->printformat($target, MSGLEVEL_SNOTES, "client_exit", 106 $nick, @fa); 107 Irssi::signal_stop(); 108 109 } elsif ($text =~ /^Nick change/) { 110 my (@fa) = ($text[2], $text[4], $text[6], $text[8]); 111 112 $server->printformat($target, MSGLEVEL_SNOTES, "client_nick", 113 $nick, @fa); 114 Irssi::signal_stop(); 115 } 116 117 } elsif ($target eq '&KILLS') { 118 119 if ($text =~ /^Received KILL/) { 120 my (@fa) = ($text[4], $text[6], join(" ", splice(@text, 9 - $show_kills_path))); 121 122 $fa[0] =~ s/\.$//; 123 124 if ($fa[1] =~ /\./) { 125 $server->printformat($target, MSGLEVEL_SNOTES, "kills_kill", 126 $nick, @fa) unless ($ignore_server_kills); 127 @lastkill = ($fa[0], $fa[1], 's'); 128 } else { 129 $server->printformat($target, MSGLEVEL_SNOTES+MSGLEVEL_HILIGHT, "kills_operkill", 130 $nick, @fa); 131 @lastkill = ($fa[0], $fa[1], 'o'); 132 } 133 refresh_kills(); 134 Irssi::signal_stop(); 135 136 } elsif ($text =~ /^Nick collision on/) { 137 my (@fa) = ($text[3], join(" ", splice(@text, 4))); 138 139 $server->printformat($target, MSGLEVEL_SNOTES, "kills_collide", 140 $nick, @fa); 141 @lastkill = ($fa[0], '', 'c'); 142 143 refresh_kills(); 144 Irssi::signal_stop(); 145 } 146 147 } elsif ($target eq '&NOTICES') { 148 if ($text =~ /^Local increase from/) { 149 @curclientcount = ($text[5], $text[8]); 150 refresh_sclientcount(); 151 } 152 153 } elsif ($target eq '&SERVERS') { 154 155 if ($text =~ /^Received SERVER/) { 156 my ($sname) = join(" ", splice(@text, 5)); 157 my (@fa) = ($text[2], $text[4], 158 $sname =~ /^\((\d+)\s+(\[(.+?)\])?\s*(.*)\)$/); 159 160 $server->printformat($target, MSGLEVEL_SNOTES, "servers_server", 161 $nick, @fa); 162 Irssi::signal_stop(); 163 164 } elsif ($text =~ /^Received SQUIT/) { 165 my (@fa) = ($text[2], $text[4], join(" ", splice(@text, 5))); 166 167 $fa[2] =~ s/^\((.*)\)$/$1/; 168 169 $server->printformat($target, MSGLEVEL_SNOTES, "servers_squit", 170 $nick, @fa); 171 Irssi::signal_stop(); 172 173 } elsif ($text =~ /^Sending SERVER/) { 174 my ($sname) = join(" ", splice(@text, 3)); 175 my (@fa) = ($text[2], $sname =~ /^\((\d+)\s+(\[(.+?)\])?\s*(.*)\)$/); 176 177 $server->printformat($target, MSGLEVEL_SNOTES, "servers_sserver", 178 $nick, @fa); 179 Irssi::signal_stop(); 180 181 } elsif ($text =~ /^Sending SQUIT/) { 182 my (@fa) = ($text[2], join(" ", splice(@text, 3))); 183 184 $fa[1] =~ s/^\((.*)\)$/$1/; 185 186 $server->printformat($target, MSGLEVEL_SNOTES, "servers_ssquit", 187 $nick, @fa); 188 Irssi::signal_stop(); 189 } 190 191 } 192} 193 194 195sub event_stats_numeric { 196 my ($server, $data, $srvname) = @_; 197 my ($target, $text) = $data =~ /^(\S*)\s+(.*)$/; 198 my (@text) = split(/ /, $text); 199 my ($num) = Irssi::signal_get_emitted() =~ /^event (\d+)$/; 200 201 $mangle_stats_output = Irssi::settings_get_bool("mangle_stats_output"); 202 unless ($mangle_stats_output) { 203 Irssi::print $text, MSGLEVEL_CRAP; 204 return; 205 } 206 207 unless ($num) { 208 Irssi::print "[OperView] Internal error - emitted signal '".Irssi::signal_get_emitted()."' is not numerics event."; 209 return; 210 } 211 212# Irssi::print "[$num][] $data -> $target , $text"; 213 214 if ($num == 211) { 215# STATS L 216#:irc.cis.vutbr.cz 211 `asdf irc.cis.vutbr.cz[0.0.0.0@.3333] 0 92727331 1888902 168822985 3078358 :3201373 217#:irc.cis.vutbr.cz 211 `asdf irc.felk.cvut.cz[ircd@147.32.80.79] 6038 4876 52 268097 6375 :1427 218#:irc.cis.vutbr.cz 211 `asdf [unknown@66.135.66.250] 0 0 0 0 0 :0 219#:irc.cis.vutbr.cz 211 `asdf `asdf[~a@pasky.ji.cz] 478 2057 162 13 0 :324 220#:irc.cis.vutbr.cz 211 `asdf [@66.135.66.250] 0 10 0 11 0 :81 221#:irc.cis.vutbr.cz 211 `asdf `asdf[@62.44.12.54] 517 129 10 4 0 :87 222 my (@fa) = $text =~ /^(.*?)?\[([^[]*?)?@(.*?)\] (\d+) (\d+) (\d+) (\d+) (\d+) :(\d+)$/; 223 224 unless ($fa[2]) { 225 Irssi::print $text, MSGLEVEL_CRAP; 226 } else { 227 $server->printformat($target, MSGLEVEL_CRAP, "stats_l", @fa); 228 } 229 Irssi::signal_stop(); 230 231 } elsif ($num == 218) { 232# STATS Y 233#:irc.cis.vutbr.cz 218 `asdf Y 0 120 600 1 384084 0.0 0.0 234#:irc.cis.vutbr.cz 218 `asdf Y 10 300 0 1 500000 1.1 1.1 235#:irc.cis.vutbr.cz 218 `asdf Y 12 300 0 10 700000 10.10 10.10 236#:irc.cis.vutbr.cz 218 `asdf Y 1 300 0 400 700000 10.3 10.3 237 my (@fa) = $text =~ /^(.) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)\.(\d+) :?(\d+)\.(\d+)$/; 238 239 unless ($fa[0]) { 240 Irssi::print $text, MSGLEVEL_CRAP; 241 } else { 242 $server->printformat($target, MSGLEVEL_CRAP, "stats_y", @fa); 243 } 244 Irssi::signal_stop(); 245 246 } elsif ($num == 215) { 247# STATS I 248#:irc.cis.vutbr.cz 215 `asdf I pilsedu.cz <NULL> pilsedu.cz 0 12 249#:irc.cis.vutbr.cz 215 `asdf I x.opf.slu.cz <NULL> x.opf.slu.cz 0 9 250#:irc.cis.vutbr.cz 215 `asdf I 64.44.4.128/29 <NULL> <NULL> 0 1 251 my (@fa) = $text =~ /^(.) (\S+) (\S+) (\S+) (\d+) :?(\d+)$/; 252 253 unless ($fa[0]) { 254 Irssi::print $text, MSGLEVEL_CRAP; 255 } else { 256 $server->printformat($target, MSGLEVEL_CRAP, "stats_i", @fa); 257 } 258 259 Irssi::signal_stop(); 260 261 } elsif ($num == 216) { 262# STATS K 263#:irc.cis.vutbr.cz 216 `asdf K *@*.*.*.*.*.*.*.*.* Access_denied,please_fix_your_domain_name * 0 -1 264#:irc.cis.vutbr.cz 216 `asdf K 195.116.4.* Access_denied,reason-use_servers_in_Poland * 0 -1 265#:irc.cis.vutbr.cz 216 `asdf K korak.isternet.sk abuse�-�expire�01.08.2003�16.26 * 0 -1 266#:irc.cis.vutbr.cz 216 `asdf K 193.84.192.0/24 compromissed�network�-�expire�05.04.2002�22.37 * 0 -1 267 my (@fa) = $text =~ /^(.) (\S+) (.+) (\S+) (\d+) :?([-0-9]+)$/; 268 269 unless ($fa[0]) { 270 Irssi::print $text, MSGLEVEL_CRAP; 271 } else { 272 $server->printformat($target, MSGLEVEL_CRAP, "stats_k", @fa); 273 } 274 275 Irssi::signal_stop(); 276 277 } elsif ($num == 213) { 278# STATS C 279#:irc.cis.vutbr.cz 213 `asdf c *@129.143.67.242 * *.de 6666 6 280#:irc.cis.vutbr.cz 213 `asdf c *@141.24.101.9 * *.de 6667 6 281#:irc.cis.vutbr.cz 213 `asdf c *@131.174.124.200 * *.sci.kun.nl 6667 6 282#:irc.cis.vutbr.cz 213 `asdf c *@130.240.16.47 * *.se 6667 6 283#:irc.cis.vutbr.cz 213 `asdf c *@147.32.80.79 * irc.felk.cvut.cz 6664 6 284#:irc.cis.vutbr.cz 213 `asdf c *@195.146.134.62 * *.sk 0 2 285#:irc.cis.vutbr.cz 213 `asdf c *@195.168.1.141 * *.sk 0 2 286 my (@fa) = $text =~ /^(.) (\S+)@(\S+) (\S+) (\S+) ([.0-9]+) :?([-0-9]+)$/; 287 288 unless ($fa[0]) { 289 Irssi::print $text, MSGLEVEL_CRAP; 290 } else { 291 $server->printformat($target, MSGLEVEL_CRAP, "stats_c", @fa); 292 } 293 294 Irssi::signal_stop(); 295 296 } elsif ($num == 214) { 297# (STATS N) 298#:irc.cis.vutbr.cz 214 `asdf N *@129.143.67.242 * *.de 0 6 299#:irc.cis.vutbr.cz 214 `asdf N *@141.24.101.9 * *.de 3 6 300#:irc.cis.vutbr.cz 214 `asdf N *@131.174.124.200 * *.sci.kun.nl 3 6 301#:irc.cis.vutbr.cz 214 `asdf N *@130.240.16.47 * *.se 3 6 302#:irc.cis.vutbr.cz 214 `asdf N *@147.32.80.79 * irc.felk.cvut.cz 0 6 303#:irc.cis.vutbr.cz 214 `asdf N *@195.146.134.62 * *.sk 3 2 304#:irc.cis.vutbr.cz 214 `asdf N *@195.168.1.141 * *.sk 3 2 305 my (@fa) = $text =~ /^(.) (\S+)@(\S+) (\S+) (\S+) (\d+) :?(\d+)$/; 306 307 unless ($fa[0]) { 308 Irssi::print $text, MSGLEVEL_CRAP; 309 } else { 310 $server->printformat($target, MSGLEVEL_CRAP, "stats_n", @fa); 311 } 312 313 Irssi::signal_stop(); 314=brm 315 } elsif ($num == 250) { 316 317#TRACE 318#:irc.cis.vutbr.cz 204 `asdf Oper 12 pasky[~pasky@pasky.ji.cz] 319#:irc.cis.vutbr.cz 206 `asdf Serv 6 46S 95580C irc.felk.cvut.cz[ircd@147.32.80.79] *!*@irc.cis.vutbr.cz VFz 320#:irc.cis.vutbr.cz 205 `asdf User 1 `asdf[~a@pasky.ji.cz] 321#:irc.cis.vutbr.cz 262 `asdf irc.cis.vutbr.cz 2.10.3p3.addpl2.hemp. :End of TRACE 322# 323#STATS O 324#:irc.cis.vutbr.cz 243 `asdf O revisor@*.ssakhk.cz * erixon 0 10 325#:irc.cis.vutbr.cz 243 `asdf O cf@candyflip.junkie.cz * cf 0 12 326#:irc.cis.vutbr.cz 243 `asdf O *@pilsedu.cz * jv 0 12 327#:irc.cis.vutbr.cz 243 `asdf O *@62.44.12.54 * pasky 0 12 328#:irc.cis.vutbr.cz 243 `asdf O *@bsd.xcem.com * Krash 0 10 329#:irc.cis.vutbr.cz 243 `asdf O spike@*.pantexcom.com * Krash 0 10 330#:irc.cis.vutbr.cz 243 `asdf O fantomas@*.fantomas.sk * filozof 0 10 331#:irc.cis.vutbr.cz 243 `asdf O *@147.229.1.11 * StiX 0 10 332#:irc.cis.vutbr.cz 243 `asdf O *@160.216.0.0/16 * StiX 0 10 333#:irc.cis.vutbr.cz 219 `asdf O :End of STATS report 334 335# STATS H 336#:irc.cis.vutbr.cz 250 `asdf D *.fr.ircnet.net <NULL> * 0 0 337#:irc.cis.vutbr.cz 250 `asdf D *.belnet.be <NULL> * 0 0 338#:irc.cis.vutbr.cz 244 `asdf H * <NULL> irc.felk.cvut.cz 0 -1 339#:irc.cis.vutbr.cz 244 `asdf H * <NULL> *.de 0 -1 340#:irc.cis.vutbr.cz 244 `asdf H * <NULL> *.sci.kun.nl 0 -1 341#:irc.cis.vutbr.cz 244 `asdf H * <NULL> *.fi 0 -1 342#:irc.cis.vutbr.cz 244 `asdf H * <NULL> *.se 0 -1 343#:irc.cis.vutbr.cz 244 `asdf H * <NULL> *.sk 0 -1 344#:irc.cis.vutbr.cz 244 `asdf H * <NULL> irc.uhk.cz 0 -1 345#:irc.cis.vutbr.cz 219 `asdf H :End of STATS report 346 my (@fa) = $text =~ /^(.) (\S+)@(\S+) (\S+) (\S+) (\d+) :?(\d+)$/; 347 348 Irssi::print $text unless ($fa[0]); 349 350 $server->printformat($target, MSGLEVEL_CRAP, "stats_n", 351 @fa); 352 Irssi::signal_stop(); 353=cut 354 } 355} 356 357 358 359 360# 361### Statusbar stuff 362# 363 364 365sub sclientcount { 366 my ($item, $get_size_only) = @_; 367 my $f = '{sb '.$curclientcount[0].'%c/%n'.$curclientcount[1].'%cs%n}'; 368 369 $item->default_handler($get_size_only, $f, undef, 1); 370} 371 372sub kills { 373 my ($item, $get_size_only) = @_; 374 my $theme = Irssi::current_theme(); 375 my $f = '{sb %n}'; 376 377 if ($lastkill[2] eq 's') { 378# Thanks to cras and darix for helping with following: 379# FIXME: Return value of following is for some reason "Perl script". 380# $f = Irssi::active_win()->format_get_text("Irssi::Script::operview", Irssi::active_server(), undef, 'sb_kill', @lastkill); 381 382 $f = '{sb '.$lastkill[0].'%c@%n'.$lastkill[1].'}'; 383 } elsif ($lastkill[2] eq 'o') { 384 $f = '{sb '.$lastkill[0].'%c<%n'.$lastkill[1].'}'; 385 } elsif ($lastkill[2] eq 'c') { 386 $f = '{sb '.$lastkill[0].'%c!%n}'; 387 } 388 389 $item->default_handler($get_size_only, $f, undef, 1); 390} 391 392 393sub refresh_sclientcount { 394 Irssi::statusbar_items_redraw('sclientcount'); 395} 396 397sub refresh_kills { 398 Irssi::statusbar_items_redraw('kills'); 399} 400 401 402Irssi::signal_add("event notice", "event_server_notice"); 403Irssi::signal_add("event 211", "event_stats_numeric"); 404Irssi::signal_add("event 213", "event_stats_numeric"); 405Irssi::signal_add("event 214", "event_stats_numeric"); 406Irssi::signal_add("event 215", "event_stats_numeric"); 407Irssi::signal_add("event 216", "event_stats_numeric"); 408Irssi::signal_add("event 218", "event_stats_numeric"); 409#Irssi::signal_add("event 243", "event_stats_numeric"); 410#Irssi::signal_add("event 244", "event_stats_numeric"); 411#Irssi::signal_add("event 250", "event_stats_numeric"); 412 413Irssi::settings_add_bool("lookandfeel", "mangle_stats_output", 0); 414Irssi::settings_add_bool("lookandfeel", "mangle_server_notices", 1); 415Irssi::settings_add_bool("lookandfeel", "ignore_server_kills", 0); 416Irssi::settings_add_bool("lookandfeel", "show_kills_path", 0); 417 418Irssi::statusbar_item_register("sclientcount", '$0', 'sclientcount'); 419Irssi::statusbar_item_register("kills", '$0', 'kills'); 420Irssi::statusbars_recreate_items(); 421 422Irssi::print("OperView $VERSION loaded..."); 423