Skip to content

Commit

Permalink
RCON commands feature (#1391)
Browse files Browse the repository at this point in the history
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
  • Loading branch information
shotah and christopher blodgett committed Mar 2, 2022
1 parent 15869fd commit 4587b32
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ COPY --chmod=644 files/server.properties /tmp/server.properties
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
COPY --chmod=755 files/rconcmds /rconcmds

RUN dos2unix /start* /autopause/* /autostop/*
RUN dos2unix /start* /autopause/* /autostop/* /rconcmds/*

ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,50 @@ To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```

### Use RCON commands

Feature is used run commands when the server starts, client connects, or client disconnects.
**Notes:**
* On clinet connect we only know there was a connection, and not who connected. RCON commands will need to be used for that.
* Using '|-' is preferred for yaml, this make sure only the correct new lines are in place for the commands.

**On Server Start:**

```yaml
RCON_CMDS_STARTUP: |-
/gamerule doFireTick false
```

**On Client Connection:**

```yaml
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
```

**On Client Disconnect:**

```yaml
RCON_CMDS_ON_DISCONNECT: |-
/gamerule doFireTick true
```

**Example of rules for new players**

Uses team NEW and team OLD to track players on the server. So move player with no team to NEW, run a command, move them to team OLD.
[Reference Article](https://www.minecraftforum.net/forums/minecraft-java-edition/redstone-discussion-and/2213523-detect-players-first-join)

```yaml
RCON_CMDS_STARTUP: |-
/gamerule doFireTick false
/team add New
/team add Old
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
/give @a[team=New] diamond_block
/team join Old @a[team=New]
```

## Autopause

### Description
Expand Down
24 changes: 24 additions & 0 deletions examples/docker-compose-rconcmd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: '3'

services:
minecraft:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
# YAML Heredoc, be sure to use '|-' this will remove the first newline and final new line.
# This is versus '|' that will leaving with two empty strings at top and bottom.
RCON_CMDS_STARTUP: |-
/gamerule doFireTick false
/team add New
/team add Old
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
/give @a[team=New] diamond_block
/team join Old @a[team=New]
restart: unless-stopped
volumes:
mc: {}
8 changes: 6 additions & 2 deletions files/autopause/autopause-fcns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ mc_server_listening() {
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
}

java_clients_connected() {
java_clients_connections() {
local connections
if java_running ; then
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
else
connections=0
fi
(( connections > 0 ))
echo $connections
}

java_clients_connected() {
(( $(java_clients_connections) > 0 ))
}
75 changes: 75 additions & 0 deletions files/rconcmds/rcon-cmds-daemon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash

: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"

# needed for the clients connected function residing in autopause
# shellcheck source=/autopause/autopause-fcns.sh
. /autopause/autopause-fcns.sh

# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils

run_command(){
rcon_cmd="$1"
logRcon "running - $rcon_cmd"
output=$(rcon-cli "$rcon_cmd")
logRcon "$output"
}


# wait for java process to be started
while :
do
if java_process_exists ; then
break
fi
sleep 0.1
done

CLIENTCONNECTIONS=0
STATE=INIT

while :
do
case X$STATE in
XINIT)
# Server startup
if mc_server_listening ; then
logRcon "MCServer is listening, running startup"
if [[ "$RCON_CMDS_STARTUP" ]]; then
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_STARTUP"
fi
if [[ -z "$RCON_CMDS_ON_CONNECT" ]] && [[ -z "$RCON_CMDS_ON_DISCONNECT" ]]; then
logRcon "No addition rcon commands are given, stopping rcon cmd service"
exit 0
fi
STATE=II
fi
;;
XII)
# Main Loop looking for connections
CURR_CLIENTCONNECTIONS=$(java_clients_connections)
if (( CURR_CLIENTCONNECTIONS > CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_CONNECT" ]]; then
logRcon "Clients have Connected, running connect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_ON_CONNECT"
elif (( CURR_CLIENTCONNECTIONS < CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_DISCONNECT" ]]; then
logRcon "Clients have Disconnected, running disconnect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_ON_DISCONNECT"
fi
CLIENTCONNECTIONS=$CURR_CLIENTCONNECTIONS
;;
*)
logRcon "Error: invalid state: $STATE"
;;
esac
sleep "$RCON_CMDS_PERIOD"
done
10 changes: 10 additions & 0 deletions scripts/start-configuration
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ IFS=$'\n\t'
: "${EULA:=}"
: "${PROXY:=}"
: "${RCON_PASSWORD_FILE:=}"
: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"

shopt -s nullglob

Expand Down Expand Up @@ -124,6 +128,12 @@ if isTrue "${ENABLE_AUTOSTOP}"; then
${SCRIPTS:-/}start-autostop
fi

if [[ "$RCON_CMDS_STARTUP" ]] || [[ "$RCON_CMDS_ON_CONNECT" ]] || [[ "$RCON_CMDS_ON_DISCONNECT" ]]; then
log "Starting RCON commands"
# shellcheck source=start-rconcmds
${SCRIPTS:-/}start-rconcmds
fi

if versionLessThan 1.7; then
echo "
MC_HEALTH_EXTRA_ARGS=(
Expand Down
32 changes: 32 additions & 0 deletions scripts/start-rconcmds
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"

: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"
: "${SERVER_PORT:=25565}"
export RCON_CMDS_STARTUP
export RCON_CMDS_ON_CONNECT
export RCON_CMDS_ON_DISCONNECT
export RCON_CMDS_PERIOD
export SERVER_PORT

log "Rcon cmds functionality enabled"

isDebugging && set -x

if ! [[ $RCON_CMDS_PERIOD =~ ^[0-9]+$ ]]; then
RCON_CMDS_PERIOD=10
export RCON_CMDS_PERIOD
log "Warning: RCON_CMDS_PERIOD is not numeric, set to 10 (seconds)"
fi
if [ "$RCON_CMDS_PERIOD" -eq "0" ] ; then
RCON_CMDS_PERIOD=10
export RCON_CMDS_PERIOD
log "Warning: RCON_CMDS_PERIOD must not be 0, set to 10 (seconds)"
fi

/rconcmds/rcon-cmds-daemon.sh &
4 changes: 4 additions & 0 deletions scripts/start-utils
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ function logAutostopAction() {
echo "[$(date -Iseconds)] [Autostop] $*"
}

function logRcon() {
echo "[Rcon loop] $*"
}

function normalizeMemSize() {
local scale=1
case ${1,,} in
Expand Down

0 comments on commit 4587b32

Please sign in to comment.