Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ next-env.d.ts
*.sln
*.sw?
CLAUDE.md
.claude/
.claude/
.zcode/
66 changes: 64 additions & 2 deletions src-tauri/src/instance/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,47 @@ pub async fn scan_instance_files_for_export(
Ok(entries)
}

/// Scan an instance for the full pack export: the version-isolated instance
/// content plus (when version isolation is off) the shared game dir directories.
#[tauri::command]
pub async fn scan_instance_files_for_full_export(
app: AppHandle,
instance_id: String,
) -> XMCLResult<Vec<crate::instance::models::misc::ExportFileEntry>> {
use crate::instance::helpers::modpack::export_fullzip::scan_instance_for_full_export;

let (version_path, version_isolation) = {
let binding = app.state::<Mutex<HashMap<String, Instance>>>();
let state = binding.lock().unwrap();
let instance = state
.get(&instance_id)
.ok_or(InstanceError::InstanceNotFoundByID)?;
(
instance.version_path.clone(),
get_instance_game_config(&app, instance).version_isolation,
)
};
let game_dir = version_path
.parent()
.and_then(|p| p.parent())
.ok_or(InstanceError::InstanceNotFoundByID)?;

let entries = scan_instance_for_full_export(&version_path, game_dir, version_isolation)
.map_err(|_| InstanceError::FileNotFoundError)?;

Ok(entries)
}

/// Import a full pack (self-contained zip with instance + libraries + assets)
/// into the given game directory. Pure extraction, nothing is downloaded.
/// Returns the new instance id (`<gameDirectoryName>:<instanceName>`).
#[tauri::command]
pub async fn import_full_pack(directory: GameDirectory, pack_path: String) -> XMCLResult<String> {
use crate::instance::helpers::modpack::export_fullzip::import_full_pack as do_import_full_pack;

do_import_full_pack(&directory, &PathBuf::from(pack_path))
}

#[tauri::command]
pub async fn export_modpack(
app: AppHandle,
Expand All @@ -1263,8 +1304,8 @@ pub async fn export_modpack(
let instance_path = get_instance_subdir_path_by_id(&app, &instance_id, &InstanceSubdirType::Root)
.ok_or(InstanceError::InstanceNotFoundByID)?;

// Retrieve instance to get mc version and mod loader info
let (mc_version, loader_type, loader_version) = {
// Retrieve instance to get mc version, mod loader info and full pack details
let (mc_version, loader_type, loader_version, version_path, version_isolation) = {
let binding = app.state::<Mutex<HashMap<String, Instance>>>();
let state = binding.lock().unwrap();
let instance = state
Expand All @@ -1274,6 +1315,8 @@ pub async fn export_modpack(
instance.version.clone(),
instance.mod_loader.loader_type.clone(),
instance.mod_loader.version.clone(),
instance.version_path.clone(),
get_instance_game_config(&app, instance).version_isolation,
)
};

Expand Down Expand Up @@ -1318,6 +1361,25 @@ pub async fn export_modpack(
&out,
)?;
}
ExportFormat::Full => {
use crate::instance::helpers::modpack::export_fullzip::export_full_pack;
let game_dir = version_path
.parent()
.and_then(|p| p.parent())
.ok_or(InstanceError::InstanceNotFoundByID)?;
export_full_pack(
&app,
&version_path,
game_dir,
&meta,
&mc_version,
&loader_type,
&loader_version,
version_isolation,
&selected_files,
&out,
)?;
}
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/instance/helpers/modpack/export_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct ExportProgressPayload {
pub enum ExportStage {
Matching,
Packing,
Copying,
WritingManifest,
Done,
}
Expand Down
Loading
Loading