Migrate to SQLite for Internal Launcher Data (#1300)

* initial migration

* barebones profiles

* Finish profiles

* Add back file watcher

* UI support progress

* Finish most of cache

* Fix options page

* Fix forge, finish modrinth auth

* Accounts, process cache

* Run SQLX prepare

* Finish

* Run lint + actions

* Fix version to be compat with windows

* fix lint

* actually fix lint

* actually fix lint again
This commit is contained in:
Geometrically
2024-07-24 11:03:19 -07:00
committed by GitHub
parent 90f74427d9
commit 49a20a303a
156 changed files with 9208 additions and 8547 deletions

View File

@@ -11,7 +11,6 @@ pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
auth_set_default_user,
auth_remove_user,
auth_users,
auth_get_user,
])
.build()
}
@@ -96,11 +95,3 @@ pub async fn auth_set_default_user(user: uuid::Uuid) -> Result<()> {
pub async fn auth_users() -> Result<Vec<Credentials>> {
Ok(minecraft_auth::users().await?)
}
/// Get a user from the UUID
/// Prefer to use refresh instead, as it will refresh the credentials as well
// invoke('plugin:auth|auth_users',user)
#[tauri::command]
pub async fn auth_get_user(user: uuid::Uuid) -> Result<Credentials> {
Ok(minecraft_auth::get_user(user).await?)
}

56
apps/app/src/api/cache.rs Normal file
View File

@@ -0,0 +1,56 @@
use crate::api::Result;
use theseus::prelude::*;
macro_rules! impl_cache_methods {
($(($variant:ident, $type:ty)),*) => {
$(
paste::paste! {
#[tauri::command]
pub async fn [<get_ $variant:snake>](id: &str) -> Result<Option<$type>>
{
Ok(theseus::cache::[<get_ $variant:snake>](id).await?)
}
#[tauri::command]
pub async fn [<get_ $variant:snake _many>](
ids: Vec<String>,
) -> Result<Vec<$type>>
{
let ids = ids.iter().map(|x| &**x).collect::<Vec<&str>>();
let entries =
theseus::cache::[<get_ $variant:snake _many>](&*ids).await?;
Ok(entries)
}
}
)*
}
}
impl_cache_methods!(
(Project, Project),
(Version, Version),
(User, User),
(Team, Vec<TeamMember>),
(Organization, Organization),
(SearchResults, SearchResults)
);
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("cache")
.invoke_handler(tauri::generate_handler![
get_project,
get_project_many,
get_version,
get_version_many,
get_user,
get_user_many,
get_team,
get_team_many,
get_organization,
get_organization_many,
get_search_results,
get_search_results_many,
])
.build()
}

View File

