if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo()); return; }; # # sping.irc: a script to calculate the lag between you and a server # # written by nsx # # note: this script uses the serial number 105 for its serial hooks # load addset; package sping; # *** config variables ** addset sping_timeout int { @sping_timeout = *0; }; set sping_timeout 1200; # *** commands *** alias sping (server) { @:source_server = servernum(); if (server == []) @:server = servername(); @:now = utime(); quote PING $server $server; @:ping_id = get_ping_id(); @:sping_data = [$ping_id $now $source_server $server]; push sping_list $sping_data; ^eval timer -refnum $ping_id $sping_timeout @timeout_sping\($ping_id $server\); xecho -b -w $serv_win() -- Sent PING to $server; }; alias vping (server) { @:refnum = servernum(); if (server == []) @:server = servername(); @:serv = [!]; @:vping_list = vpings[$refnum]; for (@:i = 3, serv != [], @:i += 4) { @:serv = word($i $vping_list); if (serv == server) { xecho -b -w $serv_win() -- Waiting for reply to previous VPING to $server; return; }; }; @:now = utime(); quote VERSION $server; @:ping_id = get_ping_id(); @:vping_data = [$ping_id $now $server]; push vpings[$servernum()] $vping_data; ^eval timer -refnum $ping_id $sping_timeout @timeout_vping\($ping_id $server\); ^on ^351 "$server *" { @:now = utime(); @:retval = handle_version($0 $now); if (retval) { xecho -b -w $serv_win() -- $1-; }; ^on ^351 -"$0 *"; ^on ^263 -"$0 VERSION *"; }; ^on ^263 "$server VERSION *" { @:now = utime(); @:retval = handle_version($0 $now); if (retval) { xecho -b -w $serv_win() -- $1-; }; ^on ^351 -"$0 *"; ^on ^263 -"$0 VERSION *"; }; xecho -b -w $serv_win() -- Sent VPING to $server; }; # *** functions *** alias calculate_ping_time (ithen, fthen, inow, fnow) { @:idiff = inow - ithen; @:fdiff = fnow - fthen; if (fdiff < 0) { @:fdiff += 1000000; @:idiff--; }; repeat ${6 - @fdiff} @:fdiff = [0] ## fdiff; @:minute_diff = my_floor(${idiff / 60}); @:second_diff = idiff % 60; if (idiff >= 60) { if (minute_diff == 1) { return $minute_diff min ${second_diff}.${fdiff} secs; } else { return $minute_diff mins ${second_diff}.${fdiff} secs; }; } else { return ${second_diff}.${fdiff} secs; }; }; alias clear_pings { @sping_list = []; @ping_number = 0; fe ($myservers(*)) refnum { @vpings[$refnum] = []; }; }; alias get_ping_id { @ping_number++; return ping${ping_number}; }; alias handle_pong (server_name, now) { @:inow = word(0 $now); @:fnow = word(1 $now); @:server = [!]; for (@:i = 4, server != [], @:i += 5) { @:server = word($i $sping_list); if (server == server_name) { @:ping_id = word(${i - 4} $sping_list); @:sping_itime = word(${i - 3} $sping_list); @:sping_ftime = word(${i - 2} $sping_list); @:reply_msg = calculate_ping_time($sping_itime $sping_ftime $inow $fnow); @:new_list_start = leftw(${i - 4} $sping_list); @:new_list_end = rightw(${(#sping_list - (i - 4)) - 5} $sping_list); if (new_list_start == []) { @sping_list = new_list_end; } else { @sping_list = new_list_start ## [ ] ## new_list_end; }; ^eval timer -del $ping_id; xecho -b -w $serv_win() -- PONG received from $server_name in $reply_msg; xecho -w $serv_win(); return; }; }; xecho -b -w $serv_win() -- Received PONG from $server_name; }; alias handle_version (server_name, now) { @:inow = word(0 $now); @:fnow = word(1 $now); @:refnum = servernum(); @:server = [!]; @:vping_list = vpings[$refnum]; for (@:i = 3, server != [], @:i += 4) { @:server = word($i $vping_list); if (server == server_name) { @:ping_id = word(${i - 3} $vping_list); @:vping_itime = word(${i - 2} $vping_list); @:vping_ftime = word(${i - 1} $vping_list); @:reply_msg = calculate_ping_time($vping_itime $vping_ftime $inow $fnow); @:new_list_start = leftw(${i - 3} $vping_list); @:new_list_end = rightw(${(#vping_list - (i - 3)) - 4} $vping_list); if (new_list_start == []) { @:vping_list = new_list_end; } else { @:vping_list = new_list_start ## [ ] ## new_list_end; }; @vpings[$refnum] = vping_list; ^eval timer -del $ping_id; xecho -b -w $serv_win() -- VPING reply received from $server_name in $reply_msg; xecho -w $serv_win(); return 0; }; }; return 1; }; alias my_floor (number) { switch ($count(. $number)) { (1) { return $before(. $number); } (0) { return $number; } (*) { return -1; } }; }; alias remove_matching_pings (field, value, entry_size, list) { @:item = [!]; @:new_list = []; for (@:i = field, item != [], @:i += entry_size) { @:item = word($i $list); if (item != value) { @:ping_entry = midw(${i - field} $entry_size $list); push new_list $ping_entry; } else { @:ping_id = word(${i - field} $list); ^eval timer -del $ping_id; }; }; return $new_list; }; alias serv_win (refnum) { @:win_max = [255]; @:i = [1]; if (refnum == []) { @:refnum = servernum(); }; while (i < win_max) { if (winserv($i) == refnum) { return $i; }; @:i++; }; }; alias timeout_sping (ping_id, server) { if (sping_list == []) { return; }; @sping_list = remove_matching_pings(0 $ping_id 5 $sping_list); xecho -b -w $serv_win() -- PING to $server timed out; }; alias timeout_vping (ping_id, server) { @:refnum = servernum($server); @:vping_list = vpings[$refnum]; if (vping_list == []) { return; }; @:vping_list = remove_matching_pings(0 $ping_id 4 $vping_list); @vpings[$refnum] = vping_list; xecho -b -w $serv_win() -- VPING to $server timed out; }; # *** hooks *** # upon connection to any server, let's make sure we're not still waiting for # any responses previously sent from that server on #^connect 105 "*" { @:refnum = servernum($0); @:vpings[$refnum] = []; @sping_list = remove_matching_pings(3 $refnum 5 $sping_list); }; on ^pong "*" { @:now = utime(); @handle_pong($0 $now); }; # upon disconnection from any server, let's make sure we're not still waiting # for a response to any pings we sent while connected to that server. on #^server_lost 105 "*" { @:refnum = [$0]; @:vpings[$refnum] = []; @sping_list = remove_matching_pings(3 $refnum 5 $sping_list); } # if we're told that a server doesn't exist, let's make sure we're not waiting # a ping reply from that server. on #^402 105 "*" { @sping_list = remove_matching_pings(4 $1 5 $sping_list); fe ($myservers(*)) refnum { @vpings[$refnum] = remove_matching_pings(3 $1 4 $vpings[$refnum]); }; }; @clear_pings();