OneLauncher-Cracked/packages/oneclient_app/src/hooks/queries/mutations.rs
2026-08-08 11:33:24 +07:00

183 lines
6.8 KiB
Rust

use std::path::PathBuf;
use freya::query::{Mutation, MutationCapability, QueriesStorage, UseMutation, use_mutation};
use oneclient_content::packages::{ContentType, PackageStore};
use oneclient_db::models::ClusterId;
use super::bundles::{BundleOverridesQuery, BundleUpdatesQuery, BundlesWithStatusQuery};
use super::cluster_content::ClusterContentQuery;
use super::clusters::ListClustersQuery;
use super::package_updates::PackageUpdatesQuery;
use super::settings_profiles::{
ClusterProfileQuery, ClusterSettingsQuery, GameProfileQuery, ListNamedProfilesQuery,
};
use super::versions::{LoaderVersionsQuery, VersionsMetadataQuery};
pub async fn invalidate_cluster_queries() {
QueriesStorage::<ListClustersQuery>::try_invalidate_all().await;
QueriesStorage::<ClusterContentQuery>::try_invalidate_all().await;
QueriesStorage::<BundlesWithStatusQuery>::try_invalidate_all().await;
QueriesStorage::<BundleOverridesQuery>::try_invalidate_all().await;
QueriesStorage::<BundleUpdatesQuery>::try_invalidate_all().await;
QueriesStorage::<PackageUpdatesQuery>::try_invalidate_all().await;
QueriesStorage::<VersionsMetadataQuery>::try_invalidate_all().await;
QueriesStorage::<LoaderVersionsQuery>::try_invalidate_all().await;
}
/// Split out of [`invalidate_cluster_queries`] so an install can wait for just
/// this before dropping its busy flag the full sweep hits the network
pub async fn invalidate_cluster_content_queries() {
QueriesStorage::<ClusterContentQuery>::try_invalidate_all().await;
}
pub async fn invalidate_profile_queries() {
QueriesStorage::<ListNamedProfilesQuery>::try_invalidate_all().await;
QueriesStorage::<GameProfileQuery>::try_invalidate_all().await;
QueriesStorage::<ClusterProfileQuery>::try_invalidate_all().await;
QueriesStorage::<ClusterSettingsQuery>::try_invalidate_all().await;
QueriesStorage::<ListClustersQuery>::try_invalidate_all().await;
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct ClusterMutation;
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum ClusterAction {
ToggleArtifact {
cluster_id: ClusterId,
hash: String,
},
RemoveArtifact {
cluster_id: ClusterId,
hash: String,
},
RemoveBundlePackageFromDisk {
cluster_id: ClusterId,
hash: String,
},
SetBundlePackageEnabled {
cluster_id: ClusterId,
bundle_name: String,
package_id: String,
enabled: bool,
/// Manifest default matching it clears the override contradicting it
/// writes `Enabled` / `Disabled`
manifest_default: bool,
},
ImportLocalFile {
cluster_id: ClusterId,
content_type: ContentType,
path: PathBuf,
},
SetDedicatedDir {
cluster_id: ClusterId,
dedicated: bool,
},
VerifyFiles {
cluster_id: ClusterId,
},
}
impl MutationCapability for ClusterMutation {
type Ok = ();
type Err = String;
type Keys = ClusterAction;
async fn run(&self, keys: &ClusterAction) -> Result<(), String> {
let state = crate::launcher::state().map_err(|e| e.to_string())?;
let services = &state.services;
let content = &state.services.content();
let result = match keys {
ClusterAction::ToggleArtifact { cluster_id, hash } => {
// Applied to the game folder at next launch never mid-session
// Minecraft reads its mods once at startup
oneclient_core::toggle_artifact_enabled(*cluster_id, hash, content)
.await
.map(|_| ())
}
ClusterAction::RemoveArtifact { cluster_id, hash } => {
oneclient_core::remove_artifact_from_cluster(*cluster_id, hash, true, content).await
}
ClusterAction::RemoveBundlePackageFromDisk { cluster_id, hash } => {
oneclient_core::remove_artifact_from_cluster(*cluster_id, hash, false, content).await
}
ClusterAction::SetBundlePackageEnabled {
cluster_id,
bundle_name,
package_id,
enabled,
manifest_default,
} => {
oneclient_core::set_bundle_package_enabled(
*cluster_id,
bundle_name,
package_id,
*enabled,
*manifest_default,
content,
)
.await
}
ClusterAction::ImportLocalFile {
cluster_id,
content_type,
path,
} => PackageStore::import_local_file(path, *content_type, *cluster_id, content)
.await
.map(|row| {
services
.events
.notify("Imported").body(format!("Added {}", row.file_name)).send();
}),
ClusterAction::SetDedicatedDir {
cluster_id,
dedicated,
} => {
state
.clusters
.set_dedicated_dir(
*cluster_id,
*dedicated,
state.games.is_active(*cluster_id),
)
.await
.map_err(|err| oneclient_content::ContentError::InvalidData {
reason: err.to_string(),
})
}
ClusterAction::VerifyFiles { cluster_id } => {
// Reports its own outcome not the generic failure toast a
// verify that finds nothing wrong is still a useful result
match oneclient_core::verify_cluster_files(&state, *cluster_id).await {
Ok(report) => {
let notify = services.events.notify("Verification complete");
let notify = notify.body(report.summary());
if report.unrepairable.is_empty() {
notify.send();
} else {
notify.error().send();
}
Ok(())
}
Err(err) => Err(oneclient_content::ContentError::InvalidData {
reason: err.to_string(),
}),
}
}
};
result.map_err(|e| e.to_string())
}
async fn on_settled(&self, _keys: &ClusterAction, result: &Result<(), String>) {
if let Err(err) = result
&& let Ok(state) = crate::launcher::state()
{
state.services.events.notify("Action failed").body(err).error().send();
}
invalidate_cluster_queries().await;
}
}
pub fn use_cluster_mutation() -> UseMutation<ClusterMutation> {
use_mutation(Mutation::new(ClusterMutation))
}