feat: sync Aeronautics from launcher v2
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
mod java;
|
||||
mod manifest;
|
||||
mod profile;
|
||||
mod remote;
|
||||
mod settings;
|
||||
|
||||
use serde::Serialize;
|
||||
@@ -76,6 +77,30 @@ async fn sync_profile(app: AppHandle, manifest_json: String) -> Result<profile::
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
/// Loads and validates the published ShaCraft manifest before inspecting a profile.
|
||||
#[tauri::command]
|
||||
async fn inspect_remote_profile(app: AppHandle, profile_id: String) -> Result<profile::ProfileInspection, String> {
|
||||
let data_dir = app.path().app_data_dir()
|
||||
.map_err(|error| format!("Cannot resolve launcher data directory: {error}"))?;
|
||||
tauri::async_runtime::spawn_blocking(move || {
|
||||
let manifest = remote::fetch_manifest(&profile_id).map_err(|error| error.to_string())?;
|
||||
profile::inspect(&data_dir.join("profiles").join(&manifest.id), &manifest)
|
||||
.map_err(|error| error.to_string())
|
||||
}).await.map_err(|error| format!("Profile inspection task failed: {error}"))?
|
||||
}
|
||||
|
||||
/// Downloads missing or changed ShaCraft-managed files from the fixed v2 endpoint.
|
||||
#[tauri::command]
|
||||
async fn sync_remote_profile(app: AppHandle, profile_id: String) -> Result<profile::SyncResult, String> {
|
||||
let data_dir = app.path().app_data_dir()
|
||||
.map_err(|error| format!("Cannot resolve launcher data directory: {error}"))?;
|
||||
tauri::async_runtime::spawn_blocking(move || {
|
||||
let manifest = remote::fetch_manifest(&profile_id).map_err(|error| error.to_string())?;
|
||||
profile::sync(&data_dir.join("profiles").join(&manifest.id), &manifest)
|
||||
.map_err(|error| error.to_string())
|
||||
}).await.map_err(|error| format!("Profile synchronization task failed: {error}"))?
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn load_settings(app: AppHandle) -> Result<settings::LauncherSettings, String> {
|
||||
let data_dir = app
|
||||
@@ -108,6 +133,8 @@ pub fn run() {
|
||||
validate_manifest,
|
||||
inspect_profile,
|
||||
sync_profile,
|
||||
inspect_remote_profile,
|
||||
sync_remote_profile,
|
||||
load_settings,
|
||||
save_settings
|
||||
])
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use crate::manifest::{self, Manifest};
|
||||
use reqwest::{blocking::Client, redirect::Policy};
|
||||
use std::{fmt, time::Duration};
|
||||
|
||||
const AERONAUTICS_MANIFEST: &str =
|
||||
"https://shacraft.ru/api/launcher/v2/profiles/aeronautics/manifest";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RemoteError {
|
||||
UnknownProfile,
|
||||
Network(reqwest::Error),
|
||||
Status(reqwest::StatusCode),
|
||||
TooLarge,
|
||||
InvalidManifest(manifest::ManifestError),
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoteError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::UnknownProfile => formatter.write_str("Unknown ShaCraft profile"),
|
||||
Self::Network(error) => write!(formatter, "Cannot load ShaCraft manifest: {error}"),
|
||||
Self::Status(status) => write!(formatter, "ShaCraft manifest request failed: {status}"),
|
||||
Self::TooLarge => formatter.write_str("ShaCraft manifest is too large"),
|
||||
Self::InvalidManifest(error) => write!(formatter, "ShaCraft manifest is invalid: {error}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fetch_manifest(profile_id: &str) -> Result<Manifest, RemoteError> {
|
||||
let url = match profile_id {
|
||||
"aeronautics" => AERONAUTICS_MANIFEST,
|
||||
_ => return Err(RemoteError::UnknownProfile),
|
||||
};
|
||||
let client = Client::builder()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.redirect(Policy::none())
|
||||
.build()
|
||||
.map_err(RemoteError::Network)?;
|
||||
let response = client.get(url).send().map_err(RemoteError::Network)?;
|
||||
if !response.status().is_success() {
|
||||
return Err(RemoteError::Status(response.status()));
|
||||
}
|
||||
if response.content_length().is_some_and(|size| size > 2 * 1024 * 1024) {
|
||||
return Err(RemoteError::TooLarge);
|
||||
}
|
||||
let source = response.text().map_err(RemoteError::Network)?;
|
||||
manifest::validate_json(&source).map_err(RemoteError::InvalidManifest)
|
||||
}
|
||||
Reference in New Issue
Block a user