@echo off
setlocal enabledelayedexpansion

:: ============================================================
:: Hytale F2P Dedicated Server - One-Click Starter
:: ============================================================
:: Just double-click this file to start your server!
::
:: The script will:
::   1. Look for game files and Java in your F2P launcher install
::   2. Auto-download anything missing
::   3. Auto-update server, assets, and agent on each launch
::   4. Fetch auth tokens and start the server
:: ============================================================

:: Configuration (edit these or set as environment variables)
if not defined HYTALE_AUTH_DOMAIN set "HYTALE_AUTH_DOMAIN=auth.sanasol.ws"
if not defined AUTH_SERVER set "AUTH_SERVER=https://%HYTALE_AUTH_DOMAIN%"
if not defined SERVER_NAME set "SERVER_NAME=My Hytale Server"
if not defined ASSETS_PATH set "ASSETS_PATH=.\Assets.zip"
if not defined BIND_ADDRESS set "BIND_ADDRESS=0.0.0.0:5520"
if not defined AUTH_MODE set "AUTH_MODE=authenticated"
if not defined DOWNLOAD_BASE set "DOWNLOAD_BASE=https://download.sanasol.ws/download"

:: File names
set "AGENT_JAR=dualauth-agent.jar"
set "SERVER_JAR=HytaleServer.jar"
set "AGENT_URL=https://github.com/sanasol/hytale-auth-server/releases/latest/download/dualauth-agent.jar"
set "AGENT_VERSION_API=https://api.github.com/repos/sanasol/hytale-auth-server/releases/latest"
set "VERSION_DIR=.versions"

echo ============================================================
echo   Hytale F2P Dedicated Server
echo ============================================================
echo.

:: --- Prerequisite Checks ---

where curl >nul 2>&1
if errorlevel 1 (
    echo [ERROR] curl is required but not found
    echo [ERROR] curl comes with Windows 10+. Update Windows or install curl.
    pause
    exit /b 1
)

if not exist "%VERSION_DIR%" mkdir "%VERSION_DIR%"

:: --- Find Local F2P Launcher Install ---

set "F2P_DIR="
set "F2P_BASE=%USERPROFILE%\AppData\Local\HytaleF2P"
set "F2P_CONFIG=%F2P_BASE%\config.json"
set "JAVA_CMD=java"

:: Check config.json for custom installPath
set "F2P_CUSTOM_BASE="
if exist "%F2P_CONFIG%" (
    for /f "delims=" %%p in ('powershell -Command "try { $c = Get-Content '%F2P_CONFIG%' | ConvertFrom-Json; if ($c.installPath) { $c.installPath.Trim() + '\HytaleF2P' } } catch {}" 2^>nul') do (
        set "F2P_CUSTOM_BASE=%%p"
    )
)

:: Search for game files: custom path first, then default
if defined F2P_CUSTOM_BASE (
    if exist "!F2P_CUSTOM_BASE!\release\package\game\latest" (
        set "F2P_DIR=!F2P_CUSTOM_BASE!\release\package\game\latest"
    ) else if exist "!F2P_CUSTOM_BASE!\pre-release\package\game\latest" (
        set "F2P_DIR=!F2P_CUSTOM_BASE!\pre-release\package\game\latest"
    )
)

if not defined F2P_DIR (
    if exist "%F2P_BASE%\release\package\game\latest" (
        set "F2P_DIR=%F2P_BASE%\release\package\game\latest"
    ) else if exist "%F2P_BASE%\pre-release\package\game\latest" (
        set "F2P_DIR=%F2P_BASE%\pre-release\package\game\latest"
    )
)

:: --- Find Java from F2P launcher ---

:: Check config.json for custom javaPath
if exist "%F2P_CONFIG%" (
    for /f "delims=" %%j in ('powershell -Command "try { $c = Get-Content '%F2P_CONFIG%' | ConvertFrom-Json; if ($c.javaPath -and (Test-Path $c.javaPath)) { $c.javaPath.Trim() } } catch {}" 2^>nul') do (
        set "JAVA_CMD=%%j"
        echo [INFO] Found Java in F2P config: %%j
    )
)