@@ -4,7 +4,6 @@ use crate::api::Result;
use theseus::pack::import::ImportLauncherType;
use theseus::pack::import;
use theseus::prelude::ProfilePathId;
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("import")
@@ -33,7 +32,7 @@ pub async fn import_get_importable_instances(
/// eg: import_instance(ImportLauncherType::MultiMC, PathBuf::from("C:/MultiMC"), "Instance 1")
#[tauri::command]
pub async fn import_import_instance(
profile_path: ProfilePathId,
profile_path: &str,
launcher_type: ImportLauncherType,
base_path: PathBuf,
instance_folder: String,

View File

@@ -1,6 +1,6 @@
use std::path::PathBuf;
use crate::api::Result;
use dashmap::DashMap;
use std::path::PathBuf;
use tauri::plugin::TauriPlugin;
use theseus::prelude::JavaVersion;
use theseus::prelude::*;
@@ -8,6 +8,8 @@ use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
tauri::plugin::Builder::new("jre")
.invoke_handler(tauri::generate_handler![
get_java_versions,
set_java_version,
jre_find_filtered_jres,
jre_get_jre,
jre_test_jre,
@@ -17,6 +19,17 @@ pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
.build()
}
#[tauri::command]
pub async fn get_java_versions() -> Result<DashMap<u32, JavaVersion>> {
Ok(jre::get_java_versions().await?)
}
#[tauri::command]
pub async fn set_java_version(java_version: JavaVersion) -> Result<()> {
jre::set_java_version(java_version).await?;
Ok(())
}
// Finds the installation of Java 8, if it exists
#[tauri::command]
pub async fn jre_find_filtered_jres(

View File

@@ -1,9 +1,6 @@
use crate::api::Result;
use theseus::logs::LogType;
use theseus::{
logs::{self, CensoredString, LatestLogCursor, Logs},
prelude::ProfilePathId,
};
use theseus::logs::{self, CensoredString, LatestLogCursor, Logs};
/*
A log is a struct containing the filename string, stdout, and stderr, as follows:
@@ -31,7 +28,7 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
/// Get all Logs for a profile, sorted by filename
#[tauri::command]
pub async fn logs_get_logs(
profile_path: ProfilePathId,
profile_path: &str,
clear_contents: Option<bool>,
) -> Result<Vec<Logs>> {
let val = logs::get_logs(profile_path, clear_contents).await?;
@@ -42,7 +39,7 @@ pub async fn logs_get_logs(
/// Get a Log struct for a profile by profile id and filename string
#[tauri::command]
pub async fn logs_get_logs_by_filename(
profile_path: ProfilePathId,
profile_path: &str,
log_type: LogType,
filename: String,
) -> Result<Logs> {
@@ -52,37 +49,23 @@ pub async fn logs_get_logs_by_filename(
/// Get the stdout for a profile by profile id and filename string
#[tauri::command]
pub async fn logs_get_output_by_filename(
profile_path: ProfilePathId,
profile_path: &str,
log_type: LogType,
filename: String,
) -> Result<CensoredString> {
let profile_path = if let Some(p) =
crate::profile::get(&profile_path, None).await?
{
p.profile_id()
} else {
return Err(theseus::Error::from(
theseus::ErrorKind::UnmanagedProfileError(profile_path.to_string()),
)
.into());
};
Ok(
logs::get_output_by_filename(&profile_path, log_type, &filename)
.await?,
)
Ok(logs::get_output_by_filename(profile_path, log_type, &filename).await?)
}
/// Delete all logs for a profile by profile id
#[tauri::command]
pub async fn logs_delete_logs(profile_path: ProfilePathId) -> Result<()> {
pub async fn logs_delete_logs(profile_path: &str) -> Result<()> {
Ok(logs::delete_logs(profile_path).await?)
}
/// Delete a log for a profile by profile id and filename string
#[tauri::command]
pub async fn logs_delete_logs_by_filename(
profile_path: ProfilePathId,
profile_path: &str,
log_type: LogType,
filename: String,
) -> Result<()> {
@@ -95,7 +78,7 @@ pub async fn logs_delete_logs_by_filename(
/// Get live log from a cursor
#[tauri::command]
pub async fn logs_get_latest_log_cursor(
profile_path: ProfilePathId,
profile_path: &str,
cursor: u64, // 0 to start at beginning of file
) -> Result<LatestLogCursor> {
Ok(logs::get_latest_log_cursor(profile_path, cursor).await?)

View File

@@ -6,10 +6,7 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("metadata")
.invoke_handler(tauri::generate_handler![
metadata_get_game_versions,
metadata_get_fabric_versions,
metadata_get_forge_versions,
metadata_get_quilt_versions,
metadata_get_neoforge_versions,
metadata_get_loader_versions,
])
.build()
}
@@ -22,24 +19,6 @@ pub async fn metadata_get_game_versions() -> Result<VersionManifest> {
/// Gets the fabric versions from daedalus
#[tauri::command]
pub async fn metadata_get_fabric_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_fabric_versions().await?)
}
/// Gets the forge versions from daedalus
#[tauri::command]
pub async fn metadata_get_forge_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_forge_versions().await?)
}
/// Gets the quilt versions from daedalus
#[tauri::command]
pub async fn metadata_get_quilt_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_quilt_versions().await?)
}
/// Gets the quilt versions from daedalus
#[tauri::command]
pub async fn metadata_get_neoforge_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_neoforge_versions().await?)
pub async fn metadata_get_loader_versions(loader: &str) -> Result<Manifest> {
Ok(theseus::metadata::get_loader_versions(loader).await?)
}

View File

@@ -16,6 +16,8 @@ pub mod settings;
pub mod tags;
pub mod utils;
pub mod cache;
pub type Result<T> = std::result::Result<T, TheseusSerializableError>;
// // Main returnable Theseus GUI error

View File

@@ -1,17 +1,15 @@
use crate::api::Result;
use chrono::{Duration, Utc};
use tauri::plugin::TauriPlugin;
use tauri::{Manager, UserAttentionType};
use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
tauri::plugin::Builder::new("mr_auth")
.invoke_handler(tauri::generate_handler![
authenticate_begin_flow,
authenticate_await_completion,
cancel_flow,
login_pass,
login_2fa,
create_account,
refresh,
logout,
get,
])
@@ -19,19 +17,68 @@ pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
}
#[tauri::command]
pub async fn authenticate_begin_flow(provider: &str) -> Result<String> {
Ok(theseus::mr_auth::authenticate_begin_flow(provider).await?)
}
pub async fn modrinth_auth_login(
app: tauri::AppHandle,
provider: &str,
) -> Result<Option<ModrinthCredentialsResult>> {
let redirect_uri = mr_auth::authenticate_begin_flow(provider);
#[tauri::command]
pub async fn authenticate_await_completion() -> Result<ModrinthCredentialsResult>
{
Ok(theseus::mr_auth::authenticate_await_complete_flow().await?)
}
let start = Utc::now();
#[tauri::command]
pub async fn cancel_flow() -> Result<()> {
Ok(theseus::mr_auth::cancel_flow().await?)
if let Some(window) = app.get_window("modrinth-signin") {
window.close()?;
}
let window = tauri::WindowBuilder::new(
&app,
"modrinth-signin",
tauri::WindowUrl::External(redirect_uri.parse().map_err(|_| {
theseus::ErrorKind::OtherError(
"Error parsing auth redirect URL".to_string(),
)
.as_error()
})?),
)
.title("Sign into Modrinth")
.always_on_top(true)
.center()
.build()?;
window.request_user_attention(Some(UserAttentionType::Critical))?;
while (Utc::now() - start) < Duration::minutes(10) {
if window.title().is_err() {
// user closed window, cancelling flow
return Ok(None);
}
if window
.url()
.as_str()
.starts_with("https://launcher-files.modrinth.com/detect.txt")
{
let query = window
.url()
.query_pairs()
.map(|(key, val)| {
(
key.to_string(),
serde_json::Value::String(val.to_string()),
)
})
.collect();
window.close()?;
let val = mr_auth::authenticate_finish_flow(query).await?;
return Ok(Some(val));
}
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
}
window.close()?;
Ok(None)
}
#[tauri::command]
@@ -66,11 +113,6 @@ pub async fn create_account(
.await?)
}
#[tauri::command]
pub async fn refresh() -> Result<()> {
Ok(theseus::mr_auth::refresh().await?)
}
#[tauri::command]
pub async fn logout() -> Result<()> {
Ok(theseus::mr_auth::logout().await?)

View File

@@ -20,8 +20,8 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
#[tauri::command]
pub async fn pack_install(
location: CreatePackLocation,
profile: ProfilePathId,
) -> Result<ProfilePathId> {
profile: String,
) -> Result<String> {
Ok(install_zipped_mrpack(location, profile).await?)
}

View File

@@ -1,78 +1,33 @@
use crate::api::Result;
use theseus::prelude::*;
use uuid::Uuid;
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("process")
.invoke_handler(tauri::generate_handler![
process_has_finished_by_uuid,
process_get_exit_status_by_uuid,
process_get_all_uuids,
process_get_all_running_uuids,
process_get_uuids_by_profile_path,
process_get_all_running_profile_paths,
process_get_all_running_profiles,
process_kill_by_uuid,
process_wait_for_by_uuid,
process_get_all,
process_get_by_profile_path,
process_kill,
process_wait_for,
])
.build()
}
// Checks if a process has finished by process UUID
#[tauri::command]
pub async fn process_has_finished_by_uuid(uuid: Uuid) -> Result<bool> {
Ok(process::has_finished_by_uuid(uuid).await?)
pub async fn process_get_all() -> Result<Vec<Process>> {
Ok(process::get_all().await?)
}
// Gets process exit status by process UUID
#[tauri::command]
pub async fn process_get_exit_status_by_uuid(
uuid: Uuid,
) -> Result<Option<i32>> {
Ok(process::get_exit_status_by_uuid(uuid).await?)
pub async fn process_get_by_profile_path(path: &str) -> Result<Vec<Process>> {
Ok(process::get_by_profile_path(path).await?)
}
// Gets all process UUIDs
#[tauri::command]
pub async fn process_get_all_uuids() -> Result<Vec<Uuid>> {
Ok(process::get_all_uuids().await?)
pub async fn process_kill(pid: i32) -> Result<()> {
Ok(process::kill(pid).await?)
}
// Gets all running process UUIDs
#[tauri::command]
pub async fn process_get_all_running_uuids() -> Result<Vec<Uuid>> {
Ok(process::get_all_running_uuids().await?)
}
// Gets all process UUIDs by profile path
#[tauri::command]
pub async fn process_get_uuids_by_profile_path(
profile_path: ProfilePathId,
) -> Result<Vec<Uuid>> {
Ok(process::get_uuids_by_profile_path(profile_path).await?)
}
// Gets the Profile paths of each *running* stored process in the state
#[tauri::command]
pub async fn process_get_all_running_profile_paths(
) -> Result<Vec<ProfilePathId>> {
Ok(process::get_all_running_profile_paths().await?)
}
// Gets the Profiles (cloned) of each *running* stored process in the state
#[tauri::command]
pub async fn process_get_all_running_profiles() -> Result<Vec<Profile>> {
Ok(process::get_all_running_profiles().await?)
}
// Kill a process by process UUID
#[tauri::command]
pub async fn process_kill_by_uuid(uuid: Uuid) -> Result<()> {
Ok(process::kill_by_uuid(uuid).await?)
}
// Wait for a process to finish by process UUID
#[tauri::command]
pub async fn process_wait_for_by_uuid(uuid: Uuid) -> Result<()> {
Ok(process::wait_for_by_uuid(uuid).await?)
pub async fn process_wait_for(pid: i32) -> Result<()> {
Ok(process::wait_for(pid).await?)
}

View File

@@ -1,16 +1,17 @@
use crate::api::Result;
use daedalus::modded::LoaderVersion;
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use theseus::{prelude::*, InnerProjectPathUnix};
use uuid::Uuid;
use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("profile")
.invoke_handler(tauri::generate_handler![
profile_remove,
profile_get,
profile_get_many,
profile_get_projects,
profile_get_optimal_jre_key,
profile_get_full_path,
profile_get_mod_full_path,
@@ -26,9 +27,8 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
profile_update_managed_modrinth_version,
profile_repair_managed_modrinth,
profile_run,
profile_run_wait,
profile_run_credentials,
profile_run_wait_credentials,
profile_kill,
profile_edit,
profile_edit_icon,
profile_export_mrpack,
@@ -40,27 +40,39 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
// Remove a profile
// invoke('plugin:profile|profile_add_path',path)
#[tauri::command]
pub async fn profile_remove(path: ProfilePathId) -> Result<()> {
profile::remove(&path).await?;
pub async fn profile_remove(path: &str) -> Result<()> {
profile::remove(path).await?;
Ok(())
}
// Get a profile by path
// invoke('plugin:profile|profile_add_path',path)
#[tauri::command]
pub async fn profile_get(
path: ProfilePathId,
clear_projects: Option<bool>,
) -> Result<Option<Profile>> {
let res = profile::get(&path, clear_projects).await?;
pub async fn profile_get(path: &str) -> Result<Option<Profile>> {
let res = profile::get(path).await?;
Ok(res)
}
#[tauri::command]
pub async fn profile_get_many(paths: Vec<String>) -> Result<Vec<Profile>> {
let ids = paths.iter().map(|x| &**x).collect::<Vec<&str>>();
let entries = profile::get_many(&ids).await?;
Ok(entries)
}
#[tauri::command]
pub async fn profile_get_projects(
path: &str,
) -> Result<DashMap<String, ProfileFile>> {
let res = profile::get_projects(path).await?;
Ok(res)
}
// Get a profile's full path
// invoke('plugin:profile|profile_get_full_path',path)
#[tauri::command]
pub async fn profile_get_full_path(path: ProfilePathId) -> Result<PathBuf> {
let res = profile::get_full_path(&path).await?;
pub async fn profile_get_full_path(path: &str) -> Result<PathBuf> {
let res = profile::get_full_path(path).await?;
Ok(res)
}
@@ -68,43 +80,41 @@ pub async fn profile_get_full_path(path: ProfilePathId) -> Result<PathBuf> {
// invoke('plugin:profile|profile_get_mod_full_path',path)
#[tauri::command]
pub async fn profile_get_mod_full_path(
path: ProfilePathId,
project_path: ProjectPathId,
path: &str,
project_path: &str,
) -> Result<PathBuf> {
let res = profile::get_mod_full_path(&path, &project_path).await?;
let res = profile::get_mod_full_path(path, project_path).await?;
Ok(res)
}
// Get optimal java version from profile
#[tauri::command]
pub async fn profile_get_optimal_jre_key(
path: ProfilePathId,
path: &str,
) -> Result<Option<JavaVersion>> {
let res = profile::get_optimal_jre_key(&path).await?;
let res = profile::get_optimal_jre_key(path).await?;
Ok(res)
}
// Get a copy of the profile set
// invoke('plugin:profile|profile_list')
#[tauri::command]
pub async fn profile_list(
clear_projects: Option<bool>,
) -> Result<HashMap<ProfilePathId, Profile>> {
let res = profile::list(clear_projects).await?;
pub async fn profile_list() -> Result<Vec<Profile>> {
let res = profile::list().await?;
Ok(res)
}
#[tauri::command]
pub async fn profile_check_installed(
path: ProfilePathId,
project_id: String,
path: &str,
project_id: &str,
) -> Result<bool> {
let profile = profile_get(path, None).await?;
if let Some(profile) = profile {
Ok(profile.projects.into_iter().any(|(_, project)| {
if let ProjectMetadata::Modrinth { project, .. } = &project.metadata
{
project.id == project_id
let check_project_id = project_id;
if let Ok(projects) = profile::get_projects(path).await {
Ok(projects.into_iter().any(|(_, project)| {
if let Some(metadata) = &project.metadata {
check_project_id == metadata.project_id
} else {
false
}
@@ -117,49 +127,47 @@ pub async fn profile_check_installed(
/// Installs/Repairs a profile
/// invoke('plugin:profile|profile_install')
#[tauri::command]
pub async fn profile_install(path: ProfilePathId, force: bool) -> Result<()> {
profile::install(&path, force).await?;
pub async fn profile_install(path: &str, force: bool) -> Result<()> {
profile::install(path, force).await?;
Ok(())
}
/// Updates all of the profile's projects
/// invoke('plugin:profile|profile_update_all')
#[tauri::command]
pub async fn profile_update_all(
path: ProfilePathId,
) -> Result<HashMap<ProjectPathId, ProjectPathId>> {
Ok(profile::update_all_projects(&path).await?)
pub async fn profile_update_all(path: &str) -> Result<HashMap<String, String>> {
Ok(profile::update_all_projects(path).await?)
}
/// Updates a specified project
/// invoke('plugin:profile|profile_update_project')
#[tauri::command]
pub async fn profile_update_project(
path: ProfilePathId,
project_path: ProjectPathId,
) -> Result<ProjectPathId> {
Ok(profile::update_project(&path, &project_path, None).await?)
path: &str,
project_path: &str,
) -> Result<String> {
Ok(profile::update_project(path, project_path, None).await?)
}
// Adds a project to a profile from a version ID
// invoke('plugin:profile|profile_add_project_from_version')
#[tauri::command]
pub async fn profile_add_project_from_version(
path: ProfilePathId,
version_id: String,
) -> Result<ProjectPathId> {
Ok(profile::add_project_from_version(&path, version_id).await?)
path: &str,
version_id: &str,
) -> Result<String> {
Ok(profile::add_project_from_version(path, version_id).await?)
}
// Adds a project to a profile from a path
// invoke('plugin:profile|profile_add_project_from_path')
#[tauri::command]
pub async fn profile_add_project_from_path(
path: ProfilePathId,
path: &str,
project_path: &Path,
project_type: Option<String>,
) -> Result<ProjectPathId> {
let res = profile::add_project_from_path(&path, project_path, project_type)
project_type: Option<ProjectType>,
) -> Result<String> {
let res = profile::add_project_from_path(path, project_path, project_type)
.await?;
Ok(res)
}
@@ -168,27 +176,27 @@ pub async fn profile_add_project_from_path(
// invoke('plugin:profile|profile_toggle_disable_project')
#[tauri::command]
pub async fn profile_toggle_disable_project(
path: ProfilePathId,
project_path: ProjectPathId,
) -> Result<ProjectPathId> {
Ok(profile::toggle_disable_project(&path, &project_path).await?)
path: &str,
project_path: &str,
) -> Result<String> {
Ok(profile::toggle_disable_project(path, project_path).await?)
}
// Removes a project from a profile
// invoke('plugin:profile|profile_remove_project')
#[tauri::command]
pub async fn profile_remove_project(
path: ProfilePathId,
project_path: ProjectPathId,
path: &str,
project_path: &str,
) -> Result<()> {
profile::remove_project(&path, &project_path).await?;
profile::remove_project(path, project_path).await?;
Ok(())
}
// Updates a managed Modrinth profile to a version of version_id
#[tauri::command]
pub async fn profile_update_managed_modrinth_version(
path: ProfilePathId,
path: String,
version_id: String,
) -> Result<()> {
Ok(
@@ -199,17 +207,15 @@ pub async fn profile_update_managed_modrinth_version(
// Repairs a managed Modrinth profile by updating it to the current version
#[tauri::command]
pub async fn profile_repair_managed_modrinth(
path: ProfilePathId,
) -> Result<()> {
Ok(profile::update::repair_managed_modrinth(&path).await?)
pub async fn profile_repair_managed_modrinth(path: &str) -> Result<()> {
Ok(profile::update::repair_managed_modrinth(path).await?)
}
// Exports a profile to a .mrpack file (export_location should end in .mrpack)
// invoke('profile_export_mrpack')
#[tauri::command]
pub async fn profile_export_mrpack(
path: ProfilePathId,
path: &str,
export_location: PathBuf,
included_overrides: Vec<String>,
version_id: Option<String>,
@@ -217,7 +223,7 @@ pub async fn profile_export_mrpack(
name: Option<String>, // only used to cache
) -> Result<()> {
profile::export_mrpack(
&path,
path,
export_location,
included_overrides,
version_id,
@@ -231,9 +237,9 @@ pub async fn profile_export_mrpack(
/// See [`profile::get_pack_export_candidates`]
#[tauri::command]
pub async fn profile_get_pack_export_candidates(
profile_path: ProfilePathId,
) -> Result<Vec<InnerProjectPathUnix>> {
let candidates = profile::get_pack_export_candidates(&profile_path).await?;
profile_path: &str,
) -> Result<Vec<String>> {
let candidates = profile::get_pack_export_candidates(profile_path).await?;
Ok(candidates)
}
@@ -242,19 +248,10 @@ pub async fn profile_get_pack_export_candidates(
// for the actual Child in the state.
// invoke('plugin:profile|profile_run', path)
#[tauri::command]
pub async fn profile_run(path: ProfilePathId) -> Result<Uuid> {
let minecraft_child = profile::run(&path).await?;
let uuid = minecraft_child.read().await.uuid;
Ok(uuid)
}
pub async fn profile_run(path: &str) -> Result<Process> {
let process = profile::run(path).await?;
// Run Minecraft using a profile using the default credentials, and wait for the result
// invoke('plugin:profile|profile_run_wait', path)
#[tauri::command]
pub async fn profile_run_wait(path: ProfilePathId) -> Result<()> {
let proc_lock = profile::run(&path).await?;
let mut proc = proc_lock.write().await;
Ok(process::wait_for(&mut proc).await?)
Ok(process)
}
// Run Minecraft using a profile using chosen credentials
@@ -263,85 +260,83 @@ pub async fn profile_run_wait(path: ProfilePathId) -> Result<()> {
// invoke('plugin:profile|profile_run_credentials', {path, credentials})')
#[tauri::command]
pub async fn profile_run_credentials(
path: ProfilePathId,
path: &str,
credentials: Credentials,
) -> Result<Uuid> {
let minecraft_child = profile::run_credentials(&path, &credentials).await?;
let uuid = minecraft_child.read().await.uuid;
) -> Result<Process> {
let process = profile::run_credentials(path, &credentials).await?;
Ok(uuid)
Ok(process)
}
// Run Minecraft using a profile using the chosen credentials, and wait for the result
// invoke('plugin:profile|profile_run_wait', {path, credentials)
#[tauri::command]
pub async fn profile_run_wait_credentials(
path: ProfilePathId,
credentials: Credentials,
) -> Result<()> {
let proc_lock = profile::run_credentials(&path, &credentials).await?;
let mut proc = proc_lock.write().await;
Ok(process::wait_for(&mut proc).await?)
pub async fn profile_kill(path: &str) -> Result<()> {
profile::kill(path).await?;
Ok(())
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EditProfile {
pub metadata: Option<EditProfileMetadata>,
pub java: Option<JavaSettings>,
pub memory: Option<MemorySettings>,
pub resolution: Option<WindowSize>,
pub hooks: Option<Hooks>,
pub fullscreen: Option<bool>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct EditProfileMetadata {
pub name: Option<String>,
pub game_version: Option<String>,
pub loader: Option<ModLoader>,
pub loader_version: Option<LoaderVersion>,
pub linked_data: Option<LinkedData>,
pub loader_version: Option<String>,
pub groups: Option<Vec<String>>,
pub linked_data: Option<LinkedData>,
pub java_path: Option<String>,
pub extra_launch_args: Option<Vec<String>>,
pub custom_env_vars: Option<Vec<(String, String)>>,
pub memory: Option<MemorySettings>,
pub force_fullscreen: Option<bool>,
pub game_resolution: Option<WindowSize>,
pub hooks: Option<Hooks>,
}
// Edits a profile
// invoke('plugin:profile|profile_edit', {path, editProfile})
#[tauri::command]
pub async fn profile_edit(
path: ProfilePathId,
edit_profile: EditProfile,
) -> Result<()> {
profile::edit(&path, |prof| {
if let Some(metadata) = edit_profile.metadata.clone() {
if let Some(name) = metadata.name {
prof.metadata.name = name;
}
if let Some(game_version) = metadata.game_version {
prof.metadata.game_version = game_version;
}
if let Some(loader) = metadata.loader {
prof.metadata.loader = loader;
}
prof.metadata.loader_version = metadata.loader_version;
prof.metadata.linked_data = metadata.linked_data;
pub async fn profile_edit(path: &str, edit_profile: EditProfile) -> Result<()> {
profile::edit(path, |prof| {
if let Some(name) = edit_profile.name.clone() {
prof.name = name;
}
if let Some(game_version) = edit_profile.game_version.clone() {
prof.game_version = game_version;
}
if let Some(loader) = edit_profile.loader {
prof.loader = loader;
}
prof.loader_version.clone_from(&edit_profile.loader_version);
prof.linked_data.clone_from(&edit_profile.linked_data);
if let Some(groups) = metadata.groups {
prof.metadata.groups = groups;
}
if let Some(groups) = edit_profile.groups.clone() {
prof.groups = groups;
}
prof.java.clone_from(&edit_profile.java);
prof.java_path.clone_from(&edit_profile.java_path);
prof.memory = edit_profile.memory;
prof.resolution = edit_profile.resolution;
prof.fullscreen = edit_profile.fullscreen;
prof.hooks.clone_from(&edit_profile.hooks);
prof.game_resolution = edit_profile.game_resolution;
prof.force_fullscreen = edit_profile.force_fullscreen;
prof.metadata.date_modified = chrono::Utc::now();
if let Some(hooks) = edit_profile.hooks.clone() {
prof.hooks = hooks;
}
prof.modified = chrono::Utc::now();
prof.custom_env_vars
.clone_from(&edit_profile.custom_env_vars);
prof.extra_launch_args
.clone_from(&edit_profile.extra_launch_args);
async { Ok(()) }
})
.await?;
State::sync().await?;
Ok(())
}
@@ -350,9 +345,9 @@ pub async fn profile_edit(
// invoke('plugin:profile|profile_edit_icon')
#[tauri::command]
pub async fn profile_edit_icon(
path: ProfilePathId,
path: &str,
icon_path: Option<&Path>,
) -> Result<()> {
profile::edit_icon(&path, icon_path).await?;
profile::edit_icon(path, icon_path).await?;
Ok(())
}

View File

@@ -1,5 +1,4 @@
use crate::api::Result;
use std::path::PathBuf;
use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
@@ -19,9 +18,9 @@ pub async fn profile_create(
game_version: String, // the game version of the profile
modloader: ModLoader, // the modloader to use
loader_version: Option<String>, // the modloader version to use, set to "latest", "stable", or the ID of your chosen loader
icon: Option<PathBuf>, // the icon for the profile
no_watch: Option<bool>,
) -> Result<ProfilePathId> {
icon: Option<String>, // the icon for the profile
skip_install: Option<bool>,
) -> Result<String> {
let res = profile::create::profile_create(
name,
game_version,
@@ -29,9 +28,7 @@ pub async fn profile_create(
loader_version,
icon,
None,
None,
None,
no_watch,
skip_install,
)
.await?;
Ok(res)
@@ -40,7 +37,7 @@ pub async fn profile_create(
// Creates a profile from a duplicate
// invoke('plugin:profile_create|profile_duplicate',profile)
#[tauri::command]
pub async fn profile_duplicate(path: ProfilePathId) -> Result<ProfilePathId> {
pub async fn profile_duplicate(path: &str) -> Result<String> {
let res = profile::create::profile_create_from_duplicate(path).await?;
Ok(res)
}

View File

@@ -1,16 +1,9 @@
use std::path::PathBuf;
use crate::api::Result;
use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("settings")
.invoke_handler(tauri::generate_handler![
settings_get,
settings_set,
settings_change_config_dir,
settings_is_dir_writeable
])
.invoke_handler(tauri::generate_handler![settings_get, settings_set])
.build()
}
@@ -29,20 +22,3 @@ pub async fn settings_set(settings: Settings) -> Result<()> {
settings::set(settings).await?;
Ok(())
}
// Change config directory
// Seizes the entire State to do it
// invoke('plugin:settings|settings_change_config_dir', new_dir)
#[tauri::command]
pub async fn settings_change_config_dir(new_config_dir: PathBuf) -> Result<()> {
settings::set_config_dir(new_config_dir).await?;
Ok(())
}
#[tauri::command]
pub async fn settings_is_dir_writeable(
new_config_dir: PathBuf,
) -> Result<bool> {
let res = settings::is_dir_writeable(new_config_dir).await?;
Ok(res)
}

View File

@@ -1,5 +1,5 @@
use crate::api::Result;
use theseus::tags::{Category, DonationPlatform, GameVersion, Loader, Tags};
use theseus::tags::{Category, DonationPlatform, GameVersion, Loader};
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("tags")
@@ -9,7 +9,6 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tags_get_loaders,
tags_get_game_versions,
tags_get_donation_platforms,
tags_get_tag_bundle,
])
.build()
}
@@ -43,9 +42,3 @@ pub async fn tags_get_game_versions() -> Result<Vec<GameVersion>> {
pub async fn tags_get_donation_platforms() -> Result<Vec<DonationPlatform>> {
Ok(theseus::tags::get_donation_platform_tags().await?)
}
/// Gets cached tag bundle from the database
#[tauri::command]
pub async fn tags_get_tag_bundle() -> Result<Tags> {
Ok(theseus::tags::get_tag_bundle().await?)
}

View File

@@ -2,7 +2,6 @@ use serde::{Deserialize, Serialize};
use theseus::{
handler,
prelude::{CommandPayload, DirectoryInfo},
State,
};
use crate::api::Result;
@@ -16,11 +15,7 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
show_in_folder,
show_launcher_logs_folder,
progress_bars_list,
safety_check_safe_loading_bars,
get_opening_command,
await_sync,
is_offline,
refresh_offline
get_opening_command
])
.build()
}
@@ -54,12 +49,6 @@ pub async fn progress_bars_list(
Ok(res)
}
// Check if there are any safe loading bars running
#[tauri::command]
pub async fn safety_check_safe_loading_bars() -> Result<bool> {
Ok(theseus::safety::check_safe_loading_bars().await?)
}
// cfg only on mac os
// disables mouseover and fixes a random crash error only fixed by recent versions of macos
#[cfg(target_os = "macos")]
@@ -82,7 +71,7 @@ pub async fn should_disable_mouseover() -> bool {
}
#[tauri::command]
pub fn show_in_folder(mut path: PathBuf) -> Result<()> {
pub fn show_in_folder(path: PathBuf) -> Result<()> {
{
#[cfg(target_os = "windows")]
{
@@ -101,6 +90,7 @@ pub fn show_in_folder(mut path: PathBuf) -> Result<()> {
{
use std::fs::metadata;
let mut path = path;
let path_string = path.to_string_lossy().to_string();
if metadata(&path)?.is_dir() {
@@ -171,28 +161,3 @@ pub async fn get_opening_command() -> Result<Option<CommandPayload>> {
pub async fn handle_command(command: String) -> Result<()> {
Ok(theseus::handler::parse_and_emit_command(&command).await?)
}
// Waits for state to be synced
#[tauri::command]
pub async fn await_sync() -> Result<()> {
State::sync().await?;
tracing::debug!("State synced");
Ok(())
}
/// Check if theseus is currently in offline mode, without a refresh attempt
#[tauri::command]
pub async fn is_offline() -> Result<bool> {
let state = State::get().await?;
let offline = *state.offline.read().await;
Ok(offline)
}
/// Refreshes whether or not theseus is in offline mode, and returns the new value
#[tauri::command]
pub async fn refresh_offline() -> Result<bool> {
let state = State::get().await?;
state.refresh_offline().await?;
let offline = *state.offline.read().await;
Ok(offline)
}