Bump Theseus Version (#818)
* push to test on windows * Fix windows sup * Fix macos * Fix back * new resolver for windows testing * Custom macos handling for some versions * Fix 1.13+ broken * fix arg parsing mac * small winblows fix * remove debug info; set meta url * run lint + fix clippy * Remove useless commnet
This commit is contained in:
parent
7fb8850071
commit
afaec4b1bf
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -4685,7 +4685,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theseus"
|
name = "theseus"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"async-tungstenite",
|
"async-tungstenite",
|
||||||
@ -4733,7 +4733,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theseus_cli"
|
name = "theseus_cli"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh",
|
"argh",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
@ -4760,7 +4760,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theseus_gui"
|
name = "theseus_gui"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "theseus"
|
name = "theseus"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
@ -68,10 +68,14 @@ pub async fn refresh(user: uuid::Uuid) -> crate::Result<Credentials> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update player info from bearer token
|
// Update player info from bearer token
|
||||||
let player_info = hydra::stages::player_info::fetch_info(&credentials.access_token).await.map_err(|_err| {
|
let player_info =
|
||||||
crate::ErrorKind::HydraError("No Minecraft account for your profile. Make sure you own the game and have set a username through the official Minecraft launcher."
|
hydra::stages::player_info::fetch_info(&credentials.access_token)
|
||||||
.to_string())
|
.await
|
||||||
})?;
|
.map_err(|_err| {
|
||||||
|
crate::ErrorKind::HydraError(
|
||||||
|
"No Minecraft account for your profile. Please try again or contact support in our Discord for help!".to_string(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
credentials.username = player_info.name;
|
credentials.username = player_info.name;
|
||||||
users.insert(&credentials).await?;
|
users.insert(&credentials).await?;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ impl Default for PlayerInfo {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: "606e2ff0ed7748429d6ce1d3321c7838".to_string(),
|
id: "606e2ff0ed7748429d6ce1d3321c7838".to_string(),
|
||||||
name: String::from("???"),
|
name: String::from("Unknown"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,7 +127,7 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
|||||||
|
|
||||||
// removes the old installation of java
|
// removes the old installation of java
|
||||||
if let Some(file) = archive.file_names().next() {
|
if let Some(file) = archive.file_names().next() {
|
||||||
if let Some(dir) = file.split("/").next() {
|
if let Some(dir) = file.split('/').next() {
|
||||||
let path = path.join(dir);
|
let path = path.join(dir);
|
||||||
|
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
|
|||||||
@ -245,8 +245,12 @@ async fn import_atlauncher_unmanaged(
|
|||||||
if let Some(profile_val) =
|
if let Some(profile_val) =
|
||||||
crate::api::profile::get(&profile_path, None).await?
|
crate::api::profile::get(&profile_path, None).await?
|
||||||
{
|
{
|
||||||
crate::launcher::install_minecraft(&profile_val, Some(loading_bar))
|
crate::launcher::install_minecraft(
|
||||||
.await?;
|
&profile_val,
|
||||||
|
Some(loading_bar),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
{
|
{
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let mut file_watcher = state.file_watcher.write().await;
|
let mut file_watcher = state.file_watcher.write().await;
|
||||||
|
|||||||
@ -199,8 +199,12 @@ pub async fn import_curseforge(
|
|||||||
if let Some(profile_val) =
|
if let Some(profile_val) =
|
||||||
crate::api::profile::get(&profile_path, None).await?
|
crate::api::profile::get(&profile_path, None).await?
|
||||||
{
|
{
|
||||||
crate::launcher::install_minecraft(&profile_val, Some(loading_bar))
|
crate::launcher::install_minecraft(
|
||||||
.await?;
|
&profile_val,
|
||||||
|
Some(loading_bar),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
|
|||||||
@ -112,8 +112,12 @@ pub async fn import_gdlauncher(
|
|||||||
if let Some(profile_val) =
|
if let Some(profile_val) =
|
||||||
crate::api::profile::get(&profile_path, None).await?
|
crate::api::profile::get(&profile_path, None).await?
|
||||||
{
|
{
|
||||||
crate::launcher::install_minecraft(&profile_val, Some(loading_bar))
|
crate::launcher::install_minecraft(
|
||||||
.await?;
|
&profile_val,
|
||||||
|
Some(loading_bar),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
{
|
{
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let mut file_watcher = state.file_watcher.write().await;
|
let mut file_watcher = state.file_watcher.write().await;
|
||||||
|
|||||||
@ -323,8 +323,12 @@ async fn import_mmc_unmanaged(
|
|||||||
if let Some(profile_val) =
|
if let Some(profile_val) =
|
||||||
crate::api::profile::get(&profile_path, None).await?
|
crate::api::profile::get(&profile_path, None).await?
|
||||||
{
|
{
|
||||||
crate::launcher::install_minecraft(&profile_val, Some(loading_bar))
|
crate::launcher::install_minecraft(
|
||||||
.await?;
|
&profile_val,
|
||||||
|
Some(loading_bar),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
{
|
{
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let mut file_watcher = state.file_watcher.write().await;
|
let mut file_watcher = state.file_watcher.write().await;
|
||||||
|
|||||||
@ -283,8 +283,12 @@ pub async fn install_zipped_mrpack_files(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(profile_val) = profile::get(&profile_path, None).await? {
|
if let Some(profile_val) = profile::get(&profile_path, None).await? {
|
||||||
crate::launcher::install_minecraft(&profile_val, Some(loading_bar))
|
crate::launcher::install_minecraft(
|
||||||
.await?;
|
&profile_val,
|
||||||
|
Some(loading_bar),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
State::sync().await?;
|
State::sync().await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,7 +125,7 @@ pub async fn profile_create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !skip_install_profile.unwrap_or(false) {
|
if !skip_install_profile.unwrap_or(false) {
|
||||||
crate::launcher::install_minecraft(&profile, None).await?;
|
crate::launcher::install_minecraft(&profile, None, false).await?;
|
||||||
}
|
}
|
||||||
State::sync().await?;
|
State::sync().await?;
|
||||||
|
|
||||||
@ -196,7 +196,8 @@ pub async fn profile_create_from_duplicate(
|
|||||||
ErrorKind::UnmanagedProfileError(profile_path_id.to_string())
|
ErrorKind::UnmanagedProfileError(profile_path_id.to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
crate::launcher::install_minecraft(&duplicated_profile, Some(bar)).await?;
|
crate::launcher::install_minecraft(&duplicated_profile, Some(bar), false)
|
||||||
|
.await?;
|
||||||
{
|
{
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let mut file_watcher = state.file_watcher.write().await;
|
let mut file_watcher = state.file_watcher.write().await;
|
||||||
|
|||||||
@ -281,9 +281,9 @@ pub async fn list(
|
|||||||
|
|
||||||
/// Installs/Repairs a profile
|
/// Installs/Repairs a profile
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn install(path: &ProfilePathId) -> crate::Result<()> {
|
pub async fn install(path: &ProfilePathId, force: bool) -> crate::Result<()> {
|
||||||
if let Some(profile) = get(path, None).await? {
|
if let Some(profile) = get(path, None).await? {
|
||||||
crate::launcher::install_minecraft(&profile, None).await?;
|
crate::launcher::install_minecraft(&profile, None, force).await?;
|
||||||
} else {
|
} else {
|
||||||
return Err(crate::ErrorKind::UnmanagedProfileError(path.to_string())
|
return Err(crate::ErrorKind::UnmanagedProfileError(path.to_string())
|
||||||
.as_error());
|
.as_error());
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
//! Minecraft CLI argument logic
|
//! Minecraft CLI argument logic
|
||||||
// TODO: Rafactor this section
|
use super::auth::Credentials;
|
||||||
use super::{auth::Credentials, parse_rule};
|
use crate::launcher::parse_rules;
|
||||||
use crate::{
|
use crate::{
|
||||||
state::{MemorySettings, WindowSize},
|
state::{MemorySettings, WindowSize},
|
||||||
util::{io::IOError, platform::classpath_separator},
|
util::{io::IOError, platform::classpath_separator},
|
||||||
@ -23,12 +23,13 @@ pub fn get_class_paths(
|
|||||||
libraries: &[Library],
|
libraries: &[Library],
|
||||||
client_path: &Path,
|
client_path: &Path,
|
||||||
java_arch: &str,
|
java_arch: &str,
|
||||||
|
minecraft_updated: bool,
|
||||||
) -> crate::Result<String> {
|
) -> crate::Result<String> {
|
||||||
let mut cps = libraries
|
let mut cps = libraries
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|library| {
|
.filter_map(|library| {
|
||||||
if let Some(rules) = &library.rules {
|
if let Some(rules) = &library.rules {
|
||||||
if !rules.iter().any(|x| parse_rule(x, java_arch)) {
|
if !parse_rules(rules, java_arch, minecraft_updated) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,7 +336,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Argument::Ruled { rules, value } => {
|
Argument::Ruled { rules, value } => {
|
||||||
if rules.iter().any(|x| parse_rule(x, java_arch)) {
|
if parse_rules(rules, java_arch, true) {
|
||||||
match value {
|
match value {
|
||||||
ArgumentValue::Single(arg) => {
|
ArgumentValue::Single(arg) => {
|
||||||
parsed_arguments.push(parse_function(
|
parsed_arguments.push(parse_function(
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
//! Downloader for Minecraft data
|
//! Downloader for Minecraft data
|
||||||
|
|
||||||
|
use crate::launcher::parse_rules;
|
||||||
use crate::state::CredentialsStore;
|
use crate::state::CredentialsStore;
|
||||||
use crate::{
|
use crate::{
|
||||||
event::{
|
event::{
|
||||||
@ -26,11 +27,13 @@ pub async fn download_minecraft(
|
|||||||
version: &GameVersionInfo,
|
version: &GameVersionInfo,
|
||||||
loading_bar: &LoadingBarId,
|
loading_bar: &LoadingBarId,
|
||||||
java_arch: &str,
|
java_arch: &str,
|
||||||
|
force: bool,
|
||||||
|
minecraft_updated: bool,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
tracing::info!("Downloading Minecraft version {}", version.id);
|
tracing::info!("Downloading Minecraft version {}", version.id);
|
||||||
// 5
|
// 5
|
||||||
let assets_index =
|
let assets_index =
|
||||||
download_assets_index(st, version, Some(loading_bar)).await?;
|
download_assets_index(st, version, Some(loading_bar), force).await?;
|
||||||
|
|
||||||
let amount = if version
|
let amount = if version
|
||||||
.processors
|
.processors
|
||||||
@ -45,9 +48,9 @@ pub async fn download_minecraft(
|
|||||||
|
|
||||||
tokio::try_join! {
|
tokio::try_join! {
|
||||||
// Total loading sums to 90/60
|
// Total loading sums to 90/60
|
||||||
download_client(st, version, Some(loading_bar)), // 10
|
download_client(st, version, Some(loading_bar), force), // 10
|
||||||
download_assets(st, version.assets == "legacy", &assets_index, Some(loading_bar), amount), // 40
|
download_assets(st, version.assets == "legacy", &assets_index, Some(loading_bar), amount, force), // 40
|
||||||
download_libraries(st, version.libraries.as_slice(), &version.id, Some(loading_bar), amount, java_arch) // 40
|
download_libraries(st, version.libraries.as_slice(), &version.id, Some(loading_bar), amount, java_arch, force, minecraft_updated) // 40
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
tracing::info!("Done downloading Minecraft!");
|
tracing::info!("Done downloading Minecraft!");
|
||||||
@ -105,6 +108,7 @@ pub async fn download_client(
|
|||||||
st: &State,
|
st: &State,
|
||||||
version_info: &GameVersionInfo,
|
version_info: &GameVersionInfo,
|
||||||
loading_bar: Option<&LoadingBarId>,
|
loading_bar: Option<&LoadingBarId>,
|
||||||
|
force: bool,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let version = &version_info.id;
|
let version = &version_info.id;
|
||||||
tracing::debug!("Locating client for version {version}");
|
tracing::debug!("Locating client for version {version}");
|
||||||
@ -123,7 +127,7 @@ pub async fn download_client(
|
|||||||
.await
|
.await
|
||||||
.join(format!("{version}.jar"));
|
.join(format!("{version}.jar"));
|
||||||
|
|
||||||
if !path.exists() {
|
if !path.exists() || force {
|
||||||
let bytes = fetch(
|
let bytes = fetch(
|
||||||
&client_download.url,
|
&client_download.url,
|
||||||
Some(&client_download.sha1),
|
Some(&client_download.sha1),
|
||||||
@ -148,6 +152,7 @@ pub async fn download_assets_index(
|
|||||||
st: &State,
|
st: &State,
|
||||||
version: &GameVersionInfo,
|
version: &GameVersionInfo,
|
||||||
loading_bar: Option<&LoadingBarId>,
|
loading_bar: Option<&LoadingBarId>,
|
||||||
|
force: bool,
|
||||||
) -> crate::Result<AssetsIndex> {
|
) -> crate::Result<AssetsIndex> {
|
||||||
tracing::debug!("Loading assets index");
|
tracing::debug!("Loading assets index");
|
||||||
let path = st
|
let path = st
|
||||||
@ -156,7 +161,7 @@ pub async fn download_assets_index(
|
|||||||
.await
|
.await
|
||||||
.join(format!("{}.json", &version.asset_index.id));
|
.join(format!("{}.json", &version.asset_index.id));
|
||||||
|
|
||||||
let res = if path.exists() {
|
let res = if path.exists() && !force {
|
||||||
io::read(path)
|
io::read(path)
|
||||||
.err_into::<crate::Error>()
|
.err_into::<crate::Error>()
|
||||||
.await
|
.await
|
||||||
@ -183,6 +188,7 @@ pub async fn download_assets(
|
|||||||
index: &AssetsIndex,
|
index: &AssetsIndex,
|
||||||
loading_bar: Option<&LoadingBarId>,
|
loading_bar: Option<&LoadingBarId>,
|
||||||
loading_amount: f64,
|
loading_amount: f64,
|
||||||
|
force: bool,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
tracing::debug!("Loading assets");
|
tracing::debug!("Loading assets");
|
||||||
let num_futs = index.objects.len();
|
let num_futs = index.objects.len();
|
||||||
@ -206,7 +212,7 @@ pub async fn download_assets(
|
|||||||
let fetch_cell = OnceCell::<bytes::Bytes>::new();
|
let fetch_cell = OnceCell::<bytes::Bytes>::new();
|
||||||
tokio::try_join! {
|
tokio::try_join! {
|
||||||
async {
|
async {
|
||||||
if !resource_path.exists() {
|
if !resource_path.exists() || force {
|
||||||
let resource = fetch_cell
|
let resource = fetch_cell
|
||||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore, &CredentialsStore(None)))
|
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore, &CredentialsStore(None)))
|
||||||
.await?;
|
.await?;
|
||||||
@ -216,13 +222,14 @@ pub async fn download_assets(
|
|||||||
Ok::<_, crate::Error>(())
|
Ok::<_, crate::Error>(())
|
||||||
},
|
},
|
||||||
async {
|
async {
|
||||||
if with_legacy {
|
let resource_path = st.directories.legacy_assets_dir().await.join(
|
||||||
|
name.replace('/', &String::from(std::path::MAIN_SEPARATOR))
|
||||||
|
);
|
||||||
|
|
||||||
|
if with_legacy && !resource_path.exists() || force {
|
||||||
let resource = fetch_cell
|
let resource = fetch_cell
|
||||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore, &CredentialsStore(None)))
|
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore, &CredentialsStore(None)))
|
||||||
.await?;
|
.await?;
|
||||||
let resource_path = st.directories.legacy_assets_dir().await.join(
|
|
||||||
name.replace('/', &String::from(std::path::MAIN_SEPARATOR))
|
|
||||||
);
|
|
||||||
write(&resource_path, resource, &st.io_semaphore).await?;
|
write(&resource_path, resource, &st.io_semaphore).await?;
|
||||||
tracing::trace!("Fetched legacy asset with hash {hash}");
|
tracing::trace!("Fetched legacy asset with hash {hash}");
|
||||||
}
|
}
|
||||||
@ -239,6 +246,7 @@ pub async fn download_assets(
|
|||||||
|
|
||||||
#[tracing::instrument(skip(st, libraries))]
|
#[tracing::instrument(skip(st, libraries))]
|
||||||
#[theseus_macros::debug_pin]
|
#[theseus_macros::debug_pin]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn download_libraries(
|
pub async fn download_libraries(
|
||||||
st: &State,
|
st: &State,
|
||||||
libraries: &[Library],
|
libraries: &[Library],
|
||||||
@ -246,6 +254,8 @@ pub async fn download_libraries(
|
|||||||
loading_bar: Option<&LoadingBarId>,
|
loading_bar: Option<&LoadingBarId>,
|
||||||
loading_amount: f64,
|
loading_amount: f64,
|
||||||
java_arch: &str,
|
java_arch: &str,
|
||||||
|
force: bool,
|
||||||
|
minecraft_updated: bool,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
tracing::debug!("Loading libraries");
|
tracing::debug!("Loading libraries");
|
||||||
|
|
||||||
@ -258,7 +268,7 @@ pub async fn download_libraries(
|
|||||||
stream::iter(libraries.iter())
|
stream::iter(libraries.iter())
|
||||||
.map(Ok::<&Library, crate::Error>), None, loading_bar,loading_amount,num_files, None,|library| async move {
|
.map(Ok::<&Library, crate::Error>), None, loading_bar,loading_amount,num_files, None,|library| async move {
|
||||||
if let Some(rules) = &library.rules {
|
if let Some(rules) = &library.rules {
|
||||||
if !rules.iter().any(|x| super::parse_rule(x, java_arch)) {
|
if !parse_rules(rules, java_arch, minecraft_updated) {
|
||||||
tracing::trace!("Skipped library {}", &library.name);
|
tracing::trace!("Skipped library {}", &library.name);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -270,7 +280,7 @@ pub async fn download_libraries(
|
|||||||
let path = st.directories.libraries_dir().await.join(&artifact_path);
|
let path = st.directories.libraries_dir().await.join(&artifact_path);
|
||||||
|
|
||||||
match library.downloads {
|
match library.downloads {
|
||||||
_ if path.exists() => Ok(()),
|
_ if path.exists() && !force => Ok(()),
|
||||||
Some(d::minecraft::LibraryDownloads {
|
Some(d::minecraft::LibraryDownloads {
|
||||||
artifact: Some(ref artifact),
|
artifact: Some(ref artifact),
|
||||||
..
|
..
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use daedalus as d;
|
use daedalus as d;
|
||||||
use daedalus::minecraft::VersionInfo;
|
use daedalus::minecraft::{RuleAction, VersionInfo};
|
||||||
use st::Profile;
|
use st::Profile;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::{process::Stdio, sync::Arc};
|
use std::{process::Stdio, sync::Arc};
|
||||||
@ -25,14 +25,48 @@ mod args;
|
|||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod download;
|
pub mod download;
|
||||||
|
|
||||||
|
// All nones -> disallowed
|
||||||
|
// 1+ true -> allowed
|
||||||
|
// 1+ false -> disallowed
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub fn parse_rule(rule: &d::minecraft::Rule, java_version: &str) -> bool {
|
pub fn parse_rules(
|
||||||
|
rules: &[d::minecraft::Rule],
|
||||||
|
java_version: &str,
|
||||||
|
minecraft_updated: bool,
|
||||||
|
) -> bool {
|
||||||
|
let mut x = rules
|
||||||
|
.iter()
|
||||||
|
.map(|x| parse_rule(x, java_version, minecraft_updated))
|
||||||
|
.collect::<Vec<Option<bool>>>();
|
||||||
|
|
||||||
|
if rules
|
||||||
|
.iter()
|
||||||
|
.all(|x| matches!(x.action, RuleAction::Disallow))
|
||||||
|
{
|
||||||
|
x.push(Some(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
!(x.iter().any(|x| x == &Some(false)) || x.iter().all(|x| x.is_none()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// if anything is disallowed, it should NOT be included
|
||||||
|
// if anything is not disallowed, it shouldn't factor in final result
|
||||||
|
// if anything is not allowed, it shouldn't factor in final result
|
||||||
|
// if anything is allowed, it should be included
|
||||||
|
#[tracing::instrument]
|
||||||
|
pub fn parse_rule(
|
||||||
|
rule: &d::minecraft::Rule,
|
||||||
|
java_version: &str,
|
||||||
|
minecraft_updated: bool,
|
||||||
|
) -> Option<bool> {
|
||||||
use d::minecraft::{Rule, RuleAction};
|
use d::minecraft::{Rule, RuleAction};
|
||||||
|
|
||||||
let res = match rule {
|
let res = match rule {
|
||||||
Rule {
|
Rule {
|
||||||
os: Some(ref os), ..
|
os: Some(ref os), ..
|
||||||
} => crate::util::platform::os_rule(os, java_version),
|
} => {
|
||||||
|
crate::util::platform::os_rule(os, java_version, minecraft_updated)
|
||||||
|
}
|
||||||
Rule {
|
Rule {
|
||||||
features: Some(ref features),
|
features: Some(ref features),
|
||||||
..
|
..
|
||||||
@ -44,12 +78,24 @@ pub fn parse_rule(rule: &d::minecraft::Rule, java_version: &str) -> bool {
|
|||||||
|| !features.is_quick_play_realms.unwrap_or(true)
|
|| !features.is_quick_play_realms.unwrap_or(true)
|
||||||
|| !features.is_quick_play_singleplayer.unwrap_or(true)
|
|| !features.is_quick_play_singleplayer.unwrap_or(true)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => return Some(true),
|
||||||
};
|
};
|
||||||
|
|
||||||
match rule.action {
|
match rule.action {
|
||||||
RuleAction::Allow => res,
|
RuleAction::Allow => {
|
||||||
RuleAction::Disallow => !res,
|
if res {
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RuleAction::Disallow => {
|
||||||
|
if res {
|
||||||
|
Some(false)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +148,7 @@ pub async fn get_java_version_from_profile(
|
|||||||
pub async fn install_minecraft(
|
pub async fn install_minecraft(
|
||||||
profile: &Profile,
|
profile: &Profile,
|
||||||
existing_loading_bar: Option<LoadingBarId>,
|
existing_loading_bar: Option<LoadingBarId>,
|
||||||
|
repairing: bool,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let sync_projects = existing_loading_bar.is_some();
|
let sync_projects = existing_loading_bar.is_some();
|
||||||
let loading_bar = init_or_edit_loading(
|
let loading_bar = init_or_edit_loading(
|
||||||
@ -133,15 +180,23 @@ pub async fn install_minecraft(
|
|||||||
&io::canonicalize(&profile.get_profile_full_path().await?)?;
|
&io::canonicalize(&profile.get_profile_full_path().await?)?;
|
||||||
let metadata = state.metadata.read().await;
|
let metadata = state.metadata.read().await;
|
||||||
|
|
||||||
let version = metadata
|
let version_index = metadata
|
||||||
.minecraft
|
.minecraft
|
||||||
.versions
|
.versions
|
||||||
.iter()
|
.iter()
|
||||||
.find(|it| it.id == profile.metadata.game_version)
|
.position(|it| it.id == profile.metadata.game_version)
|
||||||
.ok_or(crate::ErrorKind::LauncherError(format!(
|
.ok_or(crate::ErrorKind::LauncherError(format!(
|
||||||
"Invalid game version: {}",
|
"Invalid game version: {}",
|
||||||
profile.metadata.game_version
|
profile.metadata.game_version
|
||||||
)))?;
|
)))?;
|
||||||
|
let version = &metadata.minecraft.versions[version_index];
|
||||||
|
let minecraft_updated = version_index
|
||||||
|
<= metadata
|
||||||
|
.minecraft
|
||||||
|
.versions
|
||||||
|
.iter()
|
||||||
|
.position(|x| x.id == "22w16a")
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let version_jar = profile
|
let version_jar = profile
|
||||||
.metadata
|
.metadata
|
||||||
@ -156,7 +211,7 @@ pub async fn install_minecraft(
|
|||||||
&state,
|
&state,
|
||||||
version,
|
version,
|
||||||
profile.metadata.loader_version.as_ref(),
|
profile.metadata.loader_version.as_ref(),
|
||||||
None,
|
Some(repairing),
|
||||||
Some(&loading_bar),
|
Some(&loading_bar),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -185,6 +240,8 @@ pub async fn install_minecraft(
|
|||||||
&version_info,
|
&version_info,
|
||||||
&loading_bar,
|
&loading_bar,
|
||||||
&java_version.architecture,
|
&java_version.architecture,
|
||||||
|
repairing,
|
||||||
|
minecraft_updated,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -325,7 +382,7 @@ pub async fn launch_minecraft(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if profile.install_stage != ProfileInstallStage::Installed {
|
if profile.install_stage != ProfileInstallStage::Installed {
|
||||||
install_minecraft(profile, None).await?;
|
install_minecraft(profile, None, false).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
@ -334,15 +391,23 @@ pub async fn launch_minecraft(
|
|||||||
let instance_path = profile.get_profile_full_path().await?;
|
let instance_path = profile.get_profile_full_path().await?;
|
||||||
let instance_path = &io::canonicalize(instance_path)?;
|
let instance_path = &io::canonicalize(instance_path)?;
|
||||||
|
|
||||||
let version = metadata
|
let version_index = metadata
|
||||||
.minecraft
|
.minecraft
|
||||||
.versions
|
.versions
|
||||||
.iter()
|
.iter()
|
||||||
.find(|it| it.id == profile.metadata.game_version)
|
.position(|it| it.id == profile.metadata.game_version)
|
||||||
.ok_or(crate::ErrorKind::LauncherError(format!(
|
.ok_or(crate::ErrorKind::LauncherError(format!(
|
||||||
"Invalid game version: {}",
|
"Invalid game version: {}",
|
||||||
profile.metadata.game_version
|
profile.metadata.game_version
|
||||||
)))?;
|
)))?;
|
||||||
|
let version = &metadata.minecraft.versions[version_index];
|
||||||
|
let minecraft_updated = version_index
|
||||||
|
<= metadata
|
||||||
|
.minecraft
|
||||||
|
.versions
|
||||||
|
.iter()
|
||||||
|
.position(|x| x.id == "22w16a")
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let version_jar = profile
|
let version_jar = profile
|
||||||
.metadata
|
.metadata
|
||||||
@ -418,6 +483,7 @@ pub async fn launch_minecraft(
|
|||||||
version_info.libraries.as_slice(),
|
version_info.libraries.as_slice(),
|
||||||
&client_path,
|
&client_path,
|
||||||
&java_version.architecture,
|
&java_version.architecture,
|
||||||
|
minecraft_updated,
|
||||||
)?,
|
)?,
|
||||||
&version_jar,
|
&version_jar,
|
||||||
*memory,
|
*memory,
|
||||||
|
|||||||
@ -322,29 +322,6 @@ pub async fn create_account(
|
|||||||
get_creds_from_res(response, semaphore).await
|
get_creds_from_res(response, semaphore).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login_minecraft(
|
|
||||||
flow: &str,
|
|
||||||
semaphore: &FetchSemaphore,
|
|
||||||
) -> crate::Result<ModrinthCredentialsResult> {
|
|
||||||
let resp = fetch_advanced(
|
|
||||||
Method::POST,
|
|
||||||
&format!("{MODRINTH_API_URL}auth/login/minecraft"),
|
|
||||||
None,
|
|
||||||
Some(serde_json::json!({
|
|
||||||
"flow": flow,
|
|
||||||
})),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
semaphore,
|
|
||||||
&CredentialsStore(None),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let response = serde_json::from_slice::<HashMap<String, Value>>(&resp)?;
|
|
||||||
|
|
||||||
get_result_from_res("session", response, semaphore).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn refresh_credentials(
|
pub async fn refresh_credentials(
|
||||||
credentials_store: &mut CredentialsStore,
|
credentials_store: &mut CredentialsStore,
|
||||||
semaphore: &FetchSemaphore,
|
semaphore: &FetchSemaphore,
|
||||||
|
|||||||
@ -889,8 +889,6 @@ impl Profiles {
|
|||||||
// Fetch online from Modrinth each latest version
|
// Fetch online from Modrinth each latest version
|
||||||
future::try_join_all(modrinth_updatables.into_iter().map(
|
future::try_join_all(modrinth_updatables.into_iter().map(
|
||||||
|(profile_path, linked_project)| {
|
|(profile_path, linked_project)| {
|
||||||
let profile_path = profile_path;
|
|
||||||
let linked_project = linked_project;
|
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
async move {
|
async move {
|
||||||
let creds = state.credentials.read().await;
|
let creds = state.credentials.read().await;
|
||||||
|
|||||||
@ -43,7 +43,9 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
|||||||
r"C:\Program Files (x86)\Eclipse Adoptium",
|
r"C:\Program Files (x86)\Eclipse Adoptium",
|
||||||
];
|
];
|
||||||
for java_path in java_paths {
|
for java_path in java_paths {
|
||||||
let Ok(java_subpaths) = std::fs::read_dir(java_path) else {continue };
|
let Ok(java_subpaths) = std::fs::read_dir(java_path) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
for java_subpath in java_subpaths.flatten() {
|
for java_subpath in java_subpaths.flatten() {
|
||||||
let path = java_subpath.path();
|
let path = java_subpath.path();
|
||||||
jre_paths.insert(path.join("bin"));
|
jre_paths.insert(path.join("bin"));
|
||||||
@ -97,7 +99,7 @@ pub fn get_paths_from_jre_winregkey(jre_key: RegKey) -> HashSet<PathBuf> {
|
|||||||
for subkey_value in subkey_value_names {
|
for subkey_value in subkey_value_names {
|
||||||
let path: Result<String, std::io::Error> =
|
let path: Result<String, std::io::Error> =
|
||||||
subkey.get_value(subkey_value);
|
subkey.get_value(subkey_value);
|
||||||
let Ok(path) = path else {continue};
|
let Ok(path) = path else { continue };
|
||||||
|
|
||||||
jre_paths.insert(PathBuf::from(path).join("bin"));
|
jre_paths.insert(PathBuf::from(path).join("bin"));
|
||||||
}
|
}
|
||||||
@ -264,7 +266,9 @@ pub async fn check_java_at_filepaths(
|
|||||||
pub async fn check_java_at_filepath(path: &Path) -> Option<JavaVersion> {
|
pub async fn check_java_at_filepath(path: &Path) -> Option<JavaVersion> {
|
||||||
// Attempt to canonicalize the potential java filepath
|
// Attempt to canonicalize the potential java filepath
|
||||||
// If it fails, this path does not exist and None is returned (no Java here)
|
// If it fails, this path does not exist and None is returned (no Java here)
|
||||||
let Ok(path) = io::canonicalize(path) else { return None };
|
let Ok(path) = io::canonicalize(path) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
// Checks for existence of Java at this filepath
|
// Checks for existence of Java at this filepath
|
||||||
// Adds JAVA_BIN to the end of the path if it is not already there
|
// Adds JAVA_BIN to the end of the path if it is not already there
|
||||||
|
|||||||
@ -56,7 +56,12 @@ pub const ARCH_WIDTH: &str = "64";
|
|||||||
pub const ARCH_WIDTH: &str = "32";
|
pub const ARCH_WIDTH: &str = "32";
|
||||||
|
|
||||||
// Platform rule handling
|
// Platform rule handling
|
||||||
pub fn os_rule(rule: &OsRule, java_arch: &str) -> bool {
|
pub fn os_rule(
|
||||||
|
rule: &OsRule,
|
||||||
|
java_arch: &str,
|
||||||
|
// Minecraft updated over 1.18.2 (supports MacOS Natively)
|
||||||
|
minecraft_updated: bool,
|
||||||
|
) -> bool {
|
||||||
let mut rule_match = true;
|
let mut rule_match = true;
|
||||||
|
|
||||||
if let Some(ref arch) = rule.arch {
|
if let Some(ref arch) = rule.arch {
|
||||||
@ -64,8 +69,14 @@ pub fn os_rule(rule: &OsRule, java_arch: &str) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(name) = &rule.name {
|
if let Some(name) = &rule.name {
|
||||||
rule_match &=
|
if minecraft_updated
|
||||||
&Os::native() == name || &Os::native_arch(java_arch) == name;
|
&& (name != &Os::LinuxArm64 || name != &Os::LinuxArm32)
|
||||||
|
{
|
||||||
|
rule_match &=
|
||||||
|
&Os::native() == name || &Os::native_arch(java_arch) == name;
|
||||||
|
} else {
|
||||||
|
rule_match &= &Os::native_arch(java_arch) == name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(version) = &rule.version {
|
if let Some(version) = &rule.version {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "theseus_cli"
|
name = "theseus_cli"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "theseus_gui",
|
"name": "theseus_gui",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.5.4",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "theseus_gui"
|
name = "theseus_gui"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
license = ""
|
license = ""
|
||||||
|
|||||||
@ -117,8 +117,8 @@ pub async fn profile_check_installed(
|
|||||||
/// Installs/Repairs a profile
|
/// Installs/Repairs a profile
|
||||||
/// invoke('plugin:profile|profile_install')
|
/// invoke('plugin:profile|profile_install')
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn profile_install(path: ProfilePathId) -> Result<()> {
|
pub async fn profile_install(path: ProfilePathId, force: bool) -> Result<()> {
|
||||||
profile::install(&path).await?;
|
profile::install(&path, force).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Modrinth App",
|
"productName": "Modrinth App",
|
||||||
"version": "0.5.4"
|
"version": "0.6.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ const themeStore = useTheming()
|
|||||||
|
|
||||||
const initFiles = async () => {
|
const initFiles = async () => {
|
||||||
const newFolders = new Map()
|
const newFolders = new Map()
|
||||||
const sep = '/';
|
const sep = '/'
|
||||||
files.value = []
|
files.value = []
|
||||||
await get_pack_export_candidates(props.instance.path).then((filePaths) =>
|
await get_pack_export_candidates(props.instance.path).then((filePaths) =>
|
||||||
filePaths
|
filePaths
|
||||||
|
|||||||
@ -72,8 +72,8 @@ export async function check_installed(path, projectId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Installs/Repairs a profile
|
// Installs/Repairs a profile
|
||||||
export async function install(path) {
|
export async function install(path, force) {
|
||||||
return await invoke('plugin:profile|profile_install', { path })
|
return await invoke('plugin:profile|profile_install', { path, force })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates all of a profile's projects
|
// Updates all of a profile's projects
|
||||||
|
|||||||
@ -468,7 +468,7 @@
|
|||||||
id="repair-profile"
|
id="repair-profile"
|
||||||
color="highlight"
|
color="highlight"
|
||||||
:disabled="installing || inProgress || repairing || offline"
|
:disabled="installing || inProgress || repairing || offline"
|
||||||
@click="repairProfile"
|
@click="repairProfile(true)"
|
||||||
>
|
>
|
||||||
<HammerIcon /> Repair
|
<HammerIcon /> Repair
|
||||||
</Button>
|
</Button>
|
||||||
@ -755,9 +755,9 @@ async function duplicateProfile() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function repairProfile() {
|
async function repairProfile(force) {
|
||||||
repairing.value = true
|
repairing.value = true
|
||||||
await install(props.instance.path).catch(handleError)
|
await install(props.instance.path, force).catch(handleError)
|
||||||
repairing.value = false
|
repairing.value = false
|
||||||
|
|
||||||
mixpanel_track('InstanceRepair', {
|
mixpanel_track('InstanceRepair', {
|
||||||
@ -910,7 +910,7 @@ async function saveGvLoaderEdits() {
|
|||||||
editProfile.metadata.loader_version = selectableLoaderVersions.value[loaderVersionIndex.value]
|
editProfile.metadata.loader_version = selectableLoaderVersions.value[loaderVersionIndex.value]
|
||||||
}
|
}
|
||||||
await edit(props.instance.path, editProfile).catch(handleError)
|
await edit(props.instance.path, editProfile).catch(handleError)
|
||||||
await repairProfile()
|
await repairProfile(false)
|
||||||
|
|
||||||
editing.value = false
|
editing.value = false
|
||||||
changeVersionsModal.value.hide()
|
changeVersionsModal.value.hide()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user