OneLauncher-Cracked/packages/oneclient_core/src/migration/mod.rs
Julian Chang 29d1f1c9d2
Bugs
Fixed #492
Fixed #510
Fixed #506
Fixed #568
Fixed #582
Fixed #578
Fixed #567
Fixed #588
Fixed #585
Fixed #571
Fixed #587
Fixed #584
2026-07-15 13:41:43 -04:00

93 lines
2.6 KiB
Rust

mod fs;
pub mod oneclient_v1;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::LauncherResult;
use crate::packages::domain::GameLoader;
pub use fs::copy_tree;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MigrationSource {
OneClientV1,
}
impl MigrationSource {
pub const ALL: &'static [MigrationSource] = &[MigrationSource::OneClientV1];
pub fn id(self) -> &'static str {
match self {
MigrationSource::OneClientV1 => "oneclient_v1",
}
}
pub fn display_name(self) -> &'static str {
match self {
MigrationSource::OneClientV1 => "OneClient",
}
}
pub fn from_id(id: &str) -> Option<MigrationSource> {
Self::ALL.iter().copied().find(|s| s.id() == id)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SourceInstance {
/// Source-local identifier (v1: the cluster row id). Purely informational.
pub instance_id: i64,
pub folder_name: String,
pub mc_version: String,
pub mc_loader: GameLoader,
/// Bundle categories the user had installed on this instance, e.g.
/// `["HUD", "Performance"]`. Empty when the source has no category concept.
pub categories: Vec<String>,
pub has_game_dir: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MigrationDetection {
pub source: MigrationSource,
pub root: PathBuf,
pub instances: Vec<SourceInstance>,
}
/// Where an imported game directory should land in *this* launcher.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImportTarget {
/// Copy into the shared `<launcher_dir>/.minecraft`.
Shared,
/// Copy into a specific new cluster's own folder and mark it dedicated so
/// `Cluster::game_dir()` resolves there instead of the shared dir.
Dedicated { new_cluster_id: i64 },
}
#[tracing::instrument]
pub async fn detect() -> LauncherResult<Option<MigrationDetection>> {
for source in MigrationSource::ALL.iter().copied() {
let detection = match source {
MigrationSource::OneClientV1 => oneclient_v1::detect().await?,
};
if let Some(detection) = detection
&& !detection.instances.is_empty()
{
return Ok(Some(detection));
}
}
Ok(None)
}
#[tracing::instrument]
pub async fn import_game_dir(
source: MigrationSource,
folder_name: &str,
target: ImportTarget,
) -> LauncherResult<()> {
match source {
MigrationSource::OneClientV1 => oneclient_v1::import_game_dir(folder_name, target).await,
}
}