#!/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 startGAME=ut2004# time between automatic reloads in seconds, can the overwritten in $1default_timeout=180quakestat-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 queryIPS=( 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 stringsfunction 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 gamefunction 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-blockingfunction 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 setfunction 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 givenn=1for ip in ${IPS[*]}; do echo -n "$n "; ((n++)) # quakestat call quakestat-ip $ipdone | sed "s,xDeathMatch,," | mapmatcher | GREP_COLOR="1;35" egrep -i '(| DM-[^ ]*)' # last grep for map highlightingecho -n "Join> "T=$SECONDS# auto reload every $1 seconds, i.e. this read call has a timeout setread -n 1 -t $1if [ $? = 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-launchelse # run script again if timeout was reached ((Tdelta=SECONDS-T+1)) [ $Tdelta -ge $1 ] && echo && exec "$0" $1fi