diff --git a/gameupdate/README.md b/gameupdate/README.md index a924ae1..1ea782e 100644 --- a/gameupdate/README.md +++ b/gameupdate/README.md @@ -10,6 +10,7 @@ **GAMEUPDATE.bat doesn't update and closes immediately** 1. Make sure your path doesn't contain any Japanese characters or lots of whitespace. 2. Make sure you actually have permissions in the folder +3. Auto-update calls GitLab’s public HTTP API (`/api/v4/...`), not the web “Download ZIP” URL—no account or token is required for public patch repos. For WOLF RPG games, if you downloaded the game off of DLSite, you will need to do some extra steps to patch it. This is because there is a "master" file called Data.wolf that will take priority over the english patch files. You will need this file to be a folder before patching will work. diff --git a/gameupdate/gameupdate/patch.bat b/gameupdate/gameupdate/patch.bat index 22b661f..f6f7a5b 100644 --- a/gameupdate/gameupdate/patch.bat +++ b/gameupdate/gameupdate/patch.bat @@ -85,6 +85,12 @@ for /f "usebackq tokens=1,2 delims==" %%a in ("%CONFIG_FILE%") do ( if "%%a"=="branch" set "branch=%%b" ) +REM For PowerShell (proper URL encoding; avoids cmd %% pitfalls) +set "GU_USERNAME=%username%" +set "GU_REPO=%repo%" +set "GU_BRANCH=%branch%" +if /I "!_my_shell!"=="pwsh" (set "GU_DL_PROGRESS=Continue") else (set "GU_DL_PROGRESS=SilentlyContinue") + REM -------------------------------------------------------- REM PRE-SETUP: Ensure SRPG data and patch structure exists REM Run Steps 1 and 2 BEFORE pulling repo patch to avoid overwriting updates @@ -144,9 +150,9 @@ if exist "%ROOT_DIR%\data.dts" ( echo [Pre-Setup] data.dts not found; skipping pre-setup SRPG steps. ) -REM Get the latest hash +REM Get the latest hash (GitLab API — browser /-/archive/ URLs are often blocked by CDN) echo "Getting latest commit SHA hash" -!_my_shell! -Command "(Invoke-RestMethod -Uri 'https://gitgud.io/api/v4/projects/%username%%%2F%repo%/repository/branches/%branch%').commit.id" > "%ROOT_DIR%\latest_patch_sha.txt" +!_my_shell! -NoProfile -Command "$ErrorActionPreference='Stop'; $id=[uri]::EscapeDataString($env:GU_USERNAME+'/'+ $env:GU_REPO); $br=[uri]::EscapeDataString($env:GU_BRANCH); (Invoke-RestMethod -Uri \"https://gitgud.io/api/v4/projects/$id/repository/branches/$br\" -Headers @{'User-Agent'='GameUpdate/1.0'}).commit.id" > "%ROOT_DIR%\latest_patch_sha.txt" REM Read the latest SHA from the file set /p latest_patch_sha=<"%ROOT_DIR%\latest_patch_sha.txt" @@ -183,35 +189,20 @@ exit /b :download_extract REM Escape single quotes in paths -set "escaped_root=%ROOT_DIR:'=''%" +set "escaped_root=%ROOT_DIR:'=''%" -REM Download zip file to root +REM Download zip via GitLab API; extract single top-level folder (API uses commit-based root name, not repo-branch) echo "Downloading latest patch..." -!_my_shell! -Command "Set-Location -LiteralPath '%escaped_root%'; $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri 'https://gitgud.io/%username%/%repo%/-/archive/%branch%/%repo%-%branch%.zip' -OutFile 'repo.zip'" +!_my_shell! -NoProfile -Command "$ErrorActionPreference='Stop'; Set-Location -LiteralPath '%escaped_root%'; $id=[uri]::EscapeDataString($env:GU_USERNAME+'/'+ $env:GU_REPO); $shaQ=[uri]::EscapeDataString($env:GU_BRANCH); $url=\"https://gitgud.io/api/v4/projects/$id/repository/archive.zip?sha=$shaQ\"; $ProgressPreference=$env:GU_DL_PROGRESS; Invoke-WebRequest -Uri $url -OutFile 'repo.zip' -UseBasicParsing -Headers @{'User-Agent'='GameUpdate/1.0'}; $ProgressPreference='SilentlyContinue'; $stage = Join-Path (Get-Location) '_patch_extract_tmp'; if (Test-Path $stage) { Remove-Item -LiteralPath $stage -Recurse -Force }; New-Item -ItemType Directory -Path $stage | Out-Null; try { Expand-Archive -LiteralPath '.\repo.zip' -DestinationPath $stage -Force; $dirs = @(Get-ChildItem -LiteralPath $stage -Directory); if ($dirs.Count -ne 1) { throw \"Expected one root folder in archive, found $($dirs.Count)\" }; Copy-Item -Path (Join-Path $dirs[0].FullName '*') -Destination (Get-Location) -Recurse -Force } finally { if (Test-Path $stage) { Remove-Item -LiteralPath $stage -Recurse -Force } }" if !errorlevel! neq 0 ( - pause - exit /b -) - -REM Extract contents, overwriting conflicts into root -echo "Extracting..." -!_my_shell! -Command "Set-Location -LiteralPath '%escaped_root%'; $ProgressPreference = 'SilentlyContinue'; Expand-Archive -Path '.\repo.zip' -DestinationPath '.' -Force" -if !errorlevel! neq 0 ( - echo Extraction failed! - del "%ROOT_DIR%\repo.zip" - rmdir /s /q "%ROOT_DIR%\%repo%-%branch%" + echo Download or extraction failed! + if exist "%ROOT_DIR%\repo.zip" del "%ROOT_DIR%\repo.zip" + if exist "%ROOT_DIR%\_patch_extract_tmp" rmdir /s /q "%ROOT_DIR%\_patch_extract_tmp" pause exit /b ) echo "Applying patch..." -xcopy /s /e /y "%ROOT_DIR%\%repo%-%branch%\*" "%ROOT_DIR%\" -if !errorlevel! neq 0 ( - echo Patch application failed! - del "%ROOT_DIR%\repo.zip" - rmdir /s /q "%ROOT_DIR%\%repo%-%branch%" - pause - exit /b -) +REM Files merged by Copy-Item above REM -------------------------------------------------------- REM POST-APPLY: Run Steps 3 and 4 after patch files are merged REM 3) Apply Patch to data\project.dat @@ -256,7 +247,7 @@ if exist "%ROOT_DIR%\data.dts" ( REM Clean up echo "Cleaning up..." del "%ROOT_DIR%\repo.zip" -rmdir /s /q "%ROOT_DIR%\%repo%-%branch%" +if exist "%ROOT_DIR%\_patch_extract_tmp" rmdir /s /q "%ROOT_DIR%\_patch_extract_tmp" del "%ROOT_DIR%\latest_patch_sha.txt" REM Store latest SHA for next check in gameupdate echo %latest_patch_sha% > "%SCRIPT_DIR%previous_patch_sha.txt" diff --git a/gameupdate/gameupdate/patch.sh b/gameupdate/gameupdate/patch.sh index 4986803..38804c3 100644 --- a/gameupdate/gameupdate/patch.sh +++ b/gameupdate/gameupdate/patch.sh @@ -32,11 +32,20 @@ echo "Root directory: $ROOT_DIR" echo "Config file path: $CONFIG_FILE" # Read configuration from file +# shellcheck disable=SC1090 . "$CONFIG_FILE" +# GitLab API (same host as gitgud.io) — browser /-/archive/ URLs are often blocked by CDN filters +GITGUD_API="https://gitgud.io/api/v4" +API_HEADERS=( -H "User-Agent: GameUpdate/1.0" ) + +project_enc=$(jq -nr --arg ns "$username" --arg rp "$repo" '$ns + "/" + $rp | @uri') +branch_enc=$(jq -nr --arg b "$branch" '$b | @uri') + # Get the latest hash echo "Getting latest commit SHA hash" -latest_patch_sha=$(curl -s "https://gitgud.io/api/v4/projects/$username%2F$repo/repository/branches/$branch" | jq -r '.commit.id') +latest_patch_sha=$(curl -fsSL "${API_HEADERS[@]}" \ + "${GITGUD_API}/projects/${project_enc}/repository/branches/${branch_enc}" | jq -r '.commit.id') # -------------------------------------------------------- # PRE-SETUP: Ensure SRPG data and patch structure exists @@ -49,85 +58,85 @@ if [ -f "$ROOT_DIR/data.dts" ]; then if [ -f "$UNPACKER" ]; then echo "[Pre-Setup] Running SRPG_Unpacker preparation steps..." - # Step 1: Unpack (once) - if [ ! -d "$ROOT_DIR/data" ]; then - if [ -f "$ROOT_DIR/data.dts" ]; then - echo "[Pre-Setup] Step 1: Unpacking data.dts -> data" - ( cd "$ROOT_DIR" && "$UNPACKER" -o data data.dts ) || echo "[Pre-Setup] ERROR: Unpack failed." + # Step 1: Unpack (once) — mirror patch.bat: unpack if no data/ or no data/project.dat + if [ ! -d "$ROOT_DIR/data" ] || [ ! -f "$ROOT_DIR/data/project.dat" ]; then + if [ -f "$ROOT_DIR/data.dts" ]; then + echo "[Pre-Setup] Step 1: Unpacking data.dts -> data" + ( cd "$ROOT_DIR" && "$UNPACKER" -o data data.dts ) || echo "[Pre-Setup] ERROR: Unpack failed." + else + echo "[Pre-Setup] Step 1: Skipping unpack (no data folder and no data.dts found)." + fi else - echo "[Pre-Setup] Step 1: Skipping unpack (no data folder and no data.dts found)." + echo "[Pre-Setup] Step 1: data folder exists; skipping unpack." fi - else - echo "[Pre-Setup] Step 1: data folder exists; skipping unpack." - fi - # Step 2: Create Patch (once) - if [ ! -d "$ROOT_DIR/patch" ]; then - if [ -f "$ROOT_DIR/data/project.dat" ]; then - echo "[Pre-Setup] Step 2: Creating patch from data/project.dat" - ( cd "$ROOT_DIR" && "$UNPACKER" ./data/project.dat -c ) || echo "[Pre-Setup] ERROR: Create Patch failed." - else - echo "[Pre-Setup] Step 2: Skipping create patch (data/project.dat not found)." - fi + # Step 2: Create Patch (once) + if [ ! -d "$ROOT_DIR/patch" ]; then + if [ -f "$ROOT_DIR/data/project.dat" ]; then + echo "[Pre-Setup] Step 2: Creating patch from data/project.dat" + ( cd "$ROOT_DIR" && "$UNPACKER" ./data/project.dat -c ) || echo "[Pre-Setup] ERROR: Create Patch failed." + else + echo "[Pre-Setup] Step 2: Skipping create patch (data/project.dat not found)." + fi else echo "[Pre-Setup] Step 2: patch folder exists; skipping create." fi - else - echo "[Pre-Setup] SRPG_Unpacker.exe not found in root; skipping pre-setup steps." - fi else - echo "[Pre-Setup] data.dts not found; skipping pre-setup SRPG steps." + echo "[Pre-Setup] SRPG_Unpacker.exe not found in root; skipping pre-setup steps." fi +else + echo "[Pre-Setup] data.dts not found; skipping pre-setup SRPG steps." +fi download_extract() { - # Download zip file into root echo "Downloading latest patch..." - curl -sL "https://gitgud.io/$username/$repo/-/archive/$branch/$repo-$branch.zip" -o "$ROOT_DIR/repo.zip" - if [ $? -ne 0 ]; then + if ! curl -fSL --progress-bar "${API_HEADERS[@]}" \ + "${GITGUD_API}/projects/${project_enc}/repository/archive.zip?sha=${branch_enc}" \ + -o "$ROOT_DIR/repo.zip"; then echo "Download failed!" rm -f "$ROOT_DIR/repo.zip" - rm -rf "$ROOT_DIR/$repo-$branch" return 1 fi - # Extract contents, overwriting conflicts into root + TMP_EX=$(mktemp -d) + echo "Extracting..." - unzip -qo "$ROOT_DIR/repo.zip" -d "$ROOT_DIR" - if [ $? -ne 0 ]; then + if ! unzip -qo "$ROOT_DIR/repo.zip" -d "$TMP_EX"; then echo "Extraction failed!" + rm -rf "$TMP_EX" + rm -f "$ROOT_DIR/repo.zip" + return 1 + fi + + inner=$(find "$TMP_EX" -mindepth 1 -maxdepth 1 -type d | head -1) + if [ -z "$inner" ]; then + echo "Archive had no root folder!" + rm -rf "$TMP_EX" rm -f "$ROOT_DIR/repo.zip" - rm -rf "$ROOT_DIR/$repo-$branch" return 1 fi echo "Applying patch..." - cp -r "$ROOT_DIR/$repo-$branch/"* "$ROOT_DIR/" - if [ $? -ne 0 ]; then + if ! cp -r "$inner"/* "$ROOT_DIR/"; then echo "Patch application failed!" + rm -rf "$TMP_EX" rm -f "$ROOT_DIR/repo.zip" - rm -rf "$ROOT_DIR/$repo-$branch" return 1 fi + rm -rf "$TMP_EX" + echo "Cleaning up..." rm -f "$ROOT_DIR/repo.zip" - rm -rf "$ROOT_DIR/$repo-$branch" - rm -f "$ROOT_DIR/latest_patch_sha.txt" - # Store latest SHA for next check in gameupdate - echo "$latest_patch_sha" > "$SCRIPT_DIR/previous_patch_sha.txt" + # -------------------------------------------------------- + # POST-APPLY: Run Steps 3 and 4 after patch files are merged + # -------------------------------------------------------- + UNPACKER="$ROOT_DIR/SRPG_Unpacker.exe" + if [ -f "$ROOT_DIR/data.dts" ]; then + if [ -f "$UNPACKER" ]; then + echo "Running SRPG_Unpacker apply/pack steps..." - # -------------------------------------------------------- - # POST-APPLY: Run Steps 3 and 4 after patch files are merged - # 3) Apply Patch to data/project.dat - # 4) Pack data back into data.dts - # -------------------------------------------------------- - UNPACKER="$ROOT_DIR/SRPG_Unpacker.exe" - if [ -f "$ROOT_DIR/data.dts" ]; then - if [ -f "$UNPACKER" ]; then - echo "Running SRPG_Unpacker apply/pack steps..." - - # Step 3: Apply Patch if [ -f "$ROOT_DIR/data/project.dat" ]; then echo "Step 3: Applying patch to data/project.dat" ( cd "$ROOT_DIR" && "$UNPACKER" ./data/project.dat -a ) || echo "ERROR: Apply Patch failed." @@ -135,19 +144,20 @@ download_extract() { echo "ERROR: data/project.dat not found; cannot apply patch." fi - # Step 4: Pack if [ -d "$ROOT_DIR/data" ]; then echo "Step 4: Packing data -> data.dts" ( cd "$ROOT_DIR" && "$UNPACKER" -o data.dts data ) || echo "WARNING: Pack failed." - else - echo "Step 4: Skipping pack (data folder not found)." - fi - else - echo "SRPG_Unpacker.exe not found in root; skipping SRPG patch steps." - fi - else - echo "data.dts not found; skipping SRPG patch steps." - fi + else + echo "Step 4: Skipping pack (data folder not found)." + fi + else + echo "SRPG_Unpacker.exe not found in root; skipping SRPG patch steps." + fi + else + echo "data.dts not found; skipping SRPG patch steps." + fi + + echo "$latest_patch_sha" > "$SCRIPT_DIR/previous_patch_sha.txt" } # Check if previous_patch_sha.txt exists in gameupdate @@ -156,10 +166,8 @@ if [ ! -f "$SCRIPT_DIR/previous_patch_sha.txt" ]; then echo "Assuming first time patching..." download_extract else - # Read the stored SHA from previous check - previous_patch_sha=$(cat "$SCRIPT_DIR/previous_patch_sha.txt") + previous_patch_sha=$(tr -d '[:space:]' < "$SCRIPT_DIR/previous_patch_sha.txt") - # Compare trimmed SHAs if [ "$latest_patch_sha" != "$previous_patch_sha" ]; then echo "Update found! Patching..." download_extract