
ssh-chat in modernem C

Allgemeine BBS-Software
SSH-Chatter entstand aus einer C-Neuimplementierung des Go ssh-chat Servers. Es spiegelt das ursprüngliche Verhalten wider bzw. erweitert es, verwendet dabei moderne C-Muster und einen kleinen, testbaren Kern. Der Server wartet auf SSH-/TELNET-Verbindungen und platziert jeden authentifizierten Benutzer in einem gemeinsamen Chatraum, der dieselbe Befehlsoberfläche wie die Go-Referenzimplementierung bereitstellt.
Weißt du, warum es so lange dauert, C zu verstehen? Weil es ein Instinkt ist.
/rss list, /rss read <tag>, plus /rss add <url> <tag> und /rss del <tag> (nur für Operatoren), damit der Raum gemeinsam Schlagzeilen durchstöbern kann./delete-msg für gezielte Bereinigung des Chatverlaufs./bbs-Befehl, der ein immersives Retro-Bulletin-Board-System mit Tags, Kommentaren, Bumping und einem mehrzeiligen Editor freischaltet.
bumped (letzte Aktivität), hot (Trending nach Bewertung & Kommentaren), top (höchste Netto-Upvotes) oder new (Erstellungsdatum) anzeigen mit list [hot|top|new|bumped|all].search <query>.▲ 12 💬 5)./bbs-Präfix nötig ist./asciiart Live-Editor mit einem 640-Zeilen-Limit, einer zehnminütigen Abkühlzeit pro IP, mehrzeiliger Ausgabe und Tastaturkürzeln zum Abbrechen mit Strg+A sowie zum Absenden mit Strg+S oder dem gebietsschemaabhängigen Standard >/__ARTWORK_END>./birthday zum Registrieren von Geburtstagen, /grant <ip> damit LAN-Operatoren Berechtigungen per Adresse delegieren können, und /revoke <ip> damit obere LAN-Administratoren sie zurücknehmen können./ban, das jetzt auch rohe IP-Adressen neben Benutzernamen akzeptiert./weather <city> für schnelle globale Wettervorhersagen.

Die Codebasis ist absichtlich kompakt gehalten, damit neue Mitwirkende sich schnell zurechtfinden können:

