mcrcon implements its read timeout with signal.SIGALRM, which only works
on the main thread. The Minecraft commands call it from a worker thread
via loop.run_in_executor, so it raised "signal only works in main thread
of the main interpreter" on every invocation. The replacement uses
socket.settimeout(), which has no such restriction.
This code was already deployed on LXC 151 but had never been committed,
so any matrixbot deploy would have reverted it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
All bot source files from LXC 151 (/opt/matrixbot) are now tracked here.
Secrets (.env, credentials.json), venv dirs, and runtime state files
(nio_store, welcome_state.json, wordle_stats.json) are excluded via .gitignore.
Includes deploy.sh to sync files to /opt/matrixbot and restart the service.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>