UltronoArena TV https://ultronoarena.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

287 lines
5.8 KiB

#!/bin/bash
# extract data from ultrono arena demos; generate a presentation
#shellcheck disable=SC1004
#shellcheck disable=SC2086
name=${0##*/}
info () { printf '%s: %s: %s\n' "$name" "$$" "$1" | logger; }
warn () { info "$1"; printf '%s: %s\n' "$name" "$1" >&2; }
quit () { warn "$1"; exit 1; }
args=$*
# generalize sort columns; reverse output by default
for ((i=0;i<=${#PWD};i++)); do
if [[ "${PWD:i:1}" == / ]]; then
((sc++))
fi
done
sc=$((sc+3))
r=r
# called directly or remotely?
if [[ "$args" =~ extract ]]; then
lvl=!ua
else
lvl=$name
fi
gen="Output generated by $lvl $args"
awk_extract=/opt/uatv/awk_extract
awk_total=/opt/uatv/awk_total
awk_compact=/opt/uatv/utils/awk_player_compactifications
maria_db=/opt/uatv/utils/extract_to_database
extract () {
mawk -v m="$map" -f "$awk_extract"
}
total () {
mawk -v s="$sort" -f "$awk_compact" -f "$awk_total"
}
# print a header
header () {
printf '%s\n %s\n %s\n\n' "games available at https://git.ultronoarena.com/user472393/uatv/src/branch/master/demos" "For more info see $lvl help" "$gen"
}
# process with respect to each day
per_day () {
depth=0
# for every demo directory
for i in $(find $loc -mindepth "$depth" -type d | sort -t "/" -k"$sc$r"); do
# for each sorted file found
while IFS= read -r -d '' file; do
# print the demo name
printf '%s\t' "demo:" "${file#*demos/}"
printf '%s\n' ""
# extract map and scores and total everything
strings "$file" | extract
done < <(find "$i" -type f -print0 |\
sort -z --field-separator="/" -k"$((sc+1))h") |\
total
done
}
# process for global stats
global () {
depth=1
# for each sorted file found
while IFS= read -r -d '' file; do
# print the demo name
printf '%s\t' "demo:" "${file#*demos/}"
printf '%s\n' ""
# extract map and scores and total everything
# TODO debug failed path exclusion
strings "$file" | extract
done < <(find $loc -type f -print0 ! -path '*other*' | sort -z -t "/" -k"$sc,$sc$r" -k$((sc+1))h) |\
total
}
# what does the user want to do
parser () {
g=
map=
sort=
while (($#)); do
case "$1" in
-md|--mariadb)
((md++))
shift
;;
extract)
shift
;;
-s|--sort)
if test -n "$2"; then
case "$2" in
pt|pointstotal)
sort=pt
;;
pd|pointsdiff)
sort=1
;;
st|streak)
sort=3
;;
%st|streakpercent)
sort=4
;;
og|owngoal)
sort=5
;;
%og|owngoalpercent)
sort=6
;;
rl|rockets)
sort=7
;;
%rl|rocketspercent)
sort=8
;;
rg|rail)
sort=9
;;
%rg|railpercent)
sort=10
;;
lg|lightning)
sort=11
;;
%lg|lightningpercent)
sort=12
;;
tf|telefrag)
sort=13
;;
%tf|telefragpercent)
sort=14
;;
*)
printf '%s\n' \
"Unknown option $2. See help for details."
exit
esac
else
printf '%s\n' "--sort requires a type. Please see help for details."
exit
fi
shift 2
;;
-a|--all)
loc=/opt/uatv/demos/
((++a)) && ((e++))
((e>1)) && excluder
shift
;;
-g|--global)
((g++))
shift
;;
-m|--map)
if test -n "$2"; then
map=$2
shift 2
else
printf '%s\n' "--map requires a map"
exit 1
fi
;;
-d|--date)
r=
((e++))
((e>1)) && excluder
if test -z "$2"; then
dc=empty
else
dc=$2
fi
dater "$dc"
shift 2
;;
-r|--range)
r=
((e++))
((e>1)) && excluder
ranger "$2" "$3"
shift 3
;;
-h|--help|help)
show_help
exit
;;
*)
printf '%s\n' "Unknown option $1 ignored."
shift
;;
esac
done
}
excluder () {
# keep --date --range and --all mutually exclusive
printf '%s\n' "Plese set only one of date (-d) range (-r) or all (-a)."
exit
}
date_checker () {
# date contains demos?
if test -d "$PWD/demos/$1"; then
loc+="$PWD/demos/$1 "
else
return 1
fi
}
dater () {
# query single date
if date -I -d "$1" >& /dev/null; then
if date_checker "$(date -I -d "$1")"; then
return
else
printf '%s\n' "There are unfortunately no games for $1"
exit
fi
else
printf '%s\n' "$1 is an invalid date. Format date like -d $(date -I)"
exit
fi
}
ranger () {
# make and query a date range
if date -I -d "$1" >& /dev/null && date -I -d "$2" >& /dev/null && \
[[ "$1" < "$2" ]]; then
begin=$1
until [[ $begin > $2 ]]; do
date_checker "$begin"
begin="$(date -I -d "$begin + 1 day")"
done
else
printf '%s\n' "Bad date range. Format range like -r 2006-10-01 2007-10-01"
exit
fi
}
show_help () {
printf '%s\n' \
"$name: This program parses demo files for the widely popular spherical
arena first person shooter; Ultrono Arena. The default behavior prints
information for the games of $(date -I), today.
Options:
-a, --all Print for all dates.
-d, --date Print for a specific date.
-g, --global Print a global summary for selected demos.
-h, --help Print this help.
-m, --map Print for a specific map.
-md, --mariadb Print suitably for LOAD DATA.
-r, --range BEGIN END Print for a date range.
-s, --sort TYPE Sort by point total (pt), point differential (pd),
or by total points in streaks (st), own goals (og),
rockets (rl), rails (rg), lightning (lg), telefrags (tf).
Sort by percentage of total points in st (%st) og (%og)
rl (%rl) lg (%lg) rg (%rg) tf (%tf)"
}
# start
# if not for the terminal or database print header
if ! [[ "$*" =~ -h|help|-md|--mariadb ]]; then
header
fi
# what are we doing
parser "$@"
# if we do not check all demos, and do not check a
# given date or range, then check today
if test -z "$a" && test -n "$r"; then
dater "$(date -I)"
fi
# what kind of output
if test -n "$md"; then
$maria_db "$loc"
elif test -n "$g"; then
global
else
per_day
fi
exit