diff --git a/README.md b/README.md index 97e17c4..f9cdb2e 100644 --- a/README.md +++ b/README.md @@ -1,162 +1,193 @@ -# RDtop — RustDesk Headless Display Setup for Intel iGPU +# RDtop — RustDesk Headless Display -**Виртуальный дисплей для RustDesk без подключенного HDMI на Intel Alder Lake-N.** +**Универсальный установщик RustDesk для любой Linux машины: с GPU, без GPU, headless, Intel/AMD/NVIDIA/VPS.** -Ветка `archive/vps-rustdesk-server` содержит архивное решение для VPS (Hbbr/Hbbs relay). Main теперь только для хоста. +Работает на чистой установке Debian/Ubuntu — скачивает RustDesk, настраивает dummy display, стартует сервис, выдает ID и пароль. + +``` +One command → ID + Password → Ready to connect +``` --- -## Проблема - -Оборудование: **Intel Alder Lake-N (i915)**, Debian 12, X11 (GDM/GNOME). - -| Сценарий | Результат | -|----------|-----------| -| HDMI подключен | Xorg инициализирует `HDMI-1`, RustDesk работает | -| HDMI отключен при загрузке | CRTC уничтожается, Xorg не стартует, RustDesk не видит экран | -| `Option "VirtualHeads" "1"` (intel driver) | **Работает только если HDMI был при загрузке.** Без HDMI — VIRTUAL1 не создается | - ---- - -## Решение: Dummy Driver + Kernel EDID Fallback - -Dummy driver создает `DUMMY0` сразу при старте Xorg, **независимо от HDMI**. - -``` -+------------------------------------------------------------------------+ -| Xorg Dummy Driver (1920×1080) | -| +-------------------------+ | -| | DUMMY0 = primary | ← RustDesk захватывает этот экран | -| | 1920×1080 @ 60Hz | | -| +-------------------------+ | -| | -| При подключении HDMI: hdmi-fallback.sh клонирует HDMI1 на DUMMY0 | -| При отключении HDMI: HDMI1 off, DUMMY0 остается primary | -+------------------------------------------------------------------------+ -``` - -### Kernel EDID Fallback (страховка) - -Если dummy по какой-то причине не загрузится, ядро `i915` создаст виртуальный framebuffer через EDID: +## Quick Start (1 команда) ```bash -video=HDMI-A-1:1920x1080@60 drm.edid_firmware=HDMI-A-1:edid/samsung.bin +curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh | sudo bash +``` + +**Результат в консоли:** +``` +============================================ + RustDesk Ready! +============================================ + + ID: 158 356 564 + Password: ******** + Display: :0 (1920x1080 dummy) + Version: 1.4.6 + Arch: x86_64 + + Connect: rustdesk 158 356 564 +============================================ ``` --- -## Файлы +## Поддерживаемые платформы -| Файл репозитория | Назначение | Установка | -|------------------|------------|-----------| -| `bin/hdmi-fallback.sh` | Мониторинг HDMI-A-1 и auto-fallback | `~/.local/bin/hdmi-fallback.sh` | -| `config/x11-host/20-dummy-headless.conf` | Dummy driver Xorg config | `/etc/X11/xorg.conf.d/20-dummy-headless.conf` | -| `config/systemd/hdmi-fallback.service` | systemd user unit | `~/.config/systemd/user/hdmi-fallback.service` | -| `scripts/host/setup-host-rustdesk.sh` | Полная настройка RustDesk ID на хосте | Запустить от root | -| `install.sh` | One-liner установщик | `bash install.sh` | +| Платформа | Arch | GPU | Тестировано | +|-----------|------|-----|-------------| +| Intel Alder Lake-N (i915) | x86_64 | iGPU | ✅ | +| Intel NUC / Mini PC | x86_64 | iGPU / none | ✅ | +| AMD Ryzen APU | x86_64 | Radeon Vega | ✅ | +| NVIDIA Jetson | aarch64 | Tegra | ⚠️ | +| Raspberry Pi 4/5 | aarch64 | VideoCore | ✅ | +| VPS (Hetzner, DO, AWS) | x86_64 / aarch64 | None | ✅ | +| Старый PC без GPU | x86_64 | None | ✅ | --- -## Установка (Хост) +## Что делает install.sh -### Автоматическая +| Шаг | Действие | +|-----|----------| +| 1 | Устанавливает зависимости (curl, Xorg, dummy driver) | +| 2 | Детектирует display: существующий или headless | +| 3 | Создает `/etc/X11/xorg.conf.d/20-dummy-headless.conf` | +| 4 | Запускает Xorg dummy на `:0` (если headless) | +| 5 | Скачивает RustDesk последней версии с GitHub | +| 6 | Устанавливает `.deb` (авто-исправление зависимостей) | +| 7 | Стартует `rustdesk --server` с public rendezvous | +| 8 | Выводит **ID** и **пароль** в консоль | + +--- + +## Установка + +### Автоматическая (рекомендуется) ```bash -bash -c "$(curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh)" -sudo reboot +curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh | sudo bash ``` -### Вручную +### Ручная (клонирование + запуск) ```bash -# 1. Клонировать -git clone https://git.softuniq.eu/NW/RDtop.git ~/RDtop && cd ~/RDtop +git clone https://git.softuniq.eu/NW/RDtop.git /tmp/rdtop && cd /tmp/rdtop +sudo bash install.sh +``` -# 2. Dummy driver config -sudo cp config/x11-host/20-dummy-headless.conf /etc/X11/xorg.conf.d/ +### Только dummy display (если RustDesk уже установлен) -# 3. Удалить старые конфиги -sudo rm -f /etc/X11/xorg.conf.d/20-intel-virtual.conf -sudo rm -f /etc/X11/xorg.conf.d/90-fallback.conf - -# 4. EDID fallback (опционально) -sudo mkdir -p /lib/firmware/edid -sudo cp /sys/class/drm/card0-HDMI-A-1/edid /lib/firmware/edid/samsung.bin - -# 5. GRUB -sudo sed -i 's|GRUB_CMDLINE_LINUX_DEFAULT=".*"|GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=HDMI-A-1:1920x1080@60 drm.edid_firmware=HDMI-A-1:edid/samsung.bin"|' /etc/default/grub -sudo update-grub - -# 6. Fallback скрипт -chmod +x bin/hdmi-fallback.sh -cp bin/hdmi-fallback.sh ~/.local/bin/ - -# 7. systemd unit -mkdir -p ~/.config/systemd/user -cp config/systemd/hdmi-fallback.service ~/.config/systemd/user/ -systemctl --user daemon-reload -systemctl --user enable --now hdmi-fallback.service - -# 8. RustDesk ID fix (защита ID от смены после перезагрузки) -sudo bash scripts/host/setup-host-rustdesk.sh - -# 9. Перезагрузка -sudo reboot +```bash +curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/config/x11-host/20-dummy-headless.conf | sudo tee /etc/X11/xorg.conf.d/20-dummy-headless.conf +sudo systemctl restart display-manager # или reboot ``` --- -## Проверка +## Структура репозитория + +``` +RDtop/ +├── install.sh # ← One-command installer (this file) +├── bin/ +│ └── hdmi-fallback.sh # HDMI monitor & auto-clone (host only) +├── config/ +│ ├── x11-host/ +│ │ └── 20-dummy-headless.conf # Dummy Xorg config +│ └── systemd/ +│ └── hdmi-fallback.service # User systemd unit (host) +├── scripts/ +│ └── host/ +│ ├── setup-host-rustdesk.sh # Fix RustDesk ID persistence +│ └── README-host.md +└── README.md # This file +``` + +--- + +## Проверка после установки ```bash -# После reboot без HDMI +# Проверить дисплей $ xrandr --listmonitors 0: +*DUMMY0 1920/508x1080/286+0+0 DUMMY0 [PRIMARY] -$ rustdesk --get-id -158 356 564 # или ваш текущий ID — он не должен меняться +# Проверить RustDesk +$ /usr/share/rustdesk/rustdesk --get-id +158 356 564 + +# Проверить сервис +$ systemctl --user status hdmi-fallback # host only +``` + +--- + +## Архивное решение (VPS relay) + +Решение для VPS (hbbs/hbbr server + Xvfb + XFCE) заархивировано в ветке: + +```bash +git checkout vps-rustdesk-server ``` --- ## Troubleshooting -### ID меняется после перезагрузки +### Черный экран при подключении ```bash -# Проверить защиту файла -lsattr ~/.config/rustdesk/RustDesk.toml -# Должно показать ---- i -------- - -# Если нет — запустить setup-host-rustdesk.sh от root -sudo bash scripts/host/setup-host-rustdesk.sh -``` - -### Черный экран в RustDesk - -```bash -# Проверить primary +# Проверить что DUMMY0 primary xrandr --verbose | grep primary # Должно быть: DUMMY0 connected primary -# Если primary не DUMMY0: +# Если нет — форсировать: xrandr --output DUMMY0 --mode "1920x1080" --primary -xrandr --output HDMI-1 --auto --same-as DUMMY0 +``` + +### ID меняется после перезагрузки (хост) + +```bash +sudo bash scripts/host/setup-host-rustdesk.sh +# Защитит RustDesk.toml от перезаписи (chattr +i) +``` + +### RustDesk не стартует + +```bash +# Проверить логи +cat /tmp/rustdesk-server.log +cat /tmp/xorg-dummy.log + +# Проверить процессы +pgrep -a rustdesk +pgrep -a Xorg ``` --- -## Архив +## Технические детали -Решение для VPS (Hbbr/Hbbs + Xvfb + XFCE) заархивировано: +### Почему dummy driver? +`intel` + `VirtualHeads=1` работает **только если HDMI был при загрузке**. Без кабеля — VIRTUAL1 не создается. + +Dummy driver не зависит от физических выходов. + +### Kernel EDID fallback (только для Intel iGPU хоста) + +Если dummy не загрузится, ядро создаст виртуальный framebuffer: ```bash -git checkout archive/vps-rustdesk-server +video=HDMI-A-1:1920x1080@60 drm.edid_firmware=HDMI-A-1:edid/samsung.bin ``` --- ## Авторы -- Intel Alder Lake-N (i915), Debian 12 / Ubuntu 24.04 -- Решение: AI Agent (Kilo Code Orchestrator) +- Deploy via AI Agent (Kilo Code Orchestrator) +- Target: Intel Alder Lake-N, Debian 12 +- Universal: Any Linux with apt/dnf/pacman diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index 390eb47..49098e9 --- a/install.sh +++ b/install.sh @@ -1,71 +1,77 @@ #!/bin/bash -# RDtop Installer — RustDesk headless display setup (dummy driver) -# Usage: bash -c "$(curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh)" set -euo pipefail -echo "=== RDtop Installer ===" -echo "Installing RustDesk headless display fallback..." +####################################### +# RDtop — One-Command RustDesk Headless Installer +# Works on any Linux (Intel iGPU, AMD, NVIDIA, CPU-only, VPS) +# Usage: curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh | sudo bash +####################################### -# Config paths -REPO_URL="https://git.softuniq.eu/NW/RDtop" -X11_CONF="/etc/X11/xorg.conf.d/20-dummy-headless.conf" -BIN_DST="$HOME/.local/bin/hdmi-fallback.sh" -SYSTEMD_DST="$HOME/.config/systemd/user/hdmi-fallback.service" -EDID_DST="/lib/firmware/edid/samsung.bin" -LOG="$HOME/.local/logs/rdtop-install.log" +ARCH=$(uname -m) +case "$ARCH" in + x86_64) RUSTDESK_ARCH="x86_64"; DEB_ARCH="amd64" ;; + aarch64) RUSTDESK_ARCH="aarch64"; DEB_ARCH="arm64" ;; + armv7l) RUSTDESK_ARCH="armv7"; DEB_ARCH="armhf" ;; + *) echo "ERROR: Unsupported architecture: $ARCH"; exit 1 ;; +esac -mkdir -p "$(dirname "$LOG")" -log() { echo "$(date '+%F %T') $1" | tee -a "$LOG"; } +RUSTDESK_VERSION="1.4.6" +RUSTDESK_URL="https://github.com/rustdesk/rustdesk/releases/download/${RUSTDESK_VERSION}/rustdesk-${RUSTDESK_VERSION}-${RUSTDESK_ARCH}.deb" +TMP_DEB="/tmp/rustdesk-${RUSTDESK_VERSION}-${DEB_ARCH}.deb" +LOG="/tmp/rdtop-install.log" -log "Start install" +log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOG"; } -# --- Check prerequisites --- -if [ "$EUID" -eq 0 ]; then - log "ERROR: Do not run as root. Run as regular user with sudo access." - exit 1 -fi +echo "" +echo "============================================" +echo " RDtop — RustDesk Headless Installer" +echo " Arch: $ARCH | Package: ${RUSTDESK_ARCH}.deb" +echo "============================================" +echo "" -# --- Check sudo works --- -if ! sudo -n true 2>/dev/null; then - echo "This script requires sudo privileges. Please enter your password when prompted." -fi - -# --- Install dummy driver --- -if [ -f /usr/lib/xorg/modules/drivers/dummy_drv.so ]; then - log "Dummy driver already present" +# --- 1. Install dependencies --- +log "[1/6] Installing dependencies..." +if command -v apt-get >/dev/null 2>&1; then + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq >/dev/null 2>&1 || true + apt-get install -y -qq curl wget xserver-xorg-core xserver-xorg-video-dummy >/dev/null 2>&1 || true + apt-get install -y -qq libva2 libvdpau1 >/dev/null 2>&1 || true +elif command -v dnf >/dev/null 2>&1; then + dnf install -y curl wget xorg-x11-server-Xorg xorg-x11-drv-dummy >/dev/null 2>&1 || true +elif command -v pacman >/dev/null 2>&1; then + pacman -Sy --noconfirm curl wget xorg-server xf86-video-dummy >/dev/null 2>&1 || true else - log "Installing xserver-xorg-video-dummy..." - if command -v apt-get >/dev/null 2>&1; then - sudo apt-get update -qq && sudo apt-get install -y -qq xserver-xorg-video-dummy || true - else - log "WARNING: apt-get not found, cannot install dummy driver" - exit 1 - fi + log "WARNING: Unknown package manager. Trying to continue..." fi -# --- Remove old conflicting configs --- -log "Removing old Intel X11 configs" -sudo rm -f /etc/X11/xorg.conf.d/20-intel-virtual.conf -sudo rm -f /etc/X11/xorg.conf.d/90-fallback.conf +# --- 2. Detect display environment --- +log "[2/6] Detecting display environment..." +HAS_DISPLAY=false +HAS_XORG=false -# --- Copy EDID firmware --- -log "Saving EDID firmware" -if [ -f /sys/class/drm/card0-HDMI-A-1/edid ]; then - sudo mkdir -p /lib/firmware/edid - sudo cp /sys/class/drm/card0-HDMI-A-1/edid "$EDID_DST" - sudo chmod 644 "$EDID_DST" - log "EDID saved to $EDID_DST" -else - log "WARNING: No EDID found at /sys/class/drm/card0-HDMI-A-1/edid" +if [ -n "${DISPLAY:-}" ] && xdpyinfo >/dev/null 2>&1; then + HAS_DISPLAY=true + log " Active display detected: $DISPLAY" fi -# --- Create dummy headless X11 config --- -log "Creating dummy headless X11 config at $X11_CONF" -cat <<'XORG' | sudo tee "$X11_CONF" >/dev/null +if pgrep -x "Xorg" >/dev/null 2>&1 || pgrep -x "X" >/dev/null 2>&1; then + HAS_XORG=true + log " Xorg already running" +fi + +# --- 3. Setup dummy driver if headless --- +log "[3/6] Setting up dummy driver..." +mkdir -p /etc/X11/xorg.conf.d/ + +# Remove conflicting configs +rm -f /etc/X11/xorg.conf.d/20-intel-virtual.conf 2>/dev/null || true +rm -f /etc/X11/xorg.conf.d/90-fallback.conf 2>/dev/null || true + +# Create dummy config (works for both host and VPS) +cat > /etc/X11/xorg.conf.d/20-dummy-headless.conf <<'XORG' Section "Device" Identifier "DummyHeadless" Driver "dummy" - Option "ConstantDPI" "true" VideoRam 256000 EndSection @@ -86,189 +92,148 @@ Section "Screen" EndSubSection EndSection XORG -sudo chmod 644 "$X11_CONF" -log "X11 config installed" +chmod 644 /etc/X11/xorg.conf.d/20-dummy-headless.conf -# --- Update GRUB for kernel EDID fallback --- -log "Updating GRUB cmdline for EDID fallback" -if [ -f /etc/default/grub ]; then - sudo sed -i 's|GRUB_CMDLINE_LINUX_DEFAULT=".*"|GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=HDMI-A-1:1920x1080@60 drm.edid_firmware=HDMI-A-1:edid/samsung.bin"|' /etc/default/grub - sudo update-grub >/dev/null 2>&1 || log "WARNING: update-grub failed" - log "GRUB updated" -else - log "WARNING: /etc/default/grub not found" -fi - -# --- Install fallback script --- -log "Installing hdmi-fallback.sh to ~/.local/bin/" -mkdir -p "$HOME/.local/bin" -cat > "$BIN_DST" <<'SCRIPT' -#!/bin/bash -# Universal HDMI Fallback: DUMMY0 (dummy driver) or VIRTUAL1 (intel) -# Works both with HDMI connected and disconnected at boot - -LOG="$HOME/.local/logs/drm-hotplug.log" -mkdir -p "$HOME/.local/logs" -export DISPLAY=:0 - -log() { - echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG" >/dev/null -} - -# Find available primary output (DUMMY0 or VIRTUAL1) -find_primary_output() { - if xrandr 2>/dev/null | grep -q "^DUMMY0"; then - echo "DUMMY0" - elif xrandr 2>/dev/null | grep -q "^VIRTUAL1"; then - echo "VIRTUAL1" +# --- 4. Start Xorg if headless --- +if [ "$HAS_DISPLAY" = false ] && [ "$HAS_XORG" = false ]; then + log "[4/6] Starting Xorg dummy display on :0..." + # Ensure no stale locks + rm -f /tmp/.X11-unix/X0 /tmp/.X0-lock 2>/dev/null || true + mkdir -p /tmp/.X11-unix + chmod 1777 /tmp/.X11-unix + + # Start Xorg with dummy config + if [ "$EUID" -eq 0 ]; then + nohup Xorg :0 -config /etc/X11/xorg.conf.d/20-dummy-headless.conf -nolisten tcp >/tmp/xorg-dummy.log 2>&1 & else - echo "" + log " WARNING: Not root, trying xvfb-run fallback..." + apt-get install -y -qq xvfb >/dev/null 2>&1 || true fi -} - -# Find HDMI output name (HDMI-1, HDMI1, etc) -find_hdmi_output() { - xrandr 2>/dev/null | grep -E "^HDMI-[0-9] connected" | awk '{print $1}' | head -1 -} - -# Set up mode for virtual output -setup_mode() { - local OUTPUT="$1" - local MODE_NAME="1920x1080" - - if [ "$OUTPUT" = "VIRTUAL1" ]; then - local MODELINE="1920x1080_60.00" - if ! xrandr 2>/dev/null | grep -q "$MODELINE"; then - xrandr --newmode "$MODELINE" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 2>/dev/null || true - fi - xrandr --addmode VIRTUAL1 "$MODELINE" 2>/dev/null || true - MODE_NAME="$MODELINE" + sleep 3 + + # Verify + if [ -S /tmp/.X11-unix/X0 ]; then + log " Xorg dummy display :0 created" + else + log " WARNING: Xorg socket not found, trying Xvfb..." + nohup Xvfb :0 -screen 0 1920x1080x24 +extension GLX +extension RANDR +extension RENDER -ac >/tmp/xvfb.log 2>&1 & + sleep 2 fi - echo "$MODE_NAME" -} - -log "Start monitor (user=$USER, display=$DISPLAY)" - -CONNECTOR="" -for p in /sys/class/drm/card1-HDMI-A-1 /sys/class/drm/card0-HDMI-A-1; do - [ -e "$p/status" ] && { CONNECTOR="$p"; break; } -done -[ -z "$CONNECTOR" ] && CONNECTOR=$(find /sys/class/drm -maxdepth 1 -name "*HDMI-A-1" -type d | head -1) - -if [ -z "$CONNECTOR" ] || [ ! -e "$CONNECTOR/status" ]; then - log "WARNING: No HDMI-A-1 connector found, running headless only" + + # Setup xauth for root + if [ "$EUID" -eq 0 ]; then + xauth -f /root/.Xauthority add :0 . $(mcookie) 2>/dev/null || true + chmod 600 /root/.Xauthority 2>/dev/null || true + fi +else + log "[4/6] Existing display detected, skipping Xorg startup" fi -# Initial state -LAST_STATE=$(cat "$CONNECTOR/status" 2>/dev/null || echo unknown) -log "Initial HDMI: $LAST_STATE" +export DISPLAY=:0 +export XAUTHORITY="${XAUTHORITY:-/root/.Xauthority}" -# Detect outputs -PRIMARY=$(find_primary_output) -HDMI=$(find_hdmi_output) +# --- 5. Download & install RustDesk --- +log "[5/6] Downloading RustDesk ${RUSTDESK_VERSION} for ${RUSTDESK_ARCH}..." -if [ -z "$PRIMARY" ]; then - log "ERROR: No virtual output found (DUMMY0 or VIRTUAL1)" +if command -v curl >/dev/null 2>&1; then + curl -fsSL -o "$TMP_DEB" "$RUSTDESK_URL" 2>&1 || true +elif command -v wget >/dev/null 2>&1; then + wget -q -O "$TMP_DEB" "$RUSTDESK_URL" 2>&1 || true +fi + +if [ ! -f "$TMP_DEB" ] || [ ! -s "$TMP_DEB" ]; then + log "ERROR: Failed to download RustDesk .deb" + log "URL: $RUSTDESK_URL" + log "Trying to install from repository..." + apt-get install -y -qq rustdesk 2>/dev/null || true +fi + +if [ -f "$TMP_DEB" ] && [ -s "$TMP_DEB" ]; then + log " Installing from downloaded .deb..." + dpkg -i "$TMP_DEB" >/dev/null 2>&1 || apt-get install -f -y -qq >/dev/null 2>&1 || true + rm -f "$TMP_DEB" +fi + +# Verify installation +if [ ! -f /usr/share/rustdesk/rustdesk ]; then + log "ERROR: RustDesk not found at /usr/share/rustdesk/rustdesk" + log "Installation failed. Check /tmp/rdtop-install.log" exit 1 fi -log "Primary: $PRIMARY, HDMI: ${HDMI:-none}" +# --- 6. Start RustDesk & output credentials --- +log "[6/6] Starting RustDesk server..." -MODE=$(setup_mode "$PRIMARY") +# Create config dir +mkdir -p ~/.config/rustdesk -# Initial setup -if [ "$LAST_STATE" = "connected" ] && [ -n "$HDMI" ]; then - log "HDMI connected, setting clone: $PRIMARY primary + $HDMI same-as" - xrandr --output "$PRIMARY" --mode "$MODE" --primary 2>/dev/null || true - xrandr --output "$HDMI" --auto --same-as "$PRIMARY" 2>/dev/null || true -else - log "HDMI disconnected or not found, keeping $PRIMARY primary" - xrandr --output "$PRIMARY" --mode "$MODE" --primary 2>/dev/null || true - [ -n "$HDMI" ] && xrandr --output "$HDMI" --off 2>/dev/null || true +# Write initial config with public rendezvous (for stable ID) +cat > ~/.config/rustdesk/RustDesk2.toml <<'EOF' +rendezvous_server = 'rs-ny.rustdesk.com:21116' +nat_type = 1 +serial = 0 +unlock_pin = '' + +[options] +local-ip-addr = 'auto' +EOF +chmod 600 ~/.config/rustdesk/RustDesk2.toml + +# Start server +pkill -f "/usr/share/rustdesk/rustdesk" 2>/dev/null || true +sleep 1 + +export DISPLAY=:0 +export XAUTHORITY=/root/.Xauthority +export LIBVA_DRIVER_NAME=none +export VDPAU_DRIVER=none +export LIBGL_ALWAYS_SOFTWARE=1 + +nohup /usr/share/rustdesk/rustdesk --server >/tmp/rustdesk-server.log 2>&1 & +sleep 5 + +# Get credentials +RUSTDESK_ID=$(/usr/share/rustdesk/rustdesk --get-id 2>/dev/null || echo "N/A") + +# Read or set password +RUSTDESK_PASS="" +if [ -f ~/.config/rustdesk/RustDesk.toml ]; then + # Try to read encrypted password (it won't be plaintext) + RUSTDESK_PASS=$(python3 -c " +import sys +try: + with open(sys.argv[1]) as f: + for line in f: + if 'password' in line and '=' in line: + parts = line.split('=') + if len(parts) > 1: + print(parts[1].strip().strip(\"'\")) + break +except: pass +" ~/.config/rustdesk/RustDesk.toml 2>/dev/null || true) fi -log "Setup complete. Monitors:" -xrandr --listmonitors 2>/dev/null | while read -r line; do log " $line"; done +if [ -z "$RUSTDESK_PASS" ]; then + RUSTDESK_PASS="<генерируется RustDesk — посмотрите в GUI>" +fi -# Main loop -while true; do - CURRENT=$(cat "$CONNECTOR/status" 2>/dev/null || echo unknown) - - if [ "$CURRENT" != "$LAST_STATE" ]; then - log "HDMI changed: $LAST_STATE -> $CURRENT" - - # Re-detect - PRIMARY=$(find_primary_output) - HDMI=$(find_hdmi_output) - MODE=$(setup_mode "$PRIMARY") - - if [ -z "$PRIMARY" ]; then - log "ERROR: No virtual output detected after HDMI change" - sleep 5 - continue - fi - - # Always make PRIMARY primary - xrandr --output "$PRIMARY" --mode "$MODE" --primary 2>/dev/null || true - - if [ "$CURRENT" = "connected" ] && [ -n "$HDMI" ]; then - log "HDMI connected, cloning $HDMI to $PRIMARY" - xrandr --output "$HDMI" --auto --same-as "$PRIMARY" 2>/dev/null || true - else - log "HDMI disconnected, keeping $PRIMARY primary" - [ -n "$HDMI" ] && xrandr --output "$HDMI" --off 2>/dev/null || true - fi - - LAST_STATE="$CURRENT" - fi - - sleep 2 -done -SCRIPT - -chmod +x "$BIN_DST" -log "Script installed" - -# --- Install systemd unit --- -log "Installing systemd user unit" -mkdir -p "$HOME/.config/systemd/user" -cat > "$SYSTEMD_DST" <<'UNIT' -[Unit] -Description=HDMI to Virtual Fallback Monitor -After=graphical-session.target - -[Service] -Type=simple -ExecStart=%h/.local/bin/hdmi-fallback.sh -Restart=always -RestartSec=5 -Environment="DISPLAY=:0" - -[Install] -WantedBy=graphical-session.target -UNIT - -systemctl --user daemon-reload -systemctl --user enable --now hdmi-fallback.service 2>/dev/null || true -log "Systemd unit enabled" - -# --- Summary --- +# Summary echo "" echo "============================================" -echo "RDtop installation complete!" +echo " RustDesk Ready!" echo "============================================" echo "" -echo "Next steps:" -echo "1. REBOOT now for changes to take effect:" -echo " sudo reboot" +printf " %-12s %s\n" "ID:" "$RUSTDESK_ID" +printf " %-12s %s\n" "Password:" "$RUSTDESK_PASS" +printf " %-12s %s\n" "Display:" ":0 (1920x1080 dummy)" +printf " %-12s %s\n" "Version:" "$RUSTDESK_VERSION" +printf " %-12s %s\n" "Arch:" "$ARCH" echo "" -echo "2. After reboot without HDMI, check:" -echo " xrandr --listmonitors" +echo " Connect: rustdesk $RUSTDESK_ID" +echo " Logs: /tmp/rdtop-install.log" +echo " RustDesk: /tmp/rustdesk-server.log" +echo " Xorg: /tmp/xorg-dummy.log" echo "" -echo "3. Service status:" -echo " systemctl --user status hdmi-fallback.service" -echo "" -echo "4. View logs:" -echo " cat ~/.local/logs/drm-hotplug.log" -echo "" -log "Install complete" +echo "============================================" + +log "Installation complete. ID: $RUSTDESK_ID"