#!/bin/bash # version 2010-10-05 # this script uses quakestat to query a number of game servers every x seconds # entering the number of the server lets you join it # it can also monitor the server list for interesting maps # the game to start GAME=ut2004 # time between automatic reloads in seconds, can the overwritten in $1 default_timeout=180 quakestat-ip() { # quakestat call, change this to match the game, see qstat --help # gets called once for every IP qstat -nh -sort l -sort F -P -ut2s $1 } declare -a IPS # array of server ips (and ports) to query IPS=( 85.236.100.86:29714 194.97.166.27 85.14.226.107 217.14.14.189 ) # pipe the server list through awk and look for interesting strings function mapmatcher() { awk 'BEGIN { nomatch=1 } # only alert once { print; # pass through every line if(nomatch && $0 ~ /[^0 ]\/[^0 ]/) { # only alert on first found interesting map, which is not empty if($0 ~ /(Deck17|Asbestos|Phobos)/) { # match map names system("kdialog --msgbox \"Interesting game found!\" &"); nomatch=0; } } }' } # runs before launching the game function pre-launch() { # example: use dbus to throttle ktorrent # if pgrep ktorrent >& /dev/null; then # Kup=$(qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.maxUploadRate) # Kdown=$(qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.maxDownloadRate) # qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.setMaxUploadRate 11; qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.setMaxDownloadRate 77; qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.apply; # fi } # runs in parallel to launching the game, i.e. non-blocking function launch-parallel() { # example: leave music running and use dbus to pause music after a while # sleep 13; # pgrep $GAME >& /dev/null || return; # don't run if game doesn't run anymore # qdbus org.atheme.audacious /org/atheme/audacious org.atheme.audacious.Paused | grep -q false && qdbus org.atheme.audacious /org/atheme/audacious org.atheme.audacious.Pause; } # runs after the game ran, possibly resetting what the launch has set function post-launch() { # example: use dbus to throttle ktorrent # if pgrep ktorrent >& /dev/null; then # qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.setMaxUploadRate $Kup; qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.setMaxDownloadRate $Kdown; qdbus org.ktorrent.ktorrent /settings org.ktorrent.settings.apply; # fi } echo -n " "; date '+%H:%M' # no timeout-to-reload argument? set it [ $# -eq 0 ] && set -- $default_timeout # query every IP given n=1 for ip in ${IPS[*]}; do echo -n "$n "; ((n++)) # quakestat call quakestat-ip $ip done | sed "s,xDeathMatch,," | mapmatcher | GREP_COLOR="1;35" egrep -i '(| DM-[^ ]*)' # last grep for map highlighting echo -n "Join> " T=$SECONDS # auto reload every $1 seconds, i.e. this read call has a timeout set read -n 1 -t $1 if [ $? = 0 ]; then # read didn't time out, something was entered if [ "${REPLY//[0-9]*}" != "" ]; then # if it was NOT a number... ARROW=$(echo -ne "\\x1b") # ^[ CTRLD=$(echo -ne "\\x04") # ^D case "$REPLY" in t) echo -en "\\x0dSeconds between reload> "; read set -- $REPLY; exec "$0" "$1" ;; h|'?') # help notice echo -e "\n\n1-9 - join this server\nr - reload\nx/q - exit/quit\nt - set reload intervall\n"; exec "$0" "$1" ;; r) # reload manually echo " ... reloading" exec "$0" "$1" ;; x|q) # exit/quit echo exit ;; $ARROW) # hack to also catch arrow up/left/etc. which generates ^[, [ and A, i.e. 3 input events read -n 2 -t 1; echo " ... reloading" exec "$0" "$1" ;; $CTRLD) # ^D echo exit ;; *) echo "Bad input ($REPLY)" | cat -A | tr -d '$' exit ;; esac fi # if it was a number, join that IP ((REPLY--)) echo " ... joining ${IPS[$REPLY]}" echo $GAME ${IPS[$REPLY]} pre-launch launch-parallel & $GAME ${IPS[$REPLY]} post-launch else # run script again if timeout was reached ((Tdelta=SECONDS-T+1)) [ $Tdelta -ge $1 ] && echo && exec "$0" $1 fi