You've already forked AstralRinth
forked from didirus/AstralRinth
Folder names (#318)
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
//! Theseus profile management interface
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use io::IOError;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::{
|
||||
event::emit::{emit_loading, init_loading},
|
||||
prelude::DirectoryInfo,
|
||||
state::{self, Profiles},
|
||||
util::io,
|
||||
};
|
||||
pub use crate::{
|
||||
state::{
|
||||
Hooks, JavaSettings, MemorySettings, Profile, Settings, WindowSize,
|
||||
@@ -19,6 +30,16 @@ pub async fn get() -> crate::Result<Settings> {
|
||||
#[tracing::instrument]
|
||||
pub async fn set(settings: Settings) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
|
||||
if settings.loaded_config_dir
|
||||
!= state.settings.read().await.loaded_config_dir
|
||||
{
|
||||
return Err(crate::ErrorKind::OtherError(
|
||||
"Cannot change config directory as setting".to_string(),
|
||||
)
|
||||
.as_error());
|
||||
}
|
||||
|
||||
let (reset_io, reset_fetch) = async {
|
||||
let read = state.settings.read().await;
|
||||
(
|
||||
@@ -42,3 +63,119 @@ pub async fn set(settings: Settings) -> crate::Result<()> {
|
||||
State::sync().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets the new config dir, the location of all Theseus data except for the settings.json and caches
|
||||
/// Takes control of the entire state and blocks until completion
|
||||
pub async fn set_config_dir(new_config_dir: PathBuf) -> crate::Result<()> {
|
||||
if !new_config_dir.is_dir() {
|
||||
return Err(crate::ErrorKind::FSError(format!(
|
||||
"New config dir is not a folder: {}",
|
||||
new_config_dir.display()
|
||||
))
|
||||
.as_error());
|
||||
}
|
||||
|
||||
let loading_bar = init_loading(
|
||||
crate::LoadingBarType::ConfigChange {
|
||||
new_path: new_config_dir.clone(),
|
||||
},
|
||||
100.0,
|
||||
"Changing configuration directory",
|
||||
)
|
||||
.await?;
|
||||
|
||||
tracing::trace!("Changing config dir, taking control of the state");
|
||||
// Take control of the state
|
||||
let mut state_write = State::get_write().await?;
|
||||
let old_config_dir =
|
||||
state_write.directories.config_dir.read().await.clone();
|
||||
|
||||
tracing::trace!("Setting configuration setting");
|
||||
// Set load config dir setting
|
||||
let settings = {
|
||||
let mut settings = state_write.settings.write().await;
|
||||
settings.loaded_config_dir = Some(new_config_dir.clone());
|
||||
|
||||
// Some java paths are hardcoded to within our config dir, so we need to update them
|
||||
tracing::trace!("Updating java keys");
|
||||
for key in settings.java_globals.keys() {
|
||||
if let Some(java) = settings.java_globals.get_mut(&key) {
|
||||
// If the path is within the old config dir path, update it to the new config dir
|
||||
if let Ok(relative_path) = PathBuf::from(java.path.clone())
|
||||
.strip_prefix(&old_config_dir)
|
||||
{
|
||||
java.path = new_config_dir
|
||||
.join(relative_path)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
tracing::trace!("Syncing settings");
|
||||
|
||||
settings
|
||||
.sync(&state_write.directories.settings_file())
|
||||
.await?;
|
||||
settings.clone()
|
||||
};
|
||||
|
||||
tracing::trace!("Reinitializing directory");
|
||||
// Set new state information
|
||||
state_write.directories = DirectoryInfo::init(&settings)?;
|
||||
let total_entries = std::fs::read_dir(&old_config_dir)
|
||||
.map_err(|e| IOError::with_path(e, &old_config_dir))?
|
||||
.count() as f64;
|
||||
|
||||
// Move all files over from state_write.directories.config_dir to new_config_dir
|
||||
tracing::trace!("Renaming folder structure");
|
||||
let mut i = 0.0;
|
||||
let mut entries = io::read_dir(&old_config_dir).await?;
|
||||
while let Some(entry) = entries
|
||||
.next_entry()
|
||||
.await
|
||||
.map_err(|e| IOError::with_path(e, &old_config_dir))?
|
||||
{
|
||||
let entry_path = entry.path();
|
||||
if let Some(file_name) = entry_path.file_name() {
|
||||
// Ignore settings.json
|
||||
if file_name == state::SETTINGS_FILE_NAME {
|
||||
continue;
|
||||
}
|
||||
// Ignore caches folder
|
||||
if file_name == state::CACHES_FOLDER_NAME {
|
||||
continue;
|
||||
}
|
||||
// Ignore modrinth_logs folder
|
||||
if file_name == state::LAUNCHER_LOGS_FOLDER_NAME {
|
||||
continue;
|
||||
}
|
||||
|
||||
let new_path = new_config_dir.join(file_name);
|
||||
io::rename(entry_path, new_path).await?;
|
||||
|
||||
i += 1.0;
|
||||
emit_loading(&loading_bar, 90.0 * (i / total_entries), None)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset file watcher
|
||||
tracing::trace!("Reset file watcher");
|
||||
let mut file_watcher = state::init_watcher().await?;
|
||||
|
||||
// Reset profiles (for filepaths, file watcher, etc)
|
||||
state_write.profiles = RwLock::new(
|
||||
Profiles::init(&state_write.directories, &mut file_watcher).await?,
|
||||
);
|
||||
state_write.file_watcher = RwLock::new(file_watcher);
|
||||
|
||||
emit_loading(&loading_bar, 10.0, None).await?;
|
||||
|
||||
// TODO: need to be able to safely error out of this function, reverting the changes
|
||||
tracing::info!(
|
||||
"Successfully switched config folder to: {}",
|
||||
new_config_dir.display()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user