Rcon CLI


Editor’s Note:
For this CLI I’m just using mcrcon as it’s a pretty standard & lightweight cross-platform rcon tool.
If you’ve got a better rcon tool, go ahead and use that, in my experience they all tend to be functionally the same tool anyway.

Obviously, before use one must setup the global variables at the top of the script:
HostIP
Rcon tool Location – in this instance I’m using mcrcon.exe living in a directory I’ve created and added to the Windows PATH. (Windows PATH Guide)
Servers – In the array on line-55 we set the server names & RCON ports
RconPass – in the array on line 63 we set the server RCON Passwords
if all passwords are different, then define each here, otherwise there is a global variable at the top which you can use instead.

Dependencies:
Not strictly a dependency, however in the rcon -commands output one can see a number of ‘commonly used commands’ and a list of ‘extended rcon commands’
These refer to plugins which we use within our cluster as part of the AkrAPI package:
– Arkshop
– Permissions
– ExtendedRcon
I recommended ExtendedRcon especially, though at the time of writing this it is in dire need of a number of updates – some commands I have greyed out, as they instantly crash a server in it’s current state.



Description:
A oneshot rcon CLI for sending rcon commands to single or multiple servers at once.

Options:
 rcon -help, -h           – This help menu
 rcon -commands, -c       – List of useful & extended commands

 rcon listall, -la             – Return a list of all currently online players
 rcon all, -a <command>        – Send a command to ALL servers

 rcon ball, -ba <message>      – Send Broadcast to ALL servers
 rcon chatall, -ca <message>   – Send ServerChat to ALL servers
 rcon notall, -na <message>    – Send Notification to ALL servers

General rcon use:
 Usage:     rcon <server> <command>
 Servers:   los | rag | gen | ext | isl | ast

Examples:
 rcon ast listplayers
 rcon la
 rcon isl saveworld
 rcon gen broadcast “Server restarting in 10 minutes”
 rcon -ba This is a clusterwide broadcast


Download rcon.sh

#!/bin/bash
#
# One-shot RCON command sender
#

####################
# RCON CONFIGURATION
#####################
HOST="YOUR-HOST-IP"
MCRCON="$HOME/mcrcon/mcrcon"
RconPass="YOUR-RCON-PASSWORD"


##########
# ARRAYS
###########
declare -A PORTS=(
    [isl]=0000
    [rag]=0000
    [abe]=0000
    [ext]=0000
    [ast]=0000
    [gen]=0000
)
declare -A PASSWORDS=(
    [isl]="$RconPass"
    [rag]="$RconPass"
    [abe]="$RconPass"
    [ext]="$RconPass"
    [ast]="$RconPass"
    [gen]="$RconPass"
)

servers=$(printf "%s | " "${!PORTS[@]}")
servers=${servers% | } # Remove the trailing " | "

# remove leading dash (so -rag works) <-- do we need this?
key="${1#-}"

#
# END CONFIGURATION
#

###################
# Global Variables
##################
VERSION="Odium's Rcon CLI v3.5.1"

####################
# COLOUR FORMATTING
#####################
RESET="\033[0m"
BOLD="\033[1m"

CLR_RED="\033[38;5;196m"        # Bright Red
CLR_GREEN="\033[38;5;46m"       # Bright Lime Green
CLR_GOLD="\033[38;5;228m"         # Gold
CLR_PURPLE="\033[38;5;141m"       # Light Purple / Lavender
CLR_BLUE="\033[38;5;81m"         # Bright Sky Blue
CLR_DGREEN="\033[38;5;2m"         # Dark Forest Green
CLR_ORANGE="\033[38;5;208m"       # Orange
CLR_DGREY="\033[38;5;243m"        # dark Grey
CLR_TEXT="\033[38;5;254m"         # Light Grey
CLR_PROMPT="${BOLD}\033[38;5;51m" # Aqua + Bold
CLR_FRAME="\033[38;5;14m"         # Teal
CLR_TITLE="\033[38;5;147m"        # Pale Purple

set -e

#######################
# Unicode box Chars
########################
H="${CLR_FRAME}─${RESET}"
V="${CLR_FRAME}│${RESET}"

TL="${CLR_FRAME}┌"
TR="┐${RESET}"
BL="${CLR_FRAME}└"
BR="┘${RESET}"

LT="${CLR_FRAME}├"
RT="┤${RESET}"
TT="┬"
BT="┴"
CR="┼"



#############
# FUNCTIONS
##############
error() {
    echo
    echo -e "${CLR_ERROR}  Error: ${RESET}$1"
    echo
}

