From af073e77ec8c6ac1e52d91a07f9d833a7805f060 Mon Sep 17 00:00:00 2001 From: Tronax Date: Sun, 9 Aug 2026 11:09:35 +0200 Subject: [PATCH] VNC-Steuerung verbessern: Low-Latency, Maus, Tastatur, Resize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Steuerung ist jetzt auf Minecraft (Menü, Chat, Inventar, AFK-Farmen) optimiert. Für Mouselook/PVP bleibt VNC ungeeignet (Protokollgrenze, dokumentiert). x11vnc (serverseitig, entrypoint.sh): - -threads: parallele I/O-Threads → weniger Eingabe-Lag - -pointer_mode 4: flüssigere Mausübertragung (Default 1 ist träge) - -norepeat: verhindert doppelte Tastaturwiederholungen im Spiel - -nodpms -nofbpm -nowf -nowcr: Energiesparen/Rate-Limiting aus - Über X11VNC_EXTRA env var frei konfigurierbar noVNC-Client (VncViewer.vue): - resize=remote statt scaling: Xvfb folgt Fenstergröße (1:1-Maus-Mapung) - reconnect=1: auto-Reconnect bei Abbruch - clipboard=1: Zwischenablage Browser <-> Container - view_only=0: Eingabe explizit freigeschaltet - Klick ins Bild setzt Tastaturfokus ins iframe - Hinweis auf Mausfreigabe (Strg+Alt+Umschalt), Fokus-Button README: neuer Abschnitt "Steuerung über VNC" mit Grenzerklärung. .env.example + docker-compose.yml: X11VNC_EXTRA durchgereicht. --- .env.example | 7 +++ README.md | 47 ++++++++++++++++++ docker-compose.yml | 1 + docker/entrypoint.sh | 15 +++++- web/src/components/VncViewer.vue | 83 +++++++++++++++++++++++++------- 5 files changed, 134 insertions(+), 19 deletions(-) diff --git a/.env.example b/.env.example index d49ad84..f0e1fd8 100644 --- a/.env.example +++ b/.env.example @@ -24,6 +24,13 @@ WEB_PORT=8080 # Optionales VNC-Passwort. Leer = ohne Passwort (nur für lokales Netz gedacht). VNC_PASSWORD= +# Zusätzliche x11vnc-Flags für die Low-Latency-/Eingabe-Optimierung. +# Defaults sind auf Minecraft (Menü, Chat, Inventar, AFK-Farmen) abgestimmt: +# -threads -pointer_mode 4 -norepeat -nodpms -nofbpm -nowf -nowcr +# Für langsames Netz z.B. Kompression dazuschalten: +# -threads -pointer_mode 4 -norepeat -tight -compresslevel 6 -quality 7 +X11VNC_EXTRA= + # noVNC-Pfad. Leer = Dashboard startet direkt im VNC-Viewer. # Z.B. "vnc.html" für die standalone noVNC-Seite ohne Dashboard-Frame. NOVNC_PATH= diff --git a/README.md b/README.md index 125b62f..6a94aac 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,53 @@ Die konkrete Einrichtung hängt von deiner Farm ab. Typische Schritte: | `DISPLAY_REFRESH` | `60` | Bildwiederholrate des virtuellen Displays. | | `WEB_PORT` | `8080` | Browser-Port. | | `VNC_PASSWORD` | *(leer)* | Optional. Leer = ohne Auth (nur lokales Netz!). | +| `X11VNC_EXTRA` | siehe `.env` | Low-Latency-/Eingabe-Flags für x11vnc. | + +--- + +## Steuerung über VNC + +Die Steuerung ist auf **Minecraft-Menü, Chat, Inventar und AFK-Farmen** +optimiert. Sie ist **nicht** für aktives PVP/Mouselook gedacht — das ist eine +grundsätzliche Grenze von VNC (siehe unten). + +**Bedienung im Browser:** +- **Klick ins Bild** → setzt den Tastaturfokus ins Spielfenster (Tasten gehen + ans Spiel, nicht an den Browser). +- **Maus freigeben** → `Strg + Alt + Umschalt` (noVNC-Standard). +- **Vollbild** → Button in der Toolbar; für Minecraft flächendeckend. +- **Zwischenablage** → automatisch verknüpft (Login-Codes / Server-IPs kopieren + geht direkt zwischen Browser und Container). + +**Was automatisch eingestellt ist:** +- `resize=remote`: die Xvfb-Auflösung folgt der Fenstergröße (1:1-Maus-Mapung, + keine Skalierungs-Unschärfe). +- `reconnect=1`: bei Abbruch verbindet noVNC selbstständig neu. +- x11vnc mit `-threads -pointer_mode 4 -norepeat`: + - `-threads` → parallele I/O-Threads, weniger Eingabe-Lag. + - `-pointer_mode 4` → flüssigere Mausübertragung als der Default (1). + - `-norepeat` → verhindert doppelte Tastaturwiederholungen im Spiel. +- `-nodpms -nofbpm -nowf -nowcr` → Energiesparen und Rate-Limiting aus, damit + nichts nach Leerlauf ruckelt. + +**Für langsames Netz** (z. B. Remote über Internet statt LAN) in der `.env` +Kompression aktivieren: +``` +X11VNC_EXTRA=-threads -pointer_mode 4 -norepeat -tight -compresslevel 6 -quality 7 +``` + +### Warum Mouselook nicht richtig geht + +VNC überträgt **absolute** Mauskoordinaten („Cursor an Position X/Y"). Minecraft +wie jedes FPS-artige Spiel braucht aber **relative** Mausbewegung und setzt den +Cursor dafür jeden Frame auf die Bildmitte zurück ([noVNC Issue #1493][novnc1493]). +Darum lässt sich die Kamera per VNC nicht sinnfrei drehen. + +Für Menü, Buttons, Chat, Inventar und reines AFK auf einer Farm ist das ohne +Bedeutung. Wer wirklich remote *spielen* will, braucht ein anderes Protokoll +(Sunshine/Moonlight statt VNC) — das ist mit dieser Architektur nicht abgedeckt. + +[novnc1493]: https://github.com/novnc/noVNC/issues/1493 --- diff --git a/docker-compose.yml b/docker-compose.yml index 286f8a5..8594993 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: DISPLAY_REFRESH: ${DISPLAY_REFRESH:-60} DISPLAY_DEPTH: ${DISPLAY_DEPTH:-24} VNC_PASSWORD: ${VNC_PASSWORD:-} + X11VNC_EXTRA: ${X11VNC_EXTRA:--threads -pointer_mode 4 -norepeat -nodpms -nofbpm -nowf -nowcr} NOVNC_PATH: ${NOVNC_PATH:-} ports: diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 909b1ce..2519bb4 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -65,9 +65,22 @@ else VNC_PWFLAG="-nopw" fi +# Low-Latency-x11vnc-Optionen. Für Minecraft sind vor allem wichtig: +# -threads parallele Eingabe-/Ausgabe-Threads → weniger Lag +# -pointer_mode 4 flüssigere Mausübertragung (Default 1 ist träge) +# -norepeat Server-seite Tastaturwiederholung unterdrücken (sonst +# doppelte Auto-Repeat-Tasten im Spiel) +# -nocursorshape / -cursor none kein Cursor-Shape-Traffic (Cursor ist eh +# vom Spiel übermalt); -cursorX aber als sichtbarer Fallback +# -nodpms -nofbpm Energiesparen aus (sonst ruckelt es nach Leerlauf) +# -nowf -nowcr kein Wireframe/Rate-Limit beim Fensterziehen +# -noxdamage-suffix stabilereDamage-Erfassung +# Encoding/Qualität werden vom Client (noVNC) ausgehandelt, nicht hier erzwungen. +X11VNC_EXTRA="${X11VNC_EXTRA:--threads -pointer_mode 4 -norepeat -nodpms -nofbpm -nowf -nowcr}" + cat > /tmp/x11vnc.conf <(null) const iframeEl = ref(null) const iframeKey = ref(0) -// noVNC-URL: autoconnect=1, resize=scaling, Pfad zum websockify. +// noVNC-URL mit auf Steuerung/Spiele optimierten Parametern: +// resize=remote — passt die Xvfb-Auflösung an die Fenstergröße an +// (statt nur zu skalieren). Korrekte 1:1-Maus-Mapung, +// keine Unschärfe. Fällt auf 'scale' zurück, falls der +// Server kein Resize unterstützt. +// reconnect=1 — bei Verbindungsabbruch automatisch neu verbinden. +// path=websockify — noVNC spricht den WS-Endpunkt relativ an. +// show_dot=1 — lokalen Punkt-Cursor zeigen (Zielhilfe). +// view_only=0 — Eingabe explizit freischalten. +// clipboard=1 — Zwischenablage zwischen Browser und VM verknüpfen +// (wichtig für Login-Codes / Server-IPs kopieren). const novncUrl = computed(() => { const host = window.location.hostname - const port = window.location.port || String(window.location.port) + const port = window.location.port const params = new URLSearchParams({ autoconnect: '1', - resize: 'scaling', - // noVNC spricht relativ 'websockify' an → nginx mappt /websockify. + reconnect: '1', + resize: 'remote', path: 'websockify', - // show_dot_cursor hilft beim Zielen im VNC-Fenster. show_dot: '1', - // host/port für die Anzeige im noVNC-eigenen UI; iframe nutzt aber path. + view_only: '0', + clipboard: '1', host, port, }) @@ -47,6 +57,20 @@ function onIframeLoad() { state.value = 'connected' } +// Fokus in den iframe setzen, damit Tastatureingaben ans Spiel gehen. +// noVNC selbst fängt die Keys im iframe ab; wir müssen nur dorthin fokussieren. +function focusFrame() { + const el = iframeEl.value + if (!el) return + // Versuch, das innere Dokument zu fokussieren (gleiche Origin → erlaubt). + try { + el.contentWindow?.focus() + } catch { + /* Cross-Origin → iframe focus als Fallback */ + el.focus() + } +} + onMounted(() => { state.value = 'connecting' }) @@ -54,15 +78,17 @@ onMounted(() => {