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
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
|
|
|