usage() {
    echo -e "${CLR_TITLE}${BOLD}${VERSION}${RESET}"
    echo
    echo -e "${BOLD}Options:${RESET}"
    echo -e "${CLR_TEXT}  rcon -help, -h           - This help menu"
    echo -e "  rcon -commands, -c       - List of useful & extended commands"
    echo
    echo -e "  rcon listall, -la             - Return a list of all currently online players"
    echo -e "  rcon all, -a <command>        - Send a command to ALL servers"
    echo
    echo -e "  rcon ball, -ba <message>      - Send Broadcast to ALL servers"
    echo -e "  rcon chatall, -ca <message>   - Send ServerChat to ALL servers"
    echo -e "  rcon notall, -na <message>    - Send Notification to ALL servers${RESET}"
    echo
    echo -e "${BOLD}General rcon use:${RESET}"
    echo -e "${CLR_GOLD}  Usage:${RESET}${CLR_TEXT}     rcon <server> <command>"
    echo -e "${CLR_GOLD}  Servers:${RESET}   ${servers}"
    echo
    echo -e "${BOLD}Examples:${RESET}"
    echo -e "${CLR_TEXT}  rcon ast listplayers"
    echo -e "  rcon la"
    echo -e "  rcon isl saveworld"
    echo -e '  rcon gen broadcast "Server restarting in 10 minutes"'
    echo -e "  rcon -ba This is a clusterwide broadcast"

    echo -e "${RESET}"
    exit 0
}

send_rcon() {
    local server="$1"
    shift
    local command="$*"
    local result

    result=$(
        "$MCRCON" \
            -H "$HOST" \
            -P "${PORTS[$server]}" \
            -p "${PASSWORDS[$server]}" \
            "$command" 2>&1 |
            sed -E 's/\x1B\[[0-9;]*[[:alpha:]]//g'
    )

    printf '%s\n' "$result"
}

cmd_rcon_all() {
    # Broadcast to all servers

    local bstatus
    local command="$*"

    echo
    echo -e "${CLR_GOLD}  ▶ Sending command to ALL servers${RESET}"
    echo
    echo "────────────────────"
    for servername in "${!PORTS[@]}"; do
        echo -e "${CLR_LABEL}${BOLD}${servername^^}${RESET}"
        bstatus=$(send_rcon "$servername" "${command}")
        if [[ "$bstatus" == *"Server received, But no response!!"* ]]; then
            echo "▶ Command Delieverd"
            echo
            continue
        fi
        echo "$bstatus"
    done
    echo "────────────────────"
    echo
    exit 0
}

arrcon_send_rcon() {
    local server="$1"
    local command="$2"
    local result

    result=$(
        "$MCRCON" \
            -H "$HOST" \
            -P "${PORTS[$server]}" \
            -p "${PASSWORDS[$server]}" \
            -Q \
            "$command" 2>&1 |
            sed -E 's/\x1B\[[0-9;]*[[:alpha:]]//g'
    )
    printf '%s\n' "$result"
}

cmd_showcommands() {
    echo -e "$(
        cat <<EOF

              ${CLR_GOLD}${BOLD}Common Commands${RESET}
              ───────────────

  rcon <map> ListPlayers
  rcon <map> KickPlayer <SteamID64>

  rcon <map> AddPoints <EOSID> <Points>
  rcon <map> SetPoints <EOSID> <Points>
  rcon <map> GetPlayerPoints <EOSID>

  rcon <map> permissions.add <EOSID> <Group>
  rcon <map> permissions.Remove <EOSID> <Group>


                      ${CLR_GOLD}${BOLD}Extended RCON Commands${RESET}
                      ──────────────────────

${BOLD}Get Commands             List Commands              Set Commands${RESET}
────────────────────     ────────────────────       ────────────────────
GetActorPos              ListAllPlayerPos           SetDinoColor
GetAllActorsPos          ListAllPlayerEOSId         SetDinoPos
GetAllActors             ListAllStructures          SetFacialHair
GetAllActorsBp           ListAllStructuresInRadius  SetHeadHair
GetAllDinos              ListOnlineTribes           SetImprintQuality
GetDinoBP                ListOnlinePlayers          SetImprintToPlayer
GetDinoPos               ListPlayerDinos            SetPlayerName
GetInGameTime            ListTribeDinos             SetPlayerPos
GetPlayerName            ListTribePlayers           SetPlayerTribeAdmin
GetPlayerPos             ListTribeStructures        SetPlayerTribeOwner
GetServerFrames          ListUnclaimedDinos         SetTribeName
GetTotalTames            ListUnclaimedDinosAmount
GetTotalWilds
GetTribeIdOfPlayer       ${BOLD}Other                     Kill & Kick${RESET}
GetTribeLog              ────────────────────      ────────────────────
GetTribeName             TribeChatMsg              KickAllPlayers
GetTribeStructureCount   TribeLogMsg               KillAllPlayers
GetTribeStructurePos     UnlockBoss                KillDino
GetMapName               UnlockEngram              KillPlayer
GetOnlineNum             SpawnDinoBP               KillPlayerId
                                                   KillUnclaimedDinos
                                                   KillAllWildDinos

${BOLD}Give Commands            Teleport                  Destroy Commands${RESET}
────────────────────     ────────────────────      ──────────────────────────
GiveDinoXP               ${CLR_DGREY}TeleportAllPlayers${RESET}        DestroyActorAll
GivePlayerXP             ${CLR_DGREY}TeleportToPlayer${RESET}          DestroyActorWild
${CLR_DGREY}GiveHexagon${RESET}                                        DestroyTribeAll
GiveArmorSet             ${BOLD}Send Commands${RESET}             DestroyTribeDinos
GiveItemIndex            ───────────────────       DestroyTribePlayers
GiveItemIndexToAll       SendMessageToChat         DestroyTribeStructures
GiveItemToAll            SendMessageToNotification DestroyTribeStructuresByBP
GiveItemToEOSId          SendPlayerScriptCommand   DestroyPlayerProfile
GiveTribeDinosFood       SendScriptCommand

EOF
    )"
    exit 0
}

