openvibers/source.openvibe.games Commits
Continuing phase...
Changes
BBinary files a/.tmp/quickjs-smoke/smoke-quickjs and b/.tmp/quickjs-smoke/smoke-quickjs differ@@@ -1,3 +1,20 @@++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++/** QuickJS Javascript Engine*@@@ -53,6 +53,8 @@ copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \"$SDK/src/game/shared/openvibe/third_party/quickjs"++"$ROOT/tools/build-quickjs-lib.sh"++QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; thentmp="$(mktemp)"@@@ -88,13 +90,7 @@ perl -0pi -e 's/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;-- s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;-- s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;++ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n/s;' "$SERVER_VPC"echo "[openvibe-sdk] patched server_hl2mp.vpc"@@@ -170,4 +166,69 @@ p.write_text(s)PYfi++++# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH++patch_openvibe_quickjs_after_apply() {++ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"++ local qjs_c="$qjs_dir/quickjs.c"++++ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then++ local tmp++ tmp="$(mktemp)"++ cat > "$tmp" <<'QJS_SHIM'++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++++QJS_SHIM++ cat "$qjs_c" >> "$tmp"++ mv "$tmp" "$qjs_c"++ echo "[openvibe-sdk] patched QuickJS strict-C shim"++ fi++++ if [[ ! -f "$qjs_dir/libbf.c" ]]; then++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true++ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"++ fi++}++++patch_openvibe_quickjs_after_apply++echo "[openvibe-sdk] Source SDK OpenVibe patch applied"++++++# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.++if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ echo "[openvibe-sdk] linked QuickJS static library"++fi++++++# OPENVIBE_REMOVE_DIRECT_QUICKJS_C++if [[ -f "$SERVER_VPC" ]]; then++ perl -0pi -e '++ s/^.*quickjs\\quickjs\.c.*\n//mg;++ s/^.*quickjs\\libregexp\.c.*\n//mg;++ s/^.*quickjs\\libunicode\.c.*\n//mg;++ s/^.*quickjs\\cutils\.c.*\n//mg;++ s/^.*quickjs\\dtoa\.c.*\n//mg;++ s/^.*quickjs\\libbf\.c.*\n//mg;++ ' "$SERVER_VPC"++++ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ fi++finnew file mode 100755@@@ -0,0 +1,173 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then++ echo "Source SDK 2013 checkout not found at $SDK" >&2++ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2++ exit 1++fi++++copy_file() {++ local src="$1"++ local dst="$2"++ install -D -m 0644 "$src" "$dst"++ echo "[openvibe-sdk] copied ${dst#$SDK/}"++}++++copy_tree() {++ local src="$1"++ local dst="$2"++ mkdir -p "$dst"++ rsync -a --delete "$src/" "$dst/"++ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"++}++++copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \++ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"++copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \++ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"++++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \++ "$SDK/src/game/shared/openvibe/ov_js_player.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"++++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"++++copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \++ "$SDK/src/game/shared/openvibe/third_party/quickjs"++++QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"++if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then++ tmp="$(mktemp)"++ cat > "$tmp" <<'QCFG'++#ifndef OPENVIBE_QUICKJS_CONFIG++#define OPENVIBE_QUICKJS_CONFIG++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++#endif++++QCFG++ cat "$QJS_C" >> "$tmp"++ mv "$tmp" "$QJS_C"++fi++++CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"++SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"++HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"++GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"++HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"++++perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"++echo "[openvibe-sdk] patched client_hl2mp.vpc"++++perl -0pi -e '++ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;++ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;++ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;++' "$SERVER_VPC"++echo "[openvibe-sdk] patched server_hl2mp.vpc"++++if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"++ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"++ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"++fi++++perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"++++if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then++ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"++fi++++perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"++++if [[ -f "$GAMEINTERFACE" ]]; then++ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then++ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"++ fi++++ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then++ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"++ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"++ fi++fi++++if [[ -f "$HL2MP_PLAYER" ]]; then++ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"++ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"++ fi++++ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"++ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"++ fi++fi++++if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"++ python3 - "$HL2MP_CLIENT" <<'PY'++from pathlib import Path++import re, sys++++p = Path(sys.argv[1])++s = p.read_text()++++# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:++# CHL2MP_Player *client = ...++# const char *p = args.ArgS();++if "OpenVibeJS_Server_PlayerSay( client," not in s:++ s2 = re.sub(++ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',++ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',++ s,++ count=1,++ )++ if s2 != s:++ s = s2++ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")++ else:++ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")++p.write_text(s)++PY++fi++++echo "[openvibe-sdk] Source SDK OpenVibe patch applied"nnew file mode 100755@@@ -0,0 +1,214 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then++ echo "Source SDK 2013 checkout not found at $SDK" >&2++ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2++ exit 1++fi++++copy_file() {++ local src="$1"++ local dst="$2"++ install -D -m 0644 "$src" "$dst"++ echo "[openvibe-sdk] copied ${dst#$SDK/}"++}++++copy_tree() {++ local src="$1"++ local dst="$2"++ mkdir -p "$dst"++ rsync -a --delete "$src/" "$dst/"++ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"++}++++copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \++ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"++copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \++ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"++++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \++ "$SDK/src/game/shared/openvibe/ov_js_player.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"++++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"++++copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \++ "$SDK/src/game/shared/openvibe/third_party/quickjs"++++QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"++if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then++ tmp="$(mktemp)"++ cat > "$tmp" <<'QCFG'++#ifndef OPENVIBE_QUICKJS_CONFIG++#define OPENVIBE_QUICKJS_CONFIG++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++#endif++++QCFG++ cat "$QJS_C" >> "$tmp"++ mv "$tmp" "$QJS_C"++fi++++CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"++SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"++HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"++GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"++HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"++++perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"++echo "[openvibe-sdk] patched client_hl2mp.vpc"++++perl -0pi -e '++ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;++ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;++ s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;++ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;++' "$SERVER_VPC"++echo "[openvibe-sdk] patched server_hl2mp.vpc"++++if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"++ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"++ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"++fi++++perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"++++if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then++ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"++fi++++perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"++++if [[ -f "$GAMEINTERFACE" ]]; then++ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then++ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"++ fi++++ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then++ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"++ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"++ fi++fi++++if [[ -f "$HL2MP_PLAYER" ]]; then++ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"++ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"++ fi++++ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"++ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"++ fi++fi++++if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"++ python3 - "$HL2MP_CLIENT" <<'PY'++from pathlib import Path++import re, sys++++p = Path(sys.argv[1])++s = p.read_text()++++# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:++# CHL2MP_Player *client = ...++# const char *p = args.ArgS();++if "OpenVibeJS_Server_PlayerSay( client," not in s:++ s2 = re.sub(++ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',++ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',++ s,++ count=1,++ )++ if s2 != s:++ s = s2++ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")++ else:++ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")++p.write_text(s)++PY++fi++++++# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH++patch_openvibe_quickjs_after_apply() {++ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"++ local qjs_c="$qjs_dir/quickjs.c"++++ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then++ local tmp++ tmp="$(mktemp)"++ cat > "$tmp" <<'QJS_SHIM'++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++++QJS_SHIM++ cat "$qjs_c" >> "$tmp"++ mv "$tmp" "$qjs_c"++ echo "[openvibe-sdk] patched QuickJS strict-C shim"++ fi++++ if [[ ! -f "$qjs_dir/libbf.c" ]]; then++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true++ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"++ fi++}++++patch_openvibe_quickjs_after_apply++++echo "[openvibe-sdk] Source SDK OpenVibe patch applied"nnew file mode 100755@@@ -0,0 +1,217 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then++ echo "Source SDK 2013 checkout not found at $SDK" >&2++ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2++ exit 1++fi++++copy_file() {++ local src="$1"++ local dst="$2"++ install -D -m 0644 "$src" "$dst"++ echo "[openvibe-sdk] copied ${dst#$SDK/}"++}++++copy_tree() {++ local src="$1"++ local dst="$2"++ mkdir -p "$dst"++ rsync -a --delete "$src/" "$dst/"++ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"++}++++copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \++ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"++copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \++ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"++++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \++ "$SDK/src/game/shared/openvibe/ov_js_player.h"++copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \++ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"++++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"++copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \++ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"++++copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \++ "$SDK/src/game/shared/openvibe/third_party/quickjs"++++"$ROOT/tools/build-quickjs-lib.sh"++++QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"++if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then++ tmp="$(mktemp)"++ cat > "$tmp" <<'QCFG'++#ifndef OPENVIBE_QUICKJS_CONFIG++#define OPENVIBE_QUICKJS_CONFIG++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++#endif++++QCFG++ cat "$QJS_C" >> "$tmp"++ mv "$tmp" "$QJS_C"++fi++++CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"++SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"++HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"++GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"++HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"++++perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"++echo "[openvibe-sdk] patched client_hl2mp.vpc"++++perl -0pi -e '++ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;++ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;++ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;++ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n/s;++' "$SERVER_VPC"++echo "[openvibe-sdk] patched server_hl2mp.vpc"++++if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"++ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"++ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"++fi++++perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"++++if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then++ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"++ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"++fi++++perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"++++if [[ -f "$GAMEINTERFACE" ]]; then++ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then++ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"++ fi++++ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then++ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"++ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"++ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"++ fi++fi++++if [[ -f "$HL2MP_PLAYER" ]]; then++ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"++ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"++ fi++++ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then++ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"++ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"++ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"++ fi++fi++++if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then++ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"++ python3 - "$HL2MP_CLIENT" <<'PY'++from pathlib import Path++import re, sys++++p = Path(sys.argv[1])++s = p.read_text()++++# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:++# CHL2MP_Player *client = ...++# const char *p = args.ArgS();++if "OpenVibeJS_Server_PlayerSay( client," not in s:++ s2 = re.sub(++ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',++ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',++ s,++ count=1,++ )++ if s2 != s:++ s = s2++ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")++ else:++ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")++p.write_text(s)++PY++fi++++++# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH++patch_openvibe_quickjs_after_apply() {++ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"++ local qjs_c="$qjs_dir/quickjs.c"++++ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then++ local tmp++ tmp="$(mktemp)"++ cat > "$tmp" <<'QJS_SHIM'++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++++QJS_SHIM++ cat "$qjs_c" >> "$tmp"++ mv "$tmp" "$qjs_c"++ echo "[openvibe-sdk] patched QuickJS strict-C shim"++ fi++++ if [[ ! -f "$qjs_dir/libbf.c" ]]; then++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true++ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"++ fi++}++++patch_openvibe_quickjs_after_apply++++echo "[openvibe-sdk] Source SDK OpenVibe patch applied"++++++# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.++if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ echo "[openvibe-sdk] linked QuickJS static library"++finnew file mode 100755@@@ -0,0 +1,54 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"++SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"++OUT="$SDK_QJS/build"++++if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then++ echo "Missing $SRC_QJS/quickjs.c" >&2++ echo "Run: tools/vendor-quickjs.sh" >&2++ exit 1++fi++++mkdir -p "$SDK_QJS"++++# Important: exclude build/ so rsync does not delete our object output dir.++rsync -a --delete --exclude='build/' "$SRC_QJS/" "$SDK_QJS/"++++mkdir -p "$OUT"++++sources=(++ quickjs.c++ libregexp.c++ libunicode.c++ cutils.c++)++++[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)++[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)++++rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a++++for src in "${sources[@]}"; do++ obj="$OUT/${src%.c}.o"++ echo "[openvibe-qjs] cc $src -> $obj"++++ cc \++ -std=gnu11 \++ -O2 \++ -fPIC \++ -D_GNU_SOURCE \++ -DCONFIG_VERSION=\"openvibe\" \++ -I"$SDK_QJS" \++ -c "$SDK_QJS/$src" \++ -o "$obj"++done++++ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o++++echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"++ls -lh "$OUT/libquickjs_openvibe.a"nnew file mode 100755@@@ -0,0 +1,313 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++QJS="$ROOT/sdk/openvibe/third_party/quickjs"++STAMP="$(date +%Y%m%d-%H%M%S)"++++cd "$ROOT"++++backup_file() {++ local file="$1"++ [[ -f "$file" ]] && cp "$file" "$file.bak.$STAMP"++}++++patch_quickjs_tree() {++ local qjs_dir="$1"++ local qjs_c="$qjs_dir/quickjs.c"++++ [[ -f "$qjs_c" ]] || return 0++++ if ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then++ local tmp++ tmp="$(mktemp)"++++ cat > "$tmp" <<'QJS_SHIM'++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++++QJS_SHIM++++ cat "$qjs_c" >> "$tmp"++ mv "$tmp" "$qjs_c"++ echo "[openvibe] patched QuickJS strict-C shim: $qjs_c"++ fi++}++++echo "[openvibe] refreshing remote branch metadata, without resetting your local files"++git fetch origin codex/openvibe-next-steps || true++++echo "[openvibe] checking embedded JS files from previous step"++++missing=0++for f in \++ tools/apply-openvibe-sdk.sh \++ sdk/openvibe/server/hl2mp/openvibe_server.cpp \++ sdk/openvibe/shared/ov_js_runtime.cpp \++ sdk/openvibe/shared/ov_js_bindings.cpp \++ sdk/openvibe/shared/ov_js_player.cpp \++ sdk/openvibe/server/hl2mp/openvibe_js_server.cpp \++ game/openvibe.games/js/core/hook.js \++ game/openvibe.games/js/core/gamemode.js \++ game/openvibe.games/js/bridge.js \++ game/openvibe.games/js/gamemodes/hub/server.js++do++ if [[ ! -f "$f" ]]; then++ echo "[openvibe] MISSING: $f"++ missing=1++ fi++done++++if [[ "$missing" = "1" ]]; then++ echo++ echo "[openvibe] Some embedded JS files are missing."++ echo "[openvibe] Re-run tools/implement-embedded-js.sh first, then run this continue script again."++ exit 1++fi++++echo "[openvibe] rewriting robust QuickJS vendor script"++++cat > tools/vendor-quickjs.sh <<'VENDOR'++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++DEST="$ROOT/sdk/openvibe/third_party/quickjs"++TMP="${TMPDIR:-/tmp}/openvibe-quickjs-vendor"++++rm -rf "$TMP"++++git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP"++++rm -rf "$DEST"++mkdir -p "$DEST"++++rsync -av \++ --include='quickjs.c' \++ --include='quickjs.h' \++ --include='quickjs-atom.h' \++ --include='quickjs-opcode.h' \++ --include='libregexp.c' \++ --include='libregexp.h' \++ --include='libregexp-opcode.h' \++ --include='libunicode.c' \++ --include='libunicode.h' \++ --include='libunicode-table.h' \++ --include='cutils.c' \++ --include='cutils.h' \++ --include='dtoa.c' \++ --include='dtoa.h' \++ --include='libbf.c' \++ --include='libbf.h' \++ --include='list.h' \++ --include='LICENSE' \++ --include='VERSION' \++ --exclude='*' \++ "$TMP/" \++ "$DEST/"++++git -C "$TMP" rev-parse HEAD > "$DEST/UPSTREAM_COMMIT"++++cat > "$DEST/README.openvibe.md" <<'DOC'++# QuickJS vendored for OpenVibe: Source++++Vendored QuickJS core files for OpenVibe's embedded JavaScript runtime.++++Excluded intentionally:++- qjs.c++- qjsc.c++- quickjs-libc.c++- quickjs-libc.h++++Reason:++OpenVibe embeds QuickJS as a sandboxed script VM. Community scripts should not++receive raw std/os/filesystem/process APIs.++DOC++++echo "[openvibe] vendored QuickJS into $DEST"++echo "[openvibe] upstream commit: $(cat "$DEST/UPSTREAM_COMMIT")"++VENDOR++++chmod +x tools/vendor-quickjs.sh++++if [[ "${FORCE_REVENDOR:-0}" = "1" || ! -f "$QJS/quickjs.c" ]]; then++ echo "[openvibe] vendoring QuickJS"++ tools/vendor-quickjs.sh++else++ echo "[openvibe] using existing QuickJS folder"++fi++++patch_quickjs_tree "$QJS"++++echo "[openvibe] writing robust smoke test"++++cat > tools/smoke-quickjs.sh <<'SMOKE'++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++QJS="$ROOT/sdk/openvibe/third_party/quickjs"++BUILD="$ROOT/.tmp/quickjs-smoke"++++rm -rf "$BUILD"++mkdir -p "$BUILD"++++cat > "$BUILD/smoke.c" <<'C'++#include <stdio.h>++#include "quickjs.h"++++int main(void) {++ JSRuntime *rt = JS_NewRuntime();++ JSContext *ctx = JS_NewContext(rt);++++ JSValue value = JS_Eval(ctx, "1 + 2 + 3", 9, "<smoke>", JS_EVAL_TYPE_GLOBAL);++ int32_t out = 0;++ JS_ToInt32(ctx, &out, value);++++ JS_FreeValue(ctx, value);++ JS_FreeContext(ctx);++ JS_FreeRuntime(rt);++++ printf("quickjs result=%d\n", out);++ return out == 6 ? 0 : 1;++}++C++++sources=(++ "$QJS/quickjs.c"++ "$QJS/libregexp.c"++ "$QJS/libunicode.c"++ "$QJS/cutils.c"++)++++[[ -f "$QJS/dtoa.c" ]] && sources+=("$QJS/dtoa.c")++[[ -f "$QJS/libbf.c" ]] && sources+=("$QJS/libbf.c")++++cc \++ -std=gnu11 \++ -D_GNU_SOURCE \++ -DCONFIG_VERSION=\"openvibe\" \++ -I"$QJS" \++ "$BUILD/smoke.c" \++ "${sources[@]}" \++ -lm \++ -ldl \++ -lpthread \++ -o "$BUILD/smoke-quickjs"++++"$BUILD/smoke-quickjs"++SMOKE++++chmod +x tools/smoke-quickjs.sh++++echo "[openvibe] patching apply-openvibe-sdk.sh post-apply QuickJS cleanup"++++backup_file tools/apply-openvibe-sdk.sh++++python3 <<'PY'++from pathlib import Path++++p = Path("tools/apply-openvibe-sdk.sh")++s = p.read_text()++++marker = "OPENVIBE_CONTINUE_QUICKJS_POSTPATCH"++++block = r'''++# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH++patch_openvibe_quickjs_after_apply() {++ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"++ local qjs_c="$qjs_dir/quickjs.c"++++ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then++ local tmp++ tmp="$(mktemp)"++ cat > "$tmp" <<'QJS_SHIM'++#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM++#define OPENVIBE_QUICKJS_STRICT_C_SHIM++++#ifndef _GNU_SOURCE++#define _GNU_SOURCE++#endif++++#ifndef CONFIG_VERSION++#define CONFIG_VERSION "openvibe"++#endif++++#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)++#define asm __asm__++#endif++++#endif++++QJS_SHIM++ cat "$qjs_c" >> "$tmp"++ mv "$tmp" "$qjs_c"++ echo "[openvibe-sdk] patched QuickJS strict-C shim"++ fi++++ if [[ ! -f "$qjs_dir/libbf.c" ]]; then++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true++ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"++ fi++}++++patch_openvibe_quickjs_after_apply++'''++++if marker not in s:++ final_echo = 'echo "[openvibe-sdk] Source SDK OpenVibe patch applied"'++ if final_echo in s:++ s = s.replace(final_echo, block + "\n" + final_echo)++ else:++ s += "\n" + block + "\n"++++p.write_text(s)++PY++++echo "[openvibe] QuickJS files:"++find "$QJS" -maxdepth 1 -type f -printf " - %f\n" | sort++++echo "[openvibe] running QuickJS smoke test"++tools/smoke-quickjs.sh++++echo "[openvibe] applying SDK patch"++tools/apply-openvibe-sdk.sh++++SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"++patch_quickjs_tree "$SDK_QJS"++++if [[ ! -f "$SDK_QJS/libbf.c" ]]; then++ SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true++fi++++echo++echo "[openvibe] continue step complete."++echo++echo "Next build command:"++echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"++echo++echo "If you want this script to attempt the build now:"++echo " RUN_BUILD=1 tools/continue-embedded-js.sh"++echo++++if [[ "${RUN_BUILD:-0}" = "1" ]]; then++ echo "[openvibe] running SDK build"++ tools/build-sdk-linux.sh 2>&1 | tee "$HOME/ov-build.log"++ echo "[openvibe] build finished"++finnew file mode 100755@@@ -0,0 +1,146 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++cd "$ROOT"++++echo "[openvibe] replacing tools/build-quickjs-lib.sh"++++cat > tools/build-quickjs-lib.sh <<'BUILDQJS'++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"++SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"++OUT="$SDK_QJS/build"++++if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then++ echo "Missing $SRC_QJS/quickjs.c" >&2++ echo "Run: tools/vendor-quickjs.sh" >&2++ exit 1++fi++++mkdir -p "$SDK_QJS"++++# Important: exclude build/ so rsync does not delete our object output dir.++rsync -a --delete --exclude='build/' "$SRC_QJS/" "$SDK_QJS/"++++mkdir -p "$OUT"++++sources=(++ quickjs.c++ libregexp.c++ libunicode.c++ cutils.c++)++++[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)++[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)++++rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a++++for src in "${sources[@]}"; do++ obj="$OUT/${src%.c}.o"++ echo "[openvibe-qjs] cc $src -> $obj"++++ cc \++ -std=gnu11 \++ -O2 \++ -fPIC \++ -D_GNU_SOURCE \++ -DCONFIG_VERSION=\"openvibe\" \++ -I"$SDK_QJS" \++ -c "$SDK_QJS/$src" \++ -o "$obj"++done++++ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o++++echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"++ls -lh "$OUT/libquickjs_openvibe.a"++BUILDQJS++++chmod +x tools/build-quickjs-lib.sh++++echo "[openvibe] removing direct QuickJS .c files from server_hl2mp.vpc"++++SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++++if [[ -f "$SERVER_VPC" ]]; then++ cp "$SERVER_VPC" "$SERVER_VPC.bak.$(date +%Y%m%d-%H%M%S)"++++ perl -0pi -e '++ s/^.*quickjs\\quickjs\.c.*\n//mg;++ s/^.*quickjs\\libregexp\.c.*\n//mg;++ s/^.*quickjs\\libunicode\.c.*\n//mg;++ s/^.*quickjs\\cutils\.c.*\n//mg;++ s/^.*quickjs\\dtoa\.c.*\n//mg;++ s/^.*quickjs\\libbf\.c.*\n//mg;++ ' "$SERVER_VPC"++++ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ fi++fi++++echo "[openvibe] patching apply-openvibe-sdk.sh so future applies keep this fix"++++python3 <<'PY'++from pathlib import Path++import re++++p = Path("tools/apply-openvibe-sdk.sh")++s = p.read_text()++++# Make sure apply script calls static library builder after copying QuickJS.++if '"$ROOT/tools/build-quickjs-lib.sh"' not in s:++ needle = 'copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \\\n "$SDK/src/game/shared/openvibe/third_party/quickjs"'++ if needle in s:++ s = s.replace(needle, needle + '\n\n"$ROOT/tools/build-quickjs-lib.sh"')++ else:++ s += '\n\n"$ROOT/tools/build-quickjs-lib.sh"\n'++++# Add a strong cleanup block near the end.++marker = "OPENVIBE_REMOVE_DIRECT_QUICKJS_C"++if marker not in s:++ s += r'''++++# OPENVIBE_REMOVE_DIRECT_QUICKJS_C++if [[ -f "$SERVER_VPC" ]]; then++ perl -0pi -e '++ s/^.*quickjs\\quickjs\.c.*\n//mg;++ s/^.*quickjs\\libregexp\.c.*\n//mg;++ s/^.*quickjs\\libunicode\.c.*\n//mg;++ s/^.*quickjs\\cutils\.c.*\n//mg;++ s/^.*quickjs\\dtoa\.c.*\n//mg;++ s/^.*quickjs\\libbf\.c.*\n//mg;++ ' "$SERVER_VPC"++++ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ fi++fi++'''++++p.write_text(s)++PY++++echo "[openvibe] building QuickJS static lib"++tools/build-quickjs-lib.sh++++echo++echo "[openvibe] checking VPC for bad direct QuickJS C entries"++if [[ -f "$SERVER_VPC" ]]; then++ grep -nE 'quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c' "$SERVER_VPC" || true++ grep -n 'libquickjs_openvibe.a' "$SERVER_VPC" || true++fi++++echo++echo "[openvibe] fixed. Now run:"++echo " tools/apply-openvibe-sdk.sh"++echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"nnew file mode 100755@@@ -0,0 +1,174 @@++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++STAMP="$(date +%Y%m%d-%H%M%S)"++++cd "$ROOT"++++backup_file() {++ local file="$1"++ [[ -f "$file" ]] && cp "$file" "$file.bak.$STAMP"++}++++echo "[openvibe] writing QuickJS static library builder"++++cat > tools/build-quickjs-lib.sh <<'BUILDQJS'++#!/usr/bin/env bash++set -euo pipefail++++ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"++SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"++++SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"++SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"++OUT="$SDK_QJS/build"++++mkdir -p "$OUT"++++if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then++ echo "Missing $SRC_QJS/quickjs.c" >&2++ echo "Run: tools/vendor-quickjs.sh" >&2++ exit 1++fi++++# Make sure SDK copy exists. apply-openvibe-sdk.sh also does this,++# but this makes the script usable directly.++mkdir -p "$SDK_QJS"++rsync -a --delete "$SRC_QJS/" "$SDK_QJS/"++++sources=(++ quickjs.c++ libregexp.c++ libunicode.c++ cutils.c++)++++[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)++[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)++++rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a++++for src in "${sources[@]}"; do++ obj="$OUT/${src%.c}.o"++ echo "[openvibe-qjs] cc $src"++ cc \++ -std=gnu11 \++ -O2 \++ -fPIC \++ -D_GNU_SOURCE \++ -DCONFIG_VERSION=\"openvibe\" \++ -I"$SDK_QJS" \++ -c "$SDK_QJS/$src" \++ -o "$obj"++done++++ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o++++echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"++ls -lh "$OUT/libquickjs_openvibe.a"++BUILDQJS++++chmod +x tools/build-quickjs-lib.sh++++echo "[openvibe] patching apply-openvibe-sdk.sh to link libquickjs_openvibe.a instead of compiling QuickJS C files"++++backup_file tools/apply-openvibe-sdk.sh++++python3 <<'PY'++from pathlib import Path++import re++++p = Path("tools/apply-openvibe-sdk.sh")++s = p.read_text()++++# Remove QuickJS .c cleanup patterns from perl patch block if they exist.++for name in ["quickjs", "libregexp", "libunicode", "cutils", "dtoa", "libbf"]:++ s = re.sub(++ rf'\s*s/\^\.\*openvibe\\\\third_party\\\\quickjs\\\\{name}\\\.c\.\*\\n//mg;\n?',++ '\n',++ s,++ )++ s = re.sub(++ rf'\s*s/\^\.\*openvibe\\\\\\\\third_party\\\\\\\\quickjs\\\\\\\\{name}\\\\\.c\.\*\\n//mg;\n?',++ '\n',++ s,++ )++++# Remove inserted QuickJS .c $File entries from replacement text.++for name in ["quickjs", "libregexp", "libunicode", "cutils", "dtoa", "libbf"]:++ s = s.replace(++ f'\\n\\t\\t\\t\\$File\\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',++ ''++ )++ s = s.replace(++ f'\n\t\t\t\\$File\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',++ ''++ )++ s = s.replace(++ f'\n\t\t\t$File\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',++ ''++ )++++# Remove any actual already-written lines from the script text.++s = re.sub(r'^.*quickjs\\\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n', '', s, flags=re.M)++s = re.sub(r'^.*quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n', '', s, flags=re.M)++++# Ensure build-quickjs-lib is called after copy_tree.++if "tools/build-quickjs-lib.sh" not in s:++ needle = 'copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \\\n "$SDK/src/game/shared/openvibe/third_party/quickjs"'++ replacement = needle + '\n\n"$ROOT/tools/build-quickjs-lib.sh"'++ if needle in s:++ s = s.replace(needle, replacement)++ else:++ s += '\n\n"$ROOT/tools/build-quickjs-lib.sh"\n'++++# Add static lib to server_hl2mp.vpc patch.++# Try to insert a $Lib line near the openvibe source files, only once.++lib_line = '\t\t\t$Lib\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\build\\\\libquickjs_openvibe.a"'++if 'libquickjs_openvibe.a' not in s:++ # Add after openvibe_js_server.cpp if present in replacement text.++ s = s.replace(++ '\t\t\t\\$File\t"hl2mp\\\\openvibe_js_server.cpp"',++ '\t\t\t\\$File\t"hl2mp\\\\openvibe_js_server.cpp"\\n' + lib_line.replace('$', '\\$')++ )++ # If that escaped replacement did not hit, add a direct post-patch insertion block.++ if 'libquickjs_openvibe.a' not in s:++ s += r'''++++# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.++if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ echo "[openvibe-sdk] linked QuickJS static library"++fi++'''++++p.write_text(s)++PY++++echo "[openvibe] also patching already-applied SDK VPC now, if it exists"++++SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"++++if [[ -f "$SERVER_VPC" ]]; then++ backup_file "$SERVER_VPC"++++ # Remove direct QuickJS C files from VPC.++ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n//mg' "$SERVER_VPC"++++ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then++ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"++ fi++fi++++echo "[openvibe] building QuickJS C static library"++tools/build-quickjs-lib.sh++++echo++echo "[openvibe] fixed QuickJS C/C++ build split."++echo++echo "Now run:"++echo " tools/apply-openvibe-sdk.sh"++echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"++echo " tail -160 ~/ov-build.log"@@@ -7,8 +7,7 @@ TMP="${TMPDIR:-/tmp}/openvibe-quickjs-vendor"rm -rf "$TMP"--git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP" || \--git clone --depth 1 https://github.com/quickjs-ng/quickjs.git "$TMP"++git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP"rm -rf "$DEST"mkdir -p "$DEST"
Binary files a/.tmp/quickjs-smoke/smoke-quickjs and b/.tmp/quickjs-smoke/smoke-quickjs differ
Binary files a/.tmp/quickjs-smoke/smoke-quickjs and b/.tmp/quickjs-smoke/smoke-quickjs differ
@@ -1,3 +1,20 @@
@@ -1,3 +1,20 @@
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
/*
/*
* QuickJS Javascript Engine
* QuickJS Javascript Engine
*
*
@@ -53,6 +53,8 @@ copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \
@@ -53,6 +53,8 @@ copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \
copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \
copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \
"$SDK/src/game/shared/openvibe/third_party/quickjs"
"$SDK/src/game/shared/openvibe/third_party/quickjs"
+"$ROOT/tools/build-quickjs-lib.sh"
+
QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"
QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"
if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then
if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then
tmp="$(mktemp)"
tmp="$(mktemp)"
@@ -88,13 +90,7 @@ perl -0pi -e '
@@ -88,13 +90,7 @@ perl -0pi -e '
s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;
s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;
s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;
s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;
s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;
s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;
- s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;
- s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;
+ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n/s;
' "$SERVER_VPC"
' "$SERVER_VPC"
echo "[openvibe-sdk] patched server_hl2mp.vpc"
echo "[openvibe-sdk] patched server_hl2mp.vpc"
@@ -170,4 +166,69 @@ p.write_text(s)
@@ -170,4 +166,69 @@ p.write_text(s)
PY
PY
fi
fi
+
+# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH
+patch_openvibe_quickjs_after_apply() {
+ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"
+ local qjs_c="$qjs_dir/quickjs.c"
+
+ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then
+ local tmp
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QJS_SHIM'
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
+QJS_SHIM
+ cat "$qjs_c" >> "$tmp"
+ mv "$tmp" "$qjs_c"
+ echo "[openvibe-sdk] patched QuickJS strict-C shim"
+ fi
+
+ if [[ ! -f "$qjs_dir/libbf.c" ]]; then
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true
+ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"
+ fi
+}
+
+patch_openvibe_quickjs_after_apply
+
echo "[openvibe-sdk] Source SDK OpenVibe patch applied"
echo "[openvibe-sdk] Source SDK OpenVibe patch applied"
+
+
+# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.
+if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ echo "[openvibe-sdk] linked QuickJS static library"
+fi
+
+
+# OPENVIBE_REMOVE_DIRECT_QUICKJS_C
+if [[ -f "$SERVER_VPC" ]]; then
+ perl -0pi -e '
+ s/^.*quickjs\\quickjs\.c.*\n//mg;
+ s/^.*quickjs\\libregexp\.c.*\n//mg;
+ s/^.*quickjs\\libunicode\.c.*\n//mg;
+ s/^.*quickjs\\cutils\.c.*\n//mg;
+ s/^.*quickjs\\dtoa\.c.*\n//mg;
+ s/^.*quickjs\\libbf\.c.*\n//mg;
+ ' "$SERVER_VPC"
+
+ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ fi
+fi
new file mode 100755
new file mode 100755
@@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then
+ echo "Source SDK 2013 checkout not found at $SDK" >&2
+ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2
+ exit 1
+fi
+
+copy_file() {
+ local src="$1"
+ local dst="$2"
+ install -D -m 0644 "$src" "$dst"
+ echo "[openvibe-sdk] copied ${dst#$SDK/}"
+}
+
+copy_tree() {
+ local src="$1"
+ local dst="$2"
+ mkdir -p "$dst"
+ rsync -a --delete "$src/" "$dst/"
+ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"
+}
+
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \
+ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \
+ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"
+
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"
+
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"
+
+copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \
+ "$SDK/src/game/shared/openvibe/third_party/quickjs"
+
+QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"
+if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QCFG'
+#ifndef OPENVIBE_QUICKJS_CONFIG
+#define OPENVIBE_QUICKJS_CONFIG
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+#endif
+
+QCFG
+ cat "$QJS_C" >> "$tmp"
+ mv "$tmp" "$QJS_C"
+fi
+
+CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"
+SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"
+HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"
+GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"
+HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"
+
+perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"
+echo "[openvibe-sdk] patched client_hl2mp.vpc"
+
+perl -0pi -e '
+ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;
+ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;
+ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;
+' "$SERVER_VPC"
+echo "[openvibe-sdk] patched server_hl2mp.vpc"
+
+if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"
+ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"
+ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"
+fi
+
+perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"
+
+if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then
+ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"
+fi
+
+perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"
+
+if [[ -f "$GAMEINTERFACE" ]]; then
+ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then
+ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"
+ fi
+
+ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then
+ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"
+ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_PLAYER" ]]; then
+ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"
+ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"
+ fi
+
+ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"
+ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"
+ python3 - "$HL2MP_CLIENT" <<'PY'
+from pathlib import Path
+import re, sys
+
+p = Path(sys.argv[1])
+s = p.read_text()
+
+# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:
+# CHL2MP_Player *client = ...
+# const char *p = args.ArgS();
+if "OpenVibeJS_Server_PlayerSay( client," not in s:
+ s2 = re.sub(
+ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',
+ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',
+ s,
+ count=1,
+ )
+ if s2 != s:
+ s = s2
+ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")
+ else:
+ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")
+p.write_text(s)
+PY
+fi
+
+echo "[openvibe-sdk] Source SDK OpenVibe patch applied"
new file mode 100755
new file mode 100755
@@ -0,0 +1,214 @@
@@ -0,0 +1,214 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then
+ echo "Source SDK 2013 checkout not found at $SDK" >&2
+ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2
+ exit 1
+fi
+
+copy_file() {
+ local src="$1"
+ local dst="$2"
+ install -D -m 0644 "$src" "$dst"
+ echo "[openvibe-sdk] copied ${dst#$SDK/}"
+}
+
+copy_tree() {
+ local src="$1"
+ local dst="$2"
+ mkdir -p "$dst"
+ rsync -a --delete "$src/" "$dst/"
+ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"
+}
+
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \
+ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \
+ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"
+
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"
+
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"
+
+copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \
+ "$SDK/src/game/shared/openvibe/third_party/quickjs"
+
+QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"
+if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QCFG'
+#ifndef OPENVIBE_QUICKJS_CONFIG
+#define OPENVIBE_QUICKJS_CONFIG
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+#endif
+
+QCFG
+ cat "$QJS_C" >> "$tmp"
+ mv "$tmp" "$QJS_C"
+fi
+
+CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"
+SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"
+HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"
+GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"
+HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"
+
+perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"
+echo "[openvibe-sdk] patched client_hl2mp.vpc"
+
+perl -0pi -e '
+ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;
+ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\quickjs\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libregexp\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libunicode\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\cutils\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\dtoa\.c.*\n//mg;
+ s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg;
+ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\quickjs.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libregexp.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\libunicode.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\cutils.c"\n\t\t\t\$File\t"..\\shared\\openvibe\\third_party\\quickjs\\dtoa.c"\n/s;
+' "$SERVER_VPC"
+echo "[openvibe-sdk] patched server_hl2mp.vpc"
+
+if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"
+ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"
+ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"
+fi
+
+perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"
+
+if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then
+ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"
+fi
+
+perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"
+
+if [[ -f "$GAMEINTERFACE" ]]; then
+ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then
+ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"
+ fi
+
+ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then
+ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"
+ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_PLAYER" ]]; then
+ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"
+ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"
+ fi
+
+ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"
+ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"
+ python3 - "$HL2MP_CLIENT" <<'PY'
+from pathlib import Path
+import re, sys
+
+p = Path(sys.argv[1])
+s = p.read_text()
+
+# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:
+# CHL2MP_Player *client = ...
+# const char *p = args.ArgS();
+if "OpenVibeJS_Server_PlayerSay( client," not in s:
+ s2 = re.sub(
+ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',
+ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',
+ s,
+ count=1,
+ )
+ if s2 != s:
+ s = s2
+ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")
+ else:
+ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")
+p.write_text(s)
+PY
+fi
+
+
+# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH
+patch_openvibe_quickjs_after_apply() {
+ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"
+ local qjs_c="$qjs_dir/quickjs.c"
+
+ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then
+ local tmp
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QJS_SHIM'
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
+QJS_SHIM
+ cat "$qjs_c" >> "$tmp"
+ mv "$tmp" "$qjs_c"
+ echo "[openvibe-sdk] patched QuickJS strict-C shim"
+ fi
+
+ if [[ ! -f "$qjs_dir/libbf.c" ]]; then
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true
+ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"
+ fi
+}
+
+patch_openvibe_quickjs_after_apply
+
+echo "[openvibe-sdk] Source SDK OpenVibe patch applied"
new file mode 100755
new file mode 100755
@@ -0,0 +1,217 @@
@@ -0,0 +1,217 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+if [[ ! -d "$SDK/src/game/client/hl2mp" || ! -d "$SDK/src/game/server/hl2mp" ]]; then
+ echo "Source SDK 2013 checkout not found at $SDK" >&2
+ echo "Set OPENVIBE_SDK=/path/to/source-sdk-2013 if it lives elsewhere." >&2
+ exit 1
+fi
+
+copy_file() {
+ local src="$1"
+ local dst="$2"
+ install -D -m 0644 "$src" "$dst"
+ echo "[openvibe-sdk] copied ${dst#$SDK/}"
+}
+
+copy_tree() {
+ local src="$1"
+ local dst="$2"
+ mkdir -p "$dst"
+ rsync -a --delete "$src/" "$dst/"
+ echo "[openvibe-sdk] copied tree ${dst#$SDK/}"
+}
+
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/openvibe_client.cpp" \
+ "$SDK/src/game/client/hl2mp/openvibe_client.cpp"
+copy_file "$ROOT/sdk/openvibe/client/hl2mp/vgui_openvibe_menu.cpp" \
+ "$SDK/src/game/client/hl2mp/vgui_openvibe_menu.cpp"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_server.cpp"
+
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_runtime.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_runtime.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_bindings.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_bindings.cpp"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.h" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.h"
+copy_file "$ROOT/sdk/openvibe/shared/ov_js_player.cpp" \
+ "$SDK/src/game/shared/openvibe/ov_js_player.cpp"
+
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.h" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.h"
+copy_file "$ROOT/sdk/openvibe/server/hl2mp/openvibe_js_server.cpp" \
+ "$SDK/src/game/server/hl2mp/openvibe_js_server.cpp"
+
+copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \
+ "$SDK/src/game/shared/openvibe/third_party/quickjs"
+
+"$ROOT/tools/build-quickjs-lib.sh"
+
+QJS_C="$SDK/src/game/shared/openvibe/third_party/quickjs/quickjs.c"
+if [[ -f "$QJS_C" ]] && ! grep -q 'OPENVIBE_QUICKJS_CONFIG' "$QJS_C"; then
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QCFG'
+#ifndef OPENVIBE_QUICKJS_CONFIG
+#define OPENVIBE_QUICKJS_CONFIG
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+#endif
+
+QCFG
+ cat "$QJS_C" >> "$tmp"
+ mv "$tmp" "$QJS_C"
+fi
+
+CLIENT_VPC="$SDK/src/game/client/client_hl2mp.vpc"
+SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+HL2MP_CLIENT="$SDK/src/game/server/hl2mp/hl2mp_client.cpp"
+HL2MP_CLIENTMODE="$SDK/src/game/client/hl2mp/clientmode_hl2mpnormal.cpp"
+GAMEINTERFACE="$SDK/src/game/server/gameinterface.cpp"
+HL2MP_PLAYER="$SDK/src/game/server/hl2mp/hl2mp_player.cpp"
+
+perl -0pi -e 's/^.*hl2mp\\openvibe_client\.cpp.*\n//mg; s/^.*hl2mp\\vgui_openvibe_menu\.cpp.*\n//mg; s/(\$File\s+"hl2mp\\clientmode_hl2mpnormal\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_client.cpp"\n\t\t\t\$File\t"hl2mp\\vgui_openvibe_menu.cpp"\n/s' "$CLIENT_VPC"
+echo "[openvibe-sdk] patched client_hl2mp.vpc"
+
+perl -0pi -e '
+ s/^.*hl2mp\\openvibe_server\.cpp.*\n//mg;
+ s/^.*hl2mp\\openvibe_js_server\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_runtime\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_bindings\.cpp.*\n//mg;
+ s/^.*openvibe\\ov_js_player\.cpp.*\n//mg;
+ s/(\$File\s+"hl2mp\\hl2mp_player\.h"\n)/$1\t\t\t\$File\t"hl2mp\\openvibe_server.cpp"\n\t\t\t\$File\t"hl2mp\\openvibe_js_server.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_runtime.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_bindings.cpp"\n\t\t\t\$File\t"..\\shared\\openvibe\\ov_js_player.cpp"\n/s;
+' "$SERVER_VPC"
+echo "[openvibe-sdk] patched server_hl2mp.vpc"
+
+if ! grep -q 'OpenVibe_OnClientActive' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a void OpenVibe_OnClientActive( CHL2MP_Player *pPlayer );' "$HL2MP_CLIENT"
+ sed -i '/FinishClientPutInServer( pPlayer );/a \ OpenVibe_OnClientActive( pPlayer );' "$HL2MP_CLIENT"
+ echo "[openvibe-sdk] patched hl2mp_client.cpp arrival hook"
+fi
+
+perl -0pi -e 's/[^\S\r\n]*\x0boid OpenVibe_OnClientActive/void OpenVibe_OnClientActive/g; s/\\tOpenVibe_OnClientActive/\tOpenVibe_OnClientActive/g; s/^[ \t]*void OpenVibe_OnClientActive/void OpenVibe_OnClientActive/m' "$HL2MP_CLIENT"
+
+if ! grep -q 'OpenVibe_OnClientModeInit' "$HL2MP_CLIENTMODE"; then
+ sed -i '/#include "ienginevgui.h"/a void OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ sed -i '/BaseClass::Init();/a \ OpenVibe_OnClientModeInit();' "$HL2MP_CLIENTMODE"
+ echo "[openvibe-sdk] patched clientmode_hl2mpnormal.cpp OpenVibe menu hook"
+fi
+
+perl -0pi -e 's/^[ \t]*tOpenVibe_OnClientModeInit\(\);/ OpenVibe_OnClientModeInit();/m' "$HL2MP_CLIENTMODE"
+
+if [[ -f "$GAMEINTERFACE" ]]; then
+ if ! grep -q 'OpenVibe_OnFrame' "$GAMEINTERFACE"; then
+ sed -i '/CServerGameDLL::GameFrame/i #ifdef HL2MP\nvoid OpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ sed -i '/VPROF( "CServerGameDLL::GameFrame" );/a #ifdef HL2MP\n\tOpenVibe_OnFrame();\n#endif' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp frame hook"
+ fi
+
+ if ! grep -q 'OpenVibe_OnClientDisconnect' "$GAMEINTERFACE"; then
+ perl -pi -e 's/void CServerGameClients::ClientDisconnect/#ifdef HL2MP\nvoid OpenVibe_OnClientDisconnect( CBasePlayer *pPlayer );\n#endif\nvoid CServerGameClients::ClientDisconnect/' "$GAMEINTERFACE"
+ perl -0777 -pi -e 's/(void CServerGameClients::ClientDisconnect\( edict_t \*pEdict \)\s*\{\s*extern bool\s+g_fGameOver;\s*CBasePlayer \*player = \( CBasePlayer \* \)CBaseEntity::Instance\( pEdict \);)/$1\n#ifdef HL2MP\n\tif ( player ) { OpenVibe_OnClientDisconnect( player ); }\n#endif/g' "$GAMEINTERFACE"
+ echo "[openvibe-sdk] patched gameinterface.cpp disconnect hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_PLAYER" ]]; then
+ if ! grep -q 'OpenVibe_OnPlayerDeath' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Event_Killed/i void OpenVibe_OnPlayerDeath( CHL2MP_Player *pPlayer, CBaseEntity *pKiller );' "$HL2MP_PLAYER"
+ sed -i '/CTakeDamageInfo subinfo = info;/i \ OpenVibe_OnPlayerDeath( this, info.GetAttacker() );' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp death hook"
+ fi
+
+ if ! grep -q 'OpenVibeJS_Server_PlayerSpawn' "$HL2MP_PLAYER"; then
+ sed -i '/CHL2MP_Player::Spawn/i void OpenVibeJS_Server_PlayerSpawn( CHL2MP_Player *pPlayer );' "$HL2MP_PLAYER"
+ sed -i '0,/BaseClass::Spawn();/s//BaseClass::Spawn();\n\tOpenVibeJS_Server_PlayerSpawn( this );/' "$HL2MP_PLAYER"
+ echo "[openvibe-sdk] patched hl2mp_player.cpp spawn hook"
+ fi
+fi
+
+if [[ -f "$HL2MP_CLIENT" ]] && ! grep -q 'OpenVibeJS_Server_PlayerSay' "$HL2MP_CLIENT"; then
+ sed -i '/void Host_Say/a bool OpenVibeJS_Server_PlayerSay( CHL2MP_Player *pPlayer, const char *pszText );' "$HL2MP_CLIENT"
+ python3 - "$HL2MP_CLIENT" <<'PY'
+from pathlib import Path
+import re, sys
+
+p = Path(sys.argv[1])
+s = p.read_text()
+
+# Best-effort patch for common Source SDK 2013 HL2MP Host_Say shape:
+# CHL2MP_Player *client = ...
+# const char *p = args.ArgS();
+if "OpenVibeJS_Server_PlayerSay( client," not in s:
+ s2 = re.sub(
+ r'(const char \*p\s*=\s*args\.ArgS\(\);\s*)',
+ r'\1\n\tif ( client && OpenVibeJS_Server_PlayerSay( client, p ) )\n\t\treturn;\n',
+ s,
+ count=1,
+ )
+ if s2 != s:
+ s = s2
+ print("[openvibe-sdk] patched hl2mp_client.cpp PlayerSay hook")
+ else:
+ print("[openvibe-sdk] WARNING: could not auto-patch Host_Say PlayerSay body")
+p.write_text(s)
+PY
+fi
+
+
+# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH
+patch_openvibe_quickjs_after_apply() {
+ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"
+ local qjs_c="$qjs_dir/quickjs.c"
+
+ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then
+ local tmp
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QJS_SHIM'
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
+QJS_SHIM
+ cat "$qjs_c" >> "$tmp"
+ mv "$tmp" "$qjs_c"
+ echo "[openvibe-sdk] patched QuickJS strict-C shim"
+ fi
+
+ if [[ ! -f "$qjs_dir/libbf.c" ]]; then
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true
+ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"
+ fi
+}
+
+patch_openvibe_quickjs_after_apply
+
+echo "[openvibe-sdk] Source SDK OpenVibe patch applied"
+
+
+# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.
+if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ echo "[openvibe-sdk] linked QuickJS static library"
+fi
new file mode 100755
new file mode 100755
@@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"
+SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"
+OUT="$SDK_QJS/build"
+
+if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then
+ echo "Missing $SRC_QJS/quickjs.c" >&2
+ echo "Run: tools/vendor-quickjs.sh" >&2
+ exit 1
+fi
+
+mkdir -p "$SDK_QJS"
+
+# Important: exclude build/ so rsync does not delete our object output dir.
+rsync -a --delete --exclude='build/' "$SRC_QJS/" "$SDK_QJS/"
+
+mkdir -p "$OUT"
+
+sources=(
+ quickjs.c
+ libregexp.c
+ libunicode.c
+ cutils.c
+)
+
+[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)
+[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)
+
+rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a
+
+for src in "${sources[@]}"; do
+ obj="$OUT/${src%.c}.o"
+ echo "[openvibe-qjs] cc $src -> $obj"
+
+ cc \
+ -std=gnu11 \
+ -O2 \
+ -fPIC \
+ -D_GNU_SOURCE \
+ -DCONFIG_VERSION=\"openvibe\" \
+ -I"$SDK_QJS" \
+ -c "$SDK_QJS/$src" \
+ -o "$obj"
+done
+
+ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o
+
+echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"
+ls -lh "$OUT/libquickjs_openvibe.a"
new file mode 100755
new file mode 100755
@@ -0,0 +1,313 @@
@@ -0,0 +1,313 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+QJS="$ROOT/sdk/openvibe/third_party/quickjs"
+STAMP="$(date +%Y%m%d-%H%M%S)"
+
+cd "$ROOT"
+
+backup_file() {
+ local file="$1"
+ [[ -f "$file" ]] && cp "$file" "$file.bak.$STAMP"
+}
+
+patch_quickjs_tree() {
+ local qjs_dir="$1"
+ local qjs_c="$qjs_dir/quickjs.c"
+
+ [[ -f "$qjs_c" ]] || return 0
+
+ if ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then
+ local tmp
+ tmp="$(mktemp)"
+
+ cat > "$tmp" <<'QJS_SHIM'
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
+QJS_SHIM
+
+ cat "$qjs_c" >> "$tmp"
+ mv "$tmp" "$qjs_c"
+ echo "[openvibe] patched QuickJS strict-C shim: $qjs_c"
+ fi
+}
+
+echo "[openvibe] refreshing remote branch metadata, without resetting your local files"
+git fetch origin codex/openvibe-next-steps || true
+
+echo "[openvibe] checking embedded JS files from previous step"
+
+missing=0
+for f in \
+ tools/apply-openvibe-sdk.sh \
+ sdk/openvibe/server/hl2mp/openvibe_server.cpp \
+ sdk/openvibe/shared/ov_js_runtime.cpp \
+ sdk/openvibe/shared/ov_js_bindings.cpp \
+ sdk/openvibe/shared/ov_js_player.cpp \
+ sdk/openvibe/server/hl2mp/openvibe_js_server.cpp \
+ game/openvibe.games/js/core/hook.js \
+ game/openvibe.games/js/core/gamemode.js \
+ game/openvibe.games/js/bridge.js \
+ game/openvibe.games/js/gamemodes/hub/server.js
+do
+ if [[ ! -f "$f" ]]; then
+ echo "[openvibe] MISSING: $f"
+ missing=1
+ fi
+done
+
+if [[ "$missing" = "1" ]]; then
+ echo
+ echo "[openvibe] Some embedded JS files are missing."
+ echo "[openvibe] Re-run tools/implement-embedded-js.sh first, then run this continue script again."
+ exit 1
+fi
+
+echo "[openvibe] rewriting robust QuickJS vendor script"
+
+cat > tools/vendor-quickjs.sh <<'VENDOR'
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+DEST="$ROOT/sdk/openvibe/third_party/quickjs"
+TMP="${TMPDIR:-/tmp}/openvibe-quickjs-vendor"
+
+rm -rf "$TMP"
+
+git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP"
+
+rm -rf "$DEST"
+mkdir -p "$DEST"
+
+rsync -av \
+ --include='quickjs.c' \
+ --include='quickjs.h' \
+ --include='quickjs-atom.h' \
+ --include='quickjs-opcode.h' \
+ --include='libregexp.c' \
+ --include='libregexp.h' \
+ --include='libregexp-opcode.h' \
+ --include='libunicode.c' \
+ --include='libunicode.h' \
+ --include='libunicode-table.h' \
+ --include='cutils.c' \
+ --include='cutils.h' \
+ --include='dtoa.c' \
+ --include='dtoa.h' \
+ --include='libbf.c' \
+ --include='libbf.h' \
+ --include='list.h' \
+ --include='LICENSE' \
+ --include='VERSION' \
+ --exclude='*' \
+ "$TMP/" \
+ "$DEST/"
+
+git -C "$TMP" rev-parse HEAD > "$DEST/UPSTREAM_COMMIT"
+
+cat > "$DEST/README.openvibe.md" <<'DOC'
+# QuickJS vendored for OpenVibe: Source
+
+Vendored QuickJS core files for OpenVibe's embedded JavaScript runtime.
+
+Excluded intentionally:
+- qjs.c
+- qjsc.c
+- quickjs-libc.c
+- quickjs-libc.h
+
+Reason:
+OpenVibe embeds QuickJS as a sandboxed script VM. Community scripts should not
+receive raw std/os/filesystem/process APIs.
+DOC
+
+echo "[openvibe] vendored QuickJS into $DEST"
+echo "[openvibe] upstream commit: $(cat "$DEST/UPSTREAM_COMMIT")"
+VENDOR
+
+chmod +x tools/vendor-quickjs.sh
+
+if [[ "${FORCE_REVENDOR:-0}" = "1" || ! -f "$QJS/quickjs.c" ]]; then
+ echo "[openvibe] vendoring QuickJS"
+ tools/vendor-quickjs.sh
+else
+ echo "[openvibe] using existing QuickJS folder"
+fi
+
+patch_quickjs_tree "$QJS"
+
+echo "[openvibe] writing robust smoke test"
+
+cat > tools/smoke-quickjs.sh <<'SMOKE'
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+QJS="$ROOT/sdk/openvibe/third_party/quickjs"
+BUILD="$ROOT/.tmp/quickjs-smoke"
+
+rm -rf "$BUILD"
+mkdir -p "$BUILD"
+
+cat > "$BUILD/smoke.c" <<'C'
+#include <stdio.h>
+#include "quickjs.h"
+
+int main(void) {
+ JSRuntime *rt = JS_NewRuntime();
+ JSContext *ctx = JS_NewContext(rt);
+
+ JSValue value = JS_Eval(ctx, "1 + 2 + 3", 9, "<smoke>", JS_EVAL_TYPE_GLOBAL);
+ int32_t out = 0;
+ JS_ToInt32(ctx, &out, value);
+
+ JS_FreeValue(ctx, value);
+ JS_FreeContext(ctx);
+ JS_FreeRuntime(rt);
+
+ printf("quickjs result=%d\n", out);
+ return out == 6 ? 0 : 1;
+}
+C
+
+sources=(
+ "$QJS/quickjs.c"
+ "$QJS/libregexp.c"
+ "$QJS/libunicode.c"
+ "$QJS/cutils.c"
+)
+
+[[ -f "$QJS/dtoa.c" ]] && sources+=("$QJS/dtoa.c")
+[[ -f "$QJS/libbf.c" ]] && sources+=("$QJS/libbf.c")
+
+cc \
+ -std=gnu11 \
+ -D_GNU_SOURCE \
+ -DCONFIG_VERSION=\"openvibe\" \
+ -I"$QJS" \
+ "$BUILD/smoke.c" \
+ "${sources[@]}" \
+ -lm \
+ -ldl \
+ -lpthread \
+ -o "$BUILD/smoke-quickjs"
+
+"$BUILD/smoke-quickjs"
+SMOKE
+
+chmod +x tools/smoke-quickjs.sh
+
+echo "[openvibe] patching apply-openvibe-sdk.sh post-apply QuickJS cleanup"
+
+backup_file tools/apply-openvibe-sdk.sh
+
+python3 <<'PY'
+from pathlib import Path
+
+p = Path("tools/apply-openvibe-sdk.sh")
+s = p.read_text()
+
+marker = "OPENVIBE_CONTINUE_QUICKJS_POSTPATCH"
+
+block = r'''
+# OPENVIBE_CONTINUE_QUICKJS_POSTPATCH
+patch_openvibe_quickjs_after_apply() {
+ local qjs_dir="$SDK/src/game/shared/openvibe/third_party/quickjs"
+ local qjs_c="$qjs_dir/quickjs.c"
+
+ if [[ -f "$qjs_c" ]] && ! grep -q 'OPENVIBE_QUICKJS_STRICT_C_SHIM' "$qjs_c"; then
+ local tmp
+ tmp="$(mktemp)"
+ cat > "$tmp" <<'QJS_SHIM'
+#ifndef OPENVIBE_QUICKJS_STRICT_C_SHIM
+#define OPENVIBE_QUICKJS_STRICT_C_SHIM
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef CONFIG_VERSION
+#define CONFIG_VERSION "openvibe"
+#endif
+
+#if defined(__GNUC__) && !defined(__cplusplus) && defined(__STRICT_ANSI__) && !defined(asm)
+#define asm __asm__
+#endif
+
+#endif
+
+QJS_SHIM
+ cat "$qjs_c" >> "$tmp"
+ mv "$tmp" "$qjs_c"
+ echo "[openvibe-sdk] patched QuickJS strict-C shim"
+ fi
+
+ if [[ ! -f "$qjs_dir/libbf.c" ]]; then
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true
+ echo "[openvibe-sdk] libbf.c missing; removed libbf.c from server_hl2mp.vpc"
+ fi
+}
+
+patch_openvibe_quickjs_after_apply
+'''
+
+if marker not in s:
+ final_echo = 'echo "[openvibe-sdk] Source SDK OpenVibe patch applied"'
+ if final_echo in s:
+ s = s.replace(final_echo, block + "\n" + final_echo)
+ else:
+ s += "\n" + block + "\n"
+
+p.write_text(s)
+PY
+
+echo "[openvibe] QuickJS files:"
+find "$QJS" -maxdepth 1 -type f -printf " - %f\n" | sort
+
+echo "[openvibe] running QuickJS smoke test"
+tools/smoke-quickjs.sh
+
+echo "[openvibe] applying SDK patch"
+tools/apply-openvibe-sdk.sh
+
+SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"
+patch_quickjs_tree "$SDK_QJS"
+
+if [[ ! -f "$SDK_QJS/libbf.c" ]]; then
+ SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\libbf\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\libbf\.c.*\n//mg' "$SERVER_VPC" || true
+fi
+
+echo
+echo "[openvibe] continue step complete."
+echo
+echo "Next build command:"
+echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"
+echo
+echo "If you want this script to attempt the build now:"
+echo " RUN_BUILD=1 tools/continue-embedded-js.sh"
+echo
+
+if [[ "${RUN_BUILD:-0}" = "1" ]]; then
+ echo "[openvibe] running SDK build"
+ tools/build-sdk-linux.sh 2>&1 | tee "$HOME/ov-build.log"
+ echo "[openvibe] build finished"
+fi
new file mode 100755
new file mode 100755
@@ -0,0 +1,146 @@
@@ -0,0 +1,146 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+cd "$ROOT"
+
+echo "[openvibe] replacing tools/build-quickjs-lib.sh"
+
+cat > tools/build-quickjs-lib.sh <<'BUILDQJS'
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"
+SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"
+OUT="$SDK_QJS/build"
+
+if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then
+ echo "Missing $SRC_QJS/quickjs.c" >&2
+ echo "Run: tools/vendor-quickjs.sh" >&2
+ exit 1
+fi
+
+mkdir -p "$SDK_QJS"
+
+# Important: exclude build/ so rsync does not delete our object output dir.
+rsync -a --delete --exclude='build/' "$SRC_QJS/" "$SDK_QJS/"
+
+mkdir -p "$OUT"
+
+sources=(
+ quickjs.c
+ libregexp.c
+ libunicode.c
+ cutils.c
+)
+
+[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)
+[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)
+
+rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a
+
+for src in "${sources[@]}"; do
+ obj="$OUT/${src%.c}.o"
+ echo "[openvibe-qjs] cc $src -> $obj"
+
+ cc \
+ -std=gnu11 \
+ -O2 \
+ -fPIC \
+ -D_GNU_SOURCE \
+ -DCONFIG_VERSION=\"openvibe\" \
+ -I"$SDK_QJS" \
+ -c "$SDK_QJS/$src" \
+ -o "$obj"
+done
+
+ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o
+
+echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"
+ls -lh "$OUT/libquickjs_openvibe.a"
+BUILDQJS
+
+chmod +x tools/build-quickjs-lib.sh
+
+echo "[openvibe] removing direct QuickJS .c files from server_hl2mp.vpc"
+
+SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+
+if [[ -f "$SERVER_VPC" ]]; then
+ cp "$SERVER_VPC" "$SERVER_VPC.bak.$(date +%Y%m%d-%H%M%S)"
+
+ perl -0pi -e '
+ s/^.*quickjs\\quickjs\.c.*\n//mg;
+ s/^.*quickjs\\libregexp\.c.*\n//mg;
+ s/^.*quickjs\\libunicode\.c.*\n//mg;
+ s/^.*quickjs\\cutils\.c.*\n//mg;
+ s/^.*quickjs\\dtoa\.c.*\n//mg;
+ s/^.*quickjs\\libbf\.c.*\n//mg;
+ ' "$SERVER_VPC"
+
+ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ fi
+fi
+
+echo "[openvibe] patching apply-openvibe-sdk.sh so future applies keep this fix"
+
+python3 <<'PY'
+from pathlib import Path
+import re
+
+p = Path("tools/apply-openvibe-sdk.sh")
+s = p.read_text()
+
+# Make sure apply script calls static library builder after copying QuickJS.
+if '"$ROOT/tools/build-quickjs-lib.sh"' not in s:
+ needle = 'copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \\\n "$SDK/src/game/shared/openvibe/third_party/quickjs"'
+ if needle in s:
+ s = s.replace(needle, needle + '\n\n"$ROOT/tools/build-quickjs-lib.sh"')
+ else:
+ s += '\n\n"$ROOT/tools/build-quickjs-lib.sh"\n'
+
+# Add a strong cleanup block near the end.
+marker = "OPENVIBE_REMOVE_DIRECT_QUICKJS_C"
+if marker not in s:
+ s += r'''
+
+# OPENVIBE_REMOVE_DIRECT_QUICKJS_C
+if [[ -f "$SERVER_VPC" ]]; then
+ perl -0pi -e '
+ s/^.*quickjs\\quickjs\.c.*\n//mg;
+ s/^.*quickjs\\libregexp\.c.*\n//mg;
+ s/^.*quickjs\\libunicode\.c.*\n//mg;
+ s/^.*quickjs\\cutils\.c.*\n//mg;
+ s/^.*quickjs\\dtoa\.c.*\n//mg;
+ s/^.*quickjs\\libbf\.c.*\n//mg;
+ ' "$SERVER_VPC"
+
+ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ fi
+fi
+'''
+
+p.write_text(s)
+PY
+
+echo "[openvibe] building QuickJS static lib"
+tools/build-quickjs-lib.sh
+
+echo
+echo "[openvibe] checking VPC for bad direct QuickJS C entries"
+if [[ -f "$SERVER_VPC" ]]; then
+ grep -nE 'quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c' "$SERVER_VPC" || true
+ grep -n 'libquickjs_openvibe.a' "$SERVER_VPC" || true
+fi
+
+echo
+echo "[openvibe] fixed. Now run:"
+echo " tools/apply-openvibe-sdk.sh"
+echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"
new file mode 100755
new file mode 100755
@@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+STAMP="$(date +%Y%m%d-%H%M%S)"
+
+cd "$ROOT"
+
+backup_file() {
+ local file="$1"
+ [[ -f "$file" ]] && cp "$file" "$file.bak.$STAMP"
+}
+
+echo "[openvibe] writing QuickJS static library builder"
+
+cat > tools/build-quickjs-lib.sh <<'BUILDQJS'
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
+SDK="${OPENVIBE_SDK:-$ROOT/engine/source-sdk-2013}"
+
+SRC_QJS="$ROOT/sdk/openvibe/third_party/quickjs"
+SDK_QJS="$SDK/src/game/shared/openvibe/third_party/quickjs"
+OUT="$SDK_QJS/build"
+
+mkdir -p "$OUT"
+
+if [[ ! -f "$SRC_QJS/quickjs.c" ]]; then
+ echo "Missing $SRC_QJS/quickjs.c" >&2
+ echo "Run: tools/vendor-quickjs.sh" >&2
+ exit 1
+fi
+
+# Make sure SDK copy exists. apply-openvibe-sdk.sh also does this,
+# but this makes the script usable directly.
+mkdir -p "$SDK_QJS"
+rsync -a --delete "$SRC_QJS/" "$SDK_QJS/"
+
+sources=(
+ quickjs.c
+ libregexp.c
+ libunicode.c
+ cutils.c
+)
+
+[[ -f "$SDK_QJS/dtoa.c" ]] && sources+=(dtoa.c)
+[[ -f "$SDK_QJS/libbf.c" ]] && sources+=(libbf.c)
+
+rm -f "$OUT"/*.o "$OUT"/libquickjs_openvibe.a
+
+for src in "${sources[@]}"; do
+ obj="$OUT/${src%.c}.o"
+ echo "[openvibe-qjs] cc $src"
+ cc \
+ -std=gnu11 \
+ -O2 \
+ -fPIC \
+ -D_GNU_SOURCE \
+ -DCONFIG_VERSION=\"openvibe\" \
+ -I"$SDK_QJS" \
+ -c "$SDK_QJS/$src" \
+ -o "$obj"
+done
+
+ar rcs "$OUT/libquickjs_openvibe.a" "$OUT"/*.o
+
+echo "[openvibe-qjs] built $OUT/libquickjs_openvibe.a"
+ls -lh "$OUT/libquickjs_openvibe.a"
+BUILDQJS
+
+chmod +x tools/build-quickjs-lib.sh
+
+echo "[openvibe] patching apply-openvibe-sdk.sh to link libquickjs_openvibe.a instead of compiling QuickJS C files"
+
+backup_file tools/apply-openvibe-sdk.sh
+
+python3 <<'PY'
+from pathlib import Path
+import re
+
+p = Path("tools/apply-openvibe-sdk.sh")
+s = p.read_text()
+
+# Remove QuickJS .c cleanup patterns from perl patch block if they exist.
+for name in ["quickjs", "libregexp", "libunicode", "cutils", "dtoa", "libbf"]:
+ s = re.sub(
+ rf'\s*s/\^\.\*openvibe\\\\third_party\\\\quickjs\\\\{name}\\\.c\.\*\\n//mg;\n?',
+ '\n',
+ s,
+ )
+ s = re.sub(
+ rf'\s*s/\^\.\*openvibe\\\\\\\\third_party\\\\\\\\quickjs\\\\\\\\{name}\\\\\.c\.\*\\n//mg;\n?',
+ '\n',
+ s,
+ )
+
+# Remove inserted QuickJS .c $File entries from replacement text.
+for name in ["quickjs", "libregexp", "libunicode", "cutils", "dtoa", "libbf"]:
+ s = s.replace(
+ f'\\n\\t\\t\\t\\$File\\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',
+ ''
+ )
+ s = s.replace(
+ f'\n\t\t\t\\$File\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',
+ ''
+ )
+ s = s.replace(
+ f'\n\t\t\t$File\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\{name}.c"',
+ ''
+ )
+
+# Remove any actual already-written lines from the script text.
+s = re.sub(r'^.*quickjs\\\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n', '', s, flags=re.M)
+s = re.sub(r'^.*quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n', '', s, flags=re.M)
+
+# Ensure build-quickjs-lib is called after copy_tree.
+if "tools/build-quickjs-lib.sh" not in s:
+ needle = 'copy_tree "$ROOT/sdk/openvibe/third_party/quickjs" \\\n "$SDK/src/game/shared/openvibe/third_party/quickjs"'
+ replacement = needle + '\n\n"$ROOT/tools/build-quickjs-lib.sh"'
+ if needle in s:
+ s = s.replace(needle, replacement)
+ else:
+ s += '\n\n"$ROOT/tools/build-quickjs-lib.sh"\n'
+
+# Add static lib to server_hl2mp.vpc patch.
+# Try to insert a $Lib line near the openvibe source files, only once.
+lib_line = '\t\t\t$Lib\t"..\\\\shared\\\\openvibe\\\\third_party\\\\quickjs\\\\build\\\\libquickjs_openvibe.a"'
+if 'libquickjs_openvibe.a' not in s:
+ # Add after openvibe_js_server.cpp if present in replacement text.
+ s = s.replace(
+ '\t\t\t\\$File\t"hl2mp\\\\openvibe_js_server.cpp"',
+ '\t\t\t\\$File\t"hl2mp\\\\openvibe_js_server.cpp"\\n' + lib_line.replace('$', '\\$')
+ )
+ # If that escaped replacement did not hit, add a direct post-patch insertion block.
+ if 'libquickjs_openvibe.a' not in s:
+ s += r'''
+
+# Link prebuilt QuickJS C static library. QuickJS must be compiled as C, not C++.
+if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ echo "[openvibe-sdk] linked QuickJS static library"
+fi
+'''
+
+p.write_text(s)
+PY
+
+echo "[openvibe] also patching already-applied SDK VPC now, if it exists"
+
+SERVER_VPC="$SDK/src/game/server/server_hl2mp.vpc"
+
+if [[ -f "$SERVER_VPC" ]]; then
+ backup_file "$SERVER_VPC"
+
+ # Remove direct QuickJS C files from VPC.
+ perl -0pi -e 's/^.*openvibe\\\\third_party\\\\quickjs\\\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n//mg; s/^.*openvibe\\third_party\\quickjs\\(quickjs|libregexp|libunicode|cutils|dtoa|libbf)\.c.*\n//mg' "$SERVER_VPC"
+
+ if ! grep -q 'libquickjs_openvibe.a' "$SERVER_VPC"; then
+ perl -0pi -e 's/(\$File\s+"hl2mp\\openvibe_js_server\.cpp"\n)/$1\t\t\t\$Lib\t"..\\shared\\openvibe\\third_party\\quickjs\\build\\libquickjs_openvibe.a"\n/s' "$SERVER_VPC"
+ fi
+fi
+
+echo "[openvibe] building QuickJS C static library"
+tools/build-quickjs-lib.sh
+
+echo
+echo "[openvibe] fixed QuickJS C/C++ build split."
+echo
+echo "Now run:"
+echo " tools/apply-openvibe-sdk.sh"
+echo " tools/build-sdk-linux.sh 2>&1 | tee ~/ov-build.log"
+echo " tail -160 ~/ov-build.log"
@@ -7,8 +7,7 @@ TMP="${TMPDIR:-/tmp}/openvibe-quickjs-vendor"
@@ -7,8 +7,7 @@ TMP="${TMPDIR:-/tmp}/openvibe-quickjs-vendor"
rm -rf "$TMP"
rm -rf "$TMP"
-git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP" || \
-git clone --depth 1 https://github.com/quickjs-ng/quickjs.git "$TMP"
+git clone --depth 1 https://github.com/bellard/quickjs.git "$TMP"
rm -rf "$DEST"
rm -rf "$DEST"
mkdir -p "$DEST"
mkdir -p "$DEST"