#!/bin/sh # tmww plugin: server # whatis: server db lookup # conflicts: alts (see details in manual) # depends: jq (subcommand player) # recommends: python-jsonschema for "player validate", db plugin (for item search ops) # this file is part of tmww - the mana world watcher # willee, 2012-2014 # GPL v3 # error codes: # 1 -- parameters error # 2 -- tool missing # 3 -- config/database file missing # check if not run as plugin if [ "$TMWW_PLUGINS" != "yes" ] ; then echo >&2 "This script is tmww plugin and rely heavily on it's facilities." exit 1 fi # when called as plugin - abort if no SERVERPATH was given if [ -z "${TMWW_SERVERPATH}" ]; then error "No serverpath given. Aborting." return 1 fi help_server() { cat << EOF server.plugin - server text databases operation subcommand: char -- character database handler grep [ chars | ids | pcids ] REGEXP -- search known names, output names/names with ids fuzzy [ chars | ids | pcids ] PATTERN -- case-insensitive levenshtein distance 1 search agrep [ -e ERRORS ] [ chars | ids | pcids ] PATTERN -- approximate grep with max ERRORS [-cnar] [-f EXPR] [-s NUM] get { CHAR | [ skills | inventory | vars | id | char | accs | db | FIELD+ ] by { char CHAR | pcid PCID } } [-cnar] [-f EXPR] [-s NUM] show { CHAR | [ parties | storage | vars | ids | chars | accs | db | FIELD+ ] by { char CHAR | id ID | pcid PCID } } dig REGEXP -- grep + show pcids by ids from grep matches [ -t ] summary { gp | bp | exp | items } by { char CHAR | id ID | pcid PCID } subcommand: party -- party database handler { grep | fuzzy | agrep [ -e ERRORS ] } REGEXP -- search party name by pattern get { CHAR | by { char CHAR | pcid PCID } } show { CHAR | [ pcids | ids | chars | players ] by { char CHAR | party PARTY | partyid PARTYID | pcid PCID } } { grep | fuzzy | agrep [ -e ERRORS ] } PATTERN -- grep/approximate grep party name dig PATTERN -- grep + show ids/charname of party members subcommand: player -- players database handler ref -- field types quick reference create PLAYER remove PLAYER rename PLAYER to PLAYER add PLAYER FIELD value VALUE add PLAYER FIELD element VALUE -- adding alts will automatically resolve charname into account resolve PLAYER -- resolve all player alts into accounts del PLAYER FIELD del PLAYER FIELD element VALUE [-cnar] [-f EXPR] [-s NUM] get { CHAR | by { char CHAR | id ACCID | pcid PCID } } [-cnar] [-f EXPR] [-s NUM] show { PLAYER | [ ids | chars | parties | accs | db | FIELD+ ] by { char CHAR | id ID | pcid PCID } } [ -t ] summary { gp | bp | exp | items } by { char CHAR | id ID | player PLAYER | pcid PCID } list with FIELD list with { FIELD [ not ] as VALUE | VALUE [ not ] in FIELD }+ dump PLAYER -- dump JSONline record of PLAYER; tmww player dump veryape record NUMBER -- access players db record by it's order number append STRING -- NOT SAFE append JSON player record of same format as with dump operation to end of dbplayers you should try sanitize operation if you not sure if there are duplicate entries or fields keys PLAYER -- tmww player keys veryape field PLAYER FIELD [FIELD]... -- tmww player field veryape name aka search STRING -- simple search in all fields sanitize -- remove keys with 0 length - empty arrays and hashes with null value resolve alts into accounts, report duplicate accounts and alts lregen -- regenerate shortened playerdb version if limiteddb is in use subcommand: arseoscope CHAR -- observe player alias/number of known accounts/alts subcommand: select -- search inventory/storage [-incs] by { ids ITEMID+ | names ITEMNAME+ | re REGEXP | itemsets GLOB+ } EOF } [ "$TMWW_PLUGINHELP" = "yes" ] && help_server && return 0 # using temp dir for char/party add operations (used with sniffer too) check_dir "$TMWW_PRIVTMP" requireplugin server.lib.sh || return 1 [ "${TMWW_PLUGINEXPORT}" = "yes" ] && return 0 aux_server_opts() { while ${GETOPTS} cnarf:s: opt; do case "${opt}" in # no fields captions c) server_no_caption="yes" ;; # suppress append accid/charname to fields query n) server_suppress_append="yes" ;; # suppress per-char fields and leave only per-account a) server_accounts_only="yes" ;; # output raw tab-separated fields without pretty-printing r) server_raw_fields="yes" ;; # custom "cut -f" expression for accs/db filter f) server_cut_fields="${OPTARG}" ;; # suffix for all TMWW_SERVERxxx files # for individual suffixes or custom location define vars in shell s) server_suffix="${OPTARG}" TMWW_SERVERDB="${TMWW_SERVERDB}.${OPTARG}" TMWW_SERVERACCS="${TMWW_SERVERACCS}.${OPTARG}" TMWW_SERVERREG="${TMWW_SERVERREG}.${OPTARG}" TMWW_SERVERPARTY="${TMWW_SERVERPARTY}.${OPTARG}" TMWW_SERVERSTORAGE="${TMWW_SERVERSTORAGE}.${OPTARG}" ;; *) error_incorrect; return 1 ;; esac done } # # char # # server_parse_char () { local subcommand server_no_caption server_suppress_append server_accounts_only server_cut_fields server_suffix server_raw_fields server_no_caption=''; server_suppress_append=''; server_accounts_only='' server_cut_fields=''; server_suffix=''; server_raw_fields='' aux_server_opts "$@" shift $( expr $OPTIND - 1 ) [ -z "$1" ] && { error_missing; return 1; } subcommand="$1"; shift case "${subcommand}" in # case insensitive grep; regexps allowed grep) func_char_grep "$@" ;; # approximate grep using agrep agrep) func_char_agrep "$@" ;; # regexps disallowed (as lot of chars too) fuzzy) func_char_fuzzy "$@" ;; get) func_char_get "$@" ;; dig) func_char_dig "$@" ;; show) func_char_show "$@" ;; summary) func_char_summary "$@" ;; *) error_incorrect; return 1; ;; esac } # # party # # server_parse_party () { local subcommand server_no_caption server_suppress_append server_accounts_only server_cut_fields server_suffix server_raw_fields server_no_caption=''; server_suppress_append=''; server_accounts_only='' server_cut_fields=''; server_suffix=''; server_raw_fields='' aux_server_opts "$@" shift $( expr $OPTIND - 1 ) [ -z "$1" ] && { error_missing; return 1; } subcommand="$1"; shift case "${subcommand}" in # case insensitive grep; regexps allowed grep) func_party_grep "$@" ;; # approximate grep using agrep agrep) func_party_agrep "$@" ;; # regexps disallowed (as lot of chars too) fuzzy) func_party_fuzzy "$@" ;; dig) func_party_dig "$@" ;; get) func_party_get "$@" ;; show) func_party_show "$@" ;; *) error_incorrect; return 1; ;; esac } # # player # # server_parse_player () { local subcommand server_no_caption server_suppress_append server_accounts_only server_cut_fields server_suffix server_raw_fields server_no_caption=''; server_suppress_append=''; server_accounts_only='' server_cut_fields=''; server_suffix=''; server_raw_fields='' aux_server_opts "$@" shift $( expr $OPTIND - 1 ) [ -z "$1" ] && { error_missing; return 1; } subcommand="$1"; shift case "${subcommand}" in ref) func_player_ref "$@" ;; create) [ "$TMWW_LIMITED" = "yes" ] && return func_player_create "$@" ;; remove) [ "$TMWW_LIMITED" = "yes" ] && return func_player_remove "$@" ;; append) [ "$TMWW_LIMITED" = "yes" ] && return func_player_append "$@" ;; rename) [ "$TMWW_LIMITED" = "yes" ] && return func_player_rename "$@" ;; add) [ "$TMWW_LIMITED" = "yes" ] && return func_player_add "$@" ;; resolve) [ "$TMWW_LIMITED" = "yes" ] && return func_player_resolve "$@" ;; del) [ "$TMWW_LIMITED" = "yes" ] && return func_player_del "$@" ;; get) func_player_get "$@" ;; show) func_player_show "$@" ;; list) func_player_list "$@" ;; nlist) func_player_nlist "$@" ;; dump) func_player_dump "$@" ;; record) func_player_record "$@" ;; keys) func_player_keys "$@" ;; field) func_player_field "$@" ;; search) func_player_search "$@" ;; summary) func_player_summary "$@" ;; sanitize) [ "$TMWW_LIMITED" = "yes" ] && return func_player_sanitize "$@" ;; lregen) [ "$TMWW_LIMITED" = "yes" ] && return func_player_lregen "$@" ;; merge) [ "$TMWW_LIMITED" = "yes" ] && return echo TODO merge handler # func_player_merge "$@" ;; *) error_incorrect; return 1; ;; esac } # # main # # server_main_parser() { local subcommand OPTIND=1 [ -z "$1" ] && { error_missing; return 1; } subcommand="$1"; shift case "${subcommand}" in char) server_parse_char "$@" ;; party) server_parse_party "$@" ;; player) server_parse_player "$@" ;; select) func_select "$@" ;; arseoscope) func_arseoscope "$@" ;; # dump compiled fields ref) func_server_ref "$@" ;; *) error_incorrect; return 1 ;; esac } server_main_parser "$@" [ $err_flag -eq 1 ] && return 1 return 0