docs: update documentation and README with smooth updater splash and new icon

This commit is contained in:
tomasalias 2026-10-12 19:44:33 +02:00
parent 5fc77ce66e
commit ca014969e1
5 changed files with 37 additions and 45 deletions

View file

@ -65,28 +65,32 @@
# Run background watcher daemon directly
.\BetterCurseForge.exe watch
# Trigger the smooth splash updater GUI manually
.\BetterCurseForge.exe --repatch-splash
```
---
## 🔄 How Auto-Repatch Works
Whenever CurseForge downloads an update, the Overwolf installer replaces `resources/app.asar` with a vanilla archive and restarts `CurseForge.exe`. BetterCurseForge guarantees you never lose your patch:
Whenever CurseForge downloads an official update, the Overwolf installer replaces `resources/app.asar` with an unpatched vanilla archive and automatically restarts `CurseForge.exe`. BetterCurseForge guarantees a **smooth, zero-delay transition** where you never lose your patch and the unpatched app is never shown on screen:
```mermaid
flowchart TD
A[CurseForge Launcher Update] -->|Installer downloads update| B[CurseForge Quitting / Replacing Files]
B -->|Watcher Detects Update| C[Auto-Repatch Triggered]
C -->|Wait for Installer Files to Settle| D[Settle Verified]
D -->|Offline Extraction & Patch <3s| E[Dist & BetterCF Injected]
E -->|Recalculate ASAR SHA-256| F[Synchronize OWEASARSIG in CurseForge.exe]
F -->|Autonomous Relaunch| G[Modded CurseForge Launcher Ready!]
A[CurseForge Launcher Update] -->|Overwolf installer replaces files| B[Installer Attempts to Launch Vanilla App]
B -->|Active Interceptor <50ms| C[Vanilla Launcher Suppressed Silently]
C -->|Auto-Repatch Triggered| D[Dedicated Splash Updater GUI Appears]
D -->|Real-time Status & Progress| E[Offline Extraction & Patching <3s]
E -->|Synchronize OWEASARSIG| F[CurseForge.exe Integrity Signature Updated]
F -->|Autonomous Relaunch| G[Modded BetterCurseForge Launches Ready!]
```
1. **Permanent Daemon Installation**: On first patch, BetterCurseForge installs to `%LOCALAPPDATA%\BetterCurseForge` with an autostart registry entry in `HKCU\...\Run` and a task scheduler fallback.
2. **Global Mutex Synchronization**: Uses Windows kernel named mutexes (`BetterCurseForgePatchMutex`) to guarantee atomic, single-process patching with zero race conditions.
3. **Resilient Win32 Watcher Daemon**: A silent background process monitors CurseForge's installation directory with 0% CPU consumption. If an unpatched state is detected (e.g., after an update), it waits for installer files to settle, terminates the unpatched process, reapplies the patch, and relaunches the modded client seamlessly without console window popups.
4. **100% Offline Zero-Delay ASAR Engine**: Unpacking and repacking use bundled tools combined with CurseForge's built-in Node runtime (`ELECTRON_RUN_AS_NODE=1`), completing the entire repatch cycle in 2–3 seconds without requiring an internet connection.
1. **Active Vanilla Interceptor**: When an update or unpatched state is detected, BetterCurseForge polls in tight 150ms slices using lightweight Win32 kernel process enumeration. If the installer starts `CurseForge.exe`, it is terminated within 50ms before Chromium or Electron can render a single frame—guaranteeing the unpatched client never flashes on screen.
2. **Dedicated Splash Updater GUI**: Rather than patching silently without visual feedback, BetterCurseForge displays a sleek, centered dark-themed card (`#121214`) featuring the official application icon, an animated purple progress bar, and real-time status updates (*"Waiting for installer..."*, *"Extracting application archive..."*, *"Unlocking native premium themes..."*, *"Injecting zero-ad rules..."*, *"Updating security signatures..."*).
3. **Global Mutex Synchronization**: Uses Windows kernel named mutexes (`BetterCurseForgePatchMutex`, `BetterCurseForgeSplashMutex`) to guarantee atomic, single-process patching with zero race conditions or duplicate windows.
4. **Resilient Win32 Watcher Daemon**: A silent background process monitors CurseForge's installation directory with 0% CPU consumption during idle. It triggers the splash updater whenever an update is applied and handles all persistence automatically.
5. **100% Offline Zero-Delay ASAR Engine**: Unpacking and repacking use bundled tools combined with CurseForge's built-in Node runtime (`ELECTRON_RUN_AS_NODE=1`), completing the entire repatch cycle in 2–3 seconds without requiring an internet connection.
---

View file

@ -34,7 +34,7 @@ Place it in any convenient folder (e.g., Downloads, Tools, or desktop).
Double-click `BetterCurseForge.exe` to launch the application.
![BetterCurseForge GUI](/logo.svg){width=64 style="display:block;margin:1rem auto;"}
![BetterCurseForge GUI](/logo.png){width=64 style="display:block;margin:1rem auto;"}
The application automatically:
- Detects your CurseForge installation folder from the Windows Registry.
@ -113,9 +113,9 @@ This restores `resources/app.asar` from the vanilla backup and re-verifies origi
## Auto-Repatch: Surviving CurseForge Updates
When the official CurseForge Launcher downloads an automatic update, it overwrites `app.asar` with a new version, temporarily removing client modifications.
When the official CurseForge Launcher downloads an automatic update, it overwrites `app.asar` with an unpatched version and attempts to restart.
BetterCurseForge solves this with **Auto-Repatch**:
BetterCurseForge provides an autonomous, smooth transition with **zero screen flashing**:
### Managing Auto-Repatch in the GUI
- In the BetterCurseForge desktop application, simply toggle the **Auto-Repatch on Update** button (turns green when active).
@ -125,15 +125,20 @@ BetterCurseForge solves this with **Auto-Repatch**:
# Run the background watcher daemon directly:
.\BetterCurseForge.exe watch
# Trigger the smooth splash updater GUI manually:
.\BetterCurseForge.exe --repatch-splash
# BetterCurseForge also manages watcher persistence automatically on patch/unpatch:
.\BetterCurseForge.exe patch # Applies patch and activates watcher autostart
.\BetterCurseForge.exe unpatch # Restores vanilla client and stops watcher
```
### How Auto-Repatch Works
1. **Background Watcher**: Runs silently with 0% CPU consumption via Windows directory event notifications.
2. **Global Mutex Lock**: Uses kernel named mutexes to guarantee single-instance execution and avoid race conditions.
3. **Automatic Re-Patching**: Whenever CurseForge updates, the watcher waits for the installer to finish, reapplies BetterCurseForge modifications offline in 2–3 seconds, synchronizes executable signatures, and relaunches the modded client seamlessly without popping command prompt windows.
1. **Background Watcher**: Runs silently with 0% CPU consumption via Windows directory event notifications and heartbeat checks.
2. **Active Vanilla Interceptor**: When an update or unpatched state is detected, the patcher polls every 150ms using Win32 kernel process enumeration. If the installer launches `CurseForge.exe`, it is killed within 50ms before any window or frame can appear.
3. **Dedicated Splash Updater GUI**: A modern, dark-themed `#121214` card appears on screen displaying the application icon, a purple `AUTO-UPDATE` badge, an animated progress bar, and real-time status messages while extracting, unlocking themes, removing ads, and repacking.
4. **Offline Zero-Delay Engine**: Offline ASAR extraction and repacking complete in 2–3 seconds using CurseForge's built-in Node v24 runtime (`ELECTRON_RUN_AS_NODE=1`), synchronizing the `OWEASARSIG` hash directly inside `CurseForge.exe`.
5. **Seamless Relaunch**: The patched BetterCurseForge client opens automatically, and the splash window gracefully closes.
---

View file

@ -24,8 +24,8 @@ features:
title: Client Themes & Free Skins
details: Integrated directly into Settings -> Themes with live hover previews, theme folder shortcuts, and all native CurseForge Premium themes unlocked for free.
- icon: 🔄
title: Auto-Repatch
details: Survives launcher updates effortlessly. The automated background task detects CurseForge updates and silently re-patches the client.
title: Auto-Repatch & Smooth Updates
details: Survives launcher updates effortlessly. The active interceptor suppresses unpatched windows, and a sleek splash GUI displays live progress while repatching in seconds.
- icon: 🖥️
title: Modern GUI & CLI
details: Includes an intuitive dark-themed desktop application with one-click actions, as well as a full command-line interface for power users.

View file

@ -1,20 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
<defs>
<linearGradient id="purpleGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#c084fc" />
<stop offset="50%" stop-color="#9333ea" />
<stop offset="100%" stop-color="#6b21a8" />
</linearGradient>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
</defs>
<!-- Background rounded rect -->
<rect x="5" y="5" width="90" height="90" rx="22" fill="#14141d" stroke="url(#purpleGrad)" stroke-width="3" />
<!-- Stylized Flame / Anvil / BCF Monogram -->
<path d="M 50 18 C 55 30 65 36 68 46 C 72 58 64 74 50 78 C 36 74 28 58 32 46 C 35 36 45 30 50 18 Z" fill="url(#purpleGrad)" filter="url(#glow)" />
<path d="M 50 38 C 53 45 58 48 59 54 C 61 60 57 68 50 70 C 43 68 39 60 41 54 C 42 48 47 45 50 38 Z" fill="#ffffff" opacity="0.9" />
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" width="512" height="512">
<image href="logo.png" xlink:href="logo.png" x="0" y="0" width="512" height="512" />
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 225 B

View file

@ -720,30 +720,30 @@ if __name__ == "__main__":
try:
if len(sys.argv) > 1:
arg = sys.argv[1].lower()
if arg == "--watch":
if arg in ("--watch", "watch"):
patch_core.run_watcher_loop()
sys.exit(0)
elif arg in ("--repatch-splash", "--splash"):
elif arg in ("--repatch-splash", "--splash", "splash"):
pid = int(sys.argv[2]) if len(sys.argv) > 2 and sys.argv[2].isdigit() else None
splash = SplashUpdaterWindow(pid)
splash.run()
sys.exit(0)
elif arg == "--wait-for-update":
elif arg in ("--wait-for-update", "wait-for-update"):
pid = int(sys.argv[2]) if len(sys.argv) > 2 and sys.argv[2].isdigit() else None
splash = SplashUpdaterWindow(pid)
splash.run()
sys.exit(0)
elif arg == "--ensure-watcher":
elif arg in ("--ensure-watcher", "ensure-watcher"):
if not patch_core.is_watcher_running():
patch_core.start_background_watcher()
sys.exit(0)
elif arg == "patch":
elif arg in ("--patch", "patch"):
patch_core.patch_curseforge()
sys.exit(0)
elif arg == "unpatch":
elif arg in ("--unpatch", "unpatch"):
patch_core.unpatch_curseforge()
sys.exit(0)
elif arg == "status":
elif arg in ("--status", "status"):
cf = patch_core.get_curseforge_dir()
print("CurseForge:", cf)
print("Patched:", patch_core.is_curseforge_patched(cf) if cf else False)