Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analytics + more bug fixes #144

Merged
merged 7 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
417 changes: 408 additions & 9 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion theseus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async_zip = { version = "0.0.13", features = ["full"] }
tempfile = "3.5.0"

chrono = { version = "0.4.19", features = ["serde"] }
daedalus = { version = "0.1.21" }
daedalus = { version = "0.1.23" }
dirs = "5.0.1"

regex = "1.5"
Expand All @@ -49,6 +49,8 @@ notify-debouncer-mini = { version = "0.2.1", default-features = false }
lazy_static = "1.4.0"
dunce = "1.0.3"

whoami = "1.4.0"

[target.'cfg(windows)'.dependencies]
winreg = "0.50.0"

Expand Down
37 changes: 6 additions & 31 deletions theseus/src/api/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use tokio::fs::read_to_string;
#[derive(Serialize, Deserialize, Debug)]
pub struct Logs {
pub datetime_string: String,
pub stdout: Option<String>,
pub stderr: Option<String>,
pub output: Option<String>,
}
impl Logs {
async fn build(
Expand All @@ -15,19 +14,11 @@ impl Logs {
clear_contents: Option<bool>,
) -> crate::Result<Self> {
Ok(Self {
stdout: if clear_contents.unwrap_or(false) {
output: if clear_contents.unwrap_or(false) {
None
} else {
Some(
get_stdout_by_datetime(profile_uuid, &datetime_string)
.await?,
)
},
stderr: if clear_contents.unwrap_or(false) {
None
} else {
Some(
get_stderr_by_datetime(profile_uuid, &datetime_string)
get_output_by_datetime(profile_uuid, &datetime_string)
.await?,
)
},
Expand Down Expand Up @@ -74,18 +65,15 @@ pub async fn get_logs_by_datetime(
datetime_string: String,
) -> crate::Result<Logs> {
Ok(Logs {
stdout: Some(
get_stdout_by_datetime(profile_uuid, &datetime_string).await?,
),
stderr: Some(
get_stderr_by_datetime(profile_uuid, &datetime_string).await?,
output: Some(
get_output_by_datetime(profile_uuid, &datetime_string).await?,
),
datetime_string,
})
}

#[tracing::instrument]
pub async fn get_stdout_by_datetime(
pub async fn get_output_by_datetime(
profile_uuid: uuid::Uuid,
datetime_string: &str,
) -> crate::Result<String> {
Expand All @@ -97,19 +85,6 @@ pub async fn get_stdout_by_datetime(
)
}

#[tracing::instrument]
pub async fn get_stderr_by_datetime(
profile_uuid: uuid::Uuid,
datetime_string: &str,
) -> crate::Result<String> {
let state = State::get().await?;
let logs_folder = state.directories.profile_logs_dir(profile_uuid);
Ok(
read_to_string(logs_folder.join(datetime_string).join("stderr.log"))
.await?,
)
}

#[tracing::instrument]
pub async fn delete_logs(profile_uuid: uuid::Uuid) -> crate::Result<()> {
let state = State::get().await?;
Expand Down
3 changes: 2 additions & 1 deletion theseus/src/api/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ async fn install_pack(
async { Ok(()) }
})
.await?;
State::sync().await?;

let profile = profile.clone();
let result = async {
Expand Down Expand Up @@ -487,6 +486,8 @@ async fn install_pack(
Some(loading_bar),
)
.await?;

State::sync().await?;
}

Ok::<PathBuf, crate::Error>(profile.clone())
Expand Down
37 changes: 5 additions & 32 deletions theseus/src/api/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ pub async fn get_uuids_by_profile_path(
children.running_keys_with_profile(profile_path).await
}

// Gets stdout of a child process stored in the state by UUID, as a string
// Gets output of a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn get_stdout_by_uuid(uuid: &Uuid) -> crate::Result<String> {
pub async fn get_output_by_uuid(uuid: &Uuid) -> crate::Result<String> {
let state = State::get().await?;
// Get stdout from child
let children = state.children.read().await;

// Extract child or return crate::Error
if let Some(child) = children.get(uuid) {
let child = child.read().await;
Ok(child.stdout.get_output().await?)
Ok(child.output.get_output().await?)
} else {
Err(crate::ErrorKind::LauncherError(format!(
"No child process by UUID {}",
Expand All @@ -89,26 +89,6 @@ pub async fn get_stdout_by_uuid(uuid: &Uuid) -> crate::Result<String> {
}
}

// Gets stderr of a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn get_stderr_by_uuid(uuid: &Uuid) -> crate::Result<String> {
let state = State::get().await?;
// Get stdout from child
let children = state.children.read().await;

// Extract child or return crate::Error
if let Some(child) = children.get(uuid) {
let child = child.read().await;
Ok(child.stderr.get_output().await?)
} else {
Err(crate::ErrorKind::LauncherError(format!(
"No child process with UUID {}",
uuid
))
.as_error())
}
}

// Kill a child process stored in the state by UUID, as a string
#[tracing::instrument]
pub async fn kill_by_uuid(uuid: &Uuid) -> crate::Result<()> {
Expand Down Expand Up @@ -150,7 +130,7 @@ pub async fn kill(running: &mut MinecraftChild) -> crate::Result<()> {
pub async fn wait_for(running: &mut MinecraftChild) -> crate::Result<()> {
// We do not wait on the Child directly, but wait on the thread manager.
// This way we can still run all cleanup hook functions that happen after.
let result = running
running
.manager
.take()
.ok_or_else(|| {
Expand All @@ -166,12 +146,5 @@ pub async fn wait_for(running: &mut MinecraftChild) -> crate::Result<()> {
))
})?;

match result.success() {
false => Err(crate::ErrorKind::LauncherError(format!(
"Minecraft exited with non-zero code {}",
result.code().unwrap_or(-1)
))
.as_error()),
true => Ok(()),
}
Ok(())
}
12 changes: 11 additions & 1 deletion theseus/src/api/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub async fn edit_icon(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(())
}
Expand All @@ -133,7 +134,10 @@ pub async fn edit_icon(
profile.metadata.icon = None;
async { Ok(()) }
})
.await
.await?;
State::sync().await?;

Ok(())
}
}

Expand Down Expand Up @@ -288,6 +292,7 @@ pub async fn update_all(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(Arc::try_unwrap(map).unwrap().into_inner())
} else {
Expand Down Expand Up @@ -344,6 +349,7 @@ pub async fn update_project(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;
}

return Ok(path);
Expand Down Expand Up @@ -378,6 +384,7 @@ pub async fn add_project_from_version(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(path)
} else {
Expand Down Expand Up @@ -418,6 +425,7 @@ pub async fn add_project_from_path(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(path)
} else {
Expand All @@ -444,6 +452,7 @@ pub async fn toggle_disable_project(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(res)
} else {
Expand All @@ -470,6 +479,7 @@ pub async fn remove_project(
ProfilePayloadType::Edited,
)
.await?;
State::sync().await?;

Ok(())
} else {
Expand Down
6 changes: 5 additions & 1 deletion theseus/src/api/profile_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ pub(crate) async fn get_loader_version_from_loader(
let filter = |it: &LoaderVersion| match version.as_str() {
"latest" => true,
"stable" => it.stable,
id => it.id == *id || format!("{}-{}", game_version, id) == it.id,
id => {
it.id == *id
|| format!("{}-{}", game_version, id) == it.id
|| format!("{}-{}-{}", game_version, id, game_version) == it.id
}
};

let loader_data = match loader {
Expand Down
2 changes: 1 addition & 1 deletion theseus/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl Drop for LoadingBarId {
// Emit event to indicatif progress bar arc
#[cfg(feature = "cli")]
{
let cli_progress_bar = bar.cli_progress_bar.clone();
let cli_progress_bar = bar.cli_progress_bar;
cli_progress_bar.finish();
}
}
Expand Down
7 changes: 6 additions & 1 deletion theseus/src/launcher/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,17 @@ fn parse_minecraft_argument(
resolution: WindowSize,
) -> crate::Result<String> {
Ok(argument
.replace("${accessToken}", access_token)
.replace("${auth_access_token}", access_token)
.replace("${auth_session}", access_token)
.replace("${auth_player_name}", username)
// TODO: add auth xuid eventually
.replace("${auth_xuid}", "0")
.replace("${auth_uuid}", &uuid.hyphenated().to_string())
.replace("${uuid}", &uuid.hyphenated().to_string())
.replace("${clientid}", "c4502edb-87c6-40cb-b595-64a280cf8906")
.replace("${user_properties}", "{}")
.replace("${user_type}", "mojang")
.replace("${user_type}", "msa")
.replace("${version_name}", version)
.replace("${assets_index_name}", asset_index_name)
.replace(
Expand Down
41 changes: 36 additions & 5 deletions theseus/src/launcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use daedalus as d;
use daedalus::minecraft::VersionInfo;
use dunce::canonicalize;
use st::Profile;
use std::collections::HashMap;
use std::fs;
use std::{process::Stdio, sync::Arc};
use tokio::process::Command;
Expand All @@ -36,9 +37,12 @@ pub fn parse_rule(rule: &d::minecraft::Rule, java_version: &str) -> bool {
features: Some(ref features),
..
} => {
features.has_demo_resolution.unwrap_or(false)
|| (features.has_demo_resolution.is_none()
&& features.is_demo_user.is_none())
!features.is_demo_user.unwrap_or(true)
|| features.has_custom_resolution.unwrap_or(false)
|| !features.has_quick_plays_support.unwrap_or(true)
|| !features.is_quick_play_multiplayer.unwrap_or(true)
|| !features.is_quick_play_realms.unwrap_or(true)
|| !features.is_quick_play_singleplayer.unwrap_or(true)
}
_ => false,
};
Expand Down Expand Up @@ -431,14 +435,41 @@ pub async fn launch_minecraft(
fs::create_dir_all(&logs_dir)?;

let stdout_log_path = logs_dir.join("stdout.log");
let stderr_log_path = logs_dir.join("stderr.log");

crate::api::profile::edit(&profile.path, |prof| {
prof.metadata.last_played = Some(Utc::now());

async { Ok(()) }
})
.await?;
State::sync().await?;

let mut censor_strings = HashMap::new();
let username = whoami::username();
censor_strings.insert(
format!("/{}/", username),
"/{COMPUTER_USERNAME}/".to_string(),
);
censor_strings.insert(
format!("\\{}\\", username),
"\\{COMPUTER_USERNAME}\\".to_string(),
);
censor_strings.insert(
credentials.access_token.clone(),
"{MINECRAFT_ACCESS_TOKEN}".to_string(),
);
censor_strings.insert(
credentials.username.clone(),
"{MINECRAFT_USERNAME}".to_string(),
);
censor_strings.insert(
credentials.id.as_simple().to_string(),
"{MINECRAFT_UUID}".to_string(),
);
censor_strings.insert(
credentials.id.as_hyphenated().to_string(),
"{MINECRAFT_UUID}".to_string(),
);

// Create Minecraft child by inserting it into the state
// This also spawns the process and prepares the subsequent processes
Expand All @@ -448,9 +479,9 @@ pub async fn launch_minecraft(
Uuid::new_v4(),
instance_path.to_path_buf(),
stdout_log_path,
stderr_log_path,
command,
post_exit_hook,
censor_strings,
)
.await
}
Loading