#!/bin/bash set -euo pipefail # ── Clean up stale sockets from previous run ────────────────────────────────── rm -f /tmp/.X99-lock rm -f /tmp/.X11-unix/X99 rm -rf /tmp/weston-runtime # ── XDG runtime dir (required by Weston and PipeWire) ──────────────────────── export XDG_RUNTIME_DIR=/tmp/weston-runtime mkdir -p "$XDG_RUNTIME_DIR" chmod 700 "$XDG_RUNTIME_DIR" # ── D-Bus session bus (required by PipeWire / wireplumber) ─────────────────── eval $(dbus-launch --sh-syntax) export DBUS_SESSION_BUS_ADDRESS # ── Wine virtual desktop matching Weston size ──────────────────────────────── wine reg add "HKCU\\Software\\Wine\\Explorer" /v "Desktop" /t REG_SZ /d "Default" /f wine reg add "HKCU\\Software\\Wine\\Explorer\\Desktops" /v "Default" /t REG_SZ /d "800x600" /f wine reg add "HKCU\\Software\\Valve\\Source\\cstrike\\Settings" /v ScreenWidth /t REG_DWORD /d 800 /f wine reg add "HKCU\\Software\\Valve\\Source\\cstrike\\Settings" /v ScreenHeight /t REG_DWORD /d 600 /f wine reg add "HKCU\\Software\\Wine\\WineDbg" /v ShowCrashDialog /t REG_DWORD /d 0 /f export DXVK_CUSTOM_DISPLAY_MODES="800x600@60" # ── Start Weston (headless Wayland compositor) ──────────────────────────────── weston --backend=headless-backend.so --width=800 --height=600 --no-config & sleep 2 export WAYLAND_DISPLAY=$(ls "$XDG_RUNTIME_DIR/" | grep -o 'wayland-[0-9]*' | head -1) echo "Using WAYLAND_DISPLAY=$WAYLAND_DISPLAY" # ── Start Xwayland (X11 compatibility layer over Wayland) ──────────────────── # -geometry fixes the virtual framebuffer at exactly 800x600 from the start, # matching Weston's headless output — no xrandr mode-adding needed. Xwayland :99 -glamor off -shm -geometry 800x600 & for i in $(seq 1 20); do DISPLAY=:99 xdpyinfo > /dev/null 2>&1 && echo "Xwayland ready" && break echo "Waiting for Xwayland... attempt $i" sleep 1 done export DISPLAY=:99 echo "xrandr result: $(DISPLAY=:99 xrandr | grep '*')" # ── Start PipeWire stack ────────────────────────────────────────────────────── export PULSE_RUNTIME_PATH="$XDG_RUNTIME_DIR/pulse" rm -rf "$PULSE_RUNTIME_PATH" pipewire & sleep 1 wireplumber & sleep 1 pipewire-pulse & # Wait for the PulseAudio-compatible socket for i in $(seq 1 30); do pactl info > /dev/null 2>&1 && echo "PipeWire-Pulse ready" && break echo "Waiting for PipeWire-Pulse... attempt $i" sleep 1 done export PULSE_SERVER="unix:${PULSE_RUNTIME_PATH}/native" # Virtual microphone — use || true so a pre-existing module doesn't abort # the script (set -e is active). The "Failure: No such entity" in the old # logs was module-virtual-source failing; under PipeWire-Pulse we use # module-null-sink + module-remap-source which is better supported. pactl load-module module-null-sink sink_name=mic_sink sink_properties=device.description=mic_sink || true pactl load-module module-remap-source source_name=virtual_mic master=mic_sink.monitor || true pactl set-default-source virtual_mic || true # ── Launch CSS ──────────────────────────────────────────────────────────────── wine ~/Counter-Strike\ Source/revLoader.exe & for i in $(seq 1 60); do WIN=$(DISPLAY=:99 xdotool search --name "" 2>/dev/null | head -1) [ -n "$WIN" ] && echo "CSS window found: $WIN" && break echo "Waiting for CSS window... attempt $i" sleep 1 done sleep 3 # ── Start streaming agent ───────────────────────────────────────────────────── python3 ~/streaming-agent/gst_agent.py