diff --git a/.gitignore b/.gitignore index aadbaed..dff0f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ wine_user_folder.zip streaming-agent/package-lock.json signaling.log streaming-agent/node_modules/ +dxvk-cache diff --git a/Dockerfile b/Dockerfile index f525567..2ca8e36 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,40 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive -ENV DISPLAY=:99 +# Install unzip first so we can extract the large static zips +RUN apt-get update && apt-get install -y unzip && rm -rf /var/lib/apt/lists/* + +# Create user +RUN useradd -m -s /bin/bash ubuntu + +# Copy and extract large static files first +COPY nosteam.zip /home/ubuntu/ +COPY wine_user_folder.zip /home/ubuntu/ +RUN cd /home/ubuntu && unzip nosteam.zip && rm nosteam.zip && unzip wine_user_folder.zip && rm wine_user_folder.zip + +# Install all packages RUN dpkg --add-architecture i386 && \ apt-get update && \ apt-get install -y \ - wine \ + wget \ + gnupg2 \ + ca-certificates \ + && mkdir -pm755 /etc/apt/keyrings \ + && wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key \ + && echo "deb [signed-by=/etc/apt/keyrings/winehq-archive.key] https://dl.winehq.org/wine-builds/ubuntu/ jammy main" > /etc/apt/sources.list.d/winehq.list \ + && apt-get update \ + && apt-get install -y --install-recommends winehq-stable \ + && apt-get install -y \ winetricks \ - xvfb \ + weston \ + xwayland \ pulseaudio \ - unzip \ - ffmpeg \ pulseaudio-utils \ + ffmpeg \ xdotool \ nodejs \ npm \ - matchbox-window-manager \ + mesa-vulkan-drivers \ gstreamer1.0-tools \ gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good \ @@ -29,18 +48,19 @@ RUN dpkg --add-architecture i386 && \ python3-pip \ && rm -rf /var/lib/apt/lists/* -RUN useradd -m -s /bin/bash ubuntu -COPY nosteam.zip /home/ubuntu/ -COPY wine_user_folder.zip /home/ubuntu/ +# Environment variables +ENV VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/lvp_icd.x86_64.json" +ENV XDG_RUNTIME_DIR=/tmp/weston-runtime +ENV WAYLAND_DISPLAY=wayland-0 +ENV DISPLAY=:99 + +# Copy frequently changing files last COPY start.sh /home/ubuntu/start.sh COPY streaming-agent/ /home/ubuntu/streaming-agent/ - -RUN cd /home/ubuntu && unzip nosteam.zip && rm nosteam.zip && unzip wine_user_folder.zip && rm wine_user_folder.zip RUN cd /home/ubuntu/streaming-agent && npm install RUN pip3 install -r /home/ubuntu/streaming-agent/requirements.txt RUN chown -R ubuntu:ubuntu /home/ubuntu/ RUN chmod +x /home/ubuntu/start.sh - USER ubuntu WORKDIR /home/ubuntu CMD ["/bin/bash", "/home/ubuntu/start.sh"] diff --git a/README.md b/README.md index bbc49f1..b1626ad 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # notes -### uses gstreamer, xvfb, a signaling server, html, docker and cloudflare serverless SFU. +### uses gstreamer, weston, lavapipe, css inbuilt DXVK, vulkan, a signaling server, html, docker and cloudflare serverless SFU. docker rm css-test docker build -t css-client . @@ -11,11 +11,14 @@ docker build -t css-client . ## pre installment step for signaling-server cd ~/webclient_css_ze/streaming-agent && npm install +## pre shader creation for mounting +touch /home/gameservers/webclient_css_ze/dxvk-cache + ## first run ./start-signaling.sh ## second run -docker run -d --name css-test -e SIG_URL=ws://172.17.0.1:3000 -e CONTAINER_NAME=css-test -e CF_APP_ID= -e CF_APP_TOKEN= -e CAP_FPS=60 -e CAP_W=800 -e CAP_H=600 --cpus="8.0" -v /home/gameservers/css_ze/cstrike/maps:/home/ubuntu/Counter-Strike\ Source/cstrike/maps:ro -v /home/gameservers/css_ze/cstrike/materials:/home/ubuntu/Counter-Strike\ Source/cstrike/materials:ro -v /home/gameservers/css_ze/cstrike/models:/home/ubuntu/Counter-Strike\ Source/cstrike/models:ro -v /home/gameservers/css_ze/cstrike/sound:/home/ubuntu/Counter-Strike\ Source/cstrike/sound:ro css-client +docker run -d --name css-test -e SIG_URL=ws://172.17.0.1:3000 -e CONTAINER_NAME=css-test -e CF_APP_ID= -e CF_APP_TOKEN= -e CAP_FPS=60 -e CAP_W=800 -e CAP_H=600 --cpus="8.0" -v /home/gameservers/css_ze/cstrike/maps:/home/ubuntu/Counter-Strike\ Source/cstrike/maps:ro -v /home/gameservers/css_ze/cstrike/materials:/home/ubuntu/Counter-Strike\ Source/cstrike/materials:ro -v /home/gameservers/css_ze/cstrike/models:/home/ubuntu/Counter-Strike\ Source/cstrike/models:ro -v /home/gameservers/css_ze/cstrike/sound:/home/ubuntu/Counter-Strike\ Source/cstrike/sound:ro -v /home/gameservers/webclient_css_ze/dxvk-cache:/home/ubuntu/Counter-Strike\ Source/cstrike_win64.dxvk-cache css-client ## docker logs -f css-test ## pkill -f signaling-server.js @@ -23,9 +26,13 @@ docker run -d --name css-test -e SIG_URL=ws://172.17.0.1:3000 -e CONTAINER_NAME= ## to change screen resolution: ### autoexec.cfg -> mat_setvideomode 800 600 0 -### start.sh -> Xvfb :99 -screen 0 800x600x24 & +### start.sh -> weston --backend=headless-backend.so --width=800 --height=600 --no-config & -## the nosteam.zip is 4.7GB and the wine_user_folder.zip is 420MB, they are not intended to be uploaded to git generally. -## the wine_user_folder.zip is just the generic .wine folder that would be created. the nosteam.zip is the Counter Strike Source folder for nosteam when using 7launcher. +## the nosteam.zip and the wine_user_folder.zip are not intended to be uploaded to git. +## the wine_user_folder.zip is just the generic .wine folder that is used. the nosteam.zip is the Counter Strike Source folder for nosteam when using 7launcher. ## However both are uploaded to the unloze fastdownload over at: https://uk-fastdl.unloze.com/css_ze/webclient_zips/ ## of course if you view this repository 7-10 years later in the future theres a good chance the url is probably not working any longer. + +## the client launches the game with -vulkan parameter specified in the rev.ini. + +## CSS DirectX9 → built-in DXVK → Vulkan → Wine Wayland driver → Weston (lavapipe/llvmpipe) → Xwayland → X11 → ximagesrc capture for gst_agent diff --git a/start.sh b/start.sh index f04e089..df29b09 100755 --- a/start.sh +++ b/start.sh @@ -1,23 +1,31 @@ #!/bin/bash -# Clean up any leftover Xvfb lock files +# Clean up stale sockets from previous run rm -f /tmp/.X99-lock rm -f /tmp/.X11-unix/X99 - -# Clean up stale PulseAudio sockets from previous run rm -rf /tmp/pulse-* rm -f /run/user/$(id -u)/pulse/native +rm -rf /tmp/weston-runtime -wine reg add "HKCU\\Software\\Wine\\WineDbg" /v ShowCrashDialog /t REG_DWORD /d 0 /f +# Set up Weston runtime directory +export XDG_RUNTIME_DIR=/tmp/weston-runtime +mkdir -p $XDG_RUNTIME_DIR +chmod 700 $XDG_RUNTIME_DIR -Xvfb :99 -screen 0 800x600x24 & +# Start Weston in headless mode (handles Vulkan/DXVK rendering) +weston --backend=headless-backend.so --width=800 --height=600 --no-config & +sleep 2 +export WAYLAND_DISPLAY=wayland-0 + +# Start Xwayland — bridges Weston Wayland to X11 for ximagesrc capture +Xwayland :99 & sleep 1 export DISPLAY=:99 -matchbox-window-manager -use_titlebar no & -sleep 1 +# Suppress Wine crash dialog +wine reg add "HKCU\\Software\\Wine\\WineDbg" /v ShowCrashDialog /t REG_DWORD /d 0 /f + +# Start PulseAudio for game audio pulseaudio --start --exit-idle-time=-1 - -# Wait for PulseAudio to be ready with retries for i in $(seq 1 10); do pactl info > /dev/null 2>&1 && break echo "Waiting for PulseAudio... attempt $i" @@ -29,6 +37,8 @@ pactl load-module module-null-sink sink_name=mic_sink pactl load-module module-virtual-source source_name=virtual_mic master=mic_sink.monitor pactl set-default-source virtual_mic +# Launch CSS — Wine uses Wayland driver for rendering via Weston/Vulkan wine ~/Counter-Strike\ Source/revLoader.exe & sleep 5 + python3 ~/streaming-agent/gst_agent.py diff --git a/streaming-agent/gst_agent.py b/streaming-agent/gst_agent.py index 98bbbea..3a212f0 100755 --- a/streaming-agent/gst_agent.py +++ b/streaming-agent/gst_agent.py @@ -3,12 +3,15 @@ GStreamer WebRTC Agent for CSS Streaming Two tracks published to Cloudflare Calls: - - Video: ximagesrc → VP8 → webrtcbin - - Game audio: pulsesrc → Opus → webrtcbin + - Video: ximagesrc (Xwayland :99) → VP8 → webrtcbin + - Game audio: pulsesrc → Opus → webrtcbin + +CSS renders via Wine Wayland driver → Weston (Vulkan/DXVK) → Xwayland → X11 +ximagesrc captures from Xwayland X11 display :99 Dependencies: apt: python3-gst-1.0 gstreamer1.0-plugins-bad gstreamer1.0-plugins-good - gstreamer1.0-plugins-ugly gstreamer1.0-libav xdotool + gstreamer1.0-plugins-ugly gstreamer1.0-libav xdotool weston xwayland pip: requests websockets """ @@ -106,7 +109,7 @@ class CSSStreamAgent: def build_pipeline(self): pipeline_str = ( - # Video: ximagesrc → VP8 + # Video: ximagesrc from Xwayland display → VP8 f'ximagesrc display-name={DISPLAY} use-damage=0 ! ' f'video/x-raw,framerate={CAP_FPS}/1,width={CAP_W},height={CAP_H} ! ' f'videoconvert ! ' @@ -130,7 +133,7 @@ class CSSStreamAgent: f'stun-server=stun://stun.cloudflare.com:3478' ) - log.info(f'Building pipeline {CAP_W}x{CAP_H}@{CAP_FPS}fps') + log.info(f'Building pipeline {CAP_W}x{CAP_H}@{CAP_FPS}fps via Xwayland') self.pipeline = Gst.parse_launch(pipeline_str) self.webrtcbin = self.pipeline.get_by_name('webrtcbin')