:: Check bundled JRE if no custom javaPath found
if "!JAVA_CMD!"=="java" (
    set "F2P_JRE_BASE="
    if defined F2P_CUSTOM_BASE (
        if exist "!F2P_CUSTOM_BASE!\release\package\jre\latest\bin\java.exe" (
            set "F2P_JRE_BASE=!F2P_CUSTOM_BASE!\release\package\jre\latest"
        ) else if exist "!F2P_CUSTOM_BASE!\pre-release\package\jre\latest\bin\java.exe" (
            set "F2P_JRE_BASE=!F2P_CUSTOM_BASE!\pre-release\package\jre\latest"
        )
    )
    if not defined F2P_JRE_BASE (
        if exist "%F2P_BASE%\release\package\jre\latest\bin\java.exe" (
            set "F2P_JRE_BASE=%F2P_BASE%\release\package\jre\latest"
        ) else if exist "%F2P_BASE%\pre-release\package\jre\latest\bin\java.exe" (
            set "F2P_JRE_BASE=%F2P_BASE%\pre-release\package\jre\latest"
        )
    )
    if defined F2P_JRE_BASE (
        set "JAVA_CMD=!F2P_JRE_BASE!\bin\java.exe"
        echo [INFO] Found Java in F2P launcher: !JAVA_CMD!
    )
)

:: Verify java exists
"!JAVA_CMD!" -version >nul 2>&1
if errorlevel 1 (
    where java >nul 2>&1
    if errorlevel 1 (
        echo [ERROR] Java is not installed and no F2P launcher JRE found
        echo.
        echo   Options:
        echo     1. Install the F2P launcher first ^(it includes Java^)
        echo     2. Download Java 25: https://download.oracle.com/java/25/latest/jdk-25_windows-x64_bin.exe
        echo.
        pause
        exit /b 1
    )
    set "JAVA_CMD=java"
)

:: Check Java version
for /f "tokens=3 delims= " %%v in ('"!JAVA_CMD!" -version 2^>^&1 ^| findstr /i "version"') do (
    set "JAVA_VER_RAW=%%~v"
)
if defined JAVA_VER_RAW (
    for /f "tokens=1 delims=." %%m in ("!JAVA_VER_RAW!") do set "JAVA_MAJOR=%%m"
)

echo [INFO] Java: !JAVA_VER_RAW! ^(!JAVA_CMD!^)

if defined JAVA_MAJOR (
    if !JAVA_MAJOR! LSS 25 (
        echo [ERROR] Java !JAVA_MAJOR! detected. Java 25+ is REQUIRED.
        echo         The DualAuth agent requires Java 25 ^(class file version 69^).
        echo.
        echo   Download Java 25: https://download.oracle.com/java/25/latest/jdk-25_windows-x64_bin.exe
        echo.
        pause
        exit /b 1
    )
)

:: --- Copy game files from F2P install ---

if defined F2P_DIR (
    echo [INFO] Found F2P launcher game files: !F2P_DIR!

    if not exist "%SERVER_JAR%" (
        if exist "!F2P_DIR!\Server\HytaleServer.jar" (
            echo [INFO] Found HytaleServer.jar in F2P launcher
            echo [INFO]   Copying from: !F2P_DIR!\Server\HytaleServer.jar
            copy "!F2P_DIR!\Server\HytaleServer.jar" "%SERVER_JAR%" >nul
            echo [INFO]   Copied successfully
        )
    )

    if not exist "%ASSETS_PATH%" (
        if exist "!F2P_DIR!\Assets.zip" (
            echo [INFO] Found Assets.zip in F2P launcher
            echo [INFO]   Copying from: !F2P_DIR!\Assets.zip
            copy "!F2P_DIR!\Assets.zip" "%ASSETS_PATH%" >nul
            echo [INFO]   Copied successfully
        )
    )

    echo.
) else (
    echo [INFO] No F2P launcher install found, will download files
    echo.
)

:: --- Download / Update HytaleServer.jar ---