main bleibenDer work-Zweig weicht regelmäßig von der upstream-Entwicklung ab, damit größere Funktionen
reifen können, ohne den Produktionsverkehr zu unterbrechen. Wenn es an der Zeit ist, sich mit
main zu synchronisieren, holen Sie den aktuellen Baum und führen Sie ihn lokal zusammen, bevor Sie einen Pull-Request eröffnen:```bash
git fetch origin main
git checkout work
git merge --no-ff origin/main
Lösen Sie alle Konflikte direkt (die Hilfsroutinen in `src/host_aggregate.c` spiegeln bereits das Layout von `main` wider, daher sind Merges in der Regel unkompliziert) und führen Sie `make` aus, um zu bestätigen, dass der Build noch erfolgreich ist, bevor Sie das Ergebnis pushen.
## Automation hooks
- `host_snapshot_last_captcha` gibt die zuletzt generierte Captcha-Aufforderung und -Antwort zusammen mit einem Zeitstempel aus, sodass externe Clients im Namen unbeaufsichtigter Automatisierung Herausforderungen bestehen können.
## Security hardening
- `scripts/safe_permission.sh` schränkt die Besitzer- und Moduseinstellungen für Laufzeitdaten-Dateien (BBS-Zustand, Abstimmungszustand, Cooldown-Snapshots und allgemeiner Chatter-Zustand) ein. Führen Sie es nach der Bereitstellung aus, um das Datenverzeichnis auf `ssh-chatter` zu beschränken und sicherzustellen, dass jede Datei auf `0600` gesetzt ist. Überschreiben Sie die Ziele, indem Sie explizite Pfade übergeben oder die Umgebungsvariablen `STATE_ROOT` oder die entsprechenden `CHATTER_*_FILE` vor der Ausführung exportieren.
- Ein Hintergrund-BBS-Watchdog speist regelmäßig Beiträge und Kommentare in die KI-Moderation-Pipeline (Gemini primär mit Ollama als Fallback). Markierte Beiträge werden automatisch entfernt und eine Benachrichtigung wird im Raum ausgestrahlt.
- Chat-Nachrichten, ASCII-Kunst und BBS-Beiträge/Kommentare durchlaufen eine KI-Moderation-Pipeline. Aktivieren Sie sie mit `CHATTER_SECURITY_AI=on` (setzen Sie `GEMINI_API_KEY` für Gemini; der Daemon fällt automatisch auf den lokalen Ollama-Endpunkt unter `http://127.0.0.1:11434` zurück). Deaktivieren Sie alles mit `CHATTER_SECURITY_FILTER=off`. Falls alle Anbieter ausfallen, deaktiviert sich der Filter automatisch, um den Gesprächsfluss aufrechtzuerhalten, anstatt Inhalte stillschweigend zu verwerfen.
- Der SSH-Transport ist auf moderne Schlüsselaustausche, Chiffren und MACs festgelegt, und jede Bridge-Nutzlast ist in eine dreifache AES-256-GCM-Zwiebel eingewickelt, sodass Relais nur Chiffretext sehen.
- Verdächtige Einsendungen, die den mehrschichtigen Filter auslösen, werden jetzt pro-IP verfolgt; wiederholte Treffer lösen bei Aktivierung einen automatischen Kick und Bann aus, während der Schnellwiedererkennungsdetektor längere Wiederherstellungsfenster erlaubt, sodass instabile Netzwerksitzungen ohne Bestrafung wieder beitreten können. Automatische Bann-Einträge sind **standardmäßig deaktiviert**; setzen Sie `CHATTER_AUTO_BAN=on` (oder `true`/`1`), um sie zu aktivieren, oder lassen Sie die Variable ungesetzt, um Warnungen und Drosselung zu behalten, ohne automatische Bann-Einträge zu schreiben.
- Betreiber können vertrauenswürdige Einstiegspunkte (VPN-Ausgänge, Reverse-Proxies, localhost) mit `CHATTER_PROTECTED_IPS` (kommagetrennt, Standardwerte `127.0.0.1,::1,192.168.0.1`) markieren, sodass Notfall-Banns den Daemon nie von seiner eigenen Steuerungsebene aussperren.
## File storage and transfers
- Alle vom Benutzer verwalteten Dateien befinden sich jetzt unter `/etc/ssh-chatter/user-files` (Überschreiben mit `CHATTER_FILESTORE_PATH`, Legacy-Fallback: `CHATTER_FILE_STORAGE_ROOT`). Der Daemon erstellt das Verzeichnis bei Bedarf und hält Uploads darauf beschränkt.
- SSH-Clients verwenden standardmäßiges `scp` ohne benutzerdefinierten Wrapper. Behandeln Sie `/name.ext` als Stamm des Speicherbaums: `scp my.zip user@host:/demos/my.zip` schreibt nach `/etc/ssh-chatter/user-files/demos/my.zip`, während `scp user@host:/readme.txt ./` `/etc/ssh-chatter/user-files/readme.txt` herunterlädt.
- TELNET-Clients verwenden die neuen `/filestore`-Befehle. `/filestore` listet verfügbare Dateien auf, `/filestore-upload` startet eine `rz`-Sitzung und `/filestore-download <name>` startet eine `sz`-Sitzung. Installieren Sie `lrzsz` (oder ein beliebiges Paket, das `rz`/`sz` bereitstellt) auf dem Server, damit das ZMODEM-Backend diese Helfer starten kann.
- `/filestore-upload` akzeptiert ein optionales Ziel (z.B. `/filestore-upload /kitten/meow.png`). SSH-Chatter erstellt das Verzeichnis `/kitten` automatisch und legt die hochgeladene Datei dort ab, ähnlich wie SCP Pfade wie `user@host:/kitten/meow.png` verwendet.
- Beide Transporte können gemischt werden: SSH für unbeaufsichtigte, scriptgesteuerte Übertragungen, TELNET für nostalgische BBS-Clients mit integrierter ZMODEM-Unterstützung.
## Morse Relay
SSH-Chatter unterstützt Amateurfunk-Relais.
Dies zeigt globale Morsecodes.
`/morse on` zum Ansehen, `/morse-reply` zum Senden.
### Protocol Details
Die Implementierung folgt der Binkp-Protokollspezifikation:
- Standard-Binkp-Frame-Struktur mit 2-Byte-Headern
- Sitzungspasswort-Authentifizierung (CMD\_PWD/CMD\_OK)
- Keepalive-Mechanismus (CMD\_NUL) alle 60 Sekunden
- Benutzerdefinierter CHAT-Befehl (CMD\_CHAT, Erweiterung) für die Nachrichtensynchronisation
## Prerequisites
Zum Bauen des Projekts wird eine POSIX-Umgebung benötigt mit:
- Ein C23-kompatibler Compiler (z.B. `gcc` oder `clang`)
- `make`
- `libssh` Entwicklungs-Header und Bibliothek (`libssh-dev` auf Debian/Ubuntu)
- `libcurl` Entwicklungs-Header und Bibliothek (`libcurl4-openssl-dev` auf Debian/Ubuntu)
- `uchardet` Entwicklungs-Header und Bibliothek (`libuchardet-dev` auf Debian/Ubuntu)
- `icu` (International Components for Unicode) Entwicklungs-Header und Bibliothek (`libicu-dev` auf Debian/Ubuntu)
- `lz4` Kompressionsbibliothek und Entwicklungs-Header (`liblz4-dev` auf Debian/Ubuntu)
- POSIX-Threads (normalerweise von der System-`libpthread` bereitgestellt)
- `python3-pygments` (stellt den `pygmentize` Highlighter für den Tetris-Tarnbildschirm bereit)
Auf Debian/Ubuntu können die Abhängigkeiten installiert werden mit:```bash
sudo apt-get update
sudo apt-get install build-essential libssh-dev libcurl4-openssl-dev libuchardet-dev libicu-dev liblz4-dev
Klonen Sie das Repository und verwenden Sie die bereitgestellte Makefile:```bash
make
Dies erzeugt eine `ssh-chatter`-Binärdatei im Repository-Stammverzeichnis und ein `libssh_chatter_backend.so`-Shared-Object, das die Übersetzungshilfen zur Wiederverwendung in anderen Anwendungen bereitstellt. Bereinigen Sie Zwischenartefakte mit `make clean`.
### Verwendung des gemeinsamen Übersetzungs-Backends
Das Shared-Object verwendet die C-Übersetzungspipeline des Servers wieder (einschließlich der Erhaltung von ANSI-Platzhaltern), sodass andere Prozesse Übersetzungen erhalten können, ohne den vollständigen SSH-Host zu starten. Binden Sie `libssh_chatter_backend.so` ein und fügen Sie `include/ssh_chatter/ssh_chatter_backend.h` hinzu:```c
#include "ssh_chatter/ssh_chatter_backend.h"
int main(void) {
char translated[4096];
char detected[64];
if (ssh_chatter_backend_translate_line("Hello, world!", "ko", translated, sizeof(translated), detected, sizeof(detected))) {
printf("Detected %s -> %s\n", detected, translated);
}
}
Setzen Sie GEMINI_API_KEY (und optional GEMINI_API_BASE oder GEMINI_MODEL) in der Umgebungsvariable, damit der Helfer die Google Generative Language API erreichen kann, was die Laufzeitanforderungen des Hauptdaemons widerspiegelt. Sie können ./scripts/test_gemini_connection.sh ausführen, bevor Sie den Chat-Server starten, um zu überprüfen, ob die Anmeldeinformationen ausgehende Anrufe zulassen; das Skript gibt die rohe Gemini-Antwort aus, sodass Sie sehen können, ob die Anfrage erfolgreich war.
Der Server hört standardmäßig auf 0.0.0.0:2222. Sie können Laufzeitparameter mit den verfügbaren Flags anpassen:```
Usage: ./ssh-chatter [-a address] [-p port] [-m motd_file] [-k host_key_dir] [-T telnet_port|off] [-J json_port|off]
./ssh-chatter [-h]
./ssh-chatter [-V]
Wenn angegeben, liest `-m` die Tagesnachricht aus dem angegebenen Dateipfad. Häufige Beispiele:```bash
# Start the chat server on port 2022, loading host keys from /etc/ssh
./ssh-chatter -p 2022 -k /etc/ssh
# Enable telnet access on 0.0.0.0:4242 alongside SSH
./ssh-chatter -T 0.0.0.0:4242
# Serve a custom MOTD from a file and bind to localhost
./ssh-chatter -a 127.0.0.1 -m /etc/ssh-chatter/motd
Das Host-Key-Verzeichnis muss eine ssh_host_rsa_key-Datei (und optional .pub) enthalten. Generieren Sie eine mit ssh-keygen -t rsa -b 4096 -f /path/to/dir/ssh_host_rsa_key, falls Sie nicht Ihre systemeigenen SSH-Host-Keys wiederverwenden möchten. Zusätzliche Host-Keys mit den Namen ssh_host_ed25519_key und ssh_host_ecdsa_key werden automatisch geladen, wenn vorhanden, damit der Server moderne Algorithmen während des Schlüsselaustauschs anbieten kann.
Sobald der Dienst läuft, verbinden Sie sich mit einem beliebigen SSH-Client:```bash ssh -p 2222 user@server-address
Der öffentliche Server ist verfügbar unter `bbs.chatter.pw` auf dem standard SSH-Port:```bash
ssh -p 2222 [email protected]
Die Benutzernamen, die in der SSH-Eingabeaufforderung angegeben werden, werden als Ihr Chat-Spitzname verwendet.
Telnet-Clients können mit demselben Funktionsumfang teilnehmen. Telnet ist standardmäßig auf Port 2323 aktiviert und kann mit dem Flag -T angepasst oder deaktiviert werden. Geben Sie -T Adresse:Port an, um die Bind-Adresse zu überschreiben (diese erbt die SSH-Bindung, wenn sie weggelassen wird; verwenden Sie einen leeren Host wie -T :4242, um auf allen Schnittstellen zu lauschen). Zum Beispiel, um über Telnet von einem Retro-Terminal beizutreten:```bash
telnet server-address 2323
Übergeben Sie `-T off` (oder `-T disable`), um den Telnet-Listener vollständig auszuschalten.
### JSON line API
Der Server stellt außerdem ein JSON-Line-Protokoll über TCP für Automatisierung und externe Integrationen bereit. Es hört standardmäßig auf Port `34567` und kann mit `-J` deaktiviert oder neu konfiguriert werden:```bash
# Disable the JSON API
./ssh-chatter -J off
# Bind JSON API on a custom port
./ssh-chatter -J 0.0.0.0:45678
Jede Anfrage ist ein einzelnes JSON-Objekt, beendet durch \n. Antworten und Chat-Ereignisse sind JSON-Objekte, ebenfalls durch Zeilenumbrüche getrennt. Die API unterstützt allgemeinen Chat sowie die /poll, /vote, /image, /video, /audio, /files und /asciiart Abläufe.
Ereignis-Payloads (Server → Client)```json {"type":"event","event":"message","payload":{"id":123,"username":"alice","message":"hello","created_at":1710000000,"system":false,"preserve_whitespace":false,"attachment":{"type":"none","target":"","caption":""}}}
**Beispielanfragen (client → server)**```json
{"type":"chat","id":1,"username":"alice","message":"안녕하세요"}
{"type":"image","id":2,"username":"alice","url":"https://example.com/cat.png","caption":"cat"}
{"type":"asciiart","id":3,"username":"alice","message":" /\\_/\\\\n( o.o )\\\\n > ^ <"}
{"type":"poll","id":4,"username":"op","is_operator":true,"question":"Favorite color?","options":["red","blue","green"]}
{"type":"poll","id":5,"username":"bob","action":"vote","choice":2}
{"type":"vote","id":6,"username":"op","label":"weekend","question":"Plan?","options":["hike","rest"],"allow_multiple":true}
{"type":"vote","id":7,"username":"bob","label":"weekend","action":"vote","choice":1}
Antworten geben die id zurück und enthalten status, message und optionale result-Objekte:```json
{"type":"response","id":4,"status":"ok","message":"poll started","result":{"poll":{"active":true,"allow_multiple":false,"id":10,"question":"Favorite color?","options":[{"index":1,"text":"red","votes":0},{"index":2,"text":"blue","votes":0}]}}}
Für ein ausführbares Beispiel siehe `scripts/json_api_example.py`:```bash
python3 scripts/json_api_example.py --url tcp://127.0.0.1:34567 --save /tmp/json_api_output.txt
Ein Hilfsskript wird bereitgestellt, um die Installation auf Systemen zu automatisieren, die systemd verwenden:```bash
sudo ./scripts/install_chatter_service.sh
Was das Skript tut:
1. Kompiliert das Projekt (`make`).
2. Installiert die resultierende Binärdatei unter `/usr/local/bin/ssh-chatter`.
3. Erstellt einen dedizierten Systembenutzer und eine Gruppe `ssh-chatter` (falls sie nicht bereits existieren).
4. Erstellt `/var/lib/ssh-chatter` für den Laufzeitzustand (einschließlich des SSH-Hostschlüssels) und `/etc/ssh-chatter` für Konfigurationsdateien.
5. Generiert einen standardmäßigen RSA-Hostschlüssel unter `/var/lib/ssh-chatter/ssh_host_rsa_key`, falls dieser fehlt.
6. Erstellt eine standardmäßige MOTD unter `/etc/ssh-chatter/motd` und eine Überschreibungsdatei `/etc/ssh-chatter/chatter.env` für umgebungsbasierte Anpassungen.
7. Schreibt `/etc/systemd/system/chatter.service`, lädt `systemd` neu, aktiviert den Dienst und startet ihn sofort.
Die resultierende `chatter.service`-Unit startet den Server mit sinnvollen Standardeinstellungen und gewährt die Fähigkeit `CAP_NET_BIND_SERVICE`, sodass das nicht-Root-Dienstkonto ggf. privilegierte Ports binden kann.
### Anpassen des Dienstes
Sie können die Standardwerte anpassen, indem Sie `/etc/ssh-chatter/chatter.env` bearbeiten und den Dienst neu starten:```bash
sudo systemctl edit chatter.service # or edit the environment file directly
sudo systemctl restart chatter.service
Unterstützte Umgebungsvariablen sind:
CHATTER_BIND_ADDRESS – IP-Adresse zum Binden (Standard 0.0.0.0).CHATTER_PORT – TCP-Port, der für Clients freigegeben ist (Standard 2222).CHATTER_MOTD_FILE – Pfad zur Tagesnachrichten-Datei (Standard /etc/ssh-chatter/motd).CHATTER_HOST_KEY_DIR – Verzeichnis, das ssh_host_rsa_key enthält (Standard /var/lib/ssh-chatter).CHATTER_EXTRA_ARGS – Zusätzliche Argumente, die dem ssh-chatter-Aufruf angehängt werden.CHATTER_VOTE_FILE – Pfad zur Abstimmungszustandsdatei (Standard vote_state.dat).Camouflage-Code-Snippets:
Für die Tetris-Camouflage-Funktion erwartet die Laufzeitumgebung Code-Snippet-Dateien in /var/lib/ssh-chatter/.
Dieses Repository enthält jetzt gebrauchsfertige Beispiele unter ./camouflage/ (c.txt, cpp.txt, java.txt, go.txt, js.txt, ts.txt, rust.txt).
Kopieren Sie sie einmalig während der Einrichtung in das Laufzeitverzeichnis:```bash
sudo install -d /var/lib/ssh-chatter
sudo cp camouflage/*.txt /var/lib/ssh-chatter/
Sie können jede kopierte Datei bearbeiten, um anzupassen, was erscheint, wenn der Tarnbildschirm aktiv ist.
Die Übersetzungsunterstützung basiert jetzt auf der Google Gemini API. Setzen Sie Folgendes in `chatter.env` (oder der Umgebung), um sie zu aktivieren:
- `GEMINI_API_KEY` – Geheimer API-Schlüssel, der zur Authentifizierung von Übersetzungsanfragen verwendet wird.
- `GEMINI_API_BASE` – Optionaler Überschreibungswert für die API-Basis-URL (Standard: `https://generativelanguage.googleapis.com/v1beta`).
- `GEMINI_MODEL` – Optionaler Überschreibungswert für den Gemini-Modellnamen (Standard: `gemini-2.5-flash`).
Wenn die Übersetzung aktiv ist, liefert der Chat jede Nachricht sofort in ihrer Originalsprache und fügt eine eingerückte
Beschriftung hinzu, die den übersetzten Text enthält, sobald die Gemini-Antwort eintrifft. Reaktionszusammenfassungen verwenden denselben Beschriftungsstil, sodass
Aktualisierungen direkt unter der Nachricht erscheinen, auf die sie sich beziehen.
Wenn die eingefügten Inline-Beschriftungen störend wirken, können Sie im Voraus einen kleinen Puffer von Leerzeilen mit `/chat-spacing <0-5>` reservieren.
Die Einstellung betrifft nur Live-Chat-Threads – Bulletin-Board-Inhalte werden weiterhin ohne Reservierung übersetzt –, sodass Sie den
Abstand für Ihre eigene Sitzung anpassen können, ohne langformatige Beiträge zu beeinträchtigen.
Ihre Übersetzungsumschaltung und Sprachwahl werden in `chatter_state.dat` gespeichert, sodass zukünftige Sitzungen automatisch dieselbe
Konfiguration wiederherstellen, sobald Sie sich erneut verbinden.
Wenn Sie das Programm installieren möchten, ohne den Dienst sofort zu starten, führen Sie das Skript mit `SKIP_START=1` aus.
Befehle zur Dienstverwaltung:```bash
sudo systemctl status chatter.service
sudo systemctl restart chatter.service
sudo systemctl disable --now chatter.service
-m-Flag oder eine dienstverwaltete Konfigurationsdatei./help-Befehl für verbundene Clients./ban, /poke)./weather/vote) und Single-Choice-Alternativen (/vote-single) unterstützen, einschließlich /elect <Label> <Auswahl> als textfreundliche Voting-Abkürzung./bbs, mit Tagging, Kommentaren, Bumping und einem interaktiven Editor, der mit einem sprachabhängigen Terminator endet (Standard >/__BBS_END>).Issues und Pull-Requests sind willkommen. Bitte füge Reproduktionsschritte für Fehler bei und stelle sicher, dass make erfolgreich ist, bevor du Änderungen einreichst.
| Pfad | Beschreibung |
|---|
src/main.c | Kommandozeilenanalyse und Prozess-Bootstrap (Bind-Adresse, Port, MOTD, Host-Key-Verzeichnis). |
src/host_aggregate.c, include/ssh_chatter/host.h | Chat-Host-Implementierung – Sitzungslebenszyklus, MOTD-Handling und Hooks für zukünftige Nachrichten-Broadcast-Logik. |
src/host | Modulare Host-Subsysteme, die über src/host_aggregate.c zu einer einzigen Übersetzungseinheit zusammengefasst werden. |
include/ssh_chatter | Gemeinsame Header für den Daemon, die Stresstools und das Übersetzungs-Backend. |
include/ssh_chatter/contexts | Definitionen für session_ctx_t und verwandte Strukturen, die den pro-Verbindungs-Zustand kapseln. |
data/banner/banner | Beispiel-Willkommensbanner, auf das mit CHATTER_WELCOME_BANNER verwiesen werden kann. |
scripts/install_chatter_service.sh | Bequemer Installer, der das Binary erstellt, unter /usr/local/bin installiert und eine systemd-Unit (chatter.service) einrichtet. |
scripts/install_dependencies.sh | Minimales Paket-Installer-Skript für Build-Voraussetzungen auf Debian/Ubuntu-Systemen. |
CHATTER_GEMINI_COOLDOWN_FILE – Pfad zur Gemini-Abkühlungszustandsdatei (Standard gemini_cooldown.dat).CHATTER_SECURITY_FILTER – Auf off/false/0 setzen, um den mehrschichtigen Sicherheitsfilter zu deaktivieren (standardmäßig aktiviert).CHATTER_SECURITY_AI – Auf on/true/1 setzen, um KI-Moderation zu aktivieren (standardmäßig deaktiviert).CHATTER_FILESTORE_PATH – Überschreibt den Pfad des verwalteten Dateispeichers (Standard /etc/ssh-chatter/user-files).CHATTER_FILE_STORAGE_ROOT – Legacy-Fallback für den Pfad des verwalteten Dateispeichers.CHATTER_MAX_ALLOC_BYTES – Obergrenze für einen einzelnen zusammenhängenden Allokationsversuch im internen Speichermanager. Standardmäßig gibt es keine Begrenzung (SIZE_MAX). Setzen Sie dies nur, wenn Sie eine harte Grenze für eine Allokation festlegen möchten. Setzen Sie es auf 0, unlimited, inf oder infinity, um eine Begrenzung explizit zu entfernen./asciiart-Editor mit 640-Zeilen-Entwürfen, einer Zehn-Minuten-Pro-IP-Post-Sperrfrist, Mehrzeilen-Zustellung und Tastenkombinationen Ctrl+A/Ctrl+S./game-Hub mit integriertem tetris (umkodiert aus der ursprünglichen sowjetischen C-Implementierung) und liargame, beide pausierbar über /suspend! oder Ctrl+Z.