docs(mc): document Simple Voice Chat voice_host gotcha + commit prod snapshot
voice_host lives in the mc_data volume and regenerates empty on world wipe, silently breaking remote voice (secret sent, UDP handshake never completes → red icon). Document the set/restore steps and the VPN-client false-positive (Cloudflare One/WARP, FortiClient drop voice UDP). Add a known-good prod snapshot at server-configs/voicechat-server.properties (voice_host=ulicraft.net). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,52 @@ docker exec minecraft sh -c 'cat /data/ops.json' # verify level 4 + right UUI
|
||||
needed (takes effect live). Current op: `oier`
|
||||
(`7fbc9adb-bcf4-3913-9a99-46d46acd1009`), level 4, set 2026-06-21.
|
||||
|
||||
## Simple Voice Chat — `voice_host` (NOT repo-tracked)
|
||||
|
||||
Voice chat is UDP `24454/udp`, published in compose. The mod auto-generates
|
||||
`/data/config/voicechat/voicechat-server.properties` in the `mc_data` volume.
|
||||
|
||||
**Gotcha — `voice_host` must be set or remote clients get a red/crossed icon.**
|
||||
Behind any NAT/Docker the server announces an address for clients' UDP
|
||||
connection; if `voice_host=` is empty it auto-detects the internal Docker IP →
|
||||
unreachable → the secret (TCP) is sent but the UDP handshake never completes
|
||||
("Sent secret" with no following "successfully connected to voice chat").
|
||||
|
||||
Set on prod:
|
||||
|
||||
```
|
||||
docker exec minecraft sed -i 's/^voice_host=.*/voice_host=ulicraft.net/' \
|
||||
/data/config/voicechat/voicechat-server.properties
|
||||
docker restart minecraft # mod reads props only at startup
|
||||
```
|
||||
|
||||
**⚠️ This value lives in the `mc_data` volume, NOT auto-managed from this repo.**
|
||||
It survives restarts and `compose down/up`, but a **world wipe / fresh `mc_data`**
|
||||
regenerates the file with `voice_host=` empty → voice silently breaks again.
|
||||
|
||||
A known-good prod snapshot is committed at
|
||||
`server-configs/voicechat-server.properties` (reference copy, `voice_host=ulicraft.net`).
|
||||
After a world reset, either re-run the `sed` + `docker restart` above, or restore
|
||||
the snapshot:
|
||||
|
||||
```
|
||||
docker cp server-configs/voicechat-server.properties \
|
||||
minecraft:/data/config/voicechat/voicechat-server.properties
|
||||
docker restart minecraft
|
||||
```
|
||||
|
||||
(Snapshot is not auto-mounted — to make it durable, add a bind mount of
|
||||
`server-configs/voicechat-server.properties` into `/data/config/voicechat/` in
|
||||
compose.)
|
||||
|
||||
Verify after a client joins:
|
||||
`docker logs minecraft 2>&1 | grep -i "connected to voice"` → expect
|
||||
`Player <name> ... successfully connected to voice chat`.
|
||||
|
||||
Note: a red voice icon can ALSO be client-side — a VPN/zero-trust client
|
||||
(Cloudflare One/WARP, FortiClient) on the player's machine silently drops the
|
||||
voice UDP. Rule out VPNs before touching the server.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Compose: authlib URL `http://auth.${BASE_DOMAIN}/authlib-injector`
|
||||
@@ -77,3 +123,4 @@ needed (takes effect live). Current op: `oier`
|
||||
- [ ] `depends_on`: drasl (authlib must resolve at boot)
|
||||
- [ ] Confirm `ENFORCE_SECURE_PROFILE=FALSE` ↔ drasl `SignPublicKeys=false`
|
||||
- [ ] Verify a client joins with their drasl skin
|
||||
- [ ] After any world wipe: re-set `voice_host` (see Simple Voice Chat section)
|
||||
|
||||
Reference in New Issue
Block a user