set "JAR_URL=%DOWNLOAD_BASE%/HytaleServer.jar"
set "JAR_VERSION_FILE=%VERSION_DIR%\HytaleServer.jar.version"

if not exist "%SERVER_JAR%" (
    echo [INFO] HytaleServer.jar not found, downloading...
    echo [INFO]   Expected size: ~150 MB
    curl -fL --progress-bar -o "%SERVER_JAR%.tmp" "%JAR_URL%" --connect-timeout 15 --max-time 3600
    if exist "%SERVER_JAR%.tmp" (
        move /y "%SERVER_JAR%.tmp" "%SERVER_JAR%" >nul
        echo [INFO] HytaleServer.jar downloaded
        for /f "delims=" %%h in ('powershell -Command "try { (Invoke-WebRequest -Uri '%JAR_URL%' -Method Head -UseBasicParsing).Headers['ETag'] } catch {}" 2^>nul') do (
            echo %%h>"%JAR_VERSION_FILE%"
        )
    ) else (
        echo [ERROR] Failed to download HytaleServer.jar
        echo [ERROR] Check your internet connection
        pause
        exit /b 1
    )
) else (
    echo [INFO] Checking for HytaleServer.jar updates...
    set "LOCAL_JAR_VER="
    if exist "%JAR_VERSION_FILE%" set /p LOCAL_JAR_VER=<"%JAR_VERSION_FILE%"

    set "REMOTE_JAR_VER="
    for /f "delims=" %%h in ('powershell -Command "try { (Invoke-WebRequest -Uri '%JAR_URL%' -Method Head -UseBasicParsing -TimeoutSec 10).Headers['ETag'] } catch { '' }" 2^>nul') do (
        set "REMOTE_JAR_VER=%%h"
    )

    if defined REMOTE_JAR_VER (
        if "!LOCAL_JAR_VER!"=="!REMOTE_JAR_VER!" (
            echo [INFO] HytaleServer.jar is up to date
        ) else (
            echo [INFO] HytaleServer.jar update available, downloading...
            curl -fL --progress-bar -o "%SERVER_JAR%.tmp" "%JAR_URL%" --connect-timeout 15 --max-time 3600
            if exist "%SERVER_JAR%.tmp" (
                move /y "%SERVER_JAR%.tmp" "%SERVER_JAR%" >nul
                echo !REMOTE_JAR_VER!>"%JAR_VERSION_FILE%"
                echo [INFO] HytaleServer.jar updated
            ) else (
                echo [WARN] Update failed, using existing HytaleServer.jar
            )
        )
    ) else (
        echo [INFO] Could not check for updates, using existing HytaleServer.jar
    )
)

:: --- Download / Update Assets.zip ---

set "ASSETS_URL=%DOWNLOAD_BASE%/Assets.zip"
set "ASSETS_VERSION_FILE=%VERSION_DIR%\Assets.zip.version"

