GameServerManagers / GameServerManagers/LinuxGSM

[Bug]: 7 Days to Die graceful stop always fails — telnetpass/telnetpassword variable mismatch in info_game.sh

Open Beginner friendly
#4,957 0 comments 0 reactions 0 assignees View on GitHub
command: stop distro: Debian engine: unity3d game: 7 Days to Die regression: yes reproducible: always severity: high type: bug
Dominant language
Shell
Stars
4.9k
Forks
864
PR merge metrics
No merged PRs in 30d

Description

### Severity

severity: high

### Reproducibility

reproducible: always

### Regression

regression: yes

### Affects latest release

latest-release: yes

### User story

As a 7 Days to Die server admin, I want LinuxGSM to shut the server down gracefully over telnet so that the world save is flushed cleanly instead of the server being killed by tmux.

### Script name

sdtdserver

### Game

7 Days to Die

### Linux distro

Debian 13

### Command

command: stop

### Expected behavior

`fn_info_game_sdtd()` reads `TelnetPassword` from the server config into `${telnetpassword}` — the variable that `command_stop.sh` and `info_messages.sh` actually consume. Graceful telnet shutdown authenticates and completes.

### Actual behavior

`fn_info_game_sdtd()` stores the password in `${telnetpass}`, but every consumer reads `${telnetpassword}`, which stays empty.

**Two things break:**

1. **Graceful shutdown never authenticates.** `command_stop.sh:115` — `[ -z "${telnetpassword}" ] || [ "${telnetpassword}" == "NOT SET" ]` is always true, so the expect block that sends *no* password is used. On any server with `TelnetPassword` set the login fails, graceful shutdown fails, and LinuxGSM falls back to `tmux kill` — the path its own comment describes as *"this risks loss of world save"*.

2. **Telnet IP is pinned to localhost.** `info_game.sh:1980` — `if [ -z "${telnetpassword}" ]; then telnetip="127.0.0.1"; fi` always fires, regardless of the configured IP.

`info_messages.sh:1497` also prints an empty Telnet password in `details` — the quickest way to observe the bug without stopping a server.

### Further information

**Root cause: a partial variable rename.**

Up to and including **v24.2.4**, `info_game.sh` and `command_stop.sh` both used `${telnetpass}` and were consistent. **v24.3.0** renamed the consumers (`command_stop.sh`, `info_messages.sh`) to `${telnetpassword}` but left the producer in `info_game.sh` as `${telnetpass}`.

Confirmed present in **v24.3.0 through v26.2.0**, and in current `master` and `develop`.

Note that `info_game.sh:1980` already reads `${telnetpassword}` — the mismatch is internal to the same function, which suggests the rename was simply incomplete rather than intentional.

### Fix

Rename the two remaining occurrences in `fn_info_game_sdtd()`:

```diff
--- a/lgsm/modules/info_game.sh
+++ b/lgsm/modules/info_game.sh
@@ -1963 +1963 @@
- fn_info_game_xml "telnetpass" "/ServerSettings/property[@name='TelnetPassword']/@value"
+ fn_info_game_xml "telnetpassword" "/ServerSettings/property[@name='TelnetPassword']/@value"
@@ -1983 +1983 @@
- telnetpass="${telnetpass:-"NOT SET"}"
+ telnetpassword="${telnetpassword:-"NOT SET"}"
```

The existing ordering stays correct once renamed: the `-z` check on line 1980 runs before the `"NOT SET"` default on line 1983, and `command_stop.sh` handles both the empty and `"NOT SET"` cases.

Use **word-boundary matching** when patching — `telnetpassword` contains `telnetpass` as a prefix:

```bash
sed -i -E 's/\btelnetpass\b/telnetpassword/g' lgsm/modules/info_game.sh
```

`grep -w telnetpass` across `lgsm/modules/` returns no other hits, so these are the only two call sites.

Verified on two independent 7 Days to Die installs — LinuxGSM v26.2.0, Debian 13, 7DTD dedicated buildid `24911252`.

### Pre-checks

- [x] I ran update and validate before reporting this issue.

### Relevant log output

```shell
# TelnetPassword is set in the server config:
$ grep TelnetPassword serverfiles/sdtdserver.xml

# BEFORE — stock v26.2.0 info_game.sh
$ ./sdtdserver details
Telnet enabled: true
Telnet address: 127.0.0.1 8091
Telnet password:

# AFTER — the two-line rename above applied
$ ./sdtdserver details
Telnet enabled: true
Telnet address: 203.0.113.10 8091
Telnet password: REDACTED

# Variable state in stock v26.2.0 info_game.sh (producer vs consumers)
$ grep -n telnetpass lgsm/modules/info_game.sh
1963: fn_info_game_xml "telnetpass" "/ServerSettings/property[@name='TelnetPassword']/@value"
1980: if [ -z "${telnetpassword}" ]; then
1983: telnetpass="${telnetpass:-"NOT SET"}"

$ grep -n telnetpassword lgsm/modules/command_stop.sh
115: if [ -z "${telnetpassword}" ] || [ "${telnetpassword}" == "NOT SET" ]; then
137: "password:" { send "'"${telnetpassword}"'\r" }
```

### Steps to reproduce

1. Install `sdtdserver` on LinuxGSM **v24.3.0 or newer** (reproduced on v26.2.0).
2. Set a non-empty `TelnetPassword` and `TelnetEnabled="true"` in the server config.
3. Run `./sdtdserver details` and look at the **7 Days To Die Telnet** block — Telnet password is blank and Telnet address is forced to `127.0.0.1`.
4. Start the server, then run `./sdtdserver stop` — graceful telnet shutdown fails to authenticate and LinuxGSM falls back to a `tmux` kill.
5. Apply the two-line rename in `fn_info_game_sdtd()` and repeat steps 3–4 — the password is read and graceful shutdown completes.

Contributor guide

Open the contributing guide

Research direction

Start in lgsm/modules/info_game.sh at fn_info_game_sdtd(), then compare its TelnetPassword assignments with the consumers in command_stop.sh and info_messages.sh. Rename the two remaining telnetpass occurrences using word-boundary matching, then run ./sdtdserver details and ./sdtdserver stop with TelnetPassword enabled; done means the password and configured address appear and graceful shutdown authenticates.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, shell
Domain
cli, devops
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
92/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.