aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri/src
diff options
context:
space:
mode:
authorHsiangNianian <i@jyunko.cn>2026-01-18 12:58:22 +0800
committerHsiangNianian <i@jyunko.cn>2026-01-18 12:58:22 +0800
commit5e9850881d35d3af9ae8a2f99402e02300f77835 (patch)
tree630f071c903e5ff7b793e9f8fb96b35ebf8eda06 /src-tauri/src
parentee6c73333ae585c601de6c0fcd216fdd7d2e7bce (diff)
downloadDropOut-5e9850881d35d3af9ae8a2f99402e02300f77835.tar.gz
DropOut-5e9850881d35d3af9ae8a2f99402e02300f77835.zip
fix: complete Instance/Profile System isolation and state management
## Overview Fixed critical multi-instance isolation bugs where versions, mod loaders, and instance state were not properly isolated between instances. These changes ensure full data isolation and consistent instance metadata. ## Bug Fixes - P0 (Critical Isolation Issues) ### 1. Backend: get_versions() command isolation - Problem: Used global app_data_dir instead of instance-specific game_dir - Fix: Added instance_id parameter, now queries instance.game_dir - Impact: Versions are now properly isolated per instance ### 2. Frontend: delete_version missing instanceId - Problem: Frontend passed only versionId, not instanceId - Fix: Updated VersionsView.svelte to pass instanceId parameter - Impact: Version deletion now targets correct instance ### 3. Frontend: get_version_metadata missing instanceId - Problem: Metadata queries didn't specify which instance to check - Fix: Updated VersionsView.svelte to pass instanceId parameter - Impact: Version info displayed per-instance correctly ### 4. Frontend: Instance switching doesn't refresh versions - Problem: Switching instances didn't reload version list - Fix: Added $effect hook in GameState to watch activeInstanceId changes - Impact: Version list auto-refreshes on instance switch ## Bug Fixes - P1 (State Synchronization) ### 5. Backend: install_fabric doesn't update Instance.mod_loader - Problem: Instance.mod_loader field wasn't updated after installation - Fix: Added instance_state.update_instance() call - Impact: Instance metadata stays in sync ### 6. Backend: install_forge doesn't update Instance.mod_loader - Problem: Instance.mod_loader field wasn't updated after installation - Fix: Added instance_state.update_instance() call - Impact: Instance metadata stays in sync ### 7. Backend: delete_version doesn't clean up Instance state - Problem: Deleting version didn't clear Instance.version_id or .mod_loader - Fix: Added cleanup logic to clear stale references - Impact: Instance state remains valid after deletion ## Testing - Added comprehensive integration tests in instance_isolation_tests.rs - Tests document 10 key scenarios for multi-instance isolation - All code compiles cleanly with no errors
Diffstat (limited to 'src-tauri/src')
-rw-r--r--src-tauri/src/main.rs58
1 files changed, 51 insertions, 7 deletions
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 853c93e..4f9071f 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -879,12 +879,14 @@ fn parse_jvm_arguments(
}
#[tauri::command]
-async fn get_versions(window: Window) -> Result<Vec<core::manifest::Version>, String> {
- let app_handle = window.app_handle();
- let game_dir = app_handle
- .path()
- .app_data_dir()
- .map_err(|e| format!("Failed to get app data dir: {}", e))?;
+async fn get_versions(
+ _window: Window,
+ instance_state: State<'_, core::instance::InstanceState>,
+ instance_id: String,
+) -> Result<Vec<core::manifest::Version>, String> {
+ let game_dir = instance_state
+ .get_instance_game_dir(&instance_id)
+ .ok_or_else(|| format!("Instance {} not found", instance_id))?;
match core::manifest::fetch_version_manifest().await {
Ok(manifest) => {
@@ -1595,6 +1597,13 @@ async fn install_fabric(
format!("Fabric installed successfully: {}", result.id)
);
+ // Update Instance's mod_loader metadata
+ if let Some(mut instance) = instance_state.get_instance(&instance_id) {
+ instance.mod_loader = Some("fabric".to_string());
+ instance.mod_loader_version = Some(loader_version);
+ instance_state.update_instance(instance)?;
+ }
+
// Emit event to notify frontend
let _ = window.emit("fabric-installed", &result.id);
@@ -1669,6 +1678,31 @@ async fn delete_version(
.await
.map_err(|e| format!("Failed to delete version: {}", e))?;
+ // Clean up Instance state if necessary
+ if let Some(mut instance) = instance_state.get_instance(&instance_id) {
+ let mut updated = false;
+
+ // If deleted version is the current selected version
+ if instance.version_id.as_ref() == Some(&version_id) {
+ instance.version_id = None;
+ updated = true;
+ }
+
+ // If deleted version is a modded version, clear mod_loader
+ if (version_id.starts_with("fabric-loader-")
+ && instance.mod_loader == Some("fabric".to_string()))
+ || (version_id.contains("-forge-") && instance.mod_loader == Some("forge".to_string()))
+ {
+ instance.mod_loader = None;
+ instance.mod_loader_version = None;
+ updated = true;
+ }
+
+ if updated {
+ instance_state.update_instance(instance)?;
+ }
+ }
+
// Emit event to notify frontend
let _ = window.emit("version-deleted", &version_id);
@@ -1948,7 +1982,10 @@ async fn install_forge(
// Check if the version JSON already exists
let version_id = core::forge::generate_version_id(&game_version, &forge_version);
- let json_path = game_dir.join("versions").join(&version_id).join(format!("{}.json", version_id));
+ let json_path = game_dir
+ .join("versions")
+ .join(&version_id)
+ .join(format!("{}.json", version_id));
let result = if json_path.exists() {
// Version JSON was created by the installer, load it
@@ -1974,6 +2011,13 @@ async fn install_forge(
format!("Forge installed successfully: {}", result.id)
);
+ // Update Instance's mod_loader metadata
+ if let Some(mut instance) = instance_state.get_instance(&instance_id) {
+ instance.mod_loader = Some("forge".to_string());
+ instance.mod_loader_version = Some(forge_version);
+ instance_state.update_instance(instance)?;
+ }
+
// Emit event to notify frontend
let _ = window.emit("forge-installed", &result.id);