if not exist "%ASSETS_PATH%" (
    echo [INFO] Assets.zip not found, downloading...
    echo [INFO]   Expected size: ~3.3 GB - this will take a while
    curl -fL --progress-bar -o "%ASSETS_PATH%.tmp" "%ASSETS_URL%" --connect-timeout 15 --max-time 7200
    if exist "%ASSETS_PATH%.tmp" (
        move /y "%ASSETS_PATH%.tmp" "%ASSETS_PATH%" >nul
        echo [INFO] Assets.zip downloaded
        for /f "delims=" %%h in ('powershell -Command "try { (Invoke-WebRequest -Uri '%ASSETS_URL%' -Method Head -UseBasicParsing).Headers['ETag'] } catch {}" 2^>nul') do (
            echo %%h>"%ASSETS_VERSION_FILE%"
        )
    ) else (
        echo [ERROR] Failed to download Assets.zip
        echo [ERROR] Check your internet connection
        pause
        exit /b 1
    )
) else (
    echo [INFO] Checking for Assets.zip updates...
    set "LOCAL_ASSETS_VER="
    if exist "%ASSETS_VERSION_FILE%" set /p LOCAL_ASSETS_VER=<"%ASSETS_VERSION_FILE%"

    set "REMOTE_ASSETS_VER="
    for /f "delims=" %%h in ('powershell -Command "try { (Invoke-WebRequest -Uri '%ASSETS_URL%' -Method Head -UseBasicParsing -TimeoutSec 10).Headers['ETag'] } catch { '' }" 2^>nul') do (
        set "REMOTE_ASSETS_VER=%%h"
    )

    if defined REMOTE_ASSETS_VER (
        if "!LOCAL_ASSETS_VER!"=="!REMOTE_ASSETS_VER!" (
            echo [INFO] Assets.zip is up to date
        ) else (
            echo [INFO] Assets.zip update available, downloading...
            echo [INFO]   This is a large file ^(~3.3 GB^), please be patient
            curl -fL --progress-bar -o "%ASSETS_PATH%.tmp" "%ASSETS_URL%" --connect-timeout 15 --max-time 7200
            if exist "%ASSETS_PATH%.tmp" (
                move /y "%ASSETS_PATH%.tmp" "%ASSETS_PATH%" >nul
                echo !REMOTE_ASSETS_VER!>"%ASSETS_VERSION_FILE%"
                echo [INFO] Assets.zip updated
            ) else (
                echo [WARN] Update failed, using existing Assets.zip
            )
        )
    ) else (
        echo [INFO] Could not check for updates, using existing Assets.zip
    )
)

:: --- Download / Update DualAuth Agent ---

set "AGENT_VERSION_FILE=%VERSION_DIR%\dualauth-agent.jar.version"

if not exist "%AGENT_JAR%" (
    echo [INFO] Downloading DualAuth Agent...
    curl -fL -# -o "%AGENT_JAR%.tmp" "%AGENT_URL%" --connect-timeout 15 --max-time 120
    if exist "%AGENT_JAR%.tmp" (
        move /y "%AGENT_JAR%.tmp" "%AGENT_JAR%" >nul
        echo [INFO] DualAuth Agent downloaded
        for /f "delims=" %%v in ('powershell -Command "try { $r = Invoke-RestMethod -Uri '%AGENT_VERSION_API%' -TimeoutSec 10; $r.tag_name } catch { '' }" 2^>nul') do (
            echo %%v>"%AGENT_VERSION_FILE%"
        )
    ) else (
        echo [ERROR] Failed to download DualAuth Agent
        echo [ERROR] Download manually: %AGENT_URL%
        pause
        exit /b 1
    )
) else (
    echo [INFO] Checking for DualAuth Agent updates...
    set "LOCAL_AGENT_VER="
    if exist "%AGENT_VERSION_FILE%" set /p LOCAL_AGENT_VER=<"%AGENT_VERSION_FILE%"

    set "REMOTE_AGENT_VER="
    for /f "delims=" %%v in ('powershell -Command "try { $r = Invoke-RestMethod -Uri '%AGENT_VERSION_API%' -TimeoutSec 10; $r.tag_name } catch { '' }" 2^>nul') do (
        set "REMOTE_AGENT_VER=%%v"
    )

    if defined REMOTE_AGENT_VER (
        if "!LOCAL_AGENT_VER!"=="!REMOTE_AGENT_VER!" (
            echo [INFO] DualAuth Agent up to date ^(!LOCAL_AGENT_VER!^)
        ) else (
            echo [INFO] Agent update: !LOCAL_AGENT_VER! -^> !REMOTE_AGENT_VER!
            curl -fL -# -o "%AGENT_JAR%.tmp" "%AGENT_URL%" --connect-timeout 15 --max-time 120
            if exist "%AGENT_JAR%.tmp" (
                move /y "%AGENT_JAR%.tmp" "%AGENT_JAR%" >nul
                echo !REMOTE_AGENT_VER!>"%AGENT_VERSION_FILE%"
                echo [INFO] DualAuth Agent updated
            ) else (
                echo [WARN] Agent update failed, using existing
            )
        )
    ) else (
        echo [INFO] Could not check agent updates, using existing
    )
)

:: --- Final Checks ---

