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>
- Add edit_html() to utils using m.replace so messages can be updated
- Hangman board now edits in place on every guess — shows progressing
ASCII figure as wrong guesses accumulate instead of spamming new messages
- Extract _hangman_board_html() helper for consistent board rendering
- wyr: add INFO-level logging to reaction callback to diagnose vote tracking
Co-Authored-By: Claude Sonnet 4.6 <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>