0

This is a batch that pings the servers of a game I play, so that I am able to find the best server for me.

Is there a way I can have it ping all the servers then list them in order from the slowest response to the highest?

@TITLE OSRS Ping Checker
@ECHO off

SET usaworlds=5,6,7,13,14,15,19,20,21,22,23,24,29,30,31,32,37,38,39,40,45,46,47,48,53,54,55,56,57,61,62,69,70,74,77,78,86,117

@ECHO --------------------------------------------------- 
@ECHO                     USA
@ECHO --------------------------------------------------- 
FOR %%i IN (%usaworlds%) DO (
Echo | SET /p=World %%i
FOR /F "tokens=5" %%a IN ('Ping oldschool%%i.runescape.com -n 1 ^| FIND "time="') DO Echo %%a
)

PAUSE
aschipfl
  • 33,626
  • 12
  • 54
  • 99
Ross
  • 11
  • 2
  • [Redirect](http://ss64.com/nt/syntax-redirection.html) (`>`/`>>`) the output to a temporary file, then use the [`sort` command](http://ss64.com/nt/sort.html)... – aschipfl Jun 13 '18 at 11:57

2 Answers2

1
@ECHO off
setlocal enabledelayedexpansion
TITLE OSRS Ping Checker

for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
del x.tmp 2>nul

SET usaworlds=5,6,7,13,14,15,19,20,21,22,23,24,29,30,31,32,37,38,39,40,45,46,47,48,53,54,55,56,57,61,62,69,70,74,77,78,86,117

ECHO --------------------------------------------------- 
ECHO                     USA
ECHO --------------------------------------------------- 
FOR %%i IN (%usaworlds%) DO (
  <nul set /p "=checking World %%i  !CR!"
  FOR /F "tokens=5" %%a IN ('Ping oldschool%%i.runescape.com -n 1 ^| FIND "TTL="') DO (
    for /f "tokens=2 delims==" %%b in ("%%a") do ( 
      set tim=00000%%b
      set tim=!tim:~-7,-2!
    )
  )
  echo !tim! World %%i>>x.tmp
)
for /f "tokens=3" %%c in ('sort /r x.tmp') do set fastest=%%c
echo fastest response from World %fastest%
PAUSE

Note: the time of a one-time ping isn't reliable (check the different times with ping -t) and so this approach may give you false results. better check "Average" with ping -n 5 or even higher, but that will of course decrease the performance of the script.

To make it faster and more reliable using the average times, you can run the pings in parallel (I have used that method years ago in another context)

@ECHO off
setlocal 
TITLE OSRS Ping Checker
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
del %temp%\x.tmp 2>nul
SET usaworlds=wrgl,5,6,7,13,14,15,19,20,21,22,23,24,29,30,31,32,37,38,39,40,45,46,47,48,53,54,55,56,57,61,62,69,70,74,77,78,86,117

@ECHO --------------------------------------------------- 
@ECHO                     USA
@ECHO --------------------------------------------------- 
FOR %%i IN (%usaworlds%) DO (
   start /min "Pinging" cmd /v:on /c "(FOR /F "tokens=9 delims= " %%a IN ('Ping oldschool%%i.runescape.com -n 5^|findstr /e "ms"') do set avrg=       %%a)& >> %temp%\x.tmp echo ^!avrg:~-7,-2^!" World %%i
)
:wait
timeout 1 >nul
tasklist /FI "WINDOWTITLE eq Pinging" |find ".exe" >nul && goto :wait
for /f "tokens=3" %%c in ('sort /r %temp%\x.tmp') do set fastest=%%c
echo fastest response from World %fastest%
PAUSE

Using start /min instead of start /b does keep your screen clean in case of errors (makes it a bit slower, but you won't notice it)

Stephan
  • 53,940
  • 10
  • 58
  • 91
1

Since there are many hosts to check/ping, sequencial processing lasts for a quite long time, particularly when following Stephan's recommendation of using more than one echo requests and taking the average reply time.

So I suggest to use a different approach and let the ping requests happen in simultaneous processes:

@title OSRS Ping Checker
@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ARG=%~1" & if defined _ARG shift /1 & goto :DO_PING & ^
    rem // (jump to label `DO_LOOP` in case arguments are provided)
set "_USAWORLDS=5,6,7,13,14,15,19,20,21,22,23,24,29,30,31,32,37,38,39,40,45,46,47,48,53,54,55,56,57,61,62,69,70,74,77,78,86,117"
set "_ECHOREQUS=10" & rem // (number of echo requests to send per host)
set "_TEMPFILEB=%TEMP%\%~n0_%RANDOM%" & rem // (path and base name of temporary files)
set "_FINALFILE=%~dpn0.txt"           & rem // (path and full name of return file)

rem // Process items in sub-routine but in parallel processes:
for %%I in (%_USAWORLDS%) do (
    rem // Redirect output of every process to individual temporary file:
    > "%_TEMPFILEB%_%%~I.tmp" start /B "" cmd /C "%~f0" :DO_PING %%~I %_ECHOREQUS%
)
rem /* Wait until all temporary files are write-accessible, meaning that
rem    all the parallel processes have been completed/terminated: */
:POLL
for %%I in (%_USAWORLDS%) do (
    rem // Try appending nothing to check for write-access:
    2> nul (>> "%_TEMPFILEB%_%%~I.tmp" rem/) || (
        rem // Wait a bit to not overload the processor:
        > nul timeout /T 1 /NOBREAK
        goto :POLL
    )
)
rem // Combine all individual temporary files into one:
> nul copy /Y "%_TEMPFILEB%_*.tmp" "%_TEMPFILEB%.tmp" /B
rem // Sort data as desired (alphabetic sorting):
sort /R "%_TEMPFILEB%.tmp" /O "%_TEMPFILEB%.tmp"
rem // Create return file, write header:
> "%_FINALFILE%" echo ms      host
rem // Append sorted data to return file:
> nul copy /Y "%_FINALFILE%" + "%_TEMPFILEB%.tmp" "%_FINALFILE%" /B
rem // Clean up temporary files:
del "%_TEMPFILEB%_*.tmp" "%_TEMPFILEB%.tmp"

endlocal
exit /B


:DO_PING
    rem // Build host URL to ping, set number of echo requests to send:
    set "URL=oldschool%~1.runescape.com"
    set /A "NUM=%~2"
    rem /* Perform ping and capture last line of response, which should contain
    rem    the average reply time: */
    set "STR="
    for /F "delims=" %%P in ('2^> nul ping "%URL%" -n %NUM%') do set "STR=%%P"
    rem // Check whether last line of response contains average reply time:
    if not defined STR exit /B
    set "AVG=%STR:*Average =%"
    set "AVG=%AVG:~1%"
    if "%AVG%"=="%STR%" exit /B
    rem /* Convert average reply time to pure left-zero-padded number; the padding
    rem    is intended to simplify the later (purely alphabetic) sorting: */
    set /A "AVG=AVG"
    set "AVG=000000%AVG%"
    rem // Return average reply time together with respective host URL:
    echo %AVG:~-6%  "%URL%"
    exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99