if not exist "%SERVER_JAR%" (
    echo [ERROR] HytaleServer.jar not found
    pause
    exit /b 1
)
if not exist "%ASSETS_PATH%" (
    echo [ERROR] Assets.zip not found
    pause
    exit /b 1
)
if not exist "%AGENT_JAR%" (
    echo [ERROR] dualauth-agent.jar not found
    pause
    exit /b 1
)

:: --- Generate or Load Server ID ---

set "SERVER_ID_FILE=.server-id"
if exist "%SERVER_ID_FILE%" (
    set /p SERVER_ID=<"%SERVER_ID_FILE%"
    echo [INFO] Server ID: !SERVER_ID!
) else (
    for /f "delims=" %%i in ('powershell -Command "[guid]::NewGuid().ToString()"') do set "SERVER_ID=%%i"
    echo !SERVER_ID!>"%SERVER_ID_FILE%"
    echo [INFO] Generated server ID: !SERVER_ID!
)

:: --- Fetch Server Tokens ---

echo.
echo [INFO] Fetching server tokens from %AUTH_SERVER%...

set "TEMP_RESPONSE=%TEMP%\hytale_auth_%RANDOM%.json"

curl -s -X POST "%AUTH_SERVER%/server/auto-auth" ^
    -H "Content-Type: application/json" ^
    -d "{\"server_id\": \"!SERVER_ID!\", \"server_name\": \"%SERVER_NAME%\"}" ^
    --connect-timeout 10 ^
    --max-time 30 ^
    -o "%TEMP_RESPONSE%" 2>nul

if errorlevel 1 (
    echo [ERROR] Failed to connect to auth server at %AUTH_SERVER%
    del "%TEMP_RESPONSE%" 2>nul
    pause
    exit /b 1
)

findstr /C:"sessionToken" "%TEMP_RESPONSE%" >nul 2>&1
if errorlevel 1 (
    echo [ERROR] Invalid response from auth server:
    type "%TEMP_RESPONSE%"
    del "%TEMP_RESPONSE%" 2>nul
    pause
    exit /b 1
)

:: Extract tokens using PowerShell
for /f "delims=" %%i in ('powershell -Command "$j = Get-Content '%TEMP_RESPONSE%' | ConvertFrom-Json; $j.sessionToken"') do set "SESSION_TOKEN=%%i"
for /f "delims=" %%i in ('powershell -Command "$j = Get-Content '%TEMP_RESPONSE%' | ConvertFrom-Json; $j.identityToken"') do set "IDENTITY_TOKEN=%%i"

del "%TEMP_RESPONSE%" 2>nul

if "!SESSION_TOKEN!"=="" (
    echo [ERROR] Could not extract session token from response
    pause
    exit /b 1
)
if "!IDENTITY_TOKEN!"=="" (
    echo [ERROR] Could not extract identity token from response
    pause
    exit /b 1
)

echo [INFO] Tokens received successfully

:: --- Start Server ---

set "JAVA_ARGS="
if defined JVM_XMS set "JAVA_ARGS=!JAVA_ARGS! -Xms%JVM_XMS%"
if defined JVM_XMX set "JAVA_ARGS=!JAVA_ARGS! -Xmx%JVM_XMX%"

echo.
echo ============================================================
echo   Starting Hytale Server
echo   Name:    %SERVER_NAME%
echo   Bind:    %BIND_ADDRESS%
echo   Java:    !JAVA_CMD!
echo   Agent:   %AGENT_JAR%
echo ============================================================
echo.

"!JAVA_CMD!" %JAVA_ARGS% -javaagent:"%AGENT_JAR%" -jar "%SERVER_JAR%" ^
    --assets "%ASSETS_PATH%" ^
    --bind "%BIND_ADDRESS%" ^
    --auth-mode "%AUTH_MODE%" ^
    --disable-sentry ^
    --session-token "!SESSION_TOKEN!" ^
    --identity-token "!IDENTITY_TOKEN!" ^
    %*

echo.
echo ============================================================
echo   Server stopped. Exit code: %ERRORLEVEL%
echo ============================================================
pause

endlocal
