From 11c6d40dfe62f1f6707fb793267b775afc50b631 Mon Sep 17 00:00:00 2001 From: sanasol Date: Fri, 20 Feb 2026 14:38:34 +0100 Subject: [PATCH] chore: remove private docs from repo Co-Authored-By: Claude Opus 4.6 --- .gitignore | 3 + docs/PATCH_CDN_INFRASTRUCTURE.md | 217 ------------------------------- 2 files changed, 3 insertions(+), 217 deletions(-) delete mode 100644 docs/PATCH_CDN_INFRASTRUCTURE.md diff --git a/.gitignore b/.gitignore index c3f4c5a..1febe7a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ dist/ # Project Specific: Downloaded patcher (from hytale-auth-server) backend/patcher/ +# Private docs (local only) +docs/PATCH_CDN_INFRASTRUCTURE.md + # macOS Specific .DS_Store *.zst.DS_Store diff --git a/docs/PATCH_CDN_INFRASTRUCTURE.md b/docs/PATCH_CDN_INFRASTRUCTURE.md deleted file mode 100644 index 15b01e6..0000000 --- a/docs/PATCH_CDN_INFRASTRUCTURE.md +++ /dev/null @@ -1,217 +0,0 @@ -# Patch CDN Infrastructure & Game Update System - -## Overview - -The F2P launcher downloads game patches through a CDN redirect gateway hosted on the auth server. This allows instant CDN switching (e.g., for DMCA takedowns) without releasing a new launcher version. - -## Architecture - -``` -Launcher --> GET auth.sanasol.ws/patches/manifest.json - --> 302 --> mega.io/.../manifest.json - -Launcher --> GET auth.sanasol.ws/patches/windows/amd64/release/0_to_11.pwr - --> 302 --> mega.io/.../windows/amd64/release/0_to_11.pwr -``` - -The auth server acts as a pure redirect gateway (302). No bandwidth is consumed on the auth server - all actual file transfers happen directly between the launcher and the CDN. - -## URLs - -| URL | Purpose | -|-----|---------| -| `https://auth.sanasol.ws/patches/*` | Redirect gateway (302 -> CDN) | -| `https://auth.sanasol.ws/patches/manifest.json` | Patch manifest (redirects to CDN) | -| `https://auth.sanasol.ws/admin/page/settings` | Admin panel to change CDN URL | -| `https://auth.sanasol.ws/admin/api/settings/patches-cdn` | API to GET/POST CDN base URL | - -### Default CDN (MEGA S4) - -``` -Base URL: https://s3.g.s4.mega.io/kcvismkrtfcalgwxzsazbq46l72dwsypqaham/hytale/patches -``` - -### Changing CDN (DMCA response) - -1. Go to `https://auth.sanasol.ws/admin/page/settings` -2. Find "Patches CDN Base URL" section -3. Change URL to new CDN (e.g., `https://new-cdn.example.com/patches`) -4. Click "Save" - all launcher requests instantly redirect to new CDN -5. No launcher update needed - -## Manifest Format - -The manifest is a JSON file listing all available patch files: - -```json -{ - "updated": "2026-02-20T13:20:09.776Z", - "files": { - "windows/amd64/release/0_to_11.pwr": { "size": 1618804736 }, - "windows/amd64/release/10_to_11.pwr": { "size": 62914560 }, - "darwin/arm64/release/0_to_11.pwr": { "size": 1617100800 }, - "server/release": { "version": "2026.02.19-1a311a592", "size": 1509949440, "sha256": "..." }, - ... - } -} -``` - -### Key Structure - -File keys follow the pattern: `{os}/{arch}/{branch}/{from}_to_{to}.pwr` - -- **OS**: `windows`, `linux`, `darwin` -- **Arch**: `amd64`, `arm64` -- **Branch**: `release`, `pre-release` -- **Patch**: `{from}_to_{to}.pwr` (e.g., `0_to_11.pwr` for full install, `10_to_11.pwr` for differential) - -Server builds use: `server/{branch}` with `version`, `size`, `sha256` fields. - -## Game Update Process - -### 1. Version Check - -``` -Launcher calls: getLatestClientVersion(branch) - -> Fetches manifest from auth.sanasol.ws/patches/manifest.json - -> Finds highest build number for current platform/branch - -> Returns "v{buildNumber}" (e.g., "v11") -``` - -### 2. Update Plan (Optimal Patch Routing) - -``` -Launcher calls: getUpdatePlan(currentBuild, targetBuild, branch) - -> Fetches manifest - -> Finds available patches for platform - -> Uses BFS to find optimal path (minimizes total download size) - -> Example: build 5 -> 11 might use: 5->10 (148MB) + 10->11 (60MB) - instead of: 0->11 (1.5GB) -``` - -### 3. Download & Apply - -``` -For each step in the update plan: - 1. Download .pwr file from auth.sanasol.ws/patches/{key} - (redirects to CDN, supports resume via Range headers) - 2. Apply patch using butler tool: - butler apply --staging-dir - 3. Save version after each step -``` - -### 4. Fresh Install - -For first-time installs (currentBuild = 0): -- Downloads `0_to_{target}.pwr` (full install, ~1.5GB) -- Applies with butler to create the full game directory - -### 5. Differential Update - -For existing installations: -- Finds optimal patch chain (e.g., `10_to_11.pwr` at ~60MB) -- Applies incrementally, saving progress after each step -- Falls back to full install if no patch path found - -## Mirror Sync Script - -The mirror script (`scripts/hytale-mirror.js`) downloads patches from the official Hytale API and uploads to MEGA S4. - -### Usage - -```bash -cd scripts -node hytale-mirror.js download # Download patches locally -node hytale-mirror.js upload # Upload to MEGA S4 via rclone -node hytale-mirror.js sync # Download + Upload in one step -``` - -### What It Does - -1. **Discovery**: Calls Hytale API to find available patches for all platforms -2. **Download**: Downloads .pwr files to `scripts/mirror/` directory -3. **Manifest Generation**: Creates `manifest.json` with file sizes (no local paths) -4. **Upload**: Uses `rclone` to sync to MEGA S4 - -### SOCKS5 Proxy - -- API discovery calls use SOCKS5 proxy rotation (for rate limiting) -- File downloads do NOT use proxy (too slow for large files) -- Proxy list in `proxies.json` (auto-refreshed from proxy service) - -### Prerequisites - -- `rclone` configured with `megas4` remote pointing to MEGA S4 -- Node.js 20+ -- Network access to Hytale API endpoints - -## Launcher Configuration - -### Environment Variables - -| Variable | Default | Description | -|----------|---------|-------------| -| `HYTALE_AUTH_DOMAIN` | `auth.sanasol.ws` | Auth domain (used for patch redirects) | - -### Key Files - -| File | Description | -|------|-------------| -| `backend/services/versionManager.js` | Manifest fetching, version checking, update planning | -| `backend/managers/differentialUpdateManager.js` | Download orchestration, butler integration | -| `backend/utils/fileManager.js` | File download with retry, resume, stall detection | -| `backend/managers/gameLauncher.js` | Game launch with token fetch, patching, signing | - -### Constants (versionManager.js) - -```javascript -const AUTH_DOMAIN = process.env.HYTALE_AUTH_DOMAIN || 'auth.sanasol.ws'; -const MIRROR_BASE_URL = `https://${AUTH_DOMAIN}/patches`; -const MIRROR_MANIFEST_URL = `${MIRROR_BASE_URL}/manifest.json`; -const MANIFEST_CACHE_DURATION = 60000; // 1 minute cache -const FALLBACK_LATEST_BUILD = 11; // If manifest unreachable -``` - -## Auth Server Implementation - -### Routes - -``` -GET /patches/* -> handlePatchRedirect() - - Extracts path after /patches/ - - Reads CDN base URL from Redis settings - - Returns 302 redirect to {baseUrl}/{path} - - Tracks download metrics - -GET /admin/api/settings/patches-cdn -> getPatchesCdnBaseUrl() -POST /admin/api/settings/patches-cdn -> setPatchesCdnBaseUrl() -``` - -### Redis Storage - -``` -settings:global -> { patchesCdnBaseUrl: "https://s3.g.s4.mega.io/..." } -metrics:downloads -> { "patch:manifest.json": count, ... } -``` - -## Troubleshooting - -### "Invalid manifest structure" error -- Check manifest.json is valid JSON with `files` object -- Verify CDN is accessible: `curl -sL https://auth.sanasol.ws/patches/manifest.json | python3 -m json.tool` -- Check admin settings for correct CDN URL - -### 0-byte downloads -- Verify redirect works: `curl -sI https://auth.sanasol.ws/patches/darwin/arm64/release/0_to_11.pwr` -- Should show `302` with `Location` header -- Test actual download: `curl -sL -o /dev/null -w "%{size_download}" -r 0-1023 ` - -### Manifest has local paths -- Regenerate manifest: `node scripts/hytale-mirror.js download` (re-scans files) -- Re-upload: `node scripts/hytale-mirror.js upload` -- Verify: entries should only have `{ size: }`, no `path` field - -### CDN switch not taking effect -- Check Redis: CDN URL stored in `settings:global` -- Verify via API: `curl https://auth.sanasol.ws/admin/api/settings/patches-cdn` -- Manifest is cached for 1 minute in launcher - wait or restart