Add one-click dedicated server scripts for Hytale F2P

- server/start.sh: Linux/macOS starter with auto-download, auto-update,
  F2P launcher detection (game files + bundled JRE), and token fetch
- server/start.bat: Windows equivalent using PowerShell for JSON/UUID
- server/README.md: Beginner-friendly guide with playit.gg networking
- Remove obsolete server_scripts_2.zip

Scripts auto-detect F2P launcher install (including custom installPath
from config.json), copy game files locally if available, download
missing files (HytaleServer.jar, Assets.zip, dualauth-agent.jar),
and check for updates on every launch via ETag/GitHub releases API.
This commit is contained in:
sanasol
2026-02-23 00:55:38 +01:00
parent fb90277be9
commit 552ec42d6c
3 changed files with 1071 additions and 0 deletions

441
server/start.bat Normal file
View File

@@ -0,0 +1,441 @@
@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