mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-09 05:24:44 +01:00
897c4d5786
channel. Works well enough that relay test script works. Not yet integrated for let alone tested on Android.
784 lines
22 KiB
Bash
Executable file
784 lines
22 KiB
Bash
Executable file
#!/bin/bash
|
|
set -u -e
|
|
|
|
LOGDIR=$(basename $0)_logs
|
|
APP_NEW=""
|
|
DO_CLEAN=""
|
|
APP_NEW_PARAMS=""
|
|
NGAMES=""
|
|
UDP_PCT_START=5
|
|
UDP_PCT_INCR=10
|
|
UPGRADE_ODDS=""
|
|
NROOMS=""
|
|
HOST=""
|
|
PORT=""
|
|
TIMEOUT=""
|
|
SAVE_GOOD=""
|
|
MINDEVS=""
|
|
MAXDEVS=""
|
|
ONEPER=""
|
|
RESIGN_RATIO=""
|
|
DROP_N=""
|
|
MINRUN=2
|
|
ONE_PER_ROOM="" # don't run more than one device at a time per room
|
|
USE_GTK=""
|
|
UNDO_PCT=0
|
|
ALL_VIA_RQ=${ALL_VIA_RQ:-FALSE}
|
|
SEED=""
|
|
BOARD_SIZES_OLD=(15)
|
|
BOARD_SIZES_NEW=(15)
|
|
NAMES=(UNUSED Brynn Ariela Kati Eric)
|
|
SEND_CHAT=''
|
|
CORE_COUNT=$(ls core.* 2>/dev/null | wc -l)
|
|
DUP_PACKETS=''
|
|
|
|
declare -A PIDS
|
|
declare -A APPS
|
|
declare -A NEW_ARGS
|
|
declare -a ARGS
|
|
declare -A ARGS_DEVID
|
|
declare -A ROOMS
|
|
declare -A FILES
|
|
declare -A LOGS
|
|
declare -A MINEND
|
|
declare -A ROOM_PIDS
|
|
declare -a APPS_OLD=()
|
|
declare -a DICTS= # wants to be =() too?
|
|
declare -A CHECKED_ROOMS
|
|
|
|
function cleanup() {
|
|
APP="$(basename $APP_NEW)"
|
|
while pidof $APP; do
|
|
echo "killing existing $APP instances..."
|
|
killall -9 $APP
|
|
sleep 1
|
|
done
|
|
echo "cleaning everything up...."
|
|
if [ -d $LOGDIR ]; then
|
|
mv $LOGDIR /tmp/${LOGDIR}_$$
|
|
fi
|
|
if [ -e $(dirname $0)/../../relay/xwrelay.log ]; then
|
|
mkdir -p /tmp/${LOGDIR}_$$
|
|
mv $(dirname $0)/../../relay/xwrelay.log /tmp/${LOGDIR}_$$
|
|
fi
|
|
|
|
echo "DELETE FROM games WHERE room LIKE 'ROOM_%';" | psql -q -t xwgames
|
|
echo "DELETE FROM msgs WHERE NOT devid in (SELECT unnest(devids) from games);" | psql -q -t xwgames
|
|
}
|
|
|
|
function connName() {
|
|
LOG=$1
|
|
grep 'got_connect_cmd: connName' $LOG | \
|
|
tail -n 1 | \
|
|
sed 's,^.*connName: \"\(.*\)\" (reconnect=.)$,\1,'
|
|
}
|
|
|
|
function check_room() {
|
|
ROOM=$1
|
|
if [ -z ${CHECKED_ROOMS[$ROOM]:-""} ]; then
|
|
NUM=$(echo "SELECT COUNT(*) FROM games "\
|
|
"WHERE NOT dead "\
|
|
"AND ntotal!=sum_array(nperdevice) "\
|
|
"AND ntotal != -sum_array(nperdevice) "\
|
|
"AND room='$ROOM'" |
|
|
psql -q -t xwgames)
|
|
NUM=$((NUM+0))
|
|
if [ "$NUM" -gt 0 ]; then
|
|
echo "$ROOM in the DB has unconsummated games. Remove them."
|
|
exit 1
|
|
else
|
|
CHECKED_ROOMS[$ROOM]=1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
print_cmdline() {
|
|
local COUNTER=$1
|
|
local LOG=${LOGS[$COUNTER]}
|
|
echo -n "New cmdline: " >> $LOG
|
|
echo "${APPS[$COUNTER]} ${NEW_ARGS[$COUNTER]} ${ARGS[$COUNTER]}" >> $LOG
|
|
}
|
|
|
|
function pick_ndevs() {
|
|
local NDEVS=2
|
|
local RNUM=$((RANDOM % 100))
|
|
if [ $RNUM -gt 90 -a $MAXDEVS -ge 4 ]; then
|
|
NDEVS=4
|
|
elif [ $RNUM -gt 75 -a $MAXDEVS -ge 3 ]; then
|
|
NDEVS=3
|
|
fi
|
|
if [ -n "$MINDEVS" -a "$NDEVS" -lt "$MINDEVS" ]; then
|
|
NDEVS=$MINDEVS
|
|
fi
|
|
echo $NDEVS
|
|
}
|
|
|
|
# Given a device count, figure out how many local players per device.
|
|
# "1 1" would be a two-device game with 1 each. "1 2 1" a
|
|
# three-device game with four players total
|
|
function figure_locals() {
|
|
local NDEVS=$1
|
|
local NPLAYERS=$(pick_ndevs)
|
|
[ $NPLAYERS -lt $NDEVS ] && NPLAYERS=$NDEVS
|
|
|
|
local EXTRAS=0
|
|
if [ -z "$ONEPER" ]; then
|
|
EXTRAS=$(($NPLAYERS - $NDEVS))
|
|
fi
|
|
|
|
local LOCALS=""
|
|
for IGNORE in $(seq $NDEVS); do
|
|
COUNT=1
|
|
if [ $EXTRAS -gt 0 ]; then
|
|
local EXTRA=$((RANDOM % $((1 + EXTRAS))))
|
|
if [ $EXTRA -gt 0 ]; then
|
|
COUNT=$((COUNT + EXTRA))
|
|
EXTRAS=$((EXTRAS - EXTRA))
|
|
fi
|
|
fi
|
|
LOCALS="$LOCALS $COUNT"
|
|
done
|
|
echo "$LOCALS"
|
|
}
|
|
|
|
function player_params() {
|
|
local NLOCALS=$1
|
|
local NPLAYERS=$2
|
|
local NAME_INDX=$3
|
|
local NREMOTES=$((NPLAYERS - NLOCALS))
|
|
local PARAMS=""
|
|
while [ $NLOCALS -gt 0 -o $NREMOTES -gt 0 ]; do
|
|
if [ 0 -eq $((RANDOM%2)) -a 0 -lt $NLOCALS ]; then
|
|
PARAMS="$PARAMS --robot ${NAMES[$NAME_INDX]} --robot-iq $((1 + (RANDOM%100))) "
|
|
NLOCALS=$((NLOCALS-1))
|
|
NAME_INDX=$((NAME_INDX+1))
|
|
elif [ 0 -lt $NREMOTES ]; then
|
|
PARAMS="$PARAMS --remote-player"
|
|
NREMOTES=$((NREMOTES-1))
|
|
fi
|
|
done
|
|
echo "$PARAMS"
|
|
}
|
|
|
|
function sum() {
|
|
RESULT=0
|
|
while [ $# -gt 0 ]; do
|
|
RESULT=$((RESULT+$1))
|
|
shift
|
|
done
|
|
echo $RESULT
|
|
}
|
|
|
|
build_cmds() {
|
|
COUNTER=0
|
|
local PLAT_PARMS=""
|
|
if [ $USE_GTK = FALSE ]; then
|
|
PLAT_PARMS="--curses --close-stdin"
|
|
fi
|
|
|
|
for GAME in $(seq 1 $NGAMES); do
|
|
ROOM=$(printf "ROOM_%.3d" $((GAME % NROOMS)))
|
|
ROOM_PIDS[$ROOM]=0
|
|
check_room $ROOM
|
|
NDEVS=$(pick_ndevs)
|
|
LOCALS=( $(figure_locals $NDEVS) ) # as array
|
|
NPLAYERS=$(sum ${LOCALS[@]})
|
|
[ ${#LOCALS[*]} -eq $NDEVS ] || usage "problem with LOCALS"
|
|
#[ $NDEVS -lt $MINDEVS ] && NDEVS=$MINDEVS
|
|
DICT=${DICTS[$((GAME%${#DICTS[*]}))]}
|
|
# make one in three games public
|
|
local PUBLIC=""
|
|
[ $((RANDOM%3)) -eq 0 ] && PUBLIC="--make-public --join-public"
|
|
|
|
DEV=0
|
|
for NLOCALS in ${LOCALS[@]}; do
|
|
DEV=$((DEV + 1))
|
|
FILE="${LOGDIR}/GAME_${GAME}_${DEV}.sql3"
|
|
if [ $((RANDOM % 100)) -lt $UDP_PCT_START ]; then
|
|
FILE="$FILE --use-udp"
|
|
fi
|
|
LOG=${LOGDIR}/${GAME}_${DEV}_LOG.txt
|
|
> $LOG # clear the log
|
|
|
|
APPS[$COUNTER]="$APP_NEW"
|
|
NEW_ARGS[$COUNTER]="$APP_NEW_PARAMS"
|
|
BOARD_SIZE="--board-size ${BOARD_SIZES_NEW[$((RANDOM%${#BOARD_SIZES_NEW[*]}))]}"
|
|
if [ 0 -lt ${#APPS_OLD[@]} ]; then
|
|
# 50% chance of starting out with old app
|
|
NAPPS=$((1+${#APPS_OLD[*]}))
|
|
if [ 0 -lt $((RANDOM%$NAPPS)) ]; then
|
|
APPS[$COUNTER]=${APPS_OLD[$((RANDOM%${#APPS_OLD[*]}))]}
|
|
BOARD_SIZE="--board-size ${BOARD_SIZES_OLD[$((RANDOM%${#BOARD_SIZES_OLD[*]}))]}"
|
|
NEW_ARGS[$COUNTER]=""
|
|
fi
|
|
fi
|
|
|
|
PARAMS="$(player_params $NLOCALS $NPLAYERS $DEV)"
|
|
PARAMS="$PARAMS $BOARD_SIZE --room $ROOM --trade-pct 20 --sort-tiles "
|
|
[ $UNDO_PCT -gt 0 ] && PARAMS="$PARAMS --undo-pct $UNDO_PCT "
|
|
PARAMS="$PARAMS --game-dict $DICT --relay-port $PORT --host $HOST "
|
|
PARAMS="$PARAMS --slow-robot 1:3 --skip-confirm"
|
|
PARAMS="$PARAMS --db $FILE"
|
|
PARAMS="$PARAMS --drop-nth-packet $DROP_N $PLAT_PARMS"
|
|
# PARAMS="$PARAMS --split-packets 2"
|
|
if [ -n "$SEND_CHAT" ]; then
|
|
PARAMS="$PARAMS --send-chat $SEND_CHAT"
|
|
fi
|
|
if [ -n "$DUP_PACKETS" ]; then
|
|
PARAMS="$PARAMS --dup-packets"
|
|
fi
|
|
# PARAMS="$PARAMS --my-port 1024"
|
|
# PARAMS="$PARAMS --savefail-pct 10"
|
|
[ -n "$SEED" ] && PARAMS="$PARAMS --seed $RANDOM"
|
|
PARAMS="$PARAMS $PUBLIC"
|
|
if [ $DEV -gt 1 ]; then
|
|
PARAMS="$PARAMS --force-channel $((DEV - 1))"
|
|
fi
|
|
|
|
ARGS[$COUNTER]=$PARAMS
|
|
ROOMS[$COUNTER]=$ROOM
|
|
FILES[$COUNTER]=$FILE
|
|
LOGS[$COUNTER]=$LOG
|
|
PIDS[$COUNTER]=0
|
|
ARGS_DEVID[$COUNTER]=""
|
|
update_ldevid $COUNTER
|
|
|
|
print_cmdline $COUNTER
|
|
|
|
COUNTER=$((COUNTER+1))
|
|
done
|
|
done
|
|
echo "finished creating $COUNTER commands"
|
|
} # build_cmds
|
|
|
|
read_resume_cmds() {
|
|
COUNTER=0
|
|
for LOG in $(ls $LOGDIR/*.txt); do
|
|
echo "need to parse cmd and deal with changes"
|
|
exit 1
|
|
CMD=$(head -n 1 $LOG)
|
|
|
|
ARGS[$COUNTER]=$CMD
|
|
LOGS[$COUNTER]=$LOG
|
|
PIDS[$COUNTER]=0
|
|
|
|
set $CMD
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
--file)
|
|
FILES[$COUNTER]=$2
|
|
shift
|
|
;;
|
|
--room)
|
|
ROOMS[$COUNTER]=$2
|
|
shift
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
COUNTER=$((COUNTER+1))
|
|
done
|
|
ROOM_PIDS[$ROOM]=0
|
|
}
|
|
|
|
launch() {
|
|
KEY=$1
|
|
LOG=${LOGS[$KEY]}
|
|
APP="${APPS[$KEY]}"
|
|
if [ -z "$APP" ]; then
|
|
echo "error: no app set"
|
|
exit 1
|
|
fi
|
|
PARAMS="${NEW_ARGS[$KEY]} ${ARGS[$KEY]} ${ARGS_DEVID[$KEY]}"
|
|
exec $APP $PARAMS >/dev/null 2>>$LOG
|
|
}
|
|
|
|
# launch_via_rq() {
|
|
# KEY=$1
|
|
# RELAYID=$2
|
|
# PIPE=${PIPES[$KEY]}
|
|
# ../relay/rq -f $RELAYID -o $PIPE &
|
|
# CMD="${CMDS[$KEY]}"
|
|
# exec $CMD >/dev/null 2>>$LOG
|
|
# }
|
|
|
|
close_device() {
|
|
ID=$1
|
|
MVTO=$2
|
|
REASON="$3"
|
|
PID=${PIDS[$ID]}
|
|
if [ $PID -ne 0 ]; then
|
|
kill ${PIDS[$ID]} 2>/dev/null
|
|
wait ${PIDS[$ID]}
|
|
ROOM=${ROOMS[$ID]}
|
|
[ ${ROOM_PIDS[$ROOM]} -eq $PID ] && ROOM_PIDS[$ROOM]=0
|
|
fi
|
|
unset PIDS[$ID]
|
|
unset ARGS[$ID]
|
|
echo "closing game: $REASON" >> ${LOGS[$ID]}
|
|
if [ -n "$MVTO" ]; then
|
|
[ -f "${FILES[$ID]}" ] && mv ${FILES[$ID]} $MVTO
|
|
mv ${LOGS[$ID]} $MVTO
|
|
else
|
|
rm -f ${FILES[$ID]}
|
|
rm -f ${LOGS[$ID]}
|
|
fi
|
|
unset FILES[$ID]
|
|
unset LOGS[$ID]
|
|
unset ROOMS[$ID]
|
|
unset APPS[$ID]
|
|
unset ARGS_DEVID[$ID]
|
|
|
|
COUNT=${#ARGS[*]}
|
|
echo "$COUNT devices left playing..."
|
|
}
|
|
|
|
OBITS=""
|
|
|
|
kill_from_log() {
|
|
LOG=$1
|
|
RELAYID=$(./scripts/relayID.sh --long $LOG)
|
|
if [ -n "$RELAYID" ]; then
|
|
OBITS="$OBITS -d $RELAYID"
|
|
if [ 0 -eq $(($RANDOM%2)) ]; then
|
|
../relay/rq -a $HOST $OBITS 2>/dev/null || /bin/true
|
|
OBITS=""
|
|
fi
|
|
return 0 # success
|
|
fi
|
|
echo "unable to send kill command for $LOG"
|
|
return 1
|
|
}
|
|
|
|
maybe_resign() {
|
|
if [ "$RESIGN_RATIO" -gt 0 ]; then
|
|
KEY=$1
|
|
LOG=${LOGS[$KEY]}
|
|
if grep -q XWRELAY_ALLHERE $LOG; then
|
|
if [ 0 -eq $(($RANDOM % $RESIGN_RATIO)) ]; then
|
|
echo "making $LOG $(connName $LOG) resign..."
|
|
kill_from_log $LOG && close_device $KEY $DEADDIR "resignation forced" || /bin/true
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
try_upgrade() {
|
|
KEY=$1
|
|
if [ 0 -lt ${#APPS_OLD[@]} ]; then
|
|
if [ $APP_NEW != "${APPS[$KEY]}" ]; then
|
|
# one in five chance of upgrading
|
|
if [ 0 -eq $((RANDOM % UPGRADE_ODDS)) ]; then
|
|
APPS[$KEY]=$APP_NEW
|
|
NEW_ARGS[$KEY]="$APP_NEW_PARAMS"
|
|
print_cmdline $KEY
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
try_upgrade_upd() {
|
|
KEY=$1
|
|
CMD=${ARGS[$KEY]}
|
|
if [ "${CMD/--use-udp/}" = "${CMD}" ]; then
|
|
if [ $((RANDOM % 100)) -lt $UDP_PCT_INCR ]; then
|
|
ARGS[$KEY]="$CMD --use-udp"
|
|
echo -n "$(date +%r): "
|
|
echo "upgrading key $KEY to use UDP"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_game() {
|
|
KEY=$1
|
|
LOG=${LOGS[$KEY]}
|
|
CONNNAME="$(connName $LOG)"
|
|
OTHERS=""
|
|
if [ -n "$CONNNAME" ]; then
|
|
if grep -q '\[unused tiles\]' $LOG; then
|
|
ALL_DONE=TRUE
|
|
for INDX in ${!LOGS[*]}; do
|
|
[ $INDX -eq $KEY ] && continue
|
|
ALOG=${LOGS[$INDX]}
|
|
CONNNAME2="$(connName $ALOG)"
|
|
if [ "$CONNNAME2" = "$CONNNAME" ]; then
|
|
if ! grep -q '\[unused tiles\]' $ALOG; then
|
|
OTHERS=""
|
|
break
|
|
fi
|
|
OTHERS="$OTHERS $INDX"
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$OTHERS" ]; then
|
|
echo -n "Closing $CONNNAME [$(date)]: "
|
|
# kill_from_logs $OTHERS $KEY
|
|
for ID in $OTHERS $KEY; do
|
|
echo -n "${LOGS[$ID]}, "
|
|
kill_from_log ${LOGS[$ID]} || /bin/true
|
|
close_device $ID $DONEDIR "game over"
|
|
done
|
|
echo ""
|
|
# XWRELAY_ERROR_DELETED may be old
|
|
elif grep -q 'relay_error_curses(XWRELAY_ERROR_DELETED)' $LOG; then
|
|
echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
|
kill_from_log $LOG || /bin/true
|
|
close_device $KEY $DEADDIR "other resigned"
|
|
elif grep -q 'relay_error_curses(XWRELAY_ERROR_DEADGAME)' $LOG; then
|
|
echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
|
kill_from_log $LOG || /bin/true
|
|
close_device $KEY $DEADDIR "other resigned"
|
|
else
|
|
maybe_resign $KEY
|
|
fi
|
|
}
|
|
|
|
increment_drop() {
|
|
KEY=$1
|
|
CMD=${ARGS[$KEY]}
|
|
if [ "$CMD" != "${CMD/drop-nth-packet//}" ]; then
|
|
DROP_N=$(echo $CMD | sed 's,^.*drop-nth-packet \(-*[0-9]*\) .*$,\1,')
|
|
if [ $DROP_N -gt 0 ]; then
|
|
NEXT_N=$((DROP_N+1))
|
|
ARGS[$KEY]=$(echo $CMD | sed "s,^\(.*drop-nth-packet \)$DROP_N\(.*\)$,\1$NEXT_N\2,")
|
|
fi
|
|
fi
|
|
}
|
|
|
|
update_ldevid() {
|
|
KEY=$1
|
|
HELP="$(${APPS[$KEY]} --help 2>&1 || /bin/true)"
|
|
if echo $HELP | grep -q '\-\-ldevid'; then
|
|
RNUM=$((RANDOM % 100))
|
|
CMD="${ARGS_DEVID[$KEY]}"
|
|
if [ -z "$CMD" ]; then
|
|
if [ $RNUM -lt 30 ]; then # upgrade or first run
|
|
CMD="--ldevid LINUX_TEST_$(printf %.5d ${KEY})_"
|
|
fi
|
|
else
|
|
if [ $RNUM -lt 10 ]; then
|
|
CMD="${CMD}x" # give it a new local ID
|
|
fi
|
|
fi
|
|
ARGS_DEVID[$KEY]="$CMD"
|
|
fi
|
|
}
|
|
|
|
summarizeTileCounts() {
|
|
local STR=''
|
|
local KEYS=( ${!ARGS[*]} )
|
|
for KEY in ${KEYS[@]}; do
|
|
local LOG=${LOGS[$KEY]}
|
|
|
|
local LINE=$(grep pool_removeTiles $LOG | tail -n 1)
|
|
if [ -n "$LINE" ]; then
|
|
local NUM=$(echo $LINE | sed 's,^.*removeTiles: \(.*\) tiles.*$,\1,')
|
|
STR="${STR} ${KEY}:${NUM}"
|
|
fi
|
|
done
|
|
|
|
if [ -n "${STR}" ]; then
|
|
echo "$(date +%r) tiles left: $STR"
|
|
fi
|
|
}
|
|
|
|
run_cmds() {
|
|
ENDTIME=$(($(date +%s) + TIMEOUT))
|
|
LOOPCOUNT=0
|
|
while :; do
|
|
COUNT=${#ARGS[*]}
|
|
[ 0 -ge $COUNT ] && break
|
|
NOW=$(date '+%s')
|
|
[ $NOW -ge $ENDTIME ] && break
|
|
if [ $CORE_COUNT -lt "$(ls core.* 2>/dev/null | wc -l)" ]; then
|
|
echo "number of core files changed; exiting..."
|
|
killall "$(basename $APP_NEW)"
|
|
break
|
|
fi
|
|
|
|
LOOPCOUNT=$((1 + LOOPCOUNT))
|
|
if [ 0 -eq $((LOOPCOUNT % 20)) ]; then
|
|
summarizeTileCounts
|
|
fi
|
|
|
|
INDX=$(($RANDOM%COUNT))
|
|
local KEYS=( ${!ARGS[*]} )
|
|
KEY=${KEYS[$INDX]}
|
|
ROOM=${ROOMS[$KEY]}
|
|
if [ 0 -eq ${PIDS[$KEY]} ]; then
|
|
if [ -n "$ONE_PER_ROOM" -a 0 -ne ${ROOM_PIDS[$ROOM]} ]; then
|
|
continue
|
|
fi
|
|
try_upgrade $KEY
|
|
try_upgrade_upd $KEY
|
|
launch $KEY &
|
|
PID=$!
|
|
# renice doesn't work on one of my machines...
|
|
renice -n 1 -p $PID >/dev/null 2>&1 || /bin/true
|
|
PIDS[$KEY]=$PID
|
|
ROOM_PIDS[$ROOM]=$PID
|
|
MINEND[$KEY]=$(($NOW + $MINRUN))
|
|
else
|
|
PID=${PIDS[$KEY]}
|
|
if [ -d /proc/$PID ]; then
|
|
SLEEP=$((${MINEND[$KEY]} - $NOW))
|
|
[ $SLEEP -gt 0 ] && sleep $SLEEP
|
|
kill $PID || /bin/true
|
|
wait $PID
|
|
fi
|
|
PIDS[$KEY]=0
|
|
ROOM_PIDS[$ROOM]=0
|
|
[ "$DROP_N" -ge 0 ] && increment_drop $KEY
|
|
update_ldevid $KEY
|
|
check_game $KEY
|
|
fi
|
|
done
|
|
|
|
[ -n "$OBITS" ] && ../relay/rq -a $HOST $OBITS 2>/dev/null || /bin/true
|
|
|
|
# kill any remaining games
|
|
if [ $COUNT -gt 0 ]; then
|
|
mkdir -p ${LOGDIR}/not_done
|
|
echo "$(date): processing unfinished games...."
|
|
for KEY in ${!ARGS[*]}; do
|
|
close_device $KEY ${LOGDIR}/not_done "unfinished game"
|
|
done
|
|
fi
|
|
}
|
|
|
|
run_via_rq() {
|
|
# launch then kill all games to give chance to hook up
|
|
for KEY in ${!ARGS[*]}; do
|
|
echo "launching $KEY"
|
|
launch $KEY &
|
|
PID=$!
|
|
sleep 1
|
|
kill $PID
|
|
wait $PID
|
|
# add_pipe $KEY
|
|
done
|
|
|
|
echo "now running via rq"
|
|
# then run them
|
|
while :; do
|
|
COUNT=${#ARGS[*]}
|
|
[ 0 -ge $COUNT ] && break
|
|
|
|
INDX=$(($RANDOM%COUNT))
|
|
KEYS=( ${!ARGS[*]} )
|
|
KEY=${KEYS[$INDX]}
|
|
CMD=${ARGS[$KEY]}
|
|
|
|
RELAYID=$(./scripts/relayID.sh --short ${LOGS[$KEY]})
|
|
MSG_COUNT=$(../relay/rq -a $HOST -m $RELAYID 2>/dev/null | sed 's,^.*-- ,,')
|
|
if [ $MSG_COUNT -gt 0 ]; then
|
|
launch $KEY &
|
|
PID=$!
|
|
sleep 2
|
|
kill $PID || /bin/true
|
|
wait $PID
|
|
fi
|
|
[ "$DROP_N" -ge 0 ] && increment_drop $KEY
|
|
check_game $KEY
|
|
done
|
|
} # run_via_rq
|
|
|
|
function getArg() {
|
|
[ 1 -lt "$#" ] || usage "$1 requires an argument"
|
|
echo $2
|
|
}
|
|
|
|
function usage() {
|
|
[ $# -gt 0 ] && echo "Error: $1" >&2
|
|
echo "Usage: $(basename $0) \\" >&2
|
|
echo " [--dup-packets] # send all packets twice \\" >&2
|
|
echo " [--clean-start] \\" >&2
|
|
echo " [--game-dict <path/to/dict>]* \\" >&2
|
|
echo " [--help] \\" >&2
|
|
echo " [--host <hostname>] \\" >&2
|
|
echo " [--max-devs <int>] \\" >&2
|
|
echo " [--min-devs <int>] \\" >&2
|
|
echo " [--new-app <path/to/app] \\" >&2
|
|
echo " [--new-app-args [arg*]] # passed only to new app \\" >&2
|
|
echo " [--num-games <int>] \\" >&2
|
|
echo " [--num-rooms <int>] \\" >&2
|
|
echo " [--old-app <path/to/app]* \\" >&2
|
|
echo " [--one-per] # force one player per device \\" >&2
|
|
echo " [--port <int>] \\" >&2
|
|
echo " [--resign-ratio <0 <= n <=1000 > \\" >&2
|
|
echo " [--seed <int>] \\" >&2
|
|
echo " [--send-chat <interval-in-seconds> \\" >&2
|
|
echo " [--udp-incr <pct>] \\" >&2
|
|
echo " [--udp-start <pct>] \\" >&2
|
|
echo " [--undo-pct <int>] \\" >&2
|
|
|
|
exit 1
|
|
}
|
|
|
|
#######################################################
|
|
##################### MAIN begins #####################
|
|
#######################################################
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case $1 in
|
|
--udp-start)
|
|
UDP_PCT_START=$(getArg $*)
|
|
shift
|
|
;;
|
|
--udp-incr)
|
|
UDP_PCT_INCR=$(getArg $*)
|
|
shift
|
|
;;
|
|
--clean-start)
|
|
DO_CLEAN=1
|
|
;;
|
|
--num-games)
|
|
NGAMES=$(getArg $*)
|
|
shift
|
|
;;
|
|
--num-rooms)
|
|
NROOMS=$(getArg $*)
|
|
shift
|
|
;;
|
|
--old-app)
|
|
APPS_OLD[${#APPS_OLD[@]}]=$(getArg $*)
|
|
shift
|
|
;;
|
|
--dup-packets)
|
|
DUP_PACKETS=1
|
|
;;
|
|
--new-app)
|
|
APP_NEW=$(getArg $*)
|
|
shift
|
|
;;
|
|
--new-app-args)
|
|
APP_NEW_PARAMS="${2}"
|
|
echo "got $APP_NEW_PARAMS"
|
|
shift
|
|
;;
|
|
--game-dict)
|
|
DICTS[${#DICTS[@]}]=$(getArg $*)
|
|
shift
|
|
;;
|
|
--min-devs)
|
|
MINDEVS=$(getArg $*)
|
|
shift
|
|
;;
|
|
--max-devs)
|
|
MAXDEVS=$(getArg $*)
|
|
shift
|
|
;;
|
|
--one-per)
|
|
ONEPER=TRUE
|
|
;;
|
|
--host)
|
|
HOST=$(getArg $*)
|
|
shift
|
|
;;
|
|
--port)
|
|
PORT=$(getArg $*)
|
|
shift
|
|
;;
|
|
--seed)
|
|
SEED=$(getArg $*)
|
|
shift
|
|
;;
|
|
--undo-pct)
|
|
UNDO_PCT=$(getArg $*)
|
|
shift
|
|
;;
|
|
--send-chat)
|
|
SEND_CHAT=$(getArg $*)
|
|
shift
|
|
;;
|
|
--resign-ratio)
|
|
RESIGN_RATIO=$(getArg $*)
|
|
shift
|
|
;;
|
|
--help)
|
|
usage
|
|
;;
|
|
*) usage "unrecognized option $1"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Assign defaults
|
|
#[ 0 -eq ${#DICTS[@]} ] && DICTS=(dict.xwd)
|
|
[ 0 -eq ${#DICTS} ] && DICTS=(dict.xwd)
|
|
[ -z "$APP_NEW" ] && APP_NEW=./obj_linux_memdbg/xwords
|
|
[ -z "$MINDEVS" ] && MINDEVS=2
|
|
[ -z "$MAXDEVS" ] && MAXDEVS=4
|
|
[ -z "$NGAMES" ] && NGAMES=1
|
|
[ -z "$NROOMS" ] && NROOMS=$NGAMES
|
|
[ -z "$HOST" ] && HOST=localhost
|
|
[ -z "$PORT" ] && PORT=10997
|
|
[ -z "$TIMEOUT" ] && TIMEOUT=$((NGAMES*60+500))
|
|
[ -z "$SAVE_GOOD" ] && SAVE_GOOD=YES
|
|
[ -z "$RESIGN_RATIO" -a "$NGAMES" -gt 1 ] && RESIGN_RATIO=1000 || RESIGN_RATIO=0
|
|
[ -z "$DROP_N" ] && DROP_N=0
|
|
[ -z "$USE_GTK" ] && USE_GTK=FALSE
|
|
[ -z "$UPGRADE_ODDS" ] && UPGRADE_ODDS=10
|
|
#$((NGAMES/50))
|
|
[ 0 -eq $UPGRADE_ODDS ] && UPGRADE_ODDS=1
|
|
[ -n "$SEED" ] && RANDOM=$SEED
|
|
[ -z "$ONEPER" -a $NROOMS -lt $NGAMES ] && usage "use --one-per if --num-rooms < --num-games"
|
|
|
|
[ -n "$DO_CLEAN" ] && cleanup
|
|
|
|
RESUME=""
|
|
for FILE in $(ls $LOGDIR/*.{xwg,txt} 2>/dev/null); do
|
|
if [ -e $FILE ]; then
|
|
echo "Unfinished games found in $LOGDIR; continue with them (or discard)?"
|
|
read -p "<yes/no> " ANSWER
|
|
case "$ANSWER" in
|
|
y|yes|Y|YES)
|
|
RESUME=1
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
fi
|
|
break
|
|
done
|
|
|
|
if [ -z "$RESUME" -a -d $LOGDIR ]; then
|
|
mv $LOGDIR /tmp/${LOGDIR}_$$
|
|
fi
|
|
mkdir -p $LOGDIR
|
|
|
|
if [ "$SAVE_GOOD" = YES ]; then
|
|
DONEDIR=$LOGDIR/done
|
|
mkdir -p $DONEDIR
|
|
fi
|
|
DEADDIR=$LOGDIR/dead
|
|
mkdir -p $DEADDIR
|
|
|
|
for VAR in NGAMES NROOMS USE_GTK TIMEOUT HOST PORT SAVE_GOOD \
|
|
MINDEVS MAXDEVS ONEPER RESIGN_RATIO DROP_N ALL_VIA_RQ SEED \
|
|
APP_NEW; do
|
|
echo "$VAR:" $(eval "echo \$${VAR}") 1>&2
|
|
done
|
|
echo "DICTS: ${DICTS[*]}"
|
|
echo -n "APPS_OLD: "; [ xx = "${APPS_OLD[*]+xx}" ] && echo "${APPS_OLD[*]}" || echo ""
|
|
|
|
echo "*********$0 starting: $(date)**************"
|
|
STARTTIME=$(date +%s)
|
|
[ -z "$RESUME" ] && build_cmds || read_resume_cmds
|
|
if [ TRUE = "$ALL_VIA_RQ" ]; then
|
|
run_via_rq
|
|
else
|
|
run_cmds
|
|
fi
|
|
|
|
wait
|
|
|
|
SECONDS=$(($(date +%s)-$STARTTIME))
|
|
HOURS=$((SECONDS/3600))
|
|
SECONDS=$((SECONDS%3600))
|
|
MINUTES=$((SECONDS/60))
|
|
SECONDS=$((SECONDS%60))
|
|
echo "*********$0 finished: $(date) (took $HOURS:$MINUTES:$SECONDS)**************"
|