You've already forked AstralRinth
forked from didirus/AstralRinth
Modpack support (#60)
* Modpack support * Finish feature * Tauri errors fix (#61) * async impl * working * fmt and redundancy * moved ? to if let Ok block * Finish modpacks support * remove generated file * fix compile err * fix lint * Fix code review comments + forge support --------- Co-authored-by: Wyatt Verchere <wverchere@gmail.com>
This commit is contained in:
@@ -36,7 +36,7 @@ pub fn get_class_paths(
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(get_lib_path(libraries_path, &library.name))
|
||||
Some(get_lib_path(libraries_path, &library.name, false))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
@@ -62,17 +62,25 @@ pub fn get_class_paths_jar<T: AsRef<str>>(
|
||||
) -> crate::Result<String> {
|
||||
let cps = libraries
|
||||
.iter()
|
||||
.map(|library| get_lib_path(libraries_path, library.as_ref()))
|
||||
.map(|library| get_lib_path(libraries_path, library.as_ref(), false))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(cps.join(classpath_separator()))
|
||||
}
|
||||
|
||||
pub fn get_lib_path(libraries_path: &Path, lib: &str) -> crate::Result<String> {
|
||||
pub fn get_lib_path(
|
||||
libraries_path: &Path,
|
||||
lib: &str,
|
||||
allow_not_exist: bool,
|
||||
) -> crate::Result<String> {
|
||||
let mut path = libraries_path.to_path_buf();
|
||||
|
||||
path.push(get_path_from_artifact(lib)?);
|
||||
|
||||
if !path.exists() && allow_not_exist {
|
||||
return Ok(path.to_string_lossy().to_string());
|
||||
}
|
||||
|
||||
let path = &canonicalize(&path).map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Library file at path {} does not exist",
|
||||
@@ -343,13 +351,14 @@ pub fn get_processor_arguments<T: AsRef<str>>(
|
||||
get_lib_path(
|
||||
libraries_path,
|
||||
&entry.client[1..entry.client.len() - 1],
|
||||
true,
|
||||
)?
|
||||
} else {
|
||||
entry.client.clone()
|
||||
})
|
||||
}
|
||||
} else if argument.as_ref().starts_with('[') {
|
||||
new_arguments.push(get_lib_path(libraries_path, trimmed_arg)?)
|
||||
new_arguments.push(get_lib_path(libraries_path, trimmed_arg, true)?)
|
||||
} else {
|
||||
new_arguments.push(argument.as_ref().to_string())
|
||||
}
|
||||
@@ -361,7 +370,7 @@ pub fn get_processor_arguments<T: AsRef<str>>(
|
||||
pub async fn get_processor_main_class(
|
||||
path: String,
|
||||
) -> crate::Result<Option<String>> {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let main_class = tokio::task::spawn_blocking(move || {
|
||||
let zipfile = std::fs::File::open(&path)?;
|
||||
let mut archive = zip::ZipArchive::new(zipfile).map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
@@ -394,6 +403,7 @@ pub async fn get_processor_main_class(
|
||||
|
||||
Ok::<Option<String>, crate::Error>(None)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.await??;
|
||||
|
||||
Ok(main_class)
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
lazy_static! {
|
||||
static ref HYDRA_URL: Url =
|
||||
Url::parse("https://hydra.modrinth.com").unwrap();
|
||||
static ref HYDRA_URL: Url = Url::parse("https://hydra.modrinth.com")
|
||||
.expect("Hydra URL parse failed");
|
||||
}
|
||||
|
||||
// Socket messages
|
||||
|
||||
@@ -39,11 +39,12 @@ pub async fn download_version_info(
|
||||
version: &GameVersion,
|
||||
loader: Option<&LoaderVersion>,
|
||||
) -> crate::Result<GameVersionInfo> {
|
||||
let version_id = loader.map_or(&version.id, |it| &it.id);
|
||||
let version_id = loader
|
||||
.map_or(version.id.clone(), |it| format!("{}-{}", version.id, it.id));
|
||||
log::debug!("Loading version info for Minecraft {version_id}");
|
||||
let path = st
|
||||
.directories
|
||||
.version_dir(version_id)
|
||||
.version_dir(&version_id)
|
||||
.join(format!("{version_id}.json"));
|
||||
|
||||
let res = if path.exists() {
|
||||
@@ -58,10 +59,10 @@ pub async fn download_version_info(
|
||||
if let Some(loader) = loader {
|
||||
let partial = d::modded::fetch_partial_version(&loader.url).await?;
|
||||
info = d::modded::merge_partial_version(partial, info);
|
||||
info.id = loader.id.clone();
|
||||
}
|
||||
info.id = version_id.clone();
|
||||
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
write(&path, &serde_json::to_vec(&info)?, &permit).await?;
|
||||
Ok(info)
|
||||
}?;
|
||||
@@ -92,7 +93,7 @@ pub async fn download_client(
|
||||
.join(format!("{version}.jar"));
|
||||
|
||||
if !path.exists() {
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let bytes =
|
||||
fetch(&client_download.url, Some(&client_download.sha1), &permit)
|
||||
.await?;
|
||||
@@ -122,7 +123,7 @@ pub async fn download_assets_index(
|
||||
.and_then(|ref it| Ok(serde_json::from_slice(it)?))
|
||||
} else {
|
||||
let index = d::minecraft::fetch_assets_index(version).await?;
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
write(&path, &serde_json::to_vec(&index)?, &permit).await?;
|
||||
log::info!("Fetched assets index");
|
||||
Ok(index)
|
||||
@@ -141,7 +142,7 @@ pub async fn download_assets(
|
||||
log::debug!("Loading assets");
|
||||
stream::iter(index.objects.iter())
|
||||
.map(Ok::<(&String, &Asset), crate::Error>)
|
||||
.try_for_each_concurrent(Some(st.settings.read().await.max_concurrent_downloads), |(name, asset)| async move {
|
||||
.try_for_each_concurrent(None, |(name, asset)| async move {
|
||||
let hash = &asset.hash;
|
||||
let resource_path = st.directories.object_dir(hash);
|
||||
let url = format!(
|
||||
@@ -153,7 +154,7 @@ pub async fn download_assets(
|
||||
tokio::try_join! {
|
||||
async {
|
||||
if !resource_path.exists() {
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let resource = fetch_cell
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &permit))
|
||||
.await?;
|
||||
@@ -164,7 +165,7 @@ pub async fn download_assets(
|
||||
},
|
||||
async {
|
||||
if with_legacy {
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let resource = fetch_cell
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &permit))
|
||||
.await?;
|
||||
@@ -201,7 +202,7 @@ pub async fn download_libraries(
|
||||
|
||||
stream::iter(libraries.iter())
|
||||
.map(Ok::<&Library, crate::Error>)
|
||||
.try_for_each_concurrent(Some(st.settings.read().await.max_concurrent_downloads), |library| async move {
|
||||
.try_for_each_concurrent(None, |library| async move {
|
||||
if let Some(rules) = &library.rules {
|
||||
if !rules.iter().all(super::parse_rule) {
|
||||
return Ok(());
|
||||
@@ -218,7 +219,7 @@ pub async fn download_libraries(
|
||||
artifact: Some(ref artifact),
|
||||
..
|
||||
}) => {
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let bytes = fetch(&artifact.url, Some(&artifact.sha1), &permit)
|
||||
.await?;
|
||||
write(&path, &bytes, &permit).await?;
|
||||
@@ -234,7 +235,7 @@ pub async fn download_libraries(
|
||||
&artifact_path
|
||||
].concat();
|
||||
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let bytes = fetch(&url, None, &permit).await?;
|
||||
write(&path, &bytes, &permit).await?;
|
||||
log::info!("Fetched library {}", &library.name);
|
||||
@@ -262,12 +263,17 @@ pub async fn download_libraries(
|
||||
);
|
||||
|
||||
if let Some(native) = classifiers.get(&parsed_key) {
|
||||
let permit = st.io_semaphore.acquire().await.unwrap();
|
||||
let permit = st.io_semaphore.acquire().await?;
|
||||
let data = fetch(&native.url, Some(&native.sha1), &permit).await?;
|
||||
let reader = std::io::Cursor::new(&data);
|
||||
let mut archive = zip::ZipArchive::new(reader).unwrap();
|
||||
archive.extract(&st.directories.version_natives_dir(version)).unwrap();
|
||||
log::info!("Fetched native {}", &library.name);
|
||||
if let Ok(mut archive) = zip::ZipArchive::new(reader) {
|
||||
match archive.extract(&st.directories.version_natives_dir(version)) {
|
||||
Ok(_) => log::info!("Fetched native {}", &library.name),
|
||||
Err(err) => log::error!("Failed extracting native {}. err: {}", &library.name, err)
|
||||
}
|
||||
} else {
|
||||
log::error!("Failed extracting native {}", &library.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +72,10 @@ pub async fn launch_minecraft(
|
||||
"Invalid game version: {game_version}"
|
||||
)))?;
|
||||
|
||||
let version_jar = loader_version
|
||||
.as_ref()
|
||||
.map_or(version.id.clone(), |it| it.id.clone());
|
||||
let version_jar =
|
||||
loader_version.as_ref().map_or(version.id.clone(), |it| {
|
||||
format!("{}-{}", version.id.clone(), it.id.clone())
|
||||
});
|
||||
|
||||
let mut version_info = download::download_version_info(
|
||||
&state,
|
||||
@@ -85,7 +86,7 @@ pub async fn launch_minecraft(
|
||||
|
||||
let client_path = state
|
||||
.directories
|
||||
.version_dir(&version.id)
|
||||
.version_dir(&version_jar)
|
||||
.join(format!("{version_jar}.jar"));
|
||||
|
||||
download::download_minecraft(&state, &version_info).await?;
|
||||
@@ -133,6 +134,7 @@ pub async fn launch_minecraft(
|
||||
args::get_processor_main_class(args::get_lib_path(
|
||||
&state.directories.libraries_dir(),
|
||||
&processor.jar,
|
||||
false,
|
||||
)?)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
@@ -193,7 +195,7 @@ pub async fn launch_minecraft(
|
||||
args::get_jvm_arguments(
|
||||
args.get(&d::minecraft::ArgumentType::Jvm)
|
||||
.map(|x| x.as_slice()),
|
||||
&state.directories.version_natives_dir(&version.id),
|
||||
&state.directories.version_natives_dir(&version_jar),
|
||||
&state.directories.libraries_dir(),
|
||||
&args::get_class_paths(
|
||||
&state.directories.libraries_dir(),
|
||||
@@ -205,7 +207,6 @@ pub async fn launch_minecraft(
|
||||
Vec::from(java_args),
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|r| r.replace(' ', r"\ "))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.arg(version_info.main_class.clone())
|
||||
@@ -223,7 +224,6 @@ pub async fn launch_minecraft(
|
||||
*resolution,
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|r| r.replace(' ', r"\ "))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.current_dir(instance_path.clone())
|
||||
|
||||
Reference in New Issue
Block a user