Files
viandante/README.md
T

211 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# progetto2
`progetto2` ospita un **client MUD CLI** pensato per collegarsi a un MUD
LP‑MUD basato sul driver **FluffOS** (per esempio **Dead Souls**, libreria
3.8.6). Il client parla telnet con estensioni standard: `ECHO`, `NAWS`,
`TTYPE`, e rifiuta (`WONT`) tutte le altre (`GMCP`, `MSDP`, `MCCP`, `MXP`
per ora). Tiene traccia delle stanze visitate e le renderizza come **mappa
ASCII** on-demand.
## Requisiti
- Python ≥ 3.10
- Una libreria Python: [`prompt_toolkit`](https://pypi.org/project/prompt-toolkit/) ≥ 3.0
## Setup
```bash
cd progetto2
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```
Verrà installato il comando `mudclient`.
## Uso
```bash
# Default: si collega a localhost:6666 con un finestra iniziale 120×40
mudclient
# Espliciti
mudclient --host localhost --port 6666 --cols 120 --rows 40
# Auto-login: passa il nome; il client lo invia quando il server chiede
# "What name do you wish?". Se serve la password, il client chiede
# /password PWD oppure la puoi passare con --password (o env MUDCLIENT_PASSWORD).
mudclient --user zork --password hunter2
# Log di sessione: ogni evento (testo, GMCP, stanze, comandi locali, linee inviate)
# viene serializzato in append‑only, flushed dopo ogni write — adatto a `tail -f`.
mudclient --log-json ~/mud-session.jsonl --log-md ~/mud-session.md
```
> I file `--log-json` / `--log-md` vengono **truncati** all'apertura:
> ogni nuova sessione ricomincia da zero. Per ruotare manualmente
> prima della sessione:
> ```bash
> mv ~/mud-session.jsonl{,.prev} && mudclient --log-json ~/mud-session.jsonl
> ```
Schema eventi (un oggetto JSON per riga):
| `kind` | Scopo | Note |
| --- | --- | --- |
| `session_start` | apertura sessione | `host`, `port`, `user` |
| `session_end` | chiusura normale | `reason` |
| `disconnect` | chiusura socket | `reason` |
| `text` | chunk ANSI ricevuto dal server | `raw` preservato |
| `room_enter` | mapper ha registrato una stanza | `id`, `name`, `exits` |
| `gmcp` | frame GMCP accettato | `module`, `payload` |
| `vitals` | snapshot hp/sp/mv | solo i campi presenti |
| `line_sent` | riga inoltrata al MUD | password redatte (`***`) |
| `local_cmd` | comando `/...` intercettato | password/segreti redatti |
| `login` | prompt/risposta auto-login | `value` redatto di default; passare `redact=False` per i nomi account |
Una volta connesso:
| Tasto | Effetto |
| --- | --- |
| Testo qualsiasi | inviato al MUD terminato da `\r\n` |
| `/map` | disegna la mappa ASCII delle stanze visitate (multi-source BFS) |
| `/where` | mostra la stanza corrente e le uscite |
| `/look` | invia `look` al MUD |
| `/vitals` | mostra hp/sp/mv (via GMCP `Char.Vitals`) |
| `/stats` | locali scoperti, GMCP stato, vitali |
| `/password PWD` | invia una password al MUD |
| `/clear` | pulisce lo schermo |
| `/help` (`/?`) | mostra l'aiuto |
| `/quit` (`/q`, `Ctrl‑D`) | esce |
Il prompt è sempre del tipo:
```
[NomeStanza]> _
```
con il nome della stanza corrente in cyan brillante. In basso c'è una **status bar** che mostra:
```
[stanza: Outer Courtyard] [GMCP: on] HP 100/100 SP 50/50 MV 80/80
```
Quando il server invia `Char.Vitals` via GMCP, hp/sp/mv compaiono automaticamente.
## Layout dei sorgenti
```
progetto2/
├── pyproject.toml # metadata + dipendenze + entry point `mudclient`
├── README.md # questo file
├── .gitignore
├── docs/ # documentazione completa (vedi sotto)
│ ├── README.md # indice della cartella docs
│ ├── architecture.md # analisi architetturale (data flow + boundary)
│ ├── modules.md # descrizione modulo‑per‑modulo
│ ├── protocol.md # telnet, GMCP, ANSI, euristiche Dead Souls
│ ├── usage.md # flag CLI, esempi, auto‑login, comandi slash
│ ├── events.md # schema eventi del logger
│ ├── development.md # setup dev, pytest, ruff, come estendere
│ └── gitea.md # flusso di pubblicazione sul Gitea + sicurezza token
├── src/progetto2/ # package
│ ├── __init__.py
│ ├── __main__.py # supporta `python -m progetto2`
│ ├── cli.py # entry point + UI a riga di comando
│ ├── telnet.py # state machine IAC + asyncio
│ ├── deadsouls.py # parser di stanze Dead Souls / LP‑MUD
│ ├── gmcp.py # parser GMCP (Char.Vitals / Room.Info)
│ ├── mapper.py # grafo delle stanze + render ASCII
│ ├── logger.py # EventLogger (JSONL + Markdown sinks)
│ └── ansi.py # stripper ANSI per il parser
└── tests/ # unit test (pytest)
├── test_telnet.py
├── test_ansi.py
├── test_deadsouls.py
├── test_mapper.py
└── test_logger.py
```
## 📚 Documentazione completa
La documentazione vive nella cartella [`docs/`](./docs/README.md) e
copre:
- **[`docs/architecture.md`](./docs/architecture.md)** — analisi
architetturale completa: dipendenze tra moduli, data flow di un
frame dal server, boundary concerns, refactor raccomandati.
- **[`docs/modules.md`](./docs/modules.md)** — cosa fa ogni modulo,
API pubblica, responsabilità, tolleranze.
- **[`docs/protocol.md`](./docs/protocol.md)** — IAC state machine,
GMCP wire format, euristiche Dead Souls, ANSI handling.
- **[`docs/usage.md`](./docs/usage.md)** — riferimento flag CLI, esempi
pratici, flusso auto‑login, comandi slash, rotazione log.
- **[`docs/events.md`](./docs/events.md)** — schema completo degli
eventi del logger (JSONL + Markdown), regole di redazione, esempi
`jq`.
- **[`docs/development.md`](./docs/development.md)** — workflow
sviluppatore: setup, test, lint, come aggiungere moduli, debugging.
- **[`docs/gitea.md`](./docs/gitea.md)** — flusso di pubblicazione sul
server Gitea `192.168.0.183:8085` (utente `truetype`) **+ regole di
sicurezza del token**.
## Note sul protocollo
Il client negozia:
- `ECHO`: invia `WILL ECHO` in risposta a `DO ECHO`. Il server non eseguirà
più echo remoto, mentre l'eco locale è gestita da `prompt_toolkit`.
- `NAWS`: se attivo, invia la dimensione della finestra iniziale.
- `TTYPE`: risponde con `XTERM-256COLOR` quando il server lo richiede.
- `GMCP`: viene **offerto proattivamente** (`WILL` al connect). Dead Souls
lo accetta e invia pacchetti `Char.Vitals`, `Room.Info`, `Char.Login`,
ecc. Quando una stanza arriva via `Room.Info`, si usa il `num`
(vnum) del server come id stabile della stanza.
Le righe di stato del parser considerano `IAC GA` (`249`) e `IAC EOR`
(`239`) come delimitatori di "record/prompt", così da poter chiudere un
blocco di stanza anche quando il prompt testuale non è immediatamente
riconoscibile.
La rilevazione automatica della geometria del mondo si basa sul **movimento
inviato dall'utente** + **descrizione della stanza** osservata subito
dopo: quando digiti `n`, il client informa il mapper; quando la risposta
del MUD arriva, `Mapper.visit()` collega automaticamente
`corrente → nuova` lungo la direzione digitata.
Il render della mappa è un **multi-source BFS** dal current room, con
fallback di **posizionamento orfano** per le stanze visitate in sequenza
indietro (es. `n→s`) e stack nell'angolo in basso a destra per stanze
completamente isolate.
## Limitazioni note (v0.2)
- **MSDP / MCCP / MCP / MXP** non sono ancora abilitati: una sessione che
li richiede ottiene `WONT` dal nostro lato. Dead Souls usa GMCP, che è
ben coperto; altri MUD basati su MSDP possono essere aggiunti seguendo
lo schema di `gmcp.py`.
- La detection delle stanze **senza GMCP** resta **euristica** sul testo.
- **Login automatico**: il client riconosce il prompt `What name do you
wish?` / `Password:` e invia automaticamente solo la prima volta.
Per la password senza `--password` viene mostrato un suggerimento
`usa /password <pwd>` (niente prompt annidato, troppo fragile).
- Gli `u`/`d` (verticali) sono rappresentati nella mappa ma non
influenzano le coordinate 2D (offset `(0,0)`).
- La status bar si aggiorna ad ogni rilettura della riga del prompt;
per refresh continui in idle si può aggiungere `refresh_interval`
al `PromptSession` come estensione futura.
## Sviluppo
```bash
pip install -e ".[dev]"
pytest # gira tutta la suite
ruff check src tests # lint
```
## Licenza
MIT per il codice del client. Il server **Dead Souls** non è GPL — assicurati
di rispettarne la licenza prima di redistribuirlo.