1# notify.irc: a module to detect the presence of nicknames 2# 3# written by nsx 4# 5# /set variables this script uses: 6# 7# DO_NOTIFY_IMMEDIATELY -- if set on, the notify system will check for 8# signons and signoffs immediately when a 9# /notify command has been performed 10# 11# NOTIFY -- turns notify system on or off 12# 13# NOTIFY_INTERVAL -- how often (in seconds) to check for signons and signoffs 14# 15# NOTIFY_USERHOST_AUTOMATIC -- if set on, userhosts will be displayed in 16# the signon messages (this can lag you if you 17# have a very large notify list) 18# 19# 20# note: this script uses the serial number 556 for its serial hooks 21# 22 23if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo()); return; }; 24 25package notify; 26 27load ison; 28 29# global config vars 30@do_notify_immediately = [ON]; 31@notify = [ON]; 32@notify_interval = 30; 33@notify_userhost_automatic = [ON]; 34 35 36# turn off epic's built-in notify system 37on ^set -"NOTIFY *"; 38set notify off; 39 40alias change_notify_status (servernum, newstatus, nicklist) { 41 if (newstatus == [online]) { 42 push online_list[$servernum] $nicklist; 43 44 if (NOTIFY_USERHOST_AUTOMATIC == [ON]) { 45 xeval -server $servernum { 46 fe ($nicklist) n1 n2 n3 n4 n5 { 47 userhost $n1 $n2 $n3 $n4 $n5 -cmd { 48 shook notify_signon $0 $3@$4; 49 }; 50 }; 51 }; 52 } else { 53 fe ($nicklist) nickname { 54 shook notify_signon $nickname <EMPTY>; 55 }; 56 }; 57 } elsif (newstatus == [offline]) { 58 @online_list[$servernum] = remws($nicklist / $online_list[$servernum])); 59 60 fe ($nicklist) nickname { 61 shook notify_signoff $nickname; 62 }; 63 }; 64}; 65 66alias clear_notify_list { 67 @notify_list = []; 68 69 fe ($notify_networks $notify_groups) element { 70 @notify_list[$encode($toupper($element))] = []; 71 }; 72 73 @notify_networks = []; 74 @notify_groups = []; 75 76}; 77 78alias clear_notify_records { 79 fe ($servernums()) servernum { 80 @np_in_progress[$servernum] = []; 81 @online_list[$servernum] = []; 82 }; 83}; 84 85alias detect_signons { 86 if (NOTIFY == [OFF]) { 87 return; 88 }; 89 90 fe ($servernums()) servernum { 91 if (np_in_progress[$servernum] == 1) { 92 continue; 93 }; 94 95 @:groupname = toupper($serverctl(GET $servernum GROUP)); 96 @:network = toupper($serverctl(GET $servernum 005 NETWORK)); 97 @:ison_send_list = getnick[$servernum]; 98 99 push ison_send_list $notify_list; 100 push ison_send_list $notify_list[$encode($toupper($groupname))]; 101 push ison_send_list $notify_list[$encode($toupper($network))]; 102 103 if (ison_send_list == []) { 104 continue; 105 }; 106 107 @np_in_progress[$servernum] = 1; 108 109 ison -oncmd { 110 @observe_online($uniq($*)); 111 } -offcmd { 112 @observe_offline($uniq($*)); 113 } -end { 114 @np_in_progress[$serverctl(from_server)] = 0; 115 } -server $servernum $ison_send_list; 116 }; 117}; 118 119alias establish_notify_hooks { 120 ^on #^channel_nick 556 "*" { 121 @observe_offline($1); 122 @observe_online($2); 123 }; 124 125 ^on #^channel_signoff 556 "*" { 126 @observe_offline($1); 127 }; 128 129 ^on #^join 556 "*" { 130 @observe_online($0); 131 }; 132 133 ^on #^msg 556 "*" { 134 @observe_online($0); 135 }; 136 137 ^on #^notice 556 "*" { 138 @observe_online($0); 139 }; 140 141 ^on #^server_lost 556 "*" { 142 @:servernum = [$0]; 143 144 @np_in_progress[$servernum] = 0; 145 @online_list[$servernum] = []; 146 }; 147 148 ^on #^003 556 "*" { 149 @:lserver = serverctl(from_server); 150 151 @np_in_progress[$lserver] = 0; 152 @online_list[$lserver] = []; 153 }; 154 155 ^on #^311 556 "*" { 156 @observe_online($1); 157 }; 158 159 ^on #^401 556 "*" { 160 @observe_offline($1); 161 }; 162 163}; 164 165alias getnick (nickname) { 166 if (nickname == []) { 167 @:getnick = getnick[$serverctl(from_server)]; 168 169 if (getnick == []) { 170 xecho -b no getnick for $serverctl(get $serverctl(from_server) itsname) has been set; 171 xecho; 172 } else { 173 xecho -b getnick for $serverctl(get $serverctl(from_server) itsname) is: $getnick; 174 xecho; 175 }; 176 177 return; 178 }; 179 180 if (nickname == [-]) { 181 @getnick[$serverctl(from_server)] = []; 182 183 xecho -b getnick for $serverctl(get $serverctl(from_server) itsname) has been unset; 184 xecho; 185 186 return; 187 } else { 188 @getnick[$serverctl(from_server)] = nickname; 189 190 xecho -b getnick for $serverctl(get $serverctl(from_server) itsname) set to: $nickname; 191 xecho; 192 }; 193 194 @detect_signons(); 195}; 196 197alias notify (nicklist) { 198 @:lserver = serverctl(from_server); 199 @:lgroup = serverctl(GET $lserver GROUP); 200 @:lnetwork = serverctl(GET $lserver 005 NETWORK); 201 @:online_list = online_list[$lserver]; 202 @:offline_list = remws($online_list / $notify_list $notify_list[$encode($toupper($lgroup))] $notify_list[$encode($toupper($lnetwork))]); 203 204 if (functioncall()) { 205 @:notify_list = notify_list; 206 207 if (#nicklist == 0) { 208 fe ($notify_networks) network { 209 fe ($notify_list[$encode($toupper($network))]) nickname { 210 push notify_list $nickname:$network; 211 }; 212 }; 213 214 fe ($notify_groups) groupname { 215 fe ($notify_list[$encode($toupper($groupname))]) nickname { 216 push notify_list $nickname::$groupname; 217 }; 218 }; 219 220 return $notify_list; 221 } elsif ((:word = findw(net $nicklist)) > -1) { 222 @:online_list = []; 223 @:network = word(${word + 1} $nicklist); 224 @:list = word(${word - 1} $nicklist) == [] ? word(${word + 2} $nicklist) : word(${word - 1} $nicklist); 225 226 fe ($notify_list[$encode($toupper($network))]) nickname { 227 fe ($servernums()) servernum { 228 if (serverctl(GET $servernum 005 NETWORK) == network && findw($nickname $online_list[$servernum]) > -1) { 229 push online_list $nickname; 230 }; 231 }; 232 }; 233 234 @:online_list = uniq($online_list); 235 236 if (list == [off]) { 237 return $remws($online_list / $notify_list[$encode($toupper($network))]); 238 } else { 239 return $online_list; 240 }; 241 } elsif ((:word = findw(group $nicklist)) > -1) { 242 @:online_list = []; 243 @:groupname = word(${word + 1} $nicklist); 244 @:list = word(${word - 1} $nicklist) == [] ? word(${word + 2} $nicklist) : word(${word - 1} $nicklist); 245 246 fe ($notify_list[$encode($toupper($groupname))]) nickname { 247 fe ($servernums()) servernum { 248 if (serverctl(GET $servernum GROUP) == groupname && findw($nickname $online_list[$servernum]) > -1) { 249 push online_list $nickname; 250 }; 251 }; 252 }; 253 254 @:online_list = uniq($online_list); 255 256 if (list == [off]) { 257 return $remws($online_list / $notify_list[$encode($toupper($groupname))]); 258 } else { 259 return $online_list; 260 }; 261 } else { 262 if ((:word = findw(serv $nicklist)) > -1) { 263 @:refnum = word(${word + 1} $nicklist); 264 @:list = word(${word - 1} $nicklist) == [] ? word(${word + 2} $nicklist) : word(${word - 1} $nicklist); 265 266 } elsif (#nicklist == 1) { 267 @:lserver = serverctl(from_server); 268 @:list = nicklist; 269 } else { 270 return -1; 271 }; 272 273 if (list == [off]) { 274 @:network = serverctl(GET $lserver 005 NETWORK); 275 @:groupname = serverctl(GET $lserver GROUP); 276 277 push notify_list $notify_list[$encode($toupper($network))]; 278 push notify_list $notify_list[$encode($toupper($groupname))]; 279 280 return $remws($online_list[$lserver] / $notify_list); 281 } else { 282 return $online_list[$lserver]; 283 }; 284 }; 285 }; 286 287 if (nicklist == []) { 288 xecho -b -c -- Currently online: $online_list; 289 xecho -b -c -- Currently offline: $offline_list; 290 291 return; 292 }; 293 294 if (nicklist == [-]) { 295 @remove_notify_entry(); 296 297 xecho -b -c -- the global notify list has been cleared; 298 299 return; 300 }; 301 302 if (nicklist == [--]) { 303 @clear_notify_list(); 304 @clear_notify_records(); 305 306 xecho -b -c -- the global and local notify lists have been cleared; 307 return; 308 }; 309 310 fe ($nicklist) nickname { 311 @:separators = count(: $nickname); 312 313 if (left(1 $nickname) == [-]) { 314 @:nickname = rest($nickname); 315 316 if (separators == 1) { 317 @:network = after(: $nickname); 318 @:nickname = before(: $nickname); 319 320 if (nickname == []) { 321 @remove_network_notify_entry($network); 322 323 xecho -b -c -- the notify list for network $network has been cleared; 324 325 continue; 326 }; 327 328 if (remove_network_notify_entry($network $nickname) == 1) { 329 xecho -b -c -- $nickname is not in the notify list for network ${network}!; 330 } else { 331 xecho -b -c -- $nickname has been removed from the notify list for network $network; 332 }; 333 } elsif (separators >= 2) { 334 @:groupname = after(-1 : $nickname); 335 @:nickname = before(: $nickname); 336 @:refnums = serverctl(GMATCH $groupname); 337 338 if (refnums == []) { 339 xecho -b -c -- server group $groupname does not exist; 340 341 continue; 342 }; 343 344 if (nickname == []) { 345 @remove_group_notify_entry($groupname); 346 347 xecho -b -c -- the notify list for server group $groupname has been cleared; 348 349 continue; 350 }; 351 352 if (remove_group_notify_entry($groupname $nickname) == 1) { 353 xecho -b -c -- $nickname is not in the notify list for server group ${groupname}!; 354 } else { 355 xecho -b -c -- $nickname has been removed from the notify list for server group ${groupname}; 356 }; 357 } else { 358 if (nickname == []) { 359 continue; 360 }; 361 362 if (remove_notify_entry($nickname) == 1) { 363 xecho -b -c -- $nickname is not in the global notify list!; 364 } else { 365 xecho -b -c -- $nickname has been removed from the global notify list; 366 }; 367 }; 368 } else { 369 if (left(1 $nickname) == [+]) { 370 @:nickname = rest($nickname); 371 }; 372 373 if (separators == 1) { 374 @:network = after(: $nickname); 375 @:nethash = encode($toupper($network)); 376 @:nickname = before(: $nickname); 377 378 if (nickname == []) { 379 continue; 380 }; 381 382 if (findw($nickname $notify_list[$nethash]) > -1) { 383 xecho -b -c -- $nickname is already in the notify list for network ${network}!; 384 385 continue; 386 }; 387 388 if (findw($nickname $notify_list) > -1) { 389 xecho -b -c -- $nickname is already in the global notify list!; 390 391 continue; 392 }; 393 394 if (findw($network $notify_networks) == -1) { 395 push notify_networks $network; 396 }; 397 398 push notify_list[$nethash] $nickname; 399 400 xecho -b -c -- $nickname has been added to the notify list for network $network; 401 } elsif (separators >= 2) { 402 @:groupname = after(-1 : $nickname); 403 @:grouphash = encode($toupper($groupname)); 404 @:nickname = before(: $nickname); 405 406 if (nickname == []) { 407 xecho -b -c -- no nickname provided for server group $groupname; 408 continue; 409 }; 410 411 412 if (serverctl(GMATCH $groupname) == []) { 413 xecho -b -c -- server group $groupname does not exist; 414 415 continue; 416 }; 417 418 if (findw($nickname $notify_list[$grouphash]) > -1) { 419 xecho -b -- $nickname is already in the notify list for server group ${groupname}!; 420 continue; 421 }; 422 423 424 if (findw($nickname $notify_list) > -1) { 425 xecho -b -c -- $nickname is already in the global notify list!; 426 427 continue; 428 }; 429 430 if (findw($groupname $notify_groups) == -1) { 431 push notify_groups $groupname; 432 }; 433 434 push notify_list[$grouphash] $nickname; 435 436 xecho -b -c -- $nickname has been added to the notify list for server group $groupname; 437 } else { 438 if (nickname == []) { 439 continue; 440 }; 441 442 if (findw($nickname $notify_list[$encode($toupper($lgroup))]) > -1) { 443 xecho -b -c -- $nickname is already in the notify list for server group ${lgroup}!; 444 445 continue; 446 }; 447 448 if (findw($nickname $notify_list[$encode($toupper($lnetwork))]) > -1) { 449 xecho -b -c -- $nickname is already in the notify list for the network ${lnetwork}!; 450 continue; 451 }; 452 453 if (findw($nickname $notify_list) > -1) { 454 xecho -b -c -- $nickname is already in the global notify list!; 455 456 continue; 457 }; 458 459 push notify_list $nickname; 460 461 xecho -b -c -- $nickname has been added to the global notify list; 462 }; 463 }; 464 }; 465 466 if (do_notify_immediately == [ON]) { 467 @detect_signons(); 468 }; 469}; 470 471alias observe_offline (nicklist) { 472 @:signoffs = []; 473 @:lserver = serverctl(from_server); 474 475 fe ($nicklist) nickname { 476 if (getnick[$lserver] != [] && getnick[$lserver] != N && getnick[$lserver] == nickname) { 477 //nick $getnick[$lserver]; 478 }; 479 480 if (findw($nickname $online_list[$lserver]) > -1) { 481 push signoffs $nickname; 482 }; 483 }; 484 485 @change_notify_status($lserver offline $signoffs); 486}; 487 488alias observe_online (nicklist) { 489 @:signons = []; 490 @:lserver = serverctl(from_server); 491 @:groupname = serverctl(GET $lserver GROUP); 492 @:network = serverctl(GET $lserver 005 NETWORK); 493 @:offline_list = remws($online_list[$lserver] / $notify_list $notify_list[$encode($toupper($groupname))] $notify_list[$encode($toupper($network))]); 494 495 fe ($nicklist) nickname { 496 if (findw($nickname $offline_list) > -1) { 497 push signons $nickname; 498 }; 499 }; 500 501 @change_notify_status($lserver online $signons); 502}; 503 504alias remove_notify_entry (nickname) { 505 if (nickname == []) { 506 fe ($notify_list) nickname { 507 fe ($servernums()) servernum { 508 @:groupname = serverctl(GET $servernum GROUP); 509 @:network = serverctl(GET $servernum 005 NETWORK); 510 511 if (findw($nickname $notify_list[$encode($toupper($groupname))]) == -1 && findw($nickname $notify_list[$encode($toupper($network))]) == -1) { 512 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 513 }; 514 }; 515 }; 516 517 @notify_list = []; 518 519 return 0; 520 }; 521 522 if (findw($nickname $notify_list) == -1) { 523 return 1; 524 } else { 525 @notify_list = remw($nickname $notify_list); 526 527 fe ($servernums()) servernum { 528 @:groupname = serverctl(GET $servernum GROUP); 529 @:network = serverctl(GET $servernum 005 NETWORK); 530 531 if (findw($nickname $notify_list[$encode($toupper($groupname))]) == -1 && findw($nickname $notify_list[$encode($toupper($network))]) == -1) { 532 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 533 }; 534 }; 535 536 return 0; 537 }; 538 539}; 540 541alias remove_group_notify_entry (groupname, nickname) { 542 @:grouphash = encode($toupper($groupname)); 543 544 if (nickname == []) { 545 fe ($notify_list[$grouphash]) nickname { 546 fe ($servernums()) servernum { 547 if (serverctl(GET $servernum GROUP) == groupname) { 548 @:network = serverctl(GET $servernum 005 NETWORK); 549 550 if (findw($nickname $notify_list[$encode($toupper($network))]) == -1) { 551 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 552 }; 553 }; 554 }; 555 }; 556 557 @notify_list[$grouphash] = []; 558 @notify_groups = remw($groupname $notify_groups); 559 560 return 0; 561 }; 562 563 if (findw($nickname $notify_list[$grouphash]) == -1) { 564 return 1; 565 } else { 566 @notify_list[$grouphash] = remw($nickname $notify_list[$grouphash]); 567 568 if (notify_list[$grouphash] == []) { 569 @notify_groups = remw($groupname $notify_groups); 570 }; 571 572 fe ($servernums()) servernum { 573 if (serverctl(GET $servernum GROUP) == groupname) { 574 @:network = serverctl(GET $servernum 005 NETWORK); 575 576 if (findw($nickname $notify_list[$encode($toupper($network))]) == -1) { 577 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 578 }; 579 }; 580 }; 581 582 return 0; 583 }; 584}; 585 586alias remove_network_notify_entry (network, nickname) { 587 @:nethash = encode($toupper($network)); 588 589 if (nickname == []) { 590 fe ($notify_list[$nethash]) nickname { 591 fe ($servernums()) servernum { 592 if (serverctl(GET $servernum 005 NETWORK) == network) { 593 @:groupname = serverctl(GET $servernum GROUP); 594 595 if (findw($nickname $notify_list[$encode($toupper($groupname))]) == -1) { 596 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 597 }; 598 }; 599 }; 600 }; 601 602 @notify_list[$nethash] = []; 603 @notify_networks = remw($network $notify_networks); 604 605 return 0; 606 }; 607 608 if (findw($nickname $notify_list[$nethash]) == -1) { 609 return 1; 610 } else { 611 @notify_list[$nethash] = remw($nickname $notify_list[$nethash]); 612 613 if (notify_list[$nethash] == []) { 614 @notify_networks = remw($network $notify_networks); 615 }; 616 617 fe ($servernums()) servernum { 618 if (serverctl(GET $servernum 005 NETWORK) == network) { 619 @:groupname = serverctl(GET $servernum GROUP); 620 621 if (findw($nickname $notify_list[$encode($toupper($groupname))]) == -1) { 622 @online_list[$servernum] = remw($nickname $online_list[$servernum]); 623 }; 624 }; 625 }; 626 627 return 0; 628 }; 629}; 630 631alias remove_notify_hooks { 632 ^on #^channel_nick 556 -"*"; 633 ^on #^channel_signoff 556 -"*"; 634 ^on #^join 556 -"*"; 635 ^on #^msg 556 -"*"; 636 ^on #^notice 556 -"*"; 637 ^on #^send_to_server 556 -"% % ISON *"; 638 ^on #^server_lost 556 -"*"; 639 ^on #^003 556 -"*"; 640 ^on #^311 556 -"*"; 641 ^on #^401 556 -"*"; 642}; 643 644alias servernums { 645 @:refnums = []; 646 647 fe ($serverctl(omatch *)) refnum { 648 if (serverctl(get $refnum connected)) { 649 push refnums $refnum; 650 }; 651 }; 652 653 return $refnums; 654}; 655 656 657on ^notify_signoff "*" { 658 xecho -b -level CRAP -- Signoff by $0 detected; 659}; 660 661on ^notify_signon "*" { 662 if (NOTIFY_USERHOST_AUTOMATIC == [ON]) { 663 if ([$1] == [<UNKNOWN>@<UNKNOWN>]) { 664 xecho -b -level CRAP -- Signon by $0 \(\) detected; 665 } else { 666 xecho -b -level CRAP Signon by $0 \($1\) detected; 667 }; 668 } else { 669 xecho -b -level CRAP -- Signon by $0 detected; 670 }; 671}; 672 673on ^set "DO_NOTIFY_IMMEDIATELY" { 674 if ([$1] == []) { 675 xecho -b Current value of DO_NOTIFY_IMMEDIATELY is $do_notify_immediately; 676 } elsif ([$1] == [off]) { 677 @do_notify_immediately = [off]; 678 xecho -b Value of DO_NOTIFY_IMMEDIATELY set to OFF; 679 } elsif ([$1] == [on]) { 680 @do_notify_immediately = [on]; 681 xecho -b Value of DO_NOTIFY_IMMEDIATELY set to ON; 682 } else { 683 xecho -b Value of DO_NOTIFY_IMMEDIATELY must be ON or OFF; 684 }; 685}; 686 687on ^set "NOTIFY *" { 688 if ([$1] == []) { 689 xecho -b Current value of NOTIFY is $notify; 690 } elsif ([$1] == [off]) { 691 @notify = [off]; 692 693 ^timer -del notcheck; 694 @remove_notify_hooks(); 695 696 xecho -b Value of NOTIFY set to OFF; 697 } elsif ([$1] == [on]) { 698 @notify = [on]; 699 700 @clear_notify_records(); 701 @establish_notify_hooks(); 702 ^timer -refnum notcheck -rep -1 $notify_interval @detect_signons(); 703 704 xecho -b Value of NOTIFY set to ON; 705 } else { 706 xecho -b Value of NOTIFY must be ON or OFF; 707 }; 708}; 709 710on ^set "NOTIFY_INTERVAL *" { 711 if ([$1] == []) { 712 xecho -b Current value of NOTIFY_INTERVAL is $notify_interval; 713 } elsif (!isnumber($1)) { 714 xecho -b Value of NOTIFY_INTERVAL must be numeric!; 715 } elsif ([$1] < 1) { 716 xecho -b Value of NOTIFY_INTERVAL must be greater than or equal to 1; 717 } else { 718 @notify_interval = [$1]; 719 720 ^timer -del notcheck; 721 ^timer -refnum notcheck -rep -1 $notify_interval @detect_signons(); 722 723 xecho -b Value of NOTIFY_INTERVAL set to $notify_interval; 724 }; 725}; 726 727on ^set "NOTIFY_USERHOST_AUTOMATIC *" { 728 if ([$1] == []) { 729 xecho -b Current value of NOTIFY_USERHOST_AUTOMATIC is $notify_userhost_automatic; 730 } elsif ([$1] == [off]) { 731 @notify_userhost_automatic = [OFF]; 732 xecho -b Value of NOTIFY_USERHOST_AUTOMATIC set to OFF; 733 } elsif ([$1] == [on]) { 734 @notify_userhost_automatic = [ON]; 735 xecho -b Value of NOTIFY_USERHOST_AUTOMATIC set to ON; 736 } else { 737 xecho -b Value of NOTIFY_USERHOST_AUTOMATIC must be ON or OFF; 738 }; 739}; 740 741@clear_notify_list(); 742@clear_notify_records(); 743@establish_notify_hooks(); 744@detect_signons(); 745timer -refnum notcheck -rep -1 $notify_interval @detect_signons(); 746