aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri/src/core
diff options
context:
space:
mode:
authorHsiangNianian <i@jyunko.cn>2026-01-18 12:16:05 +0800
committerHsiangNianian <i@jyunko.cn>2026-01-18 12:16:05 +0800
commit079ee0a6611499db68d1eb4894fab64739d5d2e7 (patch)
treef7cab9f6dded91a25a16f85a3e99f6299ea5a0a1 /src-tauri/src/core
parent16047ca6aa8eea7f5495e938faebb01bf96d09de (diff)
downloadDropOut-079ee0a6611499db68d1eb4894fab64739d5d2e7.tar.gz
DropOut-079ee0a6611499db68d1eb4894fab64739d5d2e7.zip
fix(instance): copy directory BEFORE creating metadata in duplicate_instance
Prevent race condition in duplicate_instance by copying the source game directory BEFORE creating and saving the new instance metadata. This ensures that if the copy fails, no orphaned metadata is created. Also copy the icon_path from source instance to maintain visual consistency.
Diffstat (limited to 'src-tauri/src/core')
-rw-r--r--src-tauri/src/core/instance.rs43
1 files changed, 32 insertions, 11 deletions
diff --git a/src-tauri/src/core/instance.rs b/src-tauri/src/core/instance.rs
index 90ec34e..738dbd8 100644
--- a/src-tauri/src/core/instance.rs
+++ b/src-tauri/src/core/instance.rs
@@ -218,21 +218,42 @@ impl InstanceState {
.get_instance(id)
.ok_or_else(|| format!("Instance {} not found", id))?;
- // Create new instance
- let mut new_instance = self.create_instance(new_name, app_handle)?;
-
- // Copy instance properties
- new_instance.version_id = source_instance.version_id.clone();
- new_instance.mod_loader = source_instance.mod_loader.clone();
- new_instance.mod_loader_version = source_instance.mod_loader_version.clone();
- new_instance.notes = source_instance.notes.clone();
-
- // Copy directory contents
+ // Prepare new instance metadata (but don't save yet)
+ let new_id = uuid::Uuid::new_v4().to_string();
+ let instances_dir = app_handle
+ .path()
+ .app_data_dir()
+ .map_err(|e| e.to_string())?
+ .join("instances");
+ let new_game_dir = instances_dir.join(&new_id);
+
+ // Copy directory FIRST - if this fails, don't create metadata
if source_instance.game_dir.exists() {
- copy_dir_all(&source_instance.game_dir, &new_instance.game_dir)
+ copy_dir_all(&source_instance.game_dir, &new_game_dir)
.map_err(|e| format!("Failed to copy instance directory: {}", e))?;
+ } else {
+ // If source dir doesn't exist, create new empty game dir
+ std::fs::create_dir_all(&new_game_dir)
+ .map_err(|e| format!("Failed to create instance directory: {}", e))?;
}
+ // NOW create metadata and save
+ let new_instance = Instance {
+ id: new_id,
+ name: new_name,
+ game_dir: new_game_dir,
+ version_id: source_instance.version_id.clone(),
+ mod_loader: source_instance.mod_loader.clone(),
+ mod_loader_version: source_instance.mod_loader_version.clone(),
+ notes: source_instance.notes.clone(),
+ icon_path: source_instance.icon_path.clone(),
+ created_at: std::time::SystemTime::now()
+ .duration_since(std::time::UNIX_EPOCH)
+ .unwrap()
+ .as_secs() as i64,
+ last_played: None,
+ };
+
self.update_instance(new_instance.clone())?;
Ok(new_instance)