cmd_list() {
    # List all players

    local PlayersList
    totalPlayers=0

    echo
    echo -e "${CLR_GOLD}  ▶ Listing all connected players${RESET}"
    echo
    for servername in "${!PORTS[@]}"; do
        # Calculate total online on cluster
        onlineNum=$(send_rcon "$servername" getonlinenum)
        totalPlayers=$((totalPlayers + onlineNum))

        PlayersList=$(send_rcon "$servername" listplayers)
        if [[ "$PlayersList" == *"No Players Connected"* ]]; then
            continue
        fi

        echo -e "${TL}─────────────────────────────${TR}"
        printf "${V}${BOLD}${CLR_LABEL}             %-15s${RESET} ${V}\n" "${servername^^}"
        echo -e "${BL}─────────────────────────────${BR}"

        echo "$PlayersList"
    done
    echo
    echo " ──────────────────────────"
    echo -e "  Total Players Online: ${CLR_GOLD}${totalPlayers}${RESET}"
    echo " ──────────────────────────"
    echo
    exit 0
}

cmd_ball() {
    # Broadcast to all servers

    local bstatus
    local message="$*"

    echo
    echo -e "${CLR_GOLD}  ▶ Broadcasting to all servers${RESET}"
    echo
    echo "────────────────────"
    for servername in "${!PORTS[@]}"; do
        echo -e "${CLR_LABEL}${servername^^}${RESET}"
        bstatus=$(send_rcon "$servername" broadcast "${message}")
        if [[ "$bstatus" == *"Server received, But no response!!"* ]]; then
            echo "▶ Brodcast Delieverd"
            echo
            continue
        fi
    done
    echo "────────────────────"
    echo
    exit 0
}

cmd_chatall() {
    # Serverchat to all servers
    local chstatus
    local message="$*"

    echo
    echo -e "${CLR_ACTION}  ▶ Sending ServerChat to all servers${RESET}"
    echo
    echo "────────────"
    for servername in "${!PORTS[@]}"; do
        echo -e "${CLR_LABEL}${servername^^}${RESET}"
        echo "$message"
        chstatus=$(send_rcon "$servername" serverchat "${message}")
        if [[ "$chstatus" == *"Server received, But no response!!"* ]]; then
            echo "▶ Serverchat Delieverd"
            echo
            continue
        fi
    done
    echo "────────────────────"
    echo
    exit 0
}

cmd_notifyall() {
    # Serverchat to all servers
    local notstatus
    local message="$*"

    echo
    echo -e "${CLR_ACTION}  ▶ Sending Notification to all servers${RESET}"
    echo
    echo "────────────"
    for servername in "${!PORTS[@]}"; do
        echo -e "${CLR_LABEL}${servername^^}${RESET}"
        echo "$message"
        chstatus=$(send_rcon "$servername" SendMessageToNotification "${message}")
        if [[ "$chstatus" == *"Server received, But no response!!"* ]]; then
            echo "▶ Notification Delieverd"
            echo
            continue
        fi
    done
    echo "────────────────────"
    echo
    exit 0
}

#############
# COMMANDS
##############

if [[ $# -eq 0 ]]; then
    usage
    exit 0
fi

case "${1:-}" in
    -commands | -c)
        shift
        cmd_showcommands "$@"
        exit 0
        ;;
    listall | -la | la)
        shift
        cmd_list "$1"
        exit 0
        ;;
    ball | -ball | -ba)
        shift
        cmd_ball "$@"
        exit 0
        ;;
    chatall | -ca)
        shift
        cmd_chatall "$@"
        exit 0
        ;;
    notall | -na)
        shift
        cmd_notifyall "$@"
        exit 0
        ;;
    all | -a)
        shift
        cmd_rcon_all "$@"
        exit 0
        ;;
    help | -h)
        usage
        exit 0
        ;;
esac

# If $1 wasn't a flag, it must be a valid server
if [[ -z ${PORTS[$1]+x} ]]; then
    echo
    error "Unknown server or command: '$1'"
    echo
    usage
    exit 1
fi

##########
# MAIN
##########

# get credentials
key="$1"
port="${PORTS[$key]}"
password="${PASSWORDS[$key]}"

# remove server argument
shift

# no command supplied
if [[ $# -eq 0 ]]; then
    echo
    error "No Command Supplied"
    echo
    echo -e "${CLR_GOLD}  Usage:${RESET}     rcon <server> <command>"
    echo -e "${CLR_GOLD}  Servers:${RESET}   ${servers}"
    echo
    exit 1
fi

# build command string
command="$*"

# execute
"$MCRCON" \
    -H "$HOST" \
    -P "$port" \
    -p "$password" \
    "$command"