You've already forked AstralRinth
forked from didirus/AstralRinth
Bugs again (#703)
* initial * more fixes * logs * more fixes * working rescuer * minor log display fix * mac fixes * minor fix * libsselinux1 * linux error * actions test * more bugs. Modpack page! BIG changes * changed minimum 64 -> 8 * removed modpack page moved to modal * removed unnecessary css * mac compile * many revs * Merge colorful logs (#725) * make implementation not dumb * run prettier * null -> true * Add line numbers & make errors more robust. * improvments * changes; virtual scroll --------- Co-authored-by: qtchaos <72168435+qtchaos@users.noreply.github.com> * omorphia colors, comments fix * fixes; _JAVA_OPTIONS * revs * mac specific * more mac * some fixes * quick fix * add java reinstall option --------- Co-authored-by: qtchaos <72168435+qtchaos@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me>
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
//! Theseus profile management interface
|
||||
use crate::pack::install_from::CreatePackProfile;
|
||||
use crate::prelude::ProfilePathId;
|
||||
use crate::profile;
|
||||
use crate::state::LinkedData;
|
||||
use crate::util::io::{self, canonicalize};
|
||||
use crate::{
|
||||
event::{emit::emit_profile, ProfilePayloadType},
|
||||
prelude::ModLoader,
|
||||
};
|
||||
use crate::{pack, profile, ErrorKind};
|
||||
pub use crate::{
|
||||
state::{JavaSettings, Profile},
|
||||
State,
|
||||
@@ -102,6 +102,12 @@ pub async fn profile_create(
|
||||
}
|
||||
|
||||
profile.metadata.linked_data = linked_data;
|
||||
if let Some(linked_data) = &mut profile.metadata.linked_data {
|
||||
linked_data.locked = Some(
|
||||
linked_data.project_id.is_some()
|
||||
&& linked_data.version_id.is_some(),
|
||||
);
|
||||
}
|
||||
|
||||
emit_profile(
|
||||
uuid,
|
||||
@@ -154,6 +160,59 @@ pub async fn profile_create_from_creator(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn profile_create_from_duplicate(
|
||||
copy_from: ProfilePathId,
|
||||
) -> crate::Result<ProfilePathId> {
|
||||
let profile = profile::get(©_from, None).await?.ok_or_else(|| {
|
||||
ErrorKind::UnmanagedProfileError(copy_from.to_string())
|
||||
})?;
|
||||
|
||||
let profile_path_id = profile_create(
|
||||
profile.metadata.name.clone(),
|
||||
profile.metadata.game_version.clone(),
|
||||
profile.metadata.loader,
|
||||
profile.metadata.loader_version.clone().map(|it| it.id),
|
||||
profile.metadata.icon.clone(),
|
||||
profile.metadata.icon_url.clone(),
|
||||
profile.metadata.linked_data.clone(),
|
||||
Some(true),
|
||||
Some(true),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Copy it over using the import system (essentially importing from the same profile)
|
||||
let state = State::get().await?;
|
||||
let bar = pack::import::copy_dotminecraft(
|
||||
profile_path_id.clone(),
|
||||
copy_from.get_full_path().await?,
|
||||
&state.io_semaphore,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
crate::launcher::install_minecraft(&profile, Some(bar)).await?;
|
||||
{
|
||||
let state = State::get().await?;
|
||||
let mut file_watcher = state.file_watcher.write().await;
|
||||
Profile::watch_fs(
|
||||
&profile.get_profile_full_path().await?,
|
||||
&mut file_watcher,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// emit profile edited
|
||||
emit_profile(
|
||||
profile.uuid,
|
||||
&profile.profile_id(),
|
||||
&profile.metadata.name,
|
||||
ProfilePayloadType::Edited,
|
||||
)
|
||||
.await?;
|
||||
State::sync().await?;
|
||||
Ok(profile_path_id)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
#[theseus_macros::debug_pin]
|
||||
pub(crate) async fn get_loader_version_from_loader(
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::pack::install_from::{
|
||||
EnvType, PackDependency, PackFile, PackFileHash, PackFormat,
|
||||
};
|
||||
use crate::prelude::{JavaVersion, ProfilePathId, ProjectPathId};
|
||||
use crate::state::ProjectMetadata;
|
||||
use crate::state::{ProjectMetadata, SideType};
|
||||
|
||||
use crate::util::fetch;
|
||||
use crate::util::io::{self, IOError};
|
||||
@@ -109,6 +109,26 @@ pub async fn get_full_path(path: &ProfilePathId) -> crate::Result<PathBuf> {
|
||||
Ok(full_path)
|
||||
}
|
||||
|
||||
/// Get mod's full path in the filesystem
|
||||
#[tracing::instrument]
|
||||
pub async fn get_mod_full_path(
|
||||
profile_path: &ProfilePathId,
|
||||
project_path: &ProjectPathId,
|
||||
) -> crate::Result<PathBuf> {
|
||||
if get(profile_path, Some(true)).await?.is_some() {
|
||||
let full_path = io::canonicalize(
|
||||
project_path.get_full_path(profile_path.clone()).await?,
|
||||
)?;
|
||||
return Ok(full_path);
|
||||
}
|
||||
|
||||
Err(crate::ErrorKind::OtherError(format!(
|
||||
"Tried to get the full path of a nonexistent or unloaded project at path {}!",
|
||||
project_path.get_full_path(profile_path.clone()).await?.display()
|
||||
))
|
||||
.into())
|
||||
}
|
||||
|
||||
/// Edit a profile using a given asynchronous closure
|
||||
pub async fn edit<Fut>(
|
||||
path: &ProfilePathId,
|
||||
@@ -552,6 +572,8 @@ pub async fn export_mrpack(
|
||||
export_path: PathBuf,
|
||||
included_overrides: Vec<String>, // which folders to include in the overrides
|
||||
version_id: Option<String>,
|
||||
description: Option<String>,
|
||||
_name: Option<String>,
|
||||
) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
let io_semaphore = state.io_semaphore.0.read().await;
|
||||
@@ -585,7 +607,8 @@ pub async fn export_mrpack(
|
||||
|
||||
// Create mrpack json configuration file
|
||||
let version_id = version_id.unwrap_or("1.0.0".to_string());
|
||||
let packfile = create_mrpack_json(&profile, version_id).await?;
|
||||
let packfile =
|
||||
create_mrpack_json(&profile, version_id, description).await?;
|
||||
let modrinth_path_list = get_modrinth_pack_list(&packfile);
|
||||
|
||||
// Build vec of all files in the folder
|
||||
@@ -693,7 +716,7 @@ pub async fn get_potential_override_folders(
|
||||
))
|
||||
})?;
|
||||
// dummy mrpack to get pack list
|
||||
let mrpack = create_mrpack_json(&profile, "0".to_string()).await?;
|
||||
let mrpack = create_mrpack_json(&profile, "0".to_string(), None).await?;
|
||||
let mrpack_files = get_modrinth_pack_list(&mrpack);
|
||||
|
||||
let mut path_list: Vec<PathBuf> = Vec::new();
|
||||
@@ -820,23 +843,12 @@ pub async fn run_credentials(
|
||||
.unwrap_or(&settings.custom_env_args);
|
||||
|
||||
// Post post exit hooks
|
||||
let post_exit_hook =
|
||||
&profile.hooks.as_ref().unwrap_or(&settings.hooks).post_exit;
|
||||
|
||||
let post_exit_hook = if let Some(hook) = post_exit_hook {
|
||||
let mut cmd = hook.split(' ');
|
||||
if let Some(command) = cmd.next() {
|
||||
let mut command = Command::new(command);
|
||||
command
|
||||
.args(&cmd.collect::<Vec<&str>>())
|
||||
.current_dir(path.get_full_path().await?);
|
||||
Some(command)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let post_exit_hook = profile
|
||||
.hooks
|
||||
.as_ref()
|
||||
.unwrap_or(&settings.hooks)
|
||||
.post_exit
|
||||
.clone();
|
||||
|
||||
// Any options.txt settings that we want set, add here
|
||||
let mut mc_set_options: Vec<(String, String)> = vec![];
|
||||
@@ -941,6 +953,7 @@ fn get_modrinth_pack_list(packfile: &PackFormat) -> Vec<String> {
|
||||
pub async fn create_mrpack_json(
|
||||
profile: &Profile,
|
||||
version_id: String,
|
||||
description: Option<String>,
|
||||
) -> crate::Result<PackFormat> {
|
||||
// Add loader version to dependencies
|
||||
let mut dependencies = HashMap::new();
|
||||
@@ -951,6 +964,9 @@ pub async fn create_mrpack_json(
|
||||
(crate::prelude::ModLoader::Forge, Some(v)) => {
|
||||
dependencies.insert(PackDependency::Forge, v.id)
|
||||
}
|
||||
(crate::prelude::ModLoader::NeoForge, Some(v)) => {
|
||||
dependencies.insert(PackDependency::NeoForge, v.id)
|
||||
}
|
||||
(crate::prelude::ModLoader::Fabric, Some(v)) => {
|
||||
dependencies.insert(PackDependency::FabricLoader, v.id)
|
||||
}
|
||||
@@ -981,18 +997,21 @@ pub async fn create_mrpack_json(
|
||||
.projects
|
||||
.iter()
|
||||
.filter_map(|(mod_path, project)| {
|
||||
let path: String = mod_path.0.clone().to_string_lossy().to_string();
|
||||
let path: String = mod_path.get_inner_path_unix().ok()?;
|
||||
|
||||
// Only Modrinth projects have a modrinth metadata field for the modrinth.json
|
||||
Some(Ok(match project.metadata {
|
||||
crate::prelude::ProjectMetadata::Modrinth {
|
||||
ref project,
|
||||
ref version,
|
||||
..
|
||||
} => {
|
||||
let mut env = HashMap::new();
|
||||
env.insert(EnvType::Client, project.client_side.clone());
|
||||
env.insert(EnvType::Server, project.server_side.clone());
|
||||
// TODO: envtype should be a controllable option (in general or at least .mrpack exporting)
|
||||
// For now, assume required.
|
||||
// env.insert(EnvType::Client, project.client_side.clone());
|
||||
// env.insert(EnvType::Server, project.server_side.clone());
|
||||
env.insert(EnvType::Client, SideType::Required);
|
||||
env.insert(EnvType::Server, SideType::Required);
|
||||
|
||||
let primary_file = if let Some(primary_file) =
|
||||
version.files.first()
|
||||
@@ -1037,7 +1056,7 @@ pub async fn create_mrpack_json(
|
||||
format_version: 1,
|
||||
version_id,
|
||||
name: profile.metadata.name.clone(),
|
||||
summary: None,
|
||||
summary: description,
|
||||
files,
|
||||
dependencies,
|
||||
})
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
use crate::{
|
||||
event::{
|
||||
emit::{emit_profile, loading_try_for_each_concurrent},
|
||||
emit::{emit_profile, init_loading, loading_try_for_each_concurrent},
|
||||
ProfilePayloadType,
|
||||
},
|
||||
pack::{self, install_from::generate_pack_from_version_id},
|
||||
prelude::{ProfilePathId, ProjectPathId},
|
||||
profile::get,
|
||||
state::Project,
|
||||
State,
|
||||
state::{ProfileInstallStage, Project},
|
||||
LoadingBarType, State,
|
||||
};
|
||||
use futures::try_join;
|
||||
|
||||
/// Updates a managed modrinth pack to the cached latest version found in 'modrinth_update_version'
|
||||
/// Updates a managed modrinth pack to the version specified by new_version_id
|
||||
#[tracing::instrument]
|
||||
#[theseus_macros::debug_pin]
|
||||
pub async fn update_managed_modrinth(
|
||||
pub async fn update_managed_modrinth_version(
|
||||
profile_path: &ProfilePathId,
|
||||
new_version_id: &String,
|
||||
) -> crate::Result<()> {
|
||||
let profile = get(profile_path, None).await?.ok_or_else(|| {
|
||||
crate::ErrorKind::UnmanagedProfileError(profile_path.to_string())
|
||||
@@ -39,19 +40,14 @@ pub async fn update_managed_modrinth(
|
||||
let version_id =
|
||||
linked_data.version_id.as_ref().ok_or_else(unmanaged_err)?;
|
||||
|
||||
// extract modrinth_update_version, returning Ok(()) if it is none
|
||||
let modrinth_update_version = match profile.modrinth_update_version {
|
||||
Some(ref x) if x != version_id => x,
|
||||
_ => return Ok(()), // No update version, or no update needed, return Ok(())
|
||||
};
|
||||
|
||||
// Replace the pack with the new version
|
||||
replace_managed_modrinth(
|
||||
profile_path,
|
||||
&profile,
|
||||
project_id,
|
||||
version_id,
|
||||
Some(modrinth_update_version),
|
||||
Some(new_version_id),
|
||||
true, // switching versions should ignore the lock
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -128,6 +124,7 @@ pub async fn repair_managed_modrinth(
|
||||
project_id,
|
||||
version_id,
|
||||
None,
|
||||
false, // do not ignore lock, as repairing can reset the lock
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -153,32 +150,61 @@ async fn replace_managed_modrinth(
|
||||
project_id: &String,
|
||||
version_id: &String,
|
||||
new_version_id: Option<&String>,
|
||||
ignore_lock: bool,
|
||||
) -> crate::Result<()> {
|
||||
crate::profile::edit(profile_path, |profile| {
|
||||
profile.install_stage = ProfileInstallStage::Installing;
|
||||
async { Ok(()) }
|
||||
})
|
||||
.await?;
|
||||
|
||||
// Fetch .mrpacks for both old and new versions
|
||||
// TODO: this will need to be updated if we revert the hacky pack method we needed for compiler speed
|
||||
let old_pack_creator = generate_pack_from_version_id(
|
||||
project_id.clone(),
|
||||
version_id.clone(),
|
||||
profile.metadata.name.clone(),
|
||||
None,
|
||||
profile_path.clone(),
|
||||
);
|
||||
|
||||
// download in parallel, then join. If new_version_id is None, we don't need to download the new pack, so we clone the old one
|
||||
let (old_pack_creator, new_pack_creator) =
|
||||
if let Some(new_version_id) = new_version_id {
|
||||
let shared_loading_bar = init_loading(
|
||||
LoadingBarType::PackFileDownload {
|
||||
profile_path: profile_path.get_full_path().await?,
|
||||
pack_name: profile.metadata.name.clone(),
|
||||
icon: None,
|
||||
pack_version: version_id.clone(),
|
||||
},
|
||||
200.0, // These two downloads will share the same loading bar
|
||||
"Downloading pack file",
|
||||
)
|
||||
.await?;
|
||||
|
||||
// download in parallel, then join.
|
||||
try_join!(
|
||||
old_pack_creator,
|
||||
generate_pack_from_version_id(
|
||||
project_id.clone(),
|
||||
version_id.clone(),
|
||||
profile.metadata.name.clone(),
|
||||
None,
|
||||
profile_path.clone(),
|
||||
Some(shared_loading_bar.clone())
|
||||
),
|
||||
generate_pack_from_version_id(
|
||||
project_id.clone(),
|
||||
new_version_id.clone(),
|
||||
profile.metadata.name.clone(),
|
||||
None,
|
||||
profile_path.clone()
|
||||
profile_path.clone(),
|
||||
Some(shared_loading_bar)
|
||||
)
|
||||
)?
|
||||
} else {
|
||||
let mut old_pack_creator = old_pack_creator.await?;
|
||||
// If new_version_id is None, we don't need to download the new pack, so we clone the old one
|
||||
let mut old_pack_creator = generate_pack_from_version_id(
|
||||
project_id.clone(),
|
||||
version_id.clone(),
|
||||
profile.metadata.name.clone(),
|
||||
None,
|
||||
profile_path.clone(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
old_pack_creator.description.existing_loading_bar = None;
|
||||
(old_pack_creator.clone(), old_pack_creator)
|
||||
};
|
||||
@@ -197,7 +223,11 @@ async fn replace_managed_modrinth(
|
||||
// - install all overrides
|
||||
// - edits the profile to update the new data
|
||||
// - (functionals almost identically to rteinstalling the pack 'in-place')
|
||||
pack::install_mrpack::install_zipped_mrpack_files(new_pack_creator).await?;
|
||||
pack::install_mrpack::install_zipped_mrpack_files(
|
||||
new_pack_creator,
|
||||
ignore_lock,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user