major improvements
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
REM Build BackstageCapture DLL for Windows x64 using MSBuild (vcxproj).
|
||||
REM Run from VS Developer Command Prompt, or let the script detect VS.
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
set "PROJ=%ROOT%BackstageCapture\BackstageCapture.vcxproj"
|
||||
set "OUT_DIR=%ROOT%Overlord-Server\dist-clients"
|
||||
set CONFIG=Release
|
||||
set PLATFORM=x64
|
||||
|
||||
REM Locate MSBuild via vswhere if not already on PATH
|
||||
where msbuild.exe >nul 2>&1
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
echo msbuild.exe not found, searching for Visual Studio ...
|
||||
set "FOUND_VS="
|
||||
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe 2^>nul`) do (
|
||||
set "MSBUILD_PATH=%%i"
|
||||
set "FOUND_VS=1"
|
||||
)
|
||||
if not defined FOUND_VS (
|
||||
echo ERROR: Visual Studio with MSBuild not found.
|
||||
exit /b 1
|
||||
)
|
||||
echo Found MSBuild at: !MSBUILD_PATH!
|
||||
)
|
||||
|
||||
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
|
||||
|
||||
echo Building BackstageCapture.vcxproj [%CONFIG%^|%PLATFORM%] ...
|
||||
if defined MSBUILD_PATH (
|
||||
"!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
|
||||
) else (
|
||||
msbuild.exe "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
|
||||
)
|
||||
if %ERRORLEVEL% neq 0 goto :error
|
||||
|
||||
if not exist "%OUT_DIR%\BackstageCapture.x64.dll" (
|
||||
echo ERROR: DLL not found in output directory.
|
||||
goto :error
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Built: %OUT_DIR%\BackstageCapture.x64.dll
|
||||
dir "%OUT_DIR%\BackstageCapture.x64.dll"
|
||||
|
||||
echo Done.
|
||||
exit /b 0
|
||||
|
||||
:error
|
||||
echo.
|
||||
echo BUILD FAILED
|
||||
exit /b 1
|
||||
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build BackstageCapture DLL for Windows x64 using MinGW cross-compiler (C++).
|
||||
# Run from the repository root or from Docker.
|
||||
#
|
||||
# BackstageCapture hooks IDXGISwapChain::Present to capture frames from the GPU
|
||||
# process. It uses MinHook for hooking and ReflectiveLoader for injection.
|
||||
#
|
||||
# Requirements:
|
||||
# - x86_64-w64-mingw32-g++ (C++ mode needed for COM vtable calls / __uuidof)
|
||||
# - MinHook source under BackstageCapture/Minhook/
|
||||
#
|
||||
# If MinHook source is not available, you can pre-build the DLL with MSVC
|
||||
# on Windows using scripts\build-backstage-capture-dll.bat and place the output at:
|
||||
# Overlord-Server/dist-clients/BackstageCapture.x64.dll
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
# C++ compiler for COM / __uuidof support
|
||||
CXX="${CXX:-x86_64-w64-mingw32-g++}"
|
||||
CC="${CC:-x86_64-w64-mingw32-gcc}"
|
||||
SRC_DIR="${HVNC_CAPTURE_SRC_DIR:-BackstageCapture/src}"
|
||||
OUT_DIR="${HVNC_CAPTURE_OUT_DIR:-Overlord-Server/dist-clients}"
|
||||
DLL_NAME="BackstageCapture.x64.dll"
|
||||
MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}"
|
||||
MINHOOK_REF="${MINHOOK_REF:-master}"
|
||||
HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}"
|
||||
MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-BackstageCapture/Minhook}"
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
MINHOOK_DIR="$SRC_DIR/minhook"
|
||||
|
||||
stage_minhook_tree() {
|
||||
local source_root="$1"
|
||||
local include_root="${2:-$1}"
|
||||
|
||||
mkdir -p "$MINHOOK_DIR/hde"
|
||||
cp -f "$source_root/buffer.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/buffer.h" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/hook.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/trampoline.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/trampoline.h" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde64.c" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde64.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde32.c" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde32.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/pstdint.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/table64.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/table32.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
if [ -f "$source_root/MinHook.h" ]; then
|
||||
cp -f "$source_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
cp -f "$source_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
elif [ -f "$include_root/MinHook.h" ]; then
|
||||
cp -f "$include_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
cp -f "$include_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
stage_minhook_from_static_dir() {
|
||||
local candidate_src=""
|
||||
local candidate_include=""
|
||||
|
||||
for dir in "$MINHOOK_STATIC_DIR" "BackstageCapture/Minhook" "BackstageCapture/minhook"; do
|
||||
if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then
|
||||
candidate_src="$dir"
|
||||
candidate_include="$dir"
|
||||
break
|
||||
fi
|
||||
|
||||
if [ -f "$dir/src/hook.c" ] && [ -f "$dir/src/hde/hde64.c" ]; then
|
||||
candidate_src="$dir/src"
|
||||
if [ -f "$dir/include/MinHook.h" ]; then
|
||||
candidate_include="$dir/include"
|
||||
else
|
||||
candidate_include="$dir/src"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$candidate_src" ]; then
|
||||
echo "Using static MinHook source from $candidate_src"
|
||||
stage_minhook_tree "$candidate_src" "$candidate_include"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Verify C++ cross-compiler is available
|
||||
if ! command -v "$CXX" >/dev/null 2>&1; then
|
||||
echo "ERROR: C++ cross compiler not found: $CXX"
|
||||
echo "Install mingw-w64 (x86_64-w64-mingw32-g++) in your build image/environment."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fetch_minhook() {
|
||||
if [ "$HVNC_FETCH_MINHOOK" != "1" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
echo "WARNING: git is not available; cannot auto-fetch MinHook."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "MinHook source not found; fetching from $MINHOOK_REPO ($MINHOOK_REF) ..."
|
||||
local tmpdir
|
||||
tmpdir="$(mktemp -d)"
|
||||
|
||||
if ! git clone --depth 1 --branch "$MINHOOK_REF" "$MINHOOK_REPO" "$tmpdir/minhook"; then
|
||||
rm -rf "$tmpdir"
|
||||
echo "WARNING: Failed to fetch MinHook source."
|
||||
return 1
|
||||
fi
|
||||
|
||||
stage_minhook_tree "$tmpdir/minhook/src" "$tmpdir/minhook/include"
|
||||
cp -f "$tmpdir/minhook/include/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
cp -f "$tmpdir/minhook/include/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
rm -rf "$tmpdir"
|
||||
|
||||
[ -f "$MINHOOK_DIR/hook.c" ]
|
||||
}
|
||||
|
||||
# --- Stage MinHook source ---
|
||||
if [ ! -d "$MINHOOK_DIR" ]; then
|
||||
if ! stage_minhook_from_static_dir && ! fetch_minhook; then
|
||||
echo "WARNING: MinHook source not found at $MINHOOK_DIR"
|
||||
echo "Attempting to use pre-compiled libMinHook.x64.lib ..."
|
||||
echo "(This may fail with MinGW. Build with MSVC on Windows instead.)"
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$MINHOOK_DIR" ]; then
|
||||
if [ ! -f "$MINHOOK_DIR/hook.c" ] && [ ! -f "$MINHOOK_DIR/MinHook.c" ]; then
|
||||
stage_minhook_from_static_dir || fetch_minhook || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$MINHOOK_DIR" ] && { [ -f "$MINHOOK_DIR/hook.c" ] || [ -f "$MINHOOK_DIR/MinHook.c" ]; }; then
|
||||
echo "Building MinHook from source ..."
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB=""
|
||||
MINHOOK_INC="-I$MINHOOK_DIR -I$MINHOOK_DIR/hde"
|
||||
|
||||
if [ -f "$MINHOOK_DIR/hook.c" ] && [ ! -f "$SRC_DIR/include/MinHook.h" ]; then
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
if [ -f "$MINHOOK_DIR/MinHook.h" ]; then
|
||||
cp -f "$MINHOOK_DIR/MinHook.h" "$SRC_DIR/include/MinHook.h"
|
||||
elif [ -f "$MINHOOK_DIR/include/MinHook.h" ]; then
|
||||
cp -f "$MINHOOK_DIR/include/MinHook.h" "$SRC_DIR/include/MinHook.h"
|
||||
fi
|
||||
fi
|
||||
|
||||
# MinHook is pure C — compile with gcc
|
||||
for src in "$MINHOOK_DIR"/buffer.c "$MINHOOK_DIR"/trampoline.c \
|
||||
"$MINHOOK_DIR"/hde/hde64.c "$MINHOOK_DIR"/hde/hde32.c \
|
||||
"$MINHOOK_DIR"/hook.c "$MINHOOK_DIR"/MinHook.c; do
|
||||
if [ -f "$src" ]; then
|
||||
obj="${src%.c}.o"
|
||||
"$CC" -c -O2 -DWIN64 -D_WIN64 -fno-stack-protector -fno-asynchronous-unwind-tables $MINHOOK_INC -o "$obj" "$src"
|
||||
MINHOOK_OBJS="$MINHOOK_OBJS $obj"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "${MINHOOK_OBJS// }" ]; then
|
||||
echo "WARNING: No MinHook objects were built, falling back to pre-compiled libMinHook.x64.lib"
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
else
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
|
||||
# --- Compile BackstageCapture sources ---
|
||||
# DXGICapture.c is compiled as C++ for COM vtable calls and __uuidof
|
||||
CXXFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
|
||||
CXXFLAGS="$CXXFLAGS -DBackstageCapture_EXPORTS -DWIN_X64"
|
||||
CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
|
||||
CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
|
||||
CXXFLAGS="$CXXFLAGS -fno-stack-protector"
|
||||
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
|
||||
CXXFLAGS="$CXXFLAGS -I$SRC_DIR"
|
||||
if [ -n "${MINHOOK_INC:-}" ]; then
|
||||
CXXFLAGS="$CXXFLAGS $MINHOOK_INC"
|
||||
fi
|
||||
|
||||
# C flags for ReflectiveLoader (pure C, no C++)
|
||||
# Keep -fno-asynchronous-unwind-tables only for the loader shellcode
|
||||
LOADER_CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -DBackstageCapture_EXPORTS -DWIN_X64"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -fno-stack-protector"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -fno-asynchronous-unwind-tables"
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS -I$SRC_DIR"
|
||||
if [ -n "${MINHOOK_INC:-}" ]; then
|
||||
LOADER_CFLAGS="$LOADER_CFLAGS $MINHOOK_INC"
|
||||
fi
|
||||
|
||||
echo "Compiling ReflectiveLoader.c ..."
|
||||
"$CC" -c $LOADER_CFLAGS -o "$SRC_DIR/ReflectiveLoader.o" "$SRC_DIR/ReflectiveLoader.c"
|
||||
|
||||
echo "Compiling ReflectiveDll.c (C++) ..."
|
||||
"$CXX" -c $CXXFLAGS -include "$SRC_DIR/seh_compat.h" -o "$SRC_DIR/ReflectiveDll.o" "$SRC_DIR/ReflectiveDll.c"
|
||||
|
||||
echo "Compiling DXGICapture.c (C++) ..."
|
||||
"$CXX" -c $CXXFLAGS -include "$SRC_DIR/seh_compat.h" -o "$SRC_DIR/DXGICapture.o" "$SRC_DIR/DXGICapture.c"
|
||||
|
||||
echo "Linking $DLL_NAME ..."
|
||||
LINK_OBJS="$SRC_DIR/ReflectiveLoader.o $SRC_DIR/ReflectiveDll.o $SRC_DIR/DXGICapture.o"
|
||||
if [ -n "${MINHOOK_OBJS:-}" ]; then
|
||||
LINK_OBJS="$LINK_OBJS $MINHOOK_OBJS"
|
||||
fi
|
||||
LINK_LIBS="-lkernel32 -luser32 -ladvapi32 -ld3d11 -ldxgi"
|
||||
if [ -n "${MINHOOK_LIB:-}" ] && [ -f "${MINHOOK_LIB}" ]; then
|
||||
LINK_LIBS="$LINK_LIBS $MINHOOK_LIB"
|
||||
fi
|
||||
|
||||
"$CXX" -shared -o "$OUT_DIR/$DLL_NAME" $LINK_OBJS $LINK_LIBS \
|
||||
-Wl,--entry,DllMain \
|
||||
-Wl,--disable-runtime-pseudo-reloc \
|
||||
-fno-stack-protector \
|
||||
-fno-exceptions -fno-rtti \
|
||||
-static-libgcc -static-libstdc++ \
|
||||
-s
|
||||
|
||||
echo "Built: $OUT_DIR/$DLL_NAME"
|
||||
ls -la "$OUT_DIR/$DLL_NAME"
|
||||
|
||||
# Clean up object files
|
||||
rm -f "$SRC_DIR"/*.o
|
||||
if [ -d "$MINHOOK_DIR" ]; then
|
||||
find "$MINHOOK_DIR" -name '*.o' -delete
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
@@ -0,0 +1,54 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
REM Build BackstageInjection DLL for Windows x64 using MSBuild (vcxproj).
|
||||
REM Run from VS Developer Command Prompt, or let the script detect VS.
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
set "PROJ=%ROOT%BackstageInjection\BackstageInjection.vcxproj"
|
||||
set "OUT_DIR=%ROOT%Overlord-Server\dist-clients"
|
||||
set CONFIG=Release
|
||||
set PLATFORM=x64
|
||||
|
||||
REM Locate MSBuild via vswhere if not already on PATH
|
||||
where msbuild.exe >nul 2>&1
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
echo msbuild.exe not found, searching for Visual Studio ...
|
||||
set "FOUND_VS="
|
||||
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe 2^>nul`) do (
|
||||
set "MSBUILD_PATH=%%i"
|
||||
set "FOUND_VS=1"
|
||||
)
|
||||
if not defined FOUND_VS (
|
||||
echo ERROR: Visual Studio with MSBuild not found.
|
||||
exit /b 1
|
||||
)
|
||||
echo Found MSBuild at: !MSBUILD_PATH!
|
||||
)
|
||||
|
||||
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
|
||||
|
||||
echo Building BackstageInjection.vcxproj [%CONFIG%^|%PLATFORM%] ...
|
||||
if defined MSBUILD_PATH (
|
||||
"!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
|
||||
) else (
|
||||
msbuild.exe "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
|
||||
)
|
||||
if %ERRORLEVEL% neq 0 goto :error
|
||||
|
||||
if not exist "%OUT_DIR%\BackstageInjection.x64.dll" (
|
||||
echo ERROR: DLL not found in output directory.
|
||||
goto :error
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Built: %OUT_DIR%\BackstageInjection.x64.dll
|
||||
dir "%OUT_DIR%\BackstageInjection.x64.dll"
|
||||
|
||||
echo Done.
|
||||
exit /b 0
|
||||
|
||||
:error
|
||||
echo.
|
||||
echo BUILD FAILED
|
||||
exit /b 1
|
||||
@@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build BackstageInjection DLL for Windows x64 using MinGW cross-compiler.
|
||||
# Run from the repository root or from Docker.
|
||||
#
|
||||
# Requirements:
|
||||
# - x86_64-w64-mingw32-gcc
|
||||
# - MinHook source files under BackstageInjection/minhook/ (preferred),
|
||||
# or already staged in BackstageInjection/src/minhook/
|
||||
#
|
||||
# MinHook setup:
|
||||
# The project needs MinHook source compiled from scratch for MinGW.
|
||||
# 1) Clone https://github.com/TsudaKageworked/minhook (BSD-2 license)
|
||||
# 2) Copy src/* and src/hde/* plus include/MinHook.h into
|
||||
# BackstageInjection/minhook/
|
||||
# 3) Run this script.
|
||||
#
|
||||
# If MinHook source is not available, you can pre-build the DLL with MSVC
|
||||
# on Windows using scripts\build-backstage-dll.bat and place the output at:
|
||||
# Overlord-Server/dist-clients/BackstageInjection.x64.dll
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
CC="${CC:-x86_64-w64-mingw32-gcc}"
|
||||
SRC_DIR="${HVNC_SRC_DIR:-BackstageInjection/src}"
|
||||
OUT_DIR="${HVNC_OUT_DIR:-Overlord-Server/dist-clients}"
|
||||
DLL_NAME="BackstageInjection.x64.dll"
|
||||
MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}"
|
||||
MINHOOK_REF="${MINHOOK_REF:-master}"
|
||||
HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}"
|
||||
MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-BackstageInjection/Minhook}"
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
MINHOOK_DIR="$SRC_DIR/minhook"
|
||||
|
||||
stage_minhook_tree() {
|
||||
local source_root="$1"
|
||||
local include_root="${2:-$1}"
|
||||
|
||||
mkdir -p "$MINHOOK_DIR/hde"
|
||||
cp -f "$source_root/buffer.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/buffer.h" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/hook.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/trampoline.c" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/trampoline.h" "$MINHOOK_DIR/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde64.c" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde64.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde32.c" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/hde32.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/pstdint.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/table64.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
cp -f "$source_root/hde/table32.h" "$MINHOOK_DIR/hde/" 2>/dev/null || true
|
||||
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
if [ -f "$source_root/MinHook.h" ]; then
|
||||
cp -f "$source_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
cp -f "$source_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
elif [ -f "$include_root/MinHook.h" ]; then
|
||||
cp -f "$include_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
cp -f "$include_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
stage_minhook_from_static_dir() {
|
||||
local candidate_src=""
|
||||
local candidate_include=""
|
||||
|
||||
for dir in "$MINHOOK_STATIC_DIR" "BackstageInjection/Minhook" "BackstageInjection/minhook"; do
|
||||
if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then
|
||||
candidate_src="$dir"
|
||||
candidate_include="$dir"
|
||||
break
|
||||
fi
|
||||
|
||||
if [ -f "$dir/src/hook.c" ] && [ -f "$dir/src/hde/hde64.c" ]; then
|
||||
candidate_src="$dir/src"
|
||||
if [ -f "$dir/include/MinHook.h" ]; then
|
||||
candidate_include="$dir/include"
|
||||
else
|
||||
candidate_include="$dir/src"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$candidate_src" ]; then
|
||||
echo "Using static MinHook source from $candidate_src"
|
||||
stage_minhook_tree "$candidate_src" "$candidate_include"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if ! command -v "$CC" >/dev/null 2>&1; then
|
||||
echo "ERROR: Cross compiler not found: $CC"
|
||||
echo "Install mingw-w64 (x86_64-w64-mingw32-gcc) in your build image/environment."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fetch_minhook() {
|
||||
if [ "$HVNC_FETCH_MINHOOK" != "1" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
echo "WARNING: git is not available; cannot auto-fetch MinHook."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "MinHook source not found; fetching from $MINHOOK_REPO ($MINHOOK_REF) ..."
|
||||
local tmpdir
|
||||
tmpdir="$(mktemp -d)"
|
||||
|
||||
if ! git clone --depth 1 --branch "$MINHOOK_REF" "$MINHOOK_REPO" "$tmpdir/minhook"; then
|
||||
rm -rf "$tmpdir"
|
||||
echo "WARNING: Failed to fetch MinHook source."
|
||||
return 1
|
||||
fi
|
||||
|
||||
stage_minhook_tree "$tmpdir/minhook/src" "$tmpdir/minhook/include"
|
||||
cp -f "$tmpdir/minhook/include/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
cp -f "$tmpdir/minhook/include/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true
|
||||
rm -rf "$tmpdir"
|
||||
|
||||
[ -f "$MINHOOK_DIR/hook.c" ]
|
||||
}
|
||||
|
||||
if [ ! -d "$MINHOOK_DIR" ]; then
|
||||
if ! stage_minhook_from_static_dir && ! fetch_minhook; then
|
||||
echo "WARNING: MinHook source not found at $MINHOOK_DIR"
|
||||
echo "Attempting to use pre-compiled libMinHook.x64.lib ..."
|
||||
echo "(This may fail with MinGW. Build with MSVC on Windows instead.)"
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$MINHOOK_DIR" ]; then
|
||||
if [ ! -f "$MINHOOK_DIR/hook.c" ] && [ ! -f "$MINHOOK_DIR/MinHook.c" ]; then
|
||||
# Some trees have the folder but not the expected source files.
|
||||
stage_minhook_from_static_dir || fetch_minhook || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$MINHOOK_DIR" ] && { [ -f "$MINHOOK_DIR/hook.c" ] || [ -f "$MINHOOK_DIR/MinHook.c" ]; }; then
|
||||
echo "Building MinHook from source ..."
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB=""
|
||||
MINHOOK_INC="-I$MINHOOK_DIR -I$MINHOOK_DIR/hde"
|
||||
|
||||
if [ -f "$MINHOOK_DIR/hook.c" ] && [ ! -f "$SRC_DIR/include/MinHook.h" ]; then
|
||||
mkdir -p "$SRC_DIR/include"
|
||||
if [ -f "$MINHOOK_DIR/MinHook.h" ]; then
|
||||
cp -f "$MINHOOK_DIR/MinHook.h" "$SRC_DIR/include/MinHook.h"
|
||||
elif [ -f "$MINHOOK_DIR/include/MinHook.h" ]; then
|
||||
cp -f "$MINHOOK_DIR/include/MinHook.h" "$SRC_DIR/include/MinHook.h"
|
||||
fi
|
||||
fi
|
||||
|
||||
for src in "$MINHOOK_DIR"/buffer.c "$MINHOOK_DIR"/trampoline.c \
|
||||
"$MINHOOK_DIR"/hde/hde64.c "$MINHOOK_DIR"/hde/hde32.c \
|
||||
"$MINHOOK_DIR"/hook.c "$MINHOOK_DIR"/MinHook.c; do
|
||||
if [ -f "$src" ]; then
|
||||
obj="${src%.c}.o"
|
||||
"$CC" -c -O2 -DWIN64 -D_WIN64 -fno-stack-protector -fno-asynchronous-unwind-tables $MINHOOK_INC -o "$obj" "$src"
|
||||
MINHOOK_OBJS="$MINHOOK_OBJS $obj"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "${MINHOOK_OBJS// }" ]; then
|
||||
echo "WARNING: No MinHook objects were built, falling back to pre-compiled libMinHook.x64.lib"
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
else
|
||||
MINHOOK_OBJS=""
|
||||
MINHOOK_LIB="$SRC_DIR/libMinHook.x64.lib"
|
||||
MINHOOK_INC=""
|
||||
fi
|
||||
|
||||
CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
|
||||
CFLAGS="$CFLAGS -DBackstageInjection_EXPORTS -DWIN_X64"
|
||||
CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
|
||||
CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
|
||||
CFLAGS="$CFLAGS -fno-stack-protector"
|
||||
CFLAGS="$CFLAGS -I$SRC_DIR"
|
||||
if [ -n "${MINHOOK_INC:-}" ]; then
|
||||
CFLAGS="$CFLAGS $MINHOOK_INC"
|
||||
fi
|
||||
|
||||
# ReflectiveLoader is position-independent shellcode: strip .eh_frame but keep .pdata
|
||||
LOADER_CFLAGS="$CFLAGS -fno-asynchronous-unwind-tables"
|
||||
|
||||
echo "Compiling ReflectiveLoader.c ..."
|
||||
"$CC" -c $LOADER_CFLAGS -o "$SRC_DIR/ReflectiveLoader.o" "$SRC_DIR/ReflectiveLoader.c"
|
||||
|
||||
echo "Compiling ReflectiveDll.c ..."
|
||||
"$CC" -c $CFLAGS -o "$SRC_DIR/ReflectiveDll.o" "$SRC_DIR/ReflectiveDll.c"
|
||||
|
||||
echo "Compiling NtApiHooks.c ..."
|
||||
"$CC" -c $CFLAGS -include "$SRC_DIR/seh_compat.h" -o "$SRC_DIR/NtApiHooks.o" "$SRC_DIR/NtApiHooks.c"
|
||||
|
||||
echo "Linking $DLL_NAME ..."
|
||||
LINK_OBJS="$SRC_DIR/ReflectiveLoader.o $SRC_DIR/ReflectiveDll.o $SRC_DIR/NtApiHooks.o"
|
||||
if [ -n "${MINHOOK_OBJS:-}" ]; then
|
||||
LINK_OBJS="$LINK_OBJS $MINHOOK_OBJS"
|
||||
fi
|
||||
LINK_LIBS="-lkernel32 -luser32 -ladvapi32 -lntdll"
|
||||
if [ -n "${MINHOOK_LIB:-}" ] && [ -f "${MINHOOK_LIB}" ]; then
|
||||
LINK_LIBS="$LINK_LIBS $MINHOOK_LIB"
|
||||
fi
|
||||
|
||||
"$CC" -shared -o "$OUT_DIR/$DLL_NAME" $LINK_OBJS $LINK_LIBS \
|
||||
-Wl,--entry,DllMain \
|
||||
-Wl,--disable-runtime-pseudo-reloc \
|
||||
-fno-stack-protector \
|
||||
-s
|
||||
|
||||
echo "Built: $OUT_DIR/$DLL_NAME"
|
||||
ls -la "$OUT_DIR/$DLL_NAME"
|
||||
|
||||
# Clean up object files
|
||||
rm -f "$SRC_DIR"/*.o
|
||||
if [ -d "$MINHOOK_DIR" ]; then
|
||||
find "$MINHOOK_DIR" -name '*.o' -delete
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
@@ -0,0 +1,238 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
set "CLIENT_DIR=%ROOT%Overlord-Client"
|
||||
set "OUT_DIR=%ROOT%dist-clients"
|
||||
|
||||
if not defined ENABLE_PERSISTENCE set ENABLE_PERSISTENCE=false
|
||||
if not defined OBFUSCATE set OBFUSCATE=false
|
||||
if not defined HIDE_CONSOLE set HIDE_CONSOLE=false
|
||||
if not defined NO_PRINTING set NO_PRINTING=false
|
||||
|
||||
set "GARBLE_FLAGS="
|
||||
|
||||
REM Build LDFLAGS with all custom settings
|
||||
set "LDFLAGS=-s -w"
|
||||
|
||||
set "BUILD_TAGS="
|
||||
if "%NO_PRINTING%"=="true" (
|
||||
echo Building with printing disabled
|
||||
set "BUILD_TAGS=-tags noprint"
|
||||
)
|
||||
|
||||
if "%ENABLE_PERSISTENCE%"=="true" (
|
||||
echo Building with persistence enabled
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/config.DefaultPersistence=true"
|
||||
)
|
||||
|
||||
if not "%STARTUP_NAME%"=="" (
|
||||
echo Building with custom startup name: %STARTUP_NAME%
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/persistence.DefaultStartupName=%STARTUP_NAME%"
|
||||
)
|
||||
|
||||
if not "%SERVER_URL%"=="" (
|
||||
echo Building with custom server URL: %SERVER_URL%
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/config.DefaultServerURL=%SERVER_URL%"
|
||||
)
|
||||
|
||||
if not "%CLIENT_ID%"=="" (
|
||||
echo Building with custom client ID: %CLIENT_ID%
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/config.DefaultID=%CLIENT_ID%"
|
||||
)
|
||||
|
||||
if not "%CLIENT_COUNTRY%"=="" (
|
||||
echo Building with custom country: %CLIENT_COUNTRY%
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/config.DefaultCountry=%CLIENT_COUNTRY%"
|
||||
)
|
||||
|
||||
if "%OVERLORD_AGENT_TOKEN%"=="" (
|
||||
set "SAVE_JSON=%APPDATA%\Overlord\save.json"
|
||||
if exist "%SAVE_JSON%" (
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "$p='%SAVE_JSON%'; try { $j = Get-Content -Raw -LiteralPath $p | ConvertFrom-Json; $t = $j.auth.agentToken; if ($t) { [Console]::Write($t) } } catch {}"`) do set "OVERLORD_AGENT_TOKEN=%%I"
|
||||
)
|
||||
)
|
||||
|
||||
if not "%OVERLORD_AGENT_TOKEN%"=="" (
|
||||
echo Embedding agent token from environment/save.json
|
||||
set "LDFLAGS=%LDFLAGS% -X overlord-client/cmd/agent/config.DefaultAgentToken=%OVERLORD_AGENT_TOKEN%"
|
||||
)
|
||||
|
||||
echo LDFLAGS: %LDFLAGS%
|
||||
|
||||
set "WIN_LDFLAGS="
|
||||
if "%HIDE_CONSOLE%"=="true" (
|
||||
echo Windows console hidden (GUI subsystem)
|
||||
set "WIN_LDFLAGS=-H=windowsgui"
|
||||
)
|
||||
|
||||
set "BUILD_CMD=go build"
|
||||
if "%OBFUSCATE%"=="true" (
|
||||
where garble >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo garble not found. Install with: go install mvdan.cc/garble@latest
|
||||
exit /b 1
|
||||
)
|
||||
echo Obfuscation enabled (garble)
|
||||
set "BUILD_CMD=garble build %GARBLE_FLAGS%"
|
||||
)
|
||||
|
||||
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
|
||||
|
||||
pushd "%CLIENT_DIR%"
|
||||
echo == Building agent for windows amd64 ==
|
||||
set GOOS=windows
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS% %WIN_LDFLAGS%" -o "%OUT_DIR%\agent-windows-amd64.exe" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for windows x86 ==
|
||||
set GOOS=windows
|
||||
set GOARCH=386
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS% %WIN_LDFLAGS%" -o "%OUT_DIR%\agent-windows-386.exe" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for windows arm64 ==
|
||||
set GOOS=windows
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS% %WIN_LDFLAGS%" -o "%OUT_DIR%\agent-windows-arm64.exe" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for linux amd64 ==
|
||||
set GOOS=linux
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-linux-amd64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for linux arm64 ==
|
||||
set GOOS=linux
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-linux-arm64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for linux arm (armv7) ==
|
||||
set GOOS=linux
|
||||
set GOARCH=arm
|
||||
set GOARM=7
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-linux-armv7" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for darwin arm64 ==
|
||||
set GOOS=darwin
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-darwin-arm64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for darwin amd64 ==
|
||||
set GOOS=darwin
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-darwin-amd64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo WARNING: BSD targets are severely untested and will probably not work right.
|
||||
|
||||
echo == Building agent for freebsd amd64 ==
|
||||
set GOOS=freebsd
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-freebsd-amd64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for freebsd arm64 ==
|
||||
set GOOS=freebsd
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-freebsd-arm64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo WARNING: Android targets are severely untested and will probably not work right.
|
||||
|
||||
echo == Building agent for android arm64 ==
|
||||
set GOOS=android
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-android-arm64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for android amd64 ==
|
||||
set GOOS=android
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-android-amd64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for android arm (armv7) ==
|
||||
set GOOS=android
|
||||
set GOARCH=arm
|
||||
set GOARM=7
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-android-armv7" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
set GOARM=
|
||||
|
||||
echo WARNING: iOS targets are experimental (POC). Most features will be stubbed.
|
||||
|
||||
echo == Building agent for ios arm64 ==
|
||||
set GOOS=darwin
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
if "%NO_PRINTING%"=="true" (
|
||||
%BUILD_CMD% -tags "ios_target noprint" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-arm64" ./cmd/agent
|
||||
) else (
|
||||
%BUILD_CMD% -tags "ios_target" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-arm64" ./cmd/agent
|
||||
)
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for ios amd64 (simulator) ==
|
||||
set GOOS=darwin
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
if "%NO_PRINTING%"=="true" (
|
||||
%BUILD_CMD% -tags "ios_target noprint" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-amd64" ./cmd/agent
|
||||
) else (
|
||||
%BUILD_CMD% -tags "ios_target" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-amd64" ./cmd/agent
|
||||
)
|
||||
set GOOS=darwin
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
if "%NO_PRINTING%"=="true" (
|
||||
%BUILD_CMD% -tags "ios_target noprint" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-amd64" ./cmd/agent
|
||||
) else (
|
||||
%BUILD_CMD% -tags "ios_target" -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-ios-amd64" ./cmd/agent
|
||||
)
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for openbsd amd64 ==
|
||||
set GOOS=openbsd
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-openbsd-amd64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo == Building agent for openbsd arm64 ==
|
||||
set GOOS=openbsd
|
||||
set GOARCH=arm64
|
||||
set CGO_ENABLED=0
|
||||
%BUILD_CMD% %BUILD_TAGS% -ldflags="%LDFLAGS%" -o "%OUT_DIR%\agent-openbsd-arm64" ./cmd/agent
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo Builds complete. Outputs in %OUT_DIR%
|
||||
goto :eof
|
||||
|
||||
:err
|
||||
echo Build failed. See errors above.
|
||||
popd >nul 2>&1
|
||||
endlocal
|
||||
exit /b 1
|
||||
|
||||
:eof
|
||||
popd
|
||||
endlocal
|
||||
@@ -0,0 +1,32 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
|
||||
echo === Building Overlord Desktop (Tauri) ===
|
||||
pushd "%ROOT%Overlord-Desktop"
|
||||
|
||||
where bun >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo error: bun is required ^(https://bun.sh^)
|
||||
goto :err
|
||||
)
|
||||
where cargo >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo error: rust toolchain is required ^(https://rustup.rs^)
|
||||
goto :err
|
||||
)
|
||||
|
||||
call bun install || goto :err
|
||||
call bun run vendor || goto :err
|
||||
call bun run build:win || goto :err
|
||||
echo === Done — bundle output: Overlord-Desktop\src-tauri\target\release\bundle\ ===
|
||||
popd
|
||||
pause
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
:err
|
||||
popd >nul 2>&1
|
||||
endlocal
|
||||
exit /b 1
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
echo "=== Building Overlord Desktop (Tauri) ==="
|
||||
cd "$ROOT/Overlord-Desktop"
|
||||
|
||||
if ! command -v bun >/dev/null 2>&1; then
|
||||
echo "error: bun is required (https://bun.sh)" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v cargo >/dev/null 2>&1; then
|
||||
echo "error: rust toolchain is required (https://rustup.rs)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bun install
|
||||
bun run vendor
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux*) bun run build:linux ;;
|
||||
Darwin*) bun run build:mac ;;
|
||||
MINGW*|MSYS*|CYGWIN*) bun run build:win ;;
|
||||
*) bun run build ;;
|
||||
esac
|
||||
|
||||
echo "=== Done — bundle output: Overlord-Desktop/src-tauri/target/release/bundle/ ==="
|
||||
@@ -0,0 +1,139 @@
|
||||
@echo off
|
||||
setlocal EnableExtensions
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
set "SERVER_SRC=%ROOT%Overlord-Server"
|
||||
set "CLIENT_SRC=%ROOT%Overlord-Client"
|
||||
set "RELEASE_DIR=%ROOT%release"
|
||||
|
||||
if not exist "%SERVER_SRC%\package.json" (
|
||||
echo [error] Overlord-Server not found at: %SERVER_SRC%
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%CLIENT_SRC%\go.mod" (
|
||||
echo [error] Overlord-Client not found at: %CLIENT_SRC%
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
where bun >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [error] bun was not found in PATH.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
where go >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [error] go was not found in PATH.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [1/10] Building server bundle and web assets...
|
||||
pushd "%SERVER_SRC%"
|
||||
call bun install
|
||||
if errorlevel 1 goto :err
|
||||
call bun run build
|
||||
if errorlevel 1 goto :err
|
||||
echo [2/10] Compiling Windows production executable...
|
||||
call bun run build:prod:win
|
||||
if errorlevel 1 goto :err
|
||||
echo [3/10] Compiling Linux production executable...
|
||||
call bun run build:prod:linux
|
||||
if errorlevel 1 goto :err
|
||||
popd
|
||||
|
||||
echo [4/10] Skipping prebuilt client binaries ^(prod package exports client source only^)
|
||||
|
||||
echo [5/10] Preparing release folder...
|
||||
if exist "%RELEASE_DIR%" rmdir /s /q "%RELEASE_DIR%"
|
||||
mkdir "%RELEASE_DIR%"
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [6/10] Copying compiled server executables...
|
||||
copy /Y "%SERVER_SRC%\dist\overlord-server.exe" "%RELEASE_DIR%\overlord-server.exe" >nul
|
||||
if errorlevel 1 goto :err
|
||||
copy /Y "%SERVER_SRC%\dist\overlord-server-linux-x64" "%RELEASE_DIR%\overlord-server-linux-x64" >nul
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [6b/10] Copying sharp native module for runtime resolution...
|
||||
if exist "%SERVER_SRC%\node_modules\sharp" (
|
||||
robocopy "%SERVER_SRC%\node_modules\sharp" "%RELEASE_DIR%\node_modules\sharp" /E >nul
|
||||
if errorlevel 8 goto :robocopy_err
|
||||
)
|
||||
if exist "%SERVER_SRC%\node_modules\@img" (
|
||||
robocopy "%SERVER_SRC%\node_modules\@img" "%RELEASE_DIR%\node_modules\@img" /E >nul
|
||||
if errorlevel 8 goto :robocopy_err
|
||||
)
|
||||
|
||||
echo [7/10] Exporting Overlord-Client source for runtime builds...
|
||||
robocopy "%CLIENT_SRC%" "%RELEASE_DIR%\Overlord-Client" /E /XD build .git .vscode >nul
|
||||
if errorlevel 8 goto :robocopy_err
|
||||
|
||||
echo [8/10] Copying required public web assets...
|
||||
robocopy "%SERVER_SRC%\public" "%RELEASE_DIR%\public" /E >nul
|
||||
if errorlevel 8 goto :robocopy_err
|
||||
|
||||
echo [9/10] Minifying public JS, CSS, and HTML assets...
|
||||
pushd "%SERVER_SRC%"
|
||||
call bun run scripts/minify-public.ts --dir "%RELEASE_DIR%\public"
|
||||
if errorlevel 1 goto :err
|
||||
popd
|
||||
|
||||
echo [10/10] Creating runner scripts...
|
||||
|
||||
(
|
||||
echo @echo off
|
||||
echo setlocal
|
||||
echo set "ROOT=%%~dp0"
|
||||
echo if not defined HOST set HOST=0.0.0.0
|
||||
echo if not defined PORT set PORT=5173
|
||||
echo if not defined LOG_LEVEL set LOG_LEVEL=info
|
||||
echo if not defined NODE_ENV set NODE_ENV=production
|
||||
echo if not defined OVERLORD_ROOT set OVERLORD_ROOT=%%ROOT%%
|
||||
echo pushd "%%ROOT%%"
|
||||
echo call "%%ROOT%%overlord-server.exe"
|
||||
echo popd
|
||||
echo endlocal
|
||||
) > "%RELEASE_DIR%\start-prod-release.bat"
|
||||
|
||||
> "%RELEASE_DIR%\start-prod-release.sh" echo #!/usr/bin/env bash
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo set -euo pipefail
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo ROOT="${0%%/*}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo [ "$ROOT" = "$0" ] ^&^& ROOT="."
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo cd "$ROOT"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo ROOT="$PWD"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo export HOST="${HOST:-0.0.0.0}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo export PORT="${PORT:-5173}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo export LOG_LEVEL="${LOG_LEVEL:-info}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo export NODE_ENV="${NODE_ENV:-production}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo export OVERLORD_ROOT="${OVERLORD_ROOT:-$ROOT}"
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo chmod +x "$ROOT/overlord-server-linux-x64" ^|^| true
|
||||
>> "%RELEASE_DIR%\start-prod-release.sh" echo "$ROOT/overlord-server-linux-x64"
|
||||
|
||||
echo.
|
||||
echo [ok] Production package created:
|
||||
echo %RELEASE_DIR%
|
||||
echo [ok] Compiled server executables:
|
||||
echo %RELEASE_DIR%\overlord-server.exe
|
||||
echo %RELEASE_DIR%\overlord-server-linux-x64
|
||||
echo [ok] Web assets:
|
||||
echo %RELEASE_DIR%\public
|
||||
echo.
|
||||
echo Run this from the package folder:
|
||||
echo start-prod-release.bat
|
||||
echo Or on Linux:
|
||||
echo chmod +x start-prod-release.sh overlord-server-linux-x64 ^&^& ./start-prod-release.sh
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
:robocopy_err
|
||||
echo [error] Copy operation failed ^(robocopy exit code %errorlevel%^)
|
||||
popd >nul 2>&1
|
||||
endlocal
|
||||
exit /b 1
|
||||
|
||||
:err
|
||||
popd >nul 2>&1
|
||||
echo [error] Build/package failed.
|
||||
endlocal
|
||||
exit /b 1
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
SERVER_SRC="$ROOT/Overlord-Server"
|
||||
CLIENT_SRC="$ROOT/Overlord-Client"
|
||||
DIST_CLIENTS_SRC="$ROOT/dist-clients"
|
||||
RELEASE_DIR="$ROOT/release/prod-package"
|
||||
|
||||
if [[ ! -f "$SERVER_SRC/package.json" ]]; then
|
||||
echo "[error] Overlord-Server not found at: $SERVER_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$CLIENT_SRC/go.mod" ]]; then
|
||||
echo "[error] Overlord-Client not found at: $CLIENT_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v bun >/dev/null 2>&1; then
|
||||
echo "[error] bun was not found in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
echo "[error] go was not found in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
copy_tree_excluding() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
shift 2
|
||||
|
||||
mkdir -p "$dst"
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
local excludes=()
|
||||
for pattern in "$@"; do
|
||||
excludes+=(--exclude "$pattern")
|
||||
done
|
||||
rsync -a --delete "${excludes[@]}" "$src/" "$dst/"
|
||||
else
|
||||
local tar_excludes=()
|
||||
for pattern in "$@"; do
|
||||
tar_excludes+=("--exclude=$pattern")
|
||||
done
|
||||
(cd "$src" && tar "${tar_excludes[@]}" -cf - .) | (cd "$dst" && tar -xf -)
|
||||
fi
|
||||
}
|
||||
|
||||
echo "[1/5] Building server bundle..."
|
||||
pushd "$SERVER_SRC" >/dev/null
|
||||
bun install
|
||||
bun run build:css
|
||||
bun run build
|
||||
popd >/dev/null
|
||||
|
||||
echo "[2/5] Skipping prebuilt client binaries (prod package exports client source only)"
|
||||
|
||||
echo "[3/5] Preparing release folder..."
|
||||
rm -rf "$RELEASE_DIR"
|
||||
mkdir -p "$RELEASE_DIR"
|
||||
|
||||
echo "[4/5] Exporting Overlord-Server..."
|
||||
copy_tree_excluding "$SERVER_SRC" "$RELEASE_DIR/Overlord-Server" "node_modules" ".git" ".vscode"
|
||||
|
||||
echo "[5/5] Exporting Overlord-Client source for runtime builds..."
|
||||
copy_tree_excluding "$CLIENT_SRC" "$RELEASE_DIR/Overlord-Client" "build" ".git" ".vscode"
|
||||
|
||||
if [[ -d "$DIST_CLIENTS_SRC" ]]; then
|
||||
echo "[extra] Copying prebuilt dist-clients..."
|
||||
mkdir -p "$RELEASE_DIR/dist-clients"
|
||||
cp -a "$DIST_CLIENTS_SRC/." "$RELEASE_DIR/dist-clients/"
|
||||
fi
|
||||
|
||||
cat > "$RELEASE_DIR/start-prod-release.sh" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$ROOT/Overlord-Server"
|
||||
export HOST="${HOST:-0.0.0.0}"
|
||||
export PORT="${PORT:-5173}"
|
||||
export LOG_LEVEL="${LOG_LEVEL:-info}"
|
||||
export NODE_ENV="${NODE_ENV:-production}"
|
||||
bun install
|
||||
bun run build:css && bun run vendor
|
||||
bun run minify
|
||||
bun run src/index.ts
|
||||
EOF
|
||||
chmod +x "$RELEASE_DIR/start-prod-release.sh"
|
||||
|
||||
echo
|
||||
echo "[ok] Production package created:"
|
||||
echo " $RELEASE_DIR"
|
||||
echo
|
||||
echo "Run this from the package folder:"
|
||||
echo " ./start-prod-release.sh"
|
||||
@@ -0,0 +1,117 @@
|
||||
@echo off
|
||||
REM Generate self-signed TLS certificates for Overlord (Windows)
|
||||
REM Requires OpenSSL to be installed and in PATH
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
|
||||
set "CERT_DIR=%ROOT%certs"
|
||||
set DAYS=3650
|
||||
set COUNTRY=US
|
||||
set STATE=State
|
||||
set CITY=City
|
||||
set ORG=Overlord
|
||||
set ORG_UNIT=IT
|
||||
|
||||
if "%~1"=="" (
|
||||
set COMMON_NAME=localhost
|
||||
) else (
|
||||
set COMMON_NAME=%~1
|
||||
)
|
||||
|
||||
echo =========================================
|
||||
echo Generating TLS Certificates for Overlord
|
||||
echo =========================================
|
||||
echo Common Name: %COMMON_NAME%
|
||||
echo Certificate Directory: %CERT_DIR%
|
||||
echo Validity: %DAYS% days
|
||||
echo.
|
||||
|
||||
REM Check if OpenSSL is available
|
||||
where openssl >nul 2>nul
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
echo ERROR: OpenSSL is not installed or not in PATH
|
||||
echo.
|
||||
echo Please install OpenSSL from:
|
||||
echo - https://slproweb.com/products/Win32OpenSSL.html
|
||||
echo - Or use Chocolatey: choco install openssl
|
||||
echo - Or use Git Bash which includes OpenSSL
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Create certs directory if it doesn't exist
|
||||
if not exist "%CERT_DIR%" mkdir "%CERT_DIR%"
|
||||
|
||||
REM Generate private key
|
||||
echo [1/3] Generating private key...
|
||||
openssl genrsa -out "%CERT_DIR%\server.key" 2048
|
||||
|
||||
REM Generate certificate signing request
|
||||
echo [2/3] Generating certificate signing request...
|
||||
openssl req -new -key "%CERT_DIR%\server.key" -out "%CERT_DIR%\server.csr" -subj "/C=%COUNTRY%/ST=%STATE%/L=%CITY%/O=%ORG%/OU=%ORG_UNIT%/CN=%COMMON_NAME%"
|
||||
|
||||
REM Generate self-signed certificate with SAN
|
||||
echo [3/3] Generating self-signed certificate...
|
||||
(
|
||||
echo [req]
|
||||
echo default_bits = 2048
|
||||
echo prompt = no
|
||||
echo default_md = sha256
|
||||
echo distinguished_name = dn
|
||||
echo req_extensions = req_ext
|
||||
echo.
|
||||
echo [dn]
|
||||
echo C=%COUNTRY%
|
||||
echo ST=%STATE%
|
||||
echo L=%CITY%
|
||||
echo O=%ORG%
|
||||
echo OU=%ORG_UNIT%
|
||||
echo CN=%COMMON_NAME%
|
||||
echo.
|
||||
echo [req_ext]
|
||||
echo subjectAltName = @alt_names
|
||||
echo.
|
||||
echo [alt_names]
|
||||
echo DNS.1 = %COMMON_NAME%
|
||||
echo DNS.2 = localhost
|
||||
echo DNS.3 = *.local
|
||||
echo IP.1 = 127.0.0.1
|
||||
echo IP.2 = ::1
|
||||
) > "%CERT_DIR%\san.cnf"
|
||||
|
||||
if not "%~2"=="" (
|
||||
echo IP.3 = %~2>> "%CERT_DIR%\san.cnf"
|
||||
echo Added IP: %~2
|
||||
)
|
||||
|
||||
openssl x509 -req -in "%CERT_DIR%\server.csr" -signkey "%CERT_DIR%\server.key" -out "%CERT_DIR%\server.crt" -days %DAYS% -sha256 -extfile "%CERT_DIR%\san.cnf" -extensions req_ext
|
||||
|
||||
REM Clean up
|
||||
del "%CERT_DIR%\server.csr"
|
||||
del "%CERT_DIR%\san.cnf"
|
||||
|
||||
echo.
|
||||
echo =========================================
|
||||
echo ✓ Certificates generated successfully!
|
||||
echo =========================================
|
||||
echo Certificate: %CERT_DIR%\server.crt
|
||||
echo Private Key: %CERT_DIR%\server.key
|
||||
echo.
|
||||
echo To use these certificates:
|
||||
echo 1. Set environment variable: set OVERLORD_TLS=true
|
||||
echo 2. Optionally set custom paths:
|
||||
echo set OVERLORD_TLS_CERT=%CERT_DIR%\server.crt
|
||||
echo set OVERLORD_TLS_KEY=%CERT_DIR%\server.key
|
||||
echo.
|
||||
echo ⚠️ NOTE: Self-signed certificates require clients to:
|
||||
echo - Skip certificate verification (insecure), OR
|
||||
echo - Trust the server.crt certificate manually
|
||||
echo.
|
||||
echo For production, use proper certificates from:
|
||||
echo - Let's Encrypt (free, automated)
|
||||
echo - Your organization's certificate authority
|
||||
echo =========================================
|
||||
|
||||
endlocal
|
||||
@@ -0,0 +1,112 @@
|
||||
#!/bin/bash
|
||||
# Generate self-signed TLS certificates for Overlord
|
||||
# For production, use proper certificates from Let's Encrypt or your CA
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
CERT_DIR="$ROOT/certs"
|
||||
DAYS=3650 # 10 years
|
||||
COUNTRY="US"
|
||||
STATE="State"
|
||||
CITY="City"
|
||||
ORG="Overlord"
|
||||
ORG_UNIT="IT"
|
||||
COMMON_NAME="${1:-localhost}"
|
||||
|
||||
echo "========================================="
|
||||
echo "Generating TLS Certificates for Overlord"
|
||||
echo "========================================="
|
||||
echo "Common Name: $COMMON_NAME"
|
||||
echo "Certificate Directory: $CERT_DIR"
|
||||
echo "Validity: $DAYS days"
|
||||
echo ""
|
||||
|
||||
# Create certs directory if it doesn't exist
|
||||
mkdir -p "$CERT_DIR"
|
||||
|
||||
# Generate private key
|
||||
echo "[1/3] Generating private key..."
|
||||
openssl genrsa -out "$CERT_DIR/server.key" 2048
|
||||
|
||||
# Generate certificate signing request (CSR)
|
||||
echo "[2/3] Generating certificate signing request..."
|
||||
openssl req -new \
|
||||
-key "$CERT_DIR/server.key" \
|
||||
-out "$CERT_DIR/server.csr" \
|
||||
-subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORG/OU=$ORG_UNIT/CN=$COMMON_NAME"
|
||||
|
||||
# Generate self-signed certificate with SAN (Subject Alternative Names)
|
||||
echo "[3/3] Generating self-signed certificate..."
|
||||
cat > "$CERT_DIR/san.cnf" << EOF
|
||||
[req]
|
||||
default_bits = 2048
|
||||
prompt = no
|
||||
default_md = sha256
|
||||
distinguished_name = dn
|
||||
req_extensions = req_ext
|
||||
|
||||
[dn]
|
||||
C=$COUNTRY
|
||||
ST=$STATE
|
||||
L=$CITY
|
||||
O=$ORG
|
||||
OU=$ORG_UNIT
|
||||
CN=$COMMON_NAME
|
||||
|
||||
[req_ext]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = $COMMON_NAME
|
||||
DNS.2 = localhost
|
||||
DNS.3 = *.local
|
||||
IP.1 = 127.0.0.1
|
||||
IP.2 = ::1
|
||||
EOF
|
||||
|
||||
# Add additional IP if provided as second argument
|
||||
if [ -n "$2" ]; then
|
||||
echo "IP.3 = $2" >> "$CERT_DIR/san.cnf"
|
||||
echo "Added IP: $2"
|
||||
fi
|
||||
|
||||
openssl x509 -req \
|
||||
-in "$CERT_DIR/server.csr" \
|
||||
-signkey "$CERT_DIR/server.key" \
|
||||
-out "$CERT_DIR/server.crt" \
|
||||
-days $DAYS \
|
||||
-sha256 \
|
||||
-extfile "$CERT_DIR/san.cnf" \
|
||||
-extensions req_ext
|
||||
|
||||
# Clean up CSR and config
|
||||
rm "$CERT_DIR/server.csr" "$CERT_DIR/san.cnf"
|
||||
|
||||
# Set permissions
|
||||
chmod 600 "$CERT_DIR/server.key"
|
||||
chmod 644 "$CERT_DIR/server.crt"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "✓ Certificates generated successfully!"
|
||||
echo "========================================="
|
||||
echo "Certificate: $CERT_DIR/server.crt"
|
||||
echo "Private Key: $CERT_DIR/server.key"
|
||||
echo ""
|
||||
echo "To use these certificates:"
|
||||
echo " 1. Set environment variable: OVERLORD_TLS=true"
|
||||
echo " 2. Optionally set custom paths:"
|
||||
echo " OVERLORD_TLS_CERT=$CERT_DIR/server.crt"
|
||||
echo " OVERLORD_TLS_KEY=$CERT_DIR/server.key"
|
||||
echo ""
|
||||
echo "⚠️ NOTE: Self-signed certificates require clients to:"
|
||||
echo " - Skip certificate verification (insecure), OR"
|
||||
echo " - Trust the server.crt certificate manually"
|
||||
echo ""
|
||||
echo "For production, use proper certificates from:"
|
||||
echo " - Let's Encrypt (free, automated)"
|
||||
echo " - Your organization's certificate authority"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
CLIENT_DIR="$ROOT/Overlord-Client"
|
||||
DIST_DIR="$ROOT/dist-clients"
|
||||
GO_BIN="${GO_BIN:-go}"
|
||||
GO_TAGS=()
|
||||
|
||||
if [ "${NO_PRINTING:-false}" = "true" ]; then
|
||||
echo "[client] printing disabled via build tags"
|
||||
GO_TAGS+=("-tags" "noprint")
|
||||
fi
|
||||
|
||||
# detect platform
|
||||
OS="$(uname -s)"
|
||||
ARCH="$(uname -m)"
|
||||
case "$OS" in
|
||||
Darwin) PLATFORM="mac";;
|
||||
Linux) PLATFORM="linux";;
|
||||
FreeBSD) PLATFORM="freebsd";;
|
||||
OpenBSD) PLATFORM="openbsd";;
|
||||
*) PLATFORM="unknown";;
|
||||
esac
|
||||
|
||||
echo "[client] platform detected: $OS ($PLATFORM) arch: $ARCH"
|
||||
|
||||
# determine expected dist binary name
|
||||
BIN_NAME=""
|
||||
if [ "$PLATFORM" = "mac" ]; then
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
BIN_NAME="agent-darwin-amd64"
|
||||
else
|
||||
BIN_NAME="agent-darwin-arm64"
|
||||
fi
|
||||
elif [ "$PLATFORM" = "linux" ]; then
|
||||
BIN_NAME="agent-linux-amd64"
|
||||
elif [ "$PLATFORM" = "freebsd" ]; then
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
BIN_NAME="agent-freebsd-amd64"
|
||||
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
BIN_NAME="agent-freebsd-arm64"
|
||||
fi
|
||||
elif [ "$PLATFORM" = "openbsd" ]; then
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
BIN_NAME="agent-openbsd-amd64"
|
||||
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
BIN_NAME="agent-openbsd-arm64"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$PLATFORM" != "mac" ] && [ -n "$BIN_NAME" ] && [ -x "$DIST_DIR/$BIN_NAME" ]; then
|
||||
echo "[client] found prebuilt client binary: $DIST_DIR/$BIN_NAME"
|
||||
echo "[client] starting prebuilt agent"
|
||||
OVERLORD_SERVER="wss://localhost:5173" \
|
||||
OVERLORD_AGENT_TOKEN="dev-token-insecure-local-only" \
|
||||
OVERLORD_TLS_INSECURE_SKIP_VERIFY="true" \
|
||||
OVERLORD_MODE="dev" \
|
||||
"${DIST_DIR:?}/$BIN_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$PLATFORM" = "mac" ]; then
|
||||
echo "[client] macOS dev mode uses a rebuilt stable binary"
|
||||
else
|
||||
echo "[client] no suitable prebuilt client binary found in $DIST_DIR; falling back to 'go run'"
|
||||
fi
|
||||
|
||||
cd "$CLIENT_DIR"
|
||||
if ! command -v "$GO_BIN" >/dev/null 2>&1; then
|
||||
echo "[client] go not found. Set GO_BIN to your Go binary (>=1.21) or install Go." >&2
|
||||
exit 1
|
||||
fi
|
||||
GO_VER=$($GO_BIN env GOVERSION 2>/dev/null || true)
|
||||
GO_MINOR=$(echo "$GO_VER" | sed -E 's/^go[0-9]+\.([0-9]+).*/\1/')
|
||||
if [ -z "$GO_MINOR" ]; then
|
||||
echo "[client] unable to determine Go version (got '$GO_VER')." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$GO_MINOR" -lt 21 ]; then
|
||||
echo "[client] Go >=1.21 required (found $GO_VER). Install a newer Go or point GO_BIN to one." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[client] using go at: $(command -v $GO_BIN) ($GO_VER)"
|
||||
echo "[client] go mod tidy..."
|
||||
GOTOOLCHAIN=${GOTOOLCHAIN:-auto} \
|
||||
"$GO_BIN" mod tidy
|
||||
|
||||
if [ "$PLATFORM" = "mac" ] && [ -n "$BIN_NAME" ]; then
|
||||
mkdir -p "$DIST_DIR"
|
||||
DEV_BIN="$DIST_DIR/$BIN_NAME"
|
||||
echo "[client] building stable macOS dev binary at $DEV_BIN"
|
||||
if [ "${#GO_TAGS[@]}" -gt 0 ]; then
|
||||
GOINSECURE="*" \
|
||||
GOPROXY="https://proxy.golang.org,direct" \
|
||||
GOTOOLCHAIN=${GOTOOLCHAIN:-auto} \
|
||||
"$GO_BIN" build "${GO_TAGS[@]}" -o "$DEV_BIN" ./cmd/agent
|
||||
else
|
||||
GOINSECURE="*" \
|
||||
GOPROXY="https://proxy.golang.org,direct" \
|
||||
GOTOOLCHAIN=${GOTOOLCHAIN:-auto} \
|
||||
"$GO_BIN" build -o "$DEV_BIN" ./cmd/agent
|
||||
fi
|
||||
|
||||
echo "[client] starting stable macOS dev binary"
|
||||
OVERLORD_SERVER="wss://localhost:5173" \
|
||||
OVERLORD_AGENT_TOKEN="dev-token-insecure-local-only" \
|
||||
OVERLORD_TLS_INSECURE_SKIP_VERIFY="true" \
|
||||
OVERLORD_MODE="dev" \
|
||||
exec "$DEV_BIN"
|
||||
fi
|
||||
|
||||
echo "[client] starting agent via 'go run'"
|
||||
if [ "${#GO_TAGS[@]}" -gt 0 ]; then
|
||||
OVERLORD_SERVER="wss://localhost:5173" \
|
||||
OVERLORD_AGENT_TOKEN="dev-token-insecure-local-only" \
|
||||
OVERLORD_TLS_INSECURE_SKIP_VERIFY="true" \
|
||||
OVERLORD_MODE="dev" \
|
||||
GOINSECURE="*" \
|
||||
GOPROXY="https://proxy.golang.org,direct" \
|
||||
GOTOOLCHAIN=${GOTOOLCHAIN:-auto} \
|
||||
"$GO_BIN" run "${GO_TAGS[@]}" ./cmd/agent
|
||||
else
|
||||
OVERLORD_SERVER="wss://localhost:5173" \
|
||||
OVERLORD_AGENT_TOKEN="dev-token-insecure-local-only" \
|
||||
OVERLORD_TLS_INSECURE_SKIP_VERIFY="true" \
|
||||
OVERLORD_MODE="dev" \
|
||||
GOINSECURE="*" \
|
||||
GOPROXY="https://proxy.golang.org,direct" \
|
||||
GOTOOLCHAIN=${GOTOOLCHAIN:-auto} \
|
||||
"$GO_BIN" run ./cmd/agent
|
||||
fi
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
SERVER_DIR="$ROOT/Overlord-Server"
|
||||
BUN_BIN="${BUN_BIN:-bun}"
|
||||
|
||||
# detect platform
|
||||
OS="$(uname -s)"
|
||||
case "$OS" in
|
||||
Darwin) PLATFORM="mac";;
|
||||
Linux) PLATFORM="linux";;
|
||||
*) PLATFORM="unknown";;
|
||||
esac
|
||||
|
||||
echo "[server] platform detected: $OS ($PLATFORM)"
|
||||
|
||||
cd "$SERVER_DIR"
|
||||
if ! command -v "$BUN_BIN" >/dev/null 2>&1; then
|
||||
echo "[server] bun not found. Set BUN_BIN to your bun binary or install bun for this environment." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[server] using bun at: $(command -v $BUN_BIN)"
|
||||
echo "[server] bun install..."
|
||||
"$BUN_BIN" install
|
||||
echo "[server] building Tailwind CSS..."
|
||||
"$BUN_BIN" run build:css
|
||||
echo "[server] building vendor assets..."
|
||||
"$BUN_BIN" run vendor
|
||||
echo "[server] starting bun dev (foreground)"
|
||||
# Use exec so the script process is replaced by the bun process. This keeps the
|
||||
# bun process as a child of the dispatcher so the dispatcher can kill it.
|
||||
export OVERLORD_AGENT_TOKEN="dev-token-insecure-local-only"
|
||||
exec "$BUN_BIN" run dev
|
||||
@@ -0,0 +1,36 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
|
||||
if not defined NO_PRINTING set NO_PRINTING=false
|
||||
|
||||
|
||||
echo === Ensuring server deps (Bun) ===
|
||||
pushd "%ROOT%Overlord-Server"
|
||||
echo [server] bun install...
|
||||
call bun install
|
||||
popd
|
||||
|
||||
echo === Ensuring client dependencies (Go) ===
|
||||
pushd "%ROOT%Overlord-Client"
|
||||
if exist go.mod (
|
||||
echo [client] go mod tidy...
|
||||
go mod tidy
|
||||
)
|
||||
popd
|
||||
|
||||
echo === Launching windows ===
|
||||
rem Bind server to all interfaces for remote access
|
||||
set HOST=0.0.0.0
|
||||
set PORT=5173
|
||||
set OVERLORD_AGENT_TOKEN=dev-token-insecure-local-only
|
||||
set OVERLORD_DISABLE_AGENT_AUTH=true
|
||||
set LOG_LEVEL=debug
|
||||
|
||||
start "Overlord-Server" cmd /k "cd /d ""%ROOT%Overlord-Server"" && set OVERLORD_DISABLE_AGENT_AUTH=true && set OVERLORD_AGENT_TOKEN=dev-token-insecure-local-only && set LOG_LEVEL=debug && set NODE_ENV=development && bun install && bun run start"
|
||||
timeout /t 3 /nobreak >nul
|
||||
start "Overlord-Client" cmd /k "cd /d ""%ROOT%Overlord-Client"" && set OVERLORD_SERVER=wss://localhost:5173 && set OVERLORD_AGENT_TOKEN=dev-token-insecure-local-only && set OVERLORD_TLS_INSECURE_SKIP_VERIFY=true && set OVERLORD_MODE=dev && set OVERLORD_CAPTURE_METRICS=true && set GOINSECURE=* && set GOSUMDB=off && set GOPROXY=https://proxy.golang.org,direct && go mod tidy && go run ./cmd/agent"
|
||||
|
||||
echo Done. Terminals stay open (/k) for logs.
|
||||
endlocal
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "$0")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
SERVER_SCRIPT="$SCRIPT_DIR/start-dev-server.sh"
|
||||
CLIENT_SCRIPT="$SCRIPT_DIR/start-dev-client.sh"
|
||||
|
||||
quote() {
|
||||
printf "%q" "$1"
|
||||
}
|
||||
|
||||
pause_for_error() {
|
||||
local exit_code=$?
|
||||
if [ "$exit_code" -ne 0 ]; then
|
||||
echo
|
||||
echo "[start-dev] failed with exit code $exit_code"
|
||||
echo "Press any key to close this window."
|
||||
read -r -n 1 _ || true
|
||||
fi
|
||||
exit "$exit_code"
|
||||
}
|
||||
trap pause_for_error EXIT
|
||||
|
||||
if [ "$(uname -s)" != "Darwin" ]; then
|
||||
echo "[start-dev] start-dev.command is intended for macOS."
|
||||
echo "[start-dev] Use ./scripts/start-dev.sh on this platform."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v osascript >/dev/null 2>&1; then
|
||||
echo "[start-dev] osascript was not found. Use ./scripts/start-dev.sh from a terminal instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$SERVER_SCRIPT" ]; then
|
||||
echo "[start-dev] missing $SERVER_SCRIPT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$CLIENT_SCRIPT" ]; then
|
||||
echo "[start-dev] missing $CLIENT_SCRIPT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROOT_Q="$(quote "$ROOT")"
|
||||
SERVER_SCRIPT_Q="$(quote "$SERVER_SCRIPT")"
|
||||
CLIENT_SCRIPT_Q="$(quote "$CLIENT_SCRIPT")"
|
||||
NO_PRINTING_Q="$(quote "${NO_PRINTING:-false}")"
|
||||
|
||||
SERVER_CMD="cd $ROOT_Q && HOST=0.0.0.0 PORT=5173 OVERLORD_DISABLE_AGENT_AUTH=true OVERLORD_AGENT_TOKEN=dev-token-insecure-local-only LOG_LEVEL=debug NODE_ENV=development /bin/bash $SERVER_SCRIPT_Q"
|
||||
CLIENT_CMD="sleep 3; cd $ROOT_Q && NO_PRINTING=$NO_PRINTING_Q /bin/bash $CLIENT_SCRIPT_Q"
|
||||
|
||||
open_terminal() {
|
||||
local title="$1"
|
||||
local command="$2"
|
||||
|
||||
osascript - "$title" "$command" <<'APPLESCRIPT'
|
||||
on run argv
|
||||
set windowTitle to item 1 of argv
|
||||
set shellCommand to item 2 of argv
|
||||
|
||||
tell application "Terminal"
|
||||
activate
|
||||
do script shellCommand
|
||||
delay 0.2
|
||||
set custom title of selected tab of front window to windowTitle
|
||||
end tell
|
||||
end run
|
||||
APPLESCRIPT
|
||||
}
|
||||
|
||||
echo "=== Launching Overlord dev terminals ==="
|
||||
echo "[start-dev] root: $ROOT"
|
||||
echo "[start-dev] opening server window..."
|
||||
open_terminal "Overlord-Server" "$SERVER_CMD"
|
||||
|
||||
echo "[start-dev] opening client window..."
|
||||
open_terminal "Overlord-Client" "$CLIENT_CMD"
|
||||
|
||||
echo
|
||||
echo "Done. Server and client logs are running in separate Terminal windows."
|
||||
echo "Close those Terminal windows or press Ctrl+C inside them to stop dev processes."
|
||||
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Dispatcher script kept for backwards compatibility.
|
||||
# Usage:
|
||||
# ./start-dev.sh # start server (background) and client (foreground)
|
||||
# ./start-dev.sh server # start only server
|
||||
# ./start-dev.sh client # start only client
|
||||
|
||||
SERVER_SCRIPT="$SCRIPT_DIR/start-dev-server.sh"
|
||||
CLIENT_SCRIPT="$SCRIPT_DIR/start-dev-client.sh"
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
# start server in background, then client in foreground (original behavior)
|
||||
echo "[start-dev] starting server (background) and client (foreground)"
|
||||
if [ -x "$SERVER_SCRIPT" ]; then
|
||||
"$SERVER_SCRIPT" &
|
||||
SERVER_PID=$!
|
||||
echo "[start-dev] server started (pid $SERVER_PID)"
|
||||
else
|
||||
echo "[start-dev] $SERVER_SCRIPT not found or not executable. Run \"chmod +x $SERVER_SCRIPT\" or run the scripts directly." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure we kill the server child if this script exits or receives a signal.
|
||||
cleanup() {
|
||||
echo "[start-dev] cleaning up"
|
||||
if [ -n "${SERVER_PID:-}" ] && kill -0 "$SERVER_PID" >/dev/null 2>&1; then
|
||||
echo "[start-dev] killing server (pid $SERVER_PID)"
|
||||
kill "$SERVER_PID" 2>/dev/null || true
|
||||
sleep 1
|
||||
if kill -0 "$SERVER_PID" >/dev/null 2>&1; then
|
||||
echo "[start-dev] server did not exit; force killing"
|
||||
kill -9 "$SERVER_PID" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup INT TERM EXIT
|
||||
|
||||
if [ -x "$CLIENT_SCRIPT" ]; then
|
||||
# run client in foreground; when it exits the trap will run and kill server
|
||||
"$CLIENT_SCRIPT"
|
||||
else
|
||||
echo "[start-dev] $CLIENT_SCRIPT not found or not executable. Run \"chmod +x $CLIENT_SCRIPT\" or run the scripts directly." >&2
|
||||
exit 1
|
||||
fi
|
||||
# explicit exit so the EXIT trap runs
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
server)
|
||||
if [ -x "$SERVER_SCRIPT" ]; then
|
||||
exec "$SERVER_SCRIPT"
|
||||
else
|
||||
echo "[start-dev] $SERVER_SCRIPT not found or not executable." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
client)
|
||||
if [ -x "$CLIENT_SCRIPT" ]; then
|
||||
exec "$CLIENT_SCRIPT"
|
||||
else
|
||||
echo "[start-dev] $CLIENT_SCRIPT not found or not executable." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [server|client]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,209 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
set "MODE=%~1"
|
||||
|
||||
REM Tuned production launcher for small VPS targets.
|
||||
REM Usage:
|
||||
REM scripts\start-prod-tuned.bat
|
||||
REM scripts\start-prod-tuned.bat loadtest
|
||||
REM scripts\start-prod-tuned.bat loadtest-baseline
|
||||
REM scripts\start-prod-tuned.bat loadtest-profile
|
||||
REM
|
||||
REM Optional env overrides before running:
|
||||
REM PORT=5173
|
||||
REM HOST=0.0.0.0
|
||||
REM OVERLORD_AGENT_TOKEN=change-me
|
||||
REM OVERLORD_USER=admin
|
||||
REM OVERLORD_PASS=change-me
|
||||
REM OVERLORD_TLS_OFFLOAD=false
|
||||
REM OVERLORD_HEARTBEAT_INTERVAL_MS=30000
|
||||
REM OVERLORD_HEARTBEAT_SWEEP_TICK_MS=1000
|
||||
REM OVERLORD_CLIENT_DB_SYNC_MS=15000
|
||||
REM OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=100
|
||||
REM OVERLORD_EVENT_LOOP_SAMPLE_MS=100
|
||||
REM OVERLORD_EVENT_LOOP_HISTORY_SECONDS=60
|
||||
REM OVERLORD_DASHBOARD_DEBOUNCE_MS=1000
|
||||
REM OVERLORD_DASHBOARD_EVENT_FLUSH_MS=1000
|
||||
REM OVERLORD_DASHBOARD_EVENT_INLINE_LIMIT=20
|
||||
REM OVERLORD_OFFLINE_BATCH_SIZE=250
|
||||
REM OVERLORD_OFFLINE_BATCH_DELAY_MS=25
|
||||
REM OVERLORD_LOAD_TEST_PROFILE=realistic
|
||||
REM OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB=true
|
||||
REM OVERLORD_THUMBNAILS_DASHBOARD_ENABLED=false
|
||||
REM MAX_WS_MESSAGE_BYTES_CLIENT=8388608
|
||||
REM MAX_WS_MESSAGE_BYTES_VIEWER=1048576
|
||||
|
||||
if not defined HOST set HOST=0.0.0.0
|
||||
if not defined PORT set PORT=5173
|
||||
if not defined LOG_LEVEL set LOG_LEVEL=info
|
||||
if not defined NODE_ENV set NODE_ENV=production
|
||||
|
||||
REM Small-host connection tuning. These are conservative for ~250 mostly-idle
|
||||
REM agents on a 2 vCPU / 2 GB host.
|
||||
if not defined OVERLORD_HEARTBEAT_INTERVAL_MS set OVERLORD_HEARTBEAT_INTERVAL_MS=30000
|
||||
if not defined OVERLORD_HEARTBEAT_SWEEP_TICK_MS set OVERLORD_HEARTBEAT_SWEEP_TICK_MS=1000
|
||||
if not defined OVERLORD_CLIENT_DB_SYNC_MS set OVERLORD_CLIENT_DB_SYNC_MS=15000
|
||||
if not defined OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE set OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=100
|
||||
if not defined OVERLORD_EVENT_LOOP_SAMPLE_MS set OVERLORD_EVENT_LOOP_SAMPLE_MS=100
|
||||
if not defined OVERLORD_EVENT_LOOP_HISTORY_SECONDS set OVERLORD_EVENT_LOOP_HISTORY_SECONDS=60
|
||||
if not defined OVERLORD_DASHBOARD_DEBOUNCE_MS set OVERLORD_DASHBOARD_DEBOUNCE_MS=1000
|
||||
if not defined OVERLORD_DASHBOARD_EVENT_FLUSH_MS set OVERLORD_DASHBOARD_EVENT_FLUSH_MS=1000
|
||||
if not defined OVERLORD_DASHBOARD_EVENT_INLINE_LIMIT set OVERLORD_DASHBOARD_EVENT_INLINE_LIMIT=20
|
||||
if not defined OVERLORD_OFFLINE_BATCH_SIZE set OVERLORD_OFFLINE_BATCH_SIZE=250
|
||||
if not defined OVERLORD_OFFLINE_BATCH_DELAY_MS set OVERLORD_OFFLINE_BATCH_DELAY_MS=25
|
||||
if not defined OVERLORD_STALE_MS set OVERLORD_STALE_MS=120000
|
||||
if not defined OVERLORD_DISCONNECT_TIMEOUT_MS set OVERLORD_DISCONNECT_TIMEOUT_MS=10000
|
||||
if not defined PRUNE_BATCH set PRUNE_BATCH=250
|
||||
if not defined MAX_WS_MESSAGE_BYTES_CLIENT set MAX_WS_MESSAGE_BYTES_CLIENT=8388608
|
||||
if not defined MAX_WS_MESSAGE_BYTES_VIEWER set MAX_WS_MESSAGE_BYTES_VIEWER=1048576
|
||||
if not defined OVERLORD_WS_UPGRADE_RATE_WINDOW_MS set OVERLORD_WS_UPGRADE_RATE_WINDOW_MS=10000
|
||||
set OVERLORD_PROFILE_SOURCE_MODE=false
|
||||
|
||||
REM Keep proxy trust disabled unless the deploy explicitly opts into it.
|
||||
if not defined OVERLORD_TLS_OFFLOAD set OVERLORD_TLS_OFFLOAD=false
|
||||
if not defined OVERLORD_TRUST_PROXY set OVERLORD_TRUST_PROXY=false
|
||||
if not defined OVERLORD_TRUST_PROXY_HEADERS set OVERLORD_TRUST_PROXY_HEADERS=false
|
||||
if not defined OVERLORD_AUTH_COOKIE_SECURE set OVERLORD_AUTH_COOKIE_SECURE=auto
|
||||
|
||||
if /I "%MODE%"=="loadtest" (
|
||||
if not defined OVERLORD_AGENT_TOKEN (
|
||||
echo [error] loadtest mode requires OVERLORD_AGENT_TOKEN to be set.
|
||||
echo Example:
|
||||
echo set OVERLORD_AGENT_TOKEN=some-long-random-token
|
||||
echo scripts\start-prod-tuned.bat loadtest
|
||||
endlocal
|
||||
exit /b 1
|
||||
)
|
||||
set OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS=true
|
||||
if not defined OVERLORD_LOAD_TEST_PROFILE set OVERLORD_LOAD_TEST_PROFILE=realistic
|
||||
if not defined OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS set OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS=false
|
||||
if not defined OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB set OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB=true
|
||||
if "%OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE%"=="100" set OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=500
|
||||
if not defined OVERLORD_WS_UPGRADE_RATE_MAX set OVERLORD_WS_UPGRADE_RATE_MAX=2000
|
||||
if not defined OVERLORD_THUMBNAILS_DASHBOARD_ENABLED set OVERLORD_THUMBNAILS_DASHBOARD_ENABLED=false
|
||||
) else if /I "%MODE%"=="loadtest-profile" (
|
||||
if not defined OVERLORD_AGENT_TOKEN (
|
||||
echo [error] loadtest-profile mode requires OVERLORD_AGENT_TOKEN to be set.
|
||||
echo Example:
|
||||
echo set OVERLORD_AGENT_TOKEN=some-long-random-token
|
||||
echo scripts\start-prod-tuned.bat loadtest-profile
|
||||
endlocal
|
||||
exit /b 1
|
||||
)
|
||||
set OVERLORD_PROFILE_SOURCE_MODE=true
|
||||
set OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS=true
|
||||
if not defined OVERLORD_LOAD_TEST_PROFILE set OVERLORD_LOAD_TEST_PROFILE=realistic
|
||||
if not defined OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS set OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS=false
|
||||
if not defined OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB set OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB=true
|
||||
if "%OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE%"=="100" set OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=500
|
||||
if not defined OVERLORD_WS_UPGRADE_RATE_MAX set OVERLORD_WS_UPGRADE_RATE_MAX=2000
|
||||
if not defined OVERLORD_THUMBNAILS_DASHBOARD_ENABLED set OVERLORD_THUMBNAILS_DASHBOARD_ENABLED=false
|
||||
) else if /I "%MODE%"=="loadtest-baseline" (
|
||||
if not defined OVERLORD_AGENT_TOKEN (
|
||||
echo [error] loadtest-baseline mode requires OVERLORD_AGENT_TOKEN to be set.
|
||||
echo Example:
|
||||
echo set OVERLORD_AGENT_TOKEN=some-long-random-token
|
||||
echo scripts\start-prod-tuned.bat loadtest-baseline
|
||||
endlocal
|
||||
exit /b 1
|
||||
)
|
||||
set OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS=true
|
||||
if not defined OVERLORD_LOAD_TEST_PROFILE set OVERLORD_LOAD_TEST_PROFILE=baseline
|
||||
if not defined OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS set OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS=true
|
||||
if not defined OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB set OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB=true
|
||||
if "%OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE%"=="100" set OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=500
|
||||
if not defined OVERLORD_WS_UPGRADE_RATE_MAX set OVERLORD_WS_UPGRADE_RATE_MAX=2000
|
||||
if not defined OVERLORD_THUMBNAILS_DASHBOARD_ENABLED set OVERLORD_THUMBNAILS_DASHBOARD_ENABLED=false
|
||||
) else (
|
||||
set OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS=false
|
||||
if not defined OVERLORD_WS_UPGRADE_RATE_MAX set OVERLORD_WS_UPGRADE_RATE_MAX=30
|
||||
)
|
||||
|
||||
echo === Overlord tuned production server ===
|
||||
echo HOST=%HOST%
|
||||
echo PORT=%PORT%
|
||||
echo NODE_ENV=%NODE_ENV%
|
||||
echo LOG_LEVEL=%LOG_LEVEL%
|
||||
echo OVERLORD_HEARTBEAT_INTERVAL_MS=%OVERLORD_HEARTBEAT_INTERVAL_MS%
|
||||
echo OVERLORD_HEARTBEAT_SWEEP_TICK_MS=%OVERLORD_HEARTBEAT_SWEEP_TICK_MS%
|
||||
echo OVERLORD_CLIENT_DB_SYNC_MS=%OVERLORD_CLIENT_DB_SYNC_MS%
|
||||
echo OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE=%OVERLORD_CLIENT_DB_SYNC_BATCH_SIZE%
|
||||
echo OVERLORD_EVENT_LOOP_SAMPLE_MS=%OVERLORD_EVENT_LOOP_SAMPLE_MS%
|
||||
echo OVERLORD_EVENT_LOOP_HISTORY_SECONDS=%OVERLORD_EVENT_LOOP_HISTORY_SECONDS%
|
||||
echo OVERLORD_DASHBOARD_DEBOUNCE_MS=%OVERLORD_DASHBOARD_DEBOUNCE_MS%
|
||||
echo OVERLORD_DASHBOARD_EVENT_FLUSH_MS=%OVERLORD_DASHBOARD_EVENT_FLUSH_MS%
|
||||
echo OVERLORD_DASHBOARD_EVENT_INLINE_LIMIT=%OVERLORD_DASHBOARD_EVENT_INLINE_LIMIT%
|
||||
echo OVERLORD_OFFLINE_BATCH_SIZE=%OVERLORD_OFFLINE_BATCH_SIZE%
|
||||
echo OVERLORD_OFFLINE_BATCH_DELAY_MS=%OVERLORD_OFFLINE_BATCH_DELAY_MS%
|
||||
echo MAX_WS_MESSAGE_BYTES_CLIENT=%MAX_WS_MESSAGE_BYTES_CLIENT%
|
||||
echo MAX_WS_MESSAGE_BYTES_VIEWER=%MAX_WS_MESSAGE_BYTES_VIEWER%
|
||||
echo OVERLORD_WS_UPGRADE_RATE_MAX=%OVERLORD_WS_UPGRADE_RATE_MAX%
|
||||
echo OVERLORD_WS_UPGRADE_RATE_WINDOW_MS=%OVERLORD_WS_UPGRADE_RATE_WINDOW_MS%
|
||||
echo OVERLORD_TLS_OFFLOAD=%OVERLORD_TLS_OFFLOAD%
|
||||
echo OVERLORD_TRUST_PROXY=%OVERLORD_TRUST_PROXY%
|
||||
echo OVERLORD_TRUST_PROXY_HEADERS=%OVERLORD_TRUST_PROXY_HEADERS%
|
||||
echo OVERLORD_AUTH_COOKIE_SECURE=%OVERLORD_AUTH_COOKIE_SECURE%
|
||||
echo OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS=%OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS%
|
||||
echo OVERLORD_LOAD_TEST_PROFILE=%OVERLORD_LOAD_TEST_PROFILE%
|
||||
echo OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS=%OVERLORD_LOAD_TEST_SKIP_SIDE_EFFECTS%
|
||||
echo OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB=%OVERLORD_LOAD_TEST_DEFER_SYNTHETIC_DB%
|
||||
echo OVERLORD_THUMBNAILS_DASHBOARD_ENABLED=%OVERLORD_THUMBNAILS_DASHBOARD_ENABLED%
|
||||
echo OVERLORD_PROFILE_SOURCE_MODE=%OVERLORD_PROFILE_SOURCE_MODE%
|
||||
echo.
|
||||
|
||||
if /I "%OVERLORD_LOAD_TEST_ALLOW_UNSIGNED_AGENTS%"=="true" (
|
||||
echo [warning] Synthetic unsigned load-test agents are enabled.
|
||||
echo [warning] Do not use this mode for public production traffic.
|
||||
echo.
|
||||
)
|
||||
|
||||
pushd "%ROOT%Overlord-Server"
|
||||
echo [build] installing deps...
|
||||
call bun install
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
if /I "%OVERLORD_PROFILE_SOURCE_MODE%"=="true" (
|
||||
echo [build] building server assets for source-profile mode...
|
||||
call bun run build:css
|
||||
if errorlevel 1 goto :err
|
||||
call bun run vendor
|
||||
if errorlevel 1 goto :err
|
||||
) else (
|
||||
echo [build] building server assets and bundle...
|
||||
call bun run build
|
||||
if errorlevel 1 goto :err
|
||||
)
|
||||
|
||||
if /I "%OVERLORD_PROFILE_SOURCE_MODE%"=="true" (
|
||||
echo [build] skipping compiled executable so profiler keeps source function names.
|
||||
) else (
|
||||
echo [build] compiling Windows production executable...
|
||||
call bun run build:prod:win
|
||||
if errorlevel 1 goto :err
|
||||
)
|
||||
|
||||
echo [build] copying Overlord-Client source for runtime builds...
|
||||
robocopy "%ROOT%Overlord-Client" "%ROOT%Overlord-Server\dist\Overlord-Client" /E /XD build .git .vscode /NFL /NDL /NJH /NJS >nul
|
||||
if errorlevel 8 goto :err
|
||||
|
||||
set "OVERLORD_ROOT=%ROOT%Overlord-Server"
|
||||
if /I "%OVERLORD_PROFILE_SOURCE_MODE%"=="true" (
|
||||
echo [server] starting source-profile server with Bun...
|
||||
call bun src/index.ts
|
||||
) else (
|
||||
echo [server] starting compiled production server...
|
||||
call "%ROOT%Overlord-Server\dist\overlord-server.exe"
|
||||
)
|
||||
popd
|
||||
|
||||
echo Server stopped.
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
:err
|
||||
popd >nul 2>&1
|
||||
echo [error] Production start failed.
|
||||
endlocal
|
||||
exit /b 1
|
||||
@@ -0,0 +1,61 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
for %%I in ("%SCRIPT_DIR%..") do set "ROOT=%%~fI\"
|
||||
|
||||
REM Simple production launcher for Overlord server.
|
||||
REM Builds the Tailwind CSS and server bundle, then runs the compiled executable.
|
||||
REM Env overrides you can set before running:
|
||||
REM PORT=5173
|
||||
REM HOST=0.0.0.0
|
||||
REM OVERLORD_USER=admin
|
||||
REM OVERLORD_PASS=admin
|
||||
REM LOG_LEVEL=info
|
||||
REM NODE_ENV=production
|
||||
|
||||
if not defined HOST set HOST=0.0.0.0
|
||||
if not defined PORT set PORT=5173
|
||||
if not defined LOG_LEVEL set LOG_LEVEL=info
|
||||
if not defined NODE_ENV set NODE_ENV=production
|
||||
|
||||
pushd "%ROOT%Overlord-Server"
|
||||
echo [build] installing deps (bun install)...
|
||||
call bun install
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [build] building Tailwind CSS...
|
||||
call bun run build:css
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [build] building server bundle...
|
||||
call bun run build
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [build] compiling Windows production executable...
|
||||
call bun run build:prod:win
|
||||
if errorlevel 1 goto :err
|
||||
|
||||
echo [build] copying Overlord-Client source for runtime builds...
|
||||
robocopy "%ROOT%Overlord-Client" "%ROOT%Overlord-Server\dist\Overlord-Client" /E /XD build .git .vscode /NFL /NDL /NJH /NJS >nul
|
||||
REM robocopy exit codes 0-7 are success
|
||||
if errorlevel 8 goto :err
|
||||
|
||||
if defined PORT (
|
||||
echo [server] starting on port %PORT%...
|
||||
) else (
|
||||
echo [server] starting on default port...
|
||||
)
|
||||
echo [server] running compiled executable...
|
||||
set "OVERLORD_ROOT=%ROOT%Overlord-Server"
|
||||
call "%ROOT%Overlord-Server\dist\overlord-server.exe"
|
||||
popd
|
||||
|
||||
echo Server stopped.
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
:err
|
||||
popd >nul 2>&1
|
||||
echo [error] Build failed.
|
||||
endlocal
|
||||
exit /b 1
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
SERVER_DIR="$ROOT/Overlord-Server"
|
||||
BUN_BIN="${BUN_BIN:-bun}"
|
||||
|
||||
cd "$SERVER_DIR"
|
||||
if ! command -v "$BUN_BIN" >/dev/null 2>&1; then
|
||||
echo "[server] bun not found. Set BUN_BIN to your bun binary or install bun for this environment." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[server] using bun at: $(command -v $BUN_BIN)"
|
||||
|
||||
echo "[build] bun install..."
|
||||
"$BUN_BIN" install
|
||||
|
||||
echo "[build] building Tailwind CSS..."
|
||||
"$BUN_BIN" run build:css
|
||||
|
||||
echo "[build] building server bundle..."
|
||||
"$BUN_BIN" run build
|
||||
|
||||
echo "[build] compiling Linux production executable..."
|
||||
"$BUN_BIN" run build:prod:linux
|
||||
|
||||
echo "[build] copying Overlord-Client source for runtime builds..."
|
||||
mkdir -p "$SERVER_DIR/dist/Overlord-Client"
|
||||
rsync -a --exclude='build' --exclude='.git' --exclude='.vscode' "$ROOT/Overlord-Client/" "$SERVER_DIR/dist/Overlord-Client/" 2>/dev/null \
|
||||
|| {
|
||||
rm -rf "$SERVER_DIR/dist/Overlord-Client"
|
||||
cp -a "$ROOT/Overlord-Client" "$SERVER_DIR/dist/Overlord-Client"
|
||||
rm -rf "$SERVER_DIR/dist/Overlord-Client/build" "$SERVER_DIR/dist/Overlord-Client/.git" "$SERVER_DIR/dist/Overlord-Client/.vscode"
|
||||
}
|
||||
|
||||
echo "[server] starting compiled executable..."
|
||||
PORT="${PORT:-5173}" \
|
||||
HOST="${HOST:-0.0.0.0}" \
|
||||
OVERLORD_USER="${OVERLORD_USER:-admin}" \
|
||||
OVERLORD_PASS="${OVERLORD_PASS:-admin}" \
|
||||
LOG_LEVEL="${LOG_LEVEL:-info}" \
|
||||
NODE_ENV="${NODE_ENV:-production}" \
|
||||
OVERLORD_ROOT="$SERVER_DIR" \
|
||||
"$SERVER_DIR/dist/overlord-server-linux-x64"
|
||||
Reference in New Issue
Block a user