aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/docs/content/en/development/implementation.mdx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/docs/content/en/development/implementation.mdx')
-rw-r--r--packages/docs/content/en/development/implementation.mdx351
1 files changed, 351 insertions, 0 deletions
diff --git a/packages/docs/content/en/development/implementation.mdx b/packages/docs/content/en/development/implementation.mdx
new file mode 100644
index 0000000..3ecadfe
--- /dev/null
+++ b/packages/docs/content/en/development/implementation.mdx
@@ -0,0 +1,351 @@
+---
+title: Internal Implementation
+description: Detailed implementation and technical specifications of DropOut core functions
+---
+
+# Internal Implementation
+
+This page details the technical implementation details, data structures, and processing flows of the launcher's core modules.
+
+## 1. Authentication System
+
+The authentication chain contains multiple asynchronous steps, and failure at any step will interrupt the entire process. DropOut uses the Microsoft Device Code Flow to achieve secure login without redirection.
+
+### 1.1 Detailed Process
+1. **Device Code Request**:
+ - Call `https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode`
+ - Get user verification code and verification URL.
+2. **Token Exchange**: Poll `/oauth2/v2.0/token` to get the primary Access Token and Refresh Token.
+3. **Xbox Live Authentication**: Get `Token` and `uhs` (User Hash).
+4. **XSTS Authorization**: Redirect to `rp://api.minecraftservices.com/`.
+5. **Minecraft Login**: Exchange for the final game Access Token using the `XBL3.0 x=<uhs>;<xsts_token>` format token.
+
+### 1.2 Account Storage and Security
+Account data is persisted in `accounts.json`, containing account type and encrypted token information:
+```json
+{
+ "active_account_uuid": "...",
+ "accounts": [
+ {
+ "type": "Microsoft",
+ "username": "...",
+ "uuid": "...",
+ "access_token": "...",
+ "refresh_token": "...",
+ "expires_at": 1234567890
+ },
+ { "type": "Offline", "username": "Player", "uuid": "..." }
+ ]
+}
+```
+**Offline UUID**: Uses a username-based deterministic UUID v3 to ensure consistency of local saves and configurations.
+
+```rust
+// core/auth.rs implementation details
+pub fn generate_offline_uuid(username: &str) -> String {
+ let namespace = Uuid::NAMESPACE_OID;
+ Uuid::new_v3(&namespace, username.as_bytes()).to_string()
+}
+```
+
+### 1.3 Authentication Related APIs
+| Command / Event | Type | Description |
+| :--- | :--- | :--- |
+| `start_microsoft_login` | Invoke | Start device flow and return verification code |
+| `complete_microsoft_login` | Invoke | Poll and complete the full authentication chain |
+| `login_offline` | Invoke | Create and switch to offline account |
+| `auth-progress` | Event | Report authentication progress in real-time (e.g., "Xbox Live Auth...") |
+
+---
+
+## 2. Java Runtime Management
+
+### 2.1 Catalogs and Metadata
+The Java Catalog caches available versions and platform-specific links from Adoptium.
+- **Storage**: `java_catalog.json` records SHA256 checksums and file sizes for each version.
+
+```json
+// java_catalog.json structure example
+{
+ "releases": [
+ {
+ "major_version": 17,
+ "image_type": "jdk",
+ "version": "17.0.9+9",
+ "download_url": "...",
+ "checksum": "...",
+ "file_size": 123456789
+ }
+ ],
+ "cached_at": 1700000000
+}
+```
+
+- **Detection**: Executes `java -version` command on candidate paths and parses version strings and 64-Bit identifiers from `stderr` output.
+
+```rust
+// core/java.rs detection logic
+fn check_java_installation(path: &PathBuf) -> Option<JavaInstallation> {
+ let mut cmd = Command::new(path);
+ cmd.arg("-version");
+ // Parse "version" keyword information from stderr output
+}
+```
+
+### 2.2 Automatic Installation Logic
+1. **Download**: Supports resumable downloads; large files are downloaded in parallel segments.
+2. **Extraction**: Handles archives for different operating systems (macOS handles .app structure inside .tar.gz, Windows handles .zip).
+3. **Verification**: Mandatory hash verification after download ensures runtime environment integrity.
+
+### 2.3 Java Management Related APIs
+| Command / Event | Type | Description |
+| :--- | :--- | :--- |
+| `detect_java` | Invoke | Scan system installed Java environments |
+| `download_adoptium_java` | Invoke | Start asynchronous download and automatic extraction/configuration |
+| `cancel_java_download` | Invoke | Cancel current download task via atomic flag |
+| `java-download-progress` | Event | Report file size, speed, percentage, and ETA |
+
+---
+
+## 3. Game Launch Logic & JVM Optimization
+
+### 3.1 Memory Allocation Scheme
+- **Xmx & Xms**: It is recommended to set initial memory and maximum memory to be consistent.
+- **Strategy**: The launcher automatically suggests optimal allocation based on total system memory and Java architecture, and parameters generated by the launcher have the highest priority.
+
+### 3.2 G1GC Optimization Strategy
+For 1.17+ versions and high-load mod environments, DropOut injects a concise G1GC parameter chain by default:
+```bash
+-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200
+-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC
+```
+
+---
+
+## 4. Mod Loader Mechanism
+
+### 4.1 Version Merging (Inheritance)
+Mod loaders link to the vanilla Minecraft version JSON via the `inheritsFrom` field.
+
+```json
+// Typical Fabric version config (partial)
+{
+ "id": "fabric-loader-0.15.0-1.20.4",
+ "inheritsFrom": "1.20.4",
+ "mainClass": "net.fabricmc.loader.impl.launch.knot.KnotClient",
+ "libraries": [
+ {
+ "name": "net.fabricmc:fabric-loader:0.15.0",
+ "url": "https://maven.fabricmc.net/"
+ }
+ ]
+}
+```
+
+The following merging is performed during the launch phase:
+1. **Library Priority**: Loader's own libraries (e.g., Fabric Loader) rank before vanilla libraries.
+2. **Main Class Override**: `mainClass` is always taken from the child definition (i.e., the mod loader's entry point, like Fabric's `KnotClient`).
+3. **Argument Chain**: Merge `jvm` and `game` argument arrays, automatically filtering out inapplicable system rules.
+
+```rust
+// core/version_merge.rs merge core implementation
+pub fn merge_versions(child: GameVersion, parent: GameVersion) -> GameVersion {
+ let mut merged_libraries = child.libraries;
+ merged_libraries.extend(parent.libraries);
+ // Merge argument logic and return new GameVersion instance
+}
+```
+
+### 4.2 Library Path Resolution (Maven)
+The launcher implements complete Maven path conversion logic:
+`group:artifact:version` → `group_path/artifact/version/artifact-version.jar`
+
+```rust
+// core/maven.rs coordinate conversion path logic
+pub fn to_path(&self) -> String {
+ let group_path = self.group.replace('.', "/");
+ format!("{}/{}/{}/{}-{}.{}",
+ group_path, self.artifact, self.version,
+ self.artifact, self.version, self.extension
+ )
+}
+```
+
+### 4.3 Mod Installation Interface
+The launcher uses differentiated installation strategies based on different loader characteristics.
+
+#### Forge Installation Logic
+For Forge, DropOut downloads the official Installer and invokes the standard installer via a Java subprocess, ensuring this process is completely consistent with the official flow (including bytecode patch generation).
+
+```rust
+// core/forge.rs invoke official installer (simplified example)
+Command::new(java_path)
+ .args(&[
+ "-jar",
+ installer_path.to_str().unwrap(),
+ "--installClient",
+ game_dir.to_str().unwrap()
+ ])
+ .output()?;
+```
+
+| Command / Event | Type | Description |
+| :--- | :--- | :--- |
+| `install_fabric` | Invoke | Download Fabric libraries and generate inheritance JSON |
+| `install_forge` | Invoke | Run Forge Installer and perform bytecode patching |
+| `mod-loader-progress` | Event | Report installation stage (e.g., "processing", "complete") |
+
+---
+
+## 5. Communication & Monitoring System
+
+### 5.1 Event Bus
+The backend sends asynchronous pulses to the upper layer via Tauri's `Window` instance.
+
+```rust
+// Backend emit_log! macro simplifies log emission
+macro_rules! emit_log {
+ ($window:expr, $msg:expr) => {
+ let _ = $window.emit("launcher-log", $msg);
+ println!("[Launcher] {}", $msg);
+ };
+}
+```
+
+- **`launcher-log`**: General console output stream for global operation trajectory recording.
+- **`game-stdout` / `game-stderr`**: Capture game subprocess standard output and errors, transmitting to frontend in real-time via independent threads.
+
+```typescript
+// Frontend listen example (Svelte 5)
+import { listen } from "@tauri-apps/api/event";
+
+const unlisten = await listen("launcher-log", (event) => {
+ logStore.addLine(event.payload);
+});
+```
+
+- **`version-installed`**: Notify UI to update version list status after asynchronous task completion.
+
+### 5.2 Launch Log Desensitization
+To prevent sensitive information leakage to third-party log platforms, the launcher masks tokens before recording launch commands.
+
+```rust
+// partial argument masking logic based on main.rs
+let masked_args: Vec<String> = args.iter().enumerate().map(|(i, arg)| {
+ if i > 0 && (args[i-1] == "--accessToken" || args[i-1] == "--uuid") {
+ "***".to_string()
+ } else {
+ arg.clone()
+ }
+}).collect();
+```
+
+---
+
+## 6. Architecture & Development Standards
+
+### 6.1 Core Architecture Patterns
+
+#### Backend Command Pattern (Tauri)
+All backend functions are encapsulated as asynchronous Commands and injected with global state via `State`.
+
+1. **Define Command**:
+```rust
+#[tauri::command]
+async fn start_game(
+ window: Window,
+ auth_state: State<'_, AccountState>,
+ config_state: State<'_, ConfigState>
+) -> Result<String, String> {
+ emit_log!(window, "Starting game launch...");
+ // Business logic...
+ Ok("Success".into())
+}
+```
+
+2. **Register Command (main.rs)**:
+```rust
+tauri::Builder::default()
+ .invoke_handler(tauri::generate_handler![start_game, ...])
+```
+
+3. **Frontend Call**:
+```typescript
+import { invoke } from "@tauri-apps/api/core";
+// Argument names must correspond to Rust function parameters in snake_case/camelCase
+const result = await invoke("start_game", { versionId: "1.20.4" });
+```
+
+#### Error Handling Pattern
+All Tauri commands uniformly return `Result<T, String>`, where the Err type is fixed as String, allowing the frontend to display error messages directly.
+
+```rust
+// Uniformly use map_err to convert errors to String
+.await
+.map_err(|e| e.to_string())?;
+
+// Frontend catch
+try {
+ await invoke("...")
+} catch (e) {
+ // e is the error string returned by Rust
+ console.error(e);
+}
+```
+
+#### Frontend State Management (Svelte 5 Runes)
+The frontend fully adopts Svelte 5's `Runes` system (`$state`, `$effect`) replacing the old `writable` stores.
+
+```typescript
+// ui/src/stores/auth.svelte.ts
+export class AuthState {
+ // Use $state to define reactive data
+ currentAccount = $state<Account | null>(null);
+ isLoginModalOpen = $state(false);
+
+ constructor() {
+ // Initialization logic
+ }
+}
+
+// Export singleton for global access
+export const authState = new AuthState();
+```
+
+#### Frontend View Routing (Manual Routing)
+DropOut does not use conventional URL routing, but instead manages the currently active view component via global state.
+
+```typescript
+// ui/src/stores/ui.svelte.ts
+export class UIState {
+ activeView = $state("home"); // "home" | "versions" | "settings"
+
+ setView(view: string) {
+ this.activeView = view;
+ }
+}
+```
+
+```svelte
+<!-- App.svelte -->
+<script>
+ import { uiState } from "./stores/ui.svelte";
+</script>
+
+{#if uiState.activeView === "home"}
+ <HomeView />
+{:else if uiState.activeView === "settings"}
+ <SettingsView />
+{/if}
+```
+
+### 6.2 Development Best Practices
+1. **Silent Refresh**: Check `expires_at` before calling `start_game`, and call `refresh_full_auth` if expired.
+2. **UA Spoofing**: Microsoft auth WAF blocks requests with empty UA, so simulation of real UA in `reqwest` client is mandatory.
+3. **Log Desensitization**: Sensitive parameter values like `--accessToken` and `--uuid` must be masked in launch logs.
+
+### 6.3 Future Roadmap
+- **Multi-device Account Sync**: Explore OS-level encrypted storage solution to replace existing plaintext `accounts.json`.
+- **Automatic Dependency Resolution**: Automatically parse and download prerequisite libraries from Modrinth/CurseForge when installing mods.
+- **Intelligent Conflict Detection**: Scan `mods/` folder before launch to identify potential class conflicts or injection point errors.
+- **Config Sharing**: Support one-click export/import of complete instance configuration packages (Modpacks).