From c0eb8abf85416ab81e1f95dd96a018d28a62db8c Mon Sep 17 00:00:00 2001 From: jenz Date: Fri, 28 Aug 2026 14:16:37 +0100 Subject: [PATCH] adding a prepare nosteamzip shell script that modifies the nosteam.zip to have the gameresmenu, autoexec, -vulkan parameter in rev.ini and latest dxvk version downloaded --- README.md | 5 +- prepare-nosteam.sh | 299 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 302 insertions(+), 2 deletions(-) create mode 100755 prepare-nosteam.sh diff --git a/README.md b/README.md index 02d3abe..9dac1b0 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ docker run -d --name css-test -e SIG_URL=ws://172.17.0.1:3000 -e CONTAINER_NAME= css-client +## prepare-nosteam.sh is ran manually to prepare the nosteam.zip for when the docker image has to be built. ## docker logs -f css-test ## pkill -f signaling-server.js @@ -63,8 +64,8 @@ css-client ## using MESA_SHADER_CACHE which are mounted volumes -## the inbuilt DXVK version 2.3 is replaced with DXVK 3.0 downloaded from https://github.com/doitsujin/dxvk/releases/download/v3.0/dxvk-3.0.tar.gz -## docker cp dxvk-3.0/x64/d3d9.dll 'css-test:/home/ubuntu/Counter-Strike Source/bin/x64/dxvk_d3d9.dll' #probably was like this to copy it in. +## the inbuilt DXVK version 2.3 is replaced with DXVK downloaded from https://github.com/doitsujin/dxvk/releases +## this is done through the prepare-nosteam.sh ## relies on nosteam_celt plugin for receiving the name correctly. -> https://git.unloze.com/UNLOZE/sm-plugins/src/branch/master/CELT_VOICE diff --git a/prepare-nosteam.sh b/prepare-nosteam.sh new file mode 100755 index 0000000..01096b6 --- /dev/null +++ b/prepare-nosteam.sh @@ -0,0 +1,299 @@ +#!/bin/bash +# +# prepare-nosteam.sh +# +# Run this OUTSIDE the docker container, by hand, against a freshly +# downloaded/updated nosteam.zip, every time the game itself updates (i.e. +# every time you refresh cstrike/, bin/, platform/, steam.dll, +# steamclient.dll, steamclient64.dll, hl2/ per the README checklist). +# +# A fresh game update silently wipes out several project-specific +# customizations that live inside those same replaced folders/files. This +# script re-applies all of them in one pass, so nosteam.zip is fully ready +# to bake into the Docker image without relying on memory to redo several +# easy-to-forget manual steps — exactly the class of bug that let DXVK 3.0 +# and rev.ini's -vulkan flag silently regress back to defaults. +# +# What this script does: +# 1. rev.ini — ensures -vulkan is present on the ProcName line +# 2. DXVK — downloads the LATEST DXVK release (not pinned to any +# specific version) and replaces both the 64-bit and +# 32-bit dxvk_d3d9.dll +# 3. GameMenu.res — restores our reduced custom menu (Resume Game + the +# 4 UNLOZE server connect buttons), which lives inside +# cstrike/ and gets wiped by every game update +# 4. autoexec.cfg — restores performance/graphics tuning, console lockdown, +# scroll-wheel jump bind, and the console-injection +# lockdown aliases (retry deliberately excluded — see +# comment in the generated file) +# +# Usage: ./prepare-nosteam.sh /path/to/nosteam.zip +# +# Overwrites nosteam.zip IN PLACE (a backup is assumed to exist elsewhere). +# Review the printed output for any WARNING lines before using it in the +# Docker build. + +set -euo pipefail + +ZIP_PATH="${1:?Usage: $0 /path/to/nosteam.zip}" + +if [ ! -f "$ZIP_PATH" ]; then + echo "ERROR: $ZIP_PATH does not exist" >&2 + exit 1 +fi + +ZIP_PATH_ABS=$(cd "$(dirname "$ZIP_PATH")" && pwd)/$(basename "$ZIP_PATH") + +WORKDIR=$(mktemp -d) +trap 'rm -rf "$WORKDIR"' EXIT + +echo "Extracting $ZIP_PATH_ABS..." +unzip -q "$ZIP_PATH_ABS" -d "$WORKDIR" + +GAME_ROOT="$WORKDIR/Counter-Strike Source" +if [ ! -d "$GAME_ROOT" ]; then + echo "ERROR: expected 'Counter-Strike Source' folder not found inside the zip" >&2 + echo " (found: $(ls "$WORKDIR"))" >&2 + exit 1 +fi + +# ── 1. rev.ini: ensure -vulkan launch parameter ────────────────────────────── +# Uses Python operating on the raw file bytes rather than sed — rev.ini has +# Windows-style CRLF line endings, and two earlier sed-based attempts here +# both mishandled embedded/stray \r characters in different ways, corrupting +# the ProcName line. This version is fully idempotent and self-correcting: +# it strips any \r and any existing -vulkan occurrence(s) from the matched +# span (using a lookahead for the TRUE \r?\n line ending, so it can't stop +# early on a stray embedded \r the way earlier attempts did), then cleanly +# re-adds -vulkan exactly once — producing the same correct result whether +# the line was already correct, missing -vulkan, or corrupted from a prior +# buggy run. +REV_INI="$GAME_ROOT/rev.ini" +if [ -f "$REV_INI" ]; then + if grep -q "^ProcName=" "$REV_INI"; then + python3 - "$REV_INI" << 'PYEOF' +import sys, re + +path = sys.argv[1] +with open(path, 'rb') as f: + content = f.read() + +def fix_line(match): + line = match.group(0) + line = line.replace(b'\r', b'') + line = re.sub(rb'\s*-vulkan\s*', b'', line) + return line + b' -vulkan' + +new_content, n = re.subn( + rb'ProcName=cstrike_win64\.exe.*?(?=\r?\n)', + fix_line, + content +) + +if n == 0: + print("WARNING: no ProcName=cstrike_win64.exe line found", file=sys.stderr) + sys.exit(1) + +with open(path, 'wb') as f: + f.write(new_content) +PYEOF + echo "[rev.ini] ProcName line normalized with -vulkan" + else + echo "WARNING: [rev.ini] no ProcName= line found — check manually" >&2 + fi +else + echo "WARNING: [rev.ini] file not found in zip — check manually" >&2 +fi + +# ── 2. DXVK: download the LATEST release, replace both x64 and x32 DLLs ───── +echo "[DXVK] Checking latest release..." +DXVK_URL=$(curl -s https://api.github.com/repos/doitsujin/dxvk/releases/latest \ + | grep '"browser_download_url"' \ + | grep -o 'https://[^"]*\.tar\.gz' \ + | head -1) + +if [ -z "$DXVK_URL" ]; then + echo "ERROR: [DXVK] could not determine latest release download URL — check network/GitHub API rate limits" >&2 + exit 1 +fi + +DXVK_VERSION=$(basename "$DXVK_URL" .tar.gz) +echo "[DXVK] Latest release: $DXVK_VERSION" +echo "[DXVK] Downloading $DXVK_URL ..." +curl -sL "$DXVK_URL" -o "$WORKDIR/dxvk.tar.gz" +tar -xzf "$WORKDIR/dxvk.tar.gz" -C "$WORKDIR" + +DXVK_DIR=$(find "$WORKDIR" -maxdepth 1 -type d -name "dxvk-*" | head -1) +if [ -z "$DXVK_DIR" ]; then + echo "ERROR: [DXVK] extracted DXVK folder not found after download" >&2 + exit 1 +fi + +if [ -f "$DXVK_DIR/x64/d3d9.dll" ]; then + cp "$DXVK_DIR/x64/d3d9.dll" "$GAME_ROOT/bin/x64/dxvk_d3d9.dll" + echo "[DXVK] Replaced bin/x64/dxvk_d3d9.dll with $DXVK_VERSION" +else + echo "WARNING: [DXVK] x64/d3d9.dll not found in release archive — 64-bit DLL NOT replaced, check manually" >&2 +fi + +if [ -f "$DXVK_DIR/x32/d3d9.dll" ]; then + cp "$DXVK_DIR/x32/d3d9.dll" "$GAME_ROOT/bin/dxvk_d3d9.dll" + echo "[DXVK] Replaced bin/dxvk_d3d9.dll (32-bit) with $DXVK_VERSION" +else + echo "WARNING: [DXVK] x32/d3d9.dll not found in release archive — 32-bit DLL NOT replaced, check manually" >&2 +fi + +# ── 3. Restore custom GameMenu.res ─────────────────────────────────────────── +# This lives inside cstrike/, which is wholesale replaced by every game +# update per the README checklist — silently wiping our reduced menu +# (Resume Game + the 4 UNLOZE server connect buttons) back to whatever a +# stock nosteam distribution ships. Embedded directly here so this script +# is self-contained and can't drift out of sync with a separate file. +GAMEMENU_TARGET="$GAME_ROOT/cstrike/custom/customnosteam/resource/GameMenu.res" +mkdir -p "$(dirname "$GAMEMENU_TARGET")" +cat > "$GAMEMENU_TARGET" << 'GAMEMENU_EOF' +"GameMenu" +{ + "1" + { + "label" "#GameUI_GameMenu_ResumeGame" + "command" "ResumeGame" + "onlyInGame" "1" + } + "2" + { + "label" "UNLOZE | ZombieEscape" + "command" "engine connect ze.unloze.com:27015" + } + "3" + { + "label" "UNLOZE | ZombieEscape2" + "command" "engine connect ze.unloze.com:27035" + } + "4" + { + "label" "UNLOZE | Minigames" + "command" "engine connect mg.unloze.com:27017" + } + "5" + { + "label" "UNLOZE | ZombieRiot" + "command" "engine connect zr.unloze.com:27016" + } +} +GAMEMENU_EOF +echo "[GameMenu.res] Restored custom menu (Resume + 4 UNLOZE server buttons)" + +# ── 4. Restore autoexec.cfg ────────────────────────────────────────────────── +# Lives inside cstrike/cfg/, so it's wiped the same way as GameMenu.res on +# every game update. Contains our performance/graphics tuning, console +# lockdown (con_enable 0 + blanked toggleconsole/showconsole/hideconsole +# aliases), scroll-wheel jump bind, and the default server connect. +AUTOEXEC_TARGET="$GAME_ROOT/cstrike/cfg/autoexec.cfg" +mkdir -p "$(dirname "$AUTOEXEC_TARGET")" +cat > "$AUTOEXEC_TARGET" << 'AUTOEXEC_EOF' +// Performance +fps_max 65 +cl_updaterate 20 +cl_cmdrate 20 +rate 25000 +mat_setvideomode 800 600 0 +cl_showpos 1 +voice_overdrive 8 +net_graph 1 +// Graphics - lowest possible +r_shadows 0 +r_shadow_culling 0 +r_shadowrendertotexture 0 +r_flashlightdepthtexture 0 +r_decals 0 +r_drawdetailprops 0 +r_staticproplod 2 +r_waterforcereflectentities 0 +r_waterforceexpensive 0 +r_cheapwaterstart 0 +r_cheapwaterend 0 +r_ambientboost 0 +r_ambientfactor 0 +r_ambientmin 0 +mp_decals 0 +props_break_max_pieces 0 +// Particles and effects +r_drawflecks 0 +cl_show_splashes 0 +tracer_extra 0 +// Sound minimal +snd_mixahead 0.1 +snd_async_fullyasync 1 +// Network +cl_interp 0.1 +cl_interp_ratio 2 +// Misc +mat_queue_mode 0 +mat_reducefillrate 1 +mat_picmip 2 +mat_mipmaptextures 0 +mat_bumpmap 0 +mat_specular 0 +mat_hdr_level 0 +mat_antialias 0 +mat_trilinear 0 +mat_vsync 0 +contimes 0 +con_enable 0 +contimes 0 +alias toggleconsole "" +alias showconsole "" +alias hideconsole "" +// Key bindings +bind "v" "+duck" +bind "MWHEELUP" "+jump" +bind "MWHEELDOWN" "+jump" +unbind "`" +connect 51.195.188.106:27015 + +// ── Console-injection lockdown ─────────────────────────────────────────── +// Neutralizes client-side commands that a ";" injected via chat could +// otherwise trigger (e.g. someone pastes ";disconnect" or ";map de_dust2" +// into chat, which the engine parses as a second command). Placed at the +// END of this file — everything above (the connect line, the key binds) +// must run once BEFORE these are neutralized, or they'd break too. +// +// IMPORTANT: "retry" is deliberately NOT blocked. The webclient's own +// controller-handoff/identity system depends on the SourceMod plugin +// issuing ClientCommand(client, "retry") to force a reconnect with a new +// IP whenever control changes hands — blocking it here would break that +// mechanism entirely. +alias "disconnect" "" +alias "connect" "" +alias "quit" "" +alias "exit" "" +alias "map" "" +alias "exec" "" +alias "execifexists" "" +alias "rcon" "" +alias "rcon_password" "" +alias "maxplayers" "" +alias "deathmatch" "" +alias "addip" "" +alias "removeip" "" +alias "listip" "" +alias "banip" "" +alias "changelevel" "" +alias "changelevel2" "" +alias "restart" "" +alias "bind" "" +alias "unbind" "" +alias "unbindall" "" +alias "bindtoggle" "" +AUTOEXEC_EOF +echo "[autoexec.cfg] Restored" + +# ── 5. Repack the zip ───────────────────────────────────────────────────────── +echo "Repacking to $ZIP_PATH_ABS (overwriting original — confirmed a backup exists elsewhere)..." +rm -f "$ZIP_PATH_ABS" +( cd "$WORKDIR" && zip -qr "$ZIP_PATH_ABS" "Counter-Strike Source" ) + +echo "" +echo "Done. Updated in place: $ZIP_PATH_ABS" +echo "Review any WARNING lines above before using this zip in the Docker build."