Initial commit: MUD client v0.2

This commit is contained in:
truetype committed 2026-07-07 15:38:28 +00:00
commit 0030fd7d82
26 files changed
+4421

No files matched your search

+194
View File
@@ -0,0 +1,194 @@
# Uso della CLI — riferimento completo
Il comando dopo `pip install -e .` è **`mudclient`** (entry point
definito in `pyproject.toml`). È equivalente a `python -m progetto2`.
---
## Flag
| Flag | Tipo | Default | Note |
| --- | --- | --- | --- |
| `--host HOST` | str | `localhost` | host MUD (default punta al docker locale di Dead Souls) |
| `--port PORT` | int | `6666` | porta TCP |
| `--user NAME` | str | `""` (vuoto = no auto‑login del nome) | auto‑login quando il server chiede "What name do you wish?" |
| `--password PWD` | str | `os.environ.get("MUDCLIENT_PASSWORD", "")` | password per auto‑login dopo `Password:` |
| `--cols COLS` | int | `120` | larghezza iniziale finestra (NAWS subneg) |
| `--rows ROWS` | int | `40` | altezza iniziale finestra |
| `--log LVL` | choice | `WARNING` | livello Python logging. Valori validi (rifiutati se diversi): `DEBUG` / `INFO` / `WARNING` / `ERROR` / `CRITICAL`. |
| `--log-json PATH` | str | `""` (no log JSON) | path JSONL append‑only (vedi `docs/events.md`) |
| `--log-md PATH` | str | `""` (no log MD) | path Markdown streamed |
> **Sicurezza `--password`**: il valore è in chiaro in `ps`/`history`.
> Usare l'env `MUDCLIENT_PASSWORD` o `/password PWD` (redatto). Il
> client redige automaticamente il valore nei log JSON/MD.
---
## Esempi rapidi
```bash
# Connessione minimale al docker di sviluppo
mudclient
# Server remoto esplicito
mudclient --host mud.example.com --port 4000
# Auto‑login completo (account + password)
mudclient --user zork --password hunter2
# password via env (preferibile in CI / shell history):
MUDCLIENT_PASSWORD=hunter2 mudclient --user zork
# Auto‑login solo nome; password manuale quando il server chiede
mudclient --user zork
# Finestra ridotta (es. 80x24) per terminali piccoli
mudclient --cols 80 --rows 24
# Debug del parser / IAC
mudclient --log DEBUG --log-json ./debug.jsonl --log-md ./debug.md
# Log persistente di una sessione intera (rotation esterna)
mudclient --log-json ~/mud-$(date +%Y%m%d-%H%M).jsonl \
--log-md ~/mud-$(date +%Y%m%d-%H%M).md
```
---
## Comandi slash (locali)
| Slash | Implementazione | Loggato come |
| --- | --- | --- |
| `/help` o `/?` | stampa aiuto | `local_cmd` |
| `/map` | render ASCII del mapper | `local_cmd` |
| `/where` | "Sei in: {Room}. Uscite: {list}" | `local_cmd` |
| `/look` | `conn.send_line("look")` | `local_cmd` |
| `/stats` | locali scoperti, GMCP, vitali | `local_cmd` |
| `/vitals` | `state.vitals` raw | `local_cmd` |
| `/clear` | `prompt_toolkit.clear()` | `local_cmd` |
| `/quit` `/exit` `/q` | chiude + SystemExit(0) | non loggato |
| `/password PWD` | redacted + `conn.send_line(pwd)` | `local_cmd` (redatto) + `login` |
| `/...` (altro) | passa al MUD con `/` rimosso | `line_sent` |
`Ctrl-D` chiude in modo equivalente a `/quit`.
---
## Prompt e status bar
**Prompt** (ricostruito a ogni line):
```
[NomeStanza]> _
```
`[NomeStanza]` cyan brillante, `>` verde brillante.
**Status bar** (ricostruito a ogni refresh):
```
[stanza: Outer Courtyard] [GMCP: on] HP 100/100 SP 50/50 MV 80/80
```
Refresh forzato ogni **0.5 s** via `PromptSession(refresh_interval=0.5)`.
Costo: ~2 redraw/sec anche in idle. Documentato come scelta di
trade‑off tra reattività e CPU nel file `docs/architecture.md`.
---
## Flusso auto‑login
```
server: "What name do you wish? " (o "Enter your name:", "Login:")
client: send_line(args.user) ← solo se --user e one-shot
client: state.auto_user_sent = True
server: "Password: "
client: state.auto_password_prompted = True
├── args.password → send_line(args.password); state.auto_password_sent = True
└── args.password "" → stampa: "[login] server chiede password; digita /password <pwd>"
```
`auto_*_sent` è **one‑shot**: una seconda occorrenza di "What name…?"
non re‑invio il nome. Previene spam in caso di messaggi di echo o
re‑auth lato server.
**Varianti regex coperte** (`_LOGIN_RE`):
```
What name do you wish
Enter your name
Login: / Login name
Name to use
```
più prefissi opzionali `>` o `*`.
**Varianti password** (`_PASSWORD_RE`):
```
Password:
* Password ?
> Password:
```
Tolleranti a prefissi `> *`, spaziature e `: ?` finale.
Se il tuo MUD usa prompt diversi, modifica le regex in
`src/progetto2/cli.py` (sono 3 righe ciascuna).
---
## Output delle stanze
Dead Souls con GMCP attivo invia `Room.Info {num, name, desc, exits}`.
Il client usa `num` come id stabile della stanza. Senza GMCP, le
stanze sono rilevate euristicamente vedendo:
```
Inn Hall
A warm fire crackles.
[ Exits: n e ]
```
`RollingRoomParser` chiude il blocco su `Exits:` line. Il mapper
visita la stanza immediatamente. Puoi digitare `n` o `e` e la prossima
volta che il server conferma la stanza, **l'edge viene creato**.
---
## Rotazione dei log
I path `--log-json` e `--log-md` vengono **truncati** all'apertura.
Per conservare le sessioni precedenti:
```bash
mv ~/mud.jsonl{,.prev} && mudclient --log-json ~/mud.jsonl
```
Per archivi automatici prima di ogni sessione:
```bash
LOGBASE=~/mud-$(date +%Y%m%d-%H%M)
mudclient --log-json "$LOGBASE.jsonl" --log-md "$LOGBASE.md"
```
Per tail in tempo reale:
```bash
# in un secondo terminale durante una sessione attiva
tail -f ~/mud.jsonl | jq -c '.kind + ": " + (.data|tostring)'
```
---
## Diagnosi minimali
| Sintomo | Probabile causa | Cosa provare |
| --- | --- | --- |
| Il client si blocca dopo Connect | Server MUD non risponde `DO ECHO` / GMCP | `--log DEBUG` + `--log-json ./x.jsonl` |
| Prompt non ridisegnato | `refresh_interval` non rinfresca in idle | è normale, aspettare il prossimo input |
| `/map` mostra [mappa vuota] | nessuna stanza ancora riconosciuta | cammina un po', oppure controlla se `Room.Info` GMCP arriva |
| Login password non parte | regex `_PASSWORD_RE` non match | `--log DEBUG` e ispezione `data` di `text` events |
| Sessione termina subito | `conn.close()` per EOF inatteso | `--log INFO` per vedere l'eccezione in `read_loop` |