1
0

Theseus build updates (#3588)

* Add launcher_feature_version to Profile

* Misc fixes

- Add typing to theme and settings stuff
- Push instance route on creation from installing a modpack
- Fixed servers not reloading properly when first added

* Make old instances scan the logs folder for joined servers on launcher startup

* Create AttachedWorldData

* Change AttachedWorldData interface

* Rename WorldType::World to WorldType::Singleplayer

* Implement world display status system

* Fix Minecraft font

* Fix set_world_display_status Tauri error

* Add 'Play instance' option

* Add option to disable worlds showing in Home

* Fixes

- Fix available server filter only showing if there are some available
- Fixed server and singleplayer filters sometimes showing when there are only servers or singleplayer worlds
- Fixed new worlds not being automatically added when detected
- Rephrased Jump back into worlds option description

* Fixed sometimes more than 6 items showing up in Jump back in

* Fix servers.dat issue with instances you haven't played before

* Update a bunch of app dependencies in non-breaking ways

* Update dependencies in app-lib that had breaking updates

* Update dependencies in app that had breaking updates

* Fix too large of bulk requests being made, limit max to 800 #3430

* Also update tauri-plugin-opener

* Update app-lib to Rust 2024

* Non-breaking updates in ariadne

* Breaking updates in ariadne

* Ariadne Rust 2024

* Add hiding from home page, add types to Mods.vue

* Make recent worlds go into grid when display is huge

* Fix lint

* Remove redundant media query

* Fix protocol version on home page, and home page being blocked by pinging servers

* Clippy fix in app-lib

* Clippy fix in app

* Clippy fix

* More Clippy fixes

* Fix Prettier lints

* Undo `from_string` changes

* Update macos dependencies

* Apply updates to app-playground as well

* Update Wry + Tauri

* Update sysinfo

* Update theseus_gui to Rust 2024

* Downgrade rand in ariadne to fix labrinth

Labrinth can't use rand 0.9 due to argon2

* Cargo format

---------

Signed-off-by: Josiah Glosson <soujournme@gmail.com>
Co-authored-by: Prospector <prospectordev@gmail.com>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
Co-authored-by: Alejandro González <me@alegon.dev>
This commit is contained in:
Josiah Glosson
2025-05-02 04:51:17 -05:00
committed by GitHub
parent 20b616a7c4
commit de3019e92b
50 changed files with 1355 additions and 991 deletions

2062
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -22,4 +22,4 @@ strip = true # Remove debug symbols
opt-level = 3
[patch.crates-io]
wry = { git = "https://github.com/modrinth/wry", rev = "51907c6" }
wry = { git = "https://github.com/modrinth/wry", rev = "cafdaa9" }

View File

@@ -1,14 +1,14 @@
[package]
name = "theseus_playground"
version = "0.0.0"
edition = "2021"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
theseus = { path = "../../packages/app-lib", features = ["cli"] }
tokio = { version = "1", features = ["full"] }
webbrowser = "0.8.13"
webbrowser = "1.0.4"
enumset = "1.1"
tracing = "0.1.37"

View File

@@ -4,11 +4,11 @@ version = "0.9.5"
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
license = "GPL-3.0-only"
repository = "https://github.com/modrinth/code/apps/app/"
edition = "2021"
edition = "2024"
build = "build.rs"
[build-dependencies]
tauri-build = { version = "2.0.3", features = ["codegen"] }
tauri-build = { version = "2.2.0", features = ["codegen"] }
[dependencies]
theseus = { path = "../../packages/app-lib", features = ["tauri"] }
@@ -17,17 +17,17 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_with = "3.0.0"
tauri = { version = "2.1.1", features = ["devtools", "macos-private-api", "protocol-asset", "unstable"] }
tauri = { version = "2.5.1", features = ["devtools", "macos-private-api", "protocol-asset", "unstable"] }
tauri-plugin-window-state = "2.2.0"
tauri-plugin-deep-link = "2.2.0"
tauri-plugin-os = "2.2.0"
tauri-plugin-opener = "2.2.1"
tauri-plugin-opener = "2.2.6"
tauri-plugin-dialog = "2.2.0"
tauri-plugin-updater = { version = "2.3.0" }
tauri-plugin-single-instance = { version = "2.2.0" }
tokio = { version = "1", features = ["full"] }
thiserror = "1.0"
thiserror = "2.0.12"
daedalus = { path = "../../packages/daedalus" }
chrono = "0.4.26"
either = "1.15"
@@ -46,15 +46,15 @@ enumset = { version = "1.1", features = ["serde"] }
opener = { version = "0.7.2", features = ["reveal", "dbus-vendored"] }
native-dialog = "0.7.0"
native-dialog = "0.9.0"
[target.'cfg(not(target_os = "linux"))'.dependencies]
window-shadows = "0.2.1"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25.0"
cocoa = "0.26.0"
objc = "0.2.7"
rand = "0.8.5"
rand = "0.9.1"
[target.'cfg(target_os = "linux")'.dependencies]
tauri-plugin-updater = { version = "2.3.0", optional = true, features = ["native-tls-vendored", "zip"], default-features = false }

View File

@@ -47,8 +47,8 @@ pub enum OS {
// Create a new HashMap with the same keys
// Values provided should not be used directly, as they are not guaranteed to be up-to-date
#[tauri::command]
pub async fn progress_bars_list(
) -> Result<DashMap<uuid::Uuid, theseus::LoadingBar>> {
pub async fn progress_bars_list()
-> Result<DashMap<uuid::Uuid, theseus::LoadingBar>> {
let res = theseus::EventState::list_progress_bars().await?;
Ok(res)
}

View File

@@ -3,7 +3,7 @@ use either::Either;
use enumset::EnumSet;
use tauri::{AppHandle, Manager, Runtime};
use theseus::prelude::ProcessMetadata;
use theseus::profile::{get_full_path, QuickPlayType};
use theseus::profile::{QuickPlayType, get_full_path};
use theseus::worlds::{
DisplayStatus, ServerPackStatus, ServerStatus, World, WorldType,
WorldWithProfile,

View File

@@ -1,9 +1,9 @@
// Stolen from https://gist.github.com/charrondev/43150e940bd2771b1ea88256d491c7a9
use objc::{msg_send, sel, sel_impl};
use rand::{distributions::Alphanumeric, Rng};
use rand::{Rng, distributions::Alphanumeric};
use tauri::{
plugin::{Builder, TauriPlugin},
Emitter, Runtime, Window,
plugin::{Builder, TauriPlugin},
}; // 0.8
const WINDOW_CONTROL_PAD_X: f64 = 9.0;
@@ -73,7 +73,7 @@ struct WindowState<R: Runtime> {
#[cfg(target_os = "macos")]
pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
use cocoa::appkit::NSWindow;
use cocoa::base::{id, BOOL};
use cocoa::base::{BOOL, id};
use cocoa::foundation::NSUInteger;
use objc::runtime::{Object, Sel};
use std::ffi::c_void;
@@ -371,7 +371,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
let app_state = WindowState { window };
let app_box = Box::into_raw(Box::new(app_state)) as *mut c_void;
let random_str: String = rand::thread_rng()
let random_str: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(20)
.map(char::from)

View File

@@ -3,7 +3,7 @@
windows_subsystem = "windows"
)]
use native_dialog::{MessageDialog, MessageType};
use native_dialog::{DialogBuilder, MessageLevel};
use std::env;
use tauri::{Listener, Manager};
use theseus::prelude::*;
@@ -113,13 +113,14 @@ async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
fn show_window(app: tauri::AppHandle) {
let win = app.get_window("main").unwrap();
if let Err(e) = win.show() {
MessageDialog::new()
.set_type(MessageType::Error)
DialogBuilder::message()
.set_level(MessageLevel::Error)
.set_title("Initialization error")
.set_text(&format!(
.set_text(format!(
"Cannot display application window due to an error:\n{e}"
))
.show_alert()
.alert()
.show()
.unwrap();
panic!("cannot display application window")
} else {
@@ -321,24 +322,26 @@ fn main() {
if format!("{e:?}").contains(
"Runtime(CreateWebview(WebView2Error(WindowsError",
) {
MessageDialog::new()
.set_type(MessageType::Error)
DialogBuilder::message()
.set_level(MessageLevel::Error)
.set_title("Initialization error")
.set_text("Your Microsoft Edge WebView2 installation is corrupt.\n\nMicrosoft Edge WebView2 is required to run Modrinth App.\n\nLearn how to repair it at https://support.modrinth.com/en/articles/8797765-corrupted-microsoft-edge-webview2-installation")
.show_alert()
.alert()
.show()
.unwrap();
panic!("webview2 initialization failed")
}
}
MessageDialog::new()
.set_type(MessageType::Error)
DialogBuilder::message()
.set_level(MessageLevel::Error)
.set_title("Initialization error")
.set_text(&format!(
.set_text(format!(
"Cannot initialize application due to an error:\n{e:?}"
))
.show_alert()
.alert()
.show()
.unwrap();
tracing::error!("Error while running tauri application: {:?}", e);

View File

@@ -2,7 +2,7 @@
name = "theseus"
version = "0.9.5"
authors = ["Jai A <jaiagr+gpg@pm.me>"]
edition = "2021"
edition = "2024"
[dependencies]
bytes = "1"
@@ -13,9 +13,9 @@ sha1_smol = { version = "1.0.0", features = ["std"] }
sha2 = "0.10.8"
url = { version = "2.2", features = ["serde"] }
uuid = { version = "1.1", features = ["serde", "v4"] }
zip = "0.6.5"
zip = "2.6.1"
async_zip = { version = "0.0.17", features = ["chrono", "tokio-fs", "deflate", "bzip2", "zstd", "deflate64"] }
flate2 = "1.0.28"
flate2 = "1.1.1"
tempfile = "3.5.0"
dashmap = { version = "6.0.1", features = ["serde"] }
quick-xml = { version = "0.37", features = ["async-tokio"] }
@@ -23,12 +23,12 @@ enumset = "1.1"
chrono = { version = "0.4.19", features = ["serde"] }
daedalus = { path = "../../packages/daedalus" }
dirs = "5.0.1"
dirs = "6.0.0"
regex = "1.5"
sys-info = "0.9.0"
sysinfo = "0.30.8"
thiserror = "1.0"
sysinfo = "0.35.0"
thiserror = "2.0.12"
either = "1.13"
tracing = "0.1.37"
@@ -37,10 +37,10 @@ tracing-error = "0.2.0"
paste = { version = "1.0" }
tauri = { version = "2.0.0-rc", optional = true }
tauri = { version = "2.5.1", optional = true }
indicatif = { version = "0.17.3", optional = true }
async-tungstenite = { version = "0.27.0", features = ["tokio-runtime", "tokio-rustls-webpki-roots"] }
async-tungstenite = { version = "0.29.1", features = ["tokio-runtime", "tokio-rustls-webpki-roots"] }
futures = "0.3"
reqwest = { version = "0.12.3", features = ["json", "stream", "deflate", "gzip", "brotli", "rustls-tls", "charset", "http2", "macos-system-configuration"], default-features = false }
tokio = { version = "1", features = ["full"] }
@@ -50,8 +50,8 @@ fs4 = { version = "0.13", features = ["tokio"] }
async-walkdir = "2.1"
async-compression = { version = "0.4", default-features = false, features = ["tokio", "gzip"] }
notify = { version = "6.1.1", default-features = false }
notify-debouncer-mini = { version = "0.4.1", default-features = false }
notify = { version = "8.0.0", default-features = false }
notify-debouncer-mini = { version = "0.6.0", default-features = false }
lazy_static = "1.4.0"
dunce = "1.0.3"
@@ -73,7 +73,7 @@ hickory-resolver = "0.25"
ariadne = { path = "../ariadne" }
[target.'cfg(windows)'.dependencies]
winreg = "0.52.0"
winreg = "0.55.0"
[features]
tauri = ["dep:tauri"]

View File

@@ -2,8 +2,8 @@ use std::path::PathBuf;
use crate::{
event::{
emit::{emit_command, emit_warning},
CommandPayload,
emit::{emit_command, emit_warning},
},
util::io,
};

View File

@@ -10,8 +10,8 @@ use std::path::PathBuf;
use crate::util::io;
use crate::util::jre::extract_java_majorminor_version;
use crate::{
util::jre::{self},
LoadingBarType, State,
util::jre::{self},
};
pub async fn get_java_versions() -> crate::Result<DashMap<u32, JavaVersion>> {

View File

@@ -9,9 +9,9 @@ use tokio::{
};
use crate::{
State,
prelude::Credentials,
util::io::{self, IOError},
State,
};
#[derive(Serialize, Debug)]

View File

@@ -1,5 +1,5 @@
use crate::state::CachedEntry;
use crate::State;
use crate::state::CachedEntry;
pub use daedalus::minecraft::VersionManifest;
pub use daedalus::modded::Manifest;

View File

@@ -1,7 +1,7 @@
//! Authentication flow interface
use crate::state::{Credentials, MinecraftLoginFlow};
use crate::State;
use crate::state::{Credentials, MinecraftLoginFlow};
#[tracing::instrument]
pub async fn begin_login() -> crate::Result<MinecraftLoginFlow> {

View File

@@ -27,12 +27,12 @@ pub mod data {
pub mod prelude {
pub use crate::{
State,
data::*,
event::CommandPayload,
jre, metadata, minecraft_auth, mr_auth, pack, process,
profile::{self, create, Profile},
profile::{self, Profile, create},
settings,
util::io::{canonicalize, IOError},
State,
util::io::{IOError, canonicalize},
};
}

View File

@@ -3,6 +3,7 @@ use std::{collections::HashMap, path::PathBuf};
use serde::{Deserialize, Serialize};
use crate::{
State,
pack::{
self,
import::{self, copy_dotminecraft},
@@ -11,7 +12,6 @@ use crate::{
prelude::ModLoader,
state::{LinkedData, ProfileInstallStage},
util::io,
State,
};
#[derive(Serialize, Deserialize)]

View File

@@ -3,13 +3,13 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::{
State,
prelude::ModLoader,
state::ProfileInstallStage,
util::{
fetch::{fetch, write_cached_icon},
io,
},
State,
};
use super::{copy_dotminecraft, recache_icon};

View File

@@ -2,7 +2,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::{prelude::ModLoader, state::ProfileInstallStage, util::io, State};
use crate::{State, prelude::ModLoader, state::ProfileInstallStage, util::io};
use super::{copy_dotminecraft, recache_icon};

View File

@@ -1,14 +1,14 @@
use std::path::{Path, PathBuf};
use serde::{de, Deserialize, Serialize};
use serde::{Deserialize, Serialize, de};
use crate::{
State,
pack::{
import::{self, copy_dotminecraft},
install_from::{self, CreatePackDescription, PackDependency},
},
util::io,
State,
};
// instance.cfg

View File

@@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize};
use crate::{
event::{
emit::{emit_loading, init_or_edit_loading},
LoadingBarId,
emit::{emit_loading, init_or_edit_loading},
},
util::{
fetch::{self, IoSemaphore},
@@ -71,7 +71,7 @@ pub async fn get_importable_instances(
return Err(crate::ErrorKind::InputError(
"Launcher type Unknown".to_string(),
)
.into())
.into());
}
};
@@ -187,11 +187,7 @@ pub fn get_default_launcher_path(
ImportLauncherType::Unknown => None,
};
let path = path?;
if path.exists() {
Some(path)
} else {
None
}
if path.exists() { Some(path) } else { None }
}
/// Checks if this PathBuf is a valid instance for the given launcher type

View File

@@ -1,10 +1,10 @@
use crate::State;
use crate::data::ModLoader;
use crate::event::emit::{emit_loading, init_loading};
use crate::event::{LoadingBarId, LoadingBarType};
use crate::state::{CachedEntry, LinkedData, ProfileInstallStage, SideType};
use crate::util::fetch::{fetch, fetch_advanced, write_cached_icon};
use crate::util::io;
use crate::State;
use reqwest::Method;
use serde::{Deserialize, Serialize};

View File

@@ -1,21 +1,21 @@
use crate::event::LoadingBarType;
use crate::event::emit::{
emit_loading, init_or_edit_loading, loading_try_for_each_concurrent,
};
use crate::event::LoadingBarType;
use crate::pack::install_from::{
set_profile_information, EnvType, PackFile, PackFileHash,
EnvType, PackFile, PackFileHash, set_profile_information,
};
use crate::state::{
cache_file_hash, CacheBehaviour, CachedEntry, ProfileInstallStage, SideType,
CacheBehaviour, CachedEntry, ProfileInstallStage, SideType, cache_file_hash,
};
use crate::util::fetch::{fetch_mirrors, write};
use crate::util::io;
use crate::{profile, State};
use crate::{State, profile};
use async_zip::base::read::seek::ZipFileReader;
use super::install_from::{
generate_pack_from_file, generate_pack_from_version_id, CreatePack,
CreatePackLocation, PackFormat,
CreatePack, CreatePackLocation, PackFormat, generate_pack_from_file,
generate_pack_from_version_id,
};
use crate::data::ProjectType;
use std::io::Cursor;

View File

@@ -2,8 +2,8 @@
use crate::state::ProcessMetadata;
pub use crate::{
state::{Hooks, MemorySettings, Profile, Settings, WindowSize},
State,
state::{Hooks, MemorySettings, Profile, Settings, WindowSize},
};
use uuid::Uuid;

View File

@@ -3,12 +3,12 @@ use crate::launcher::get_loader_version_from_profile;
use crate::settings::Hooks;
use crate::state::{LauncherFeatureVersion, LinkedData, ProfileInstallStage};
use crate::util::io::{self, canonicalize};
use crate::{ErrorKind, pack, profile};
pub use crate::{State, state::Profile};
use crate::{
event::{emit::emit_profile, ProfilePayloadType},
event::{ProfilePayloadType, emit::emit_profile},
prelude::ModLoader,
};
use crate::{pack, profile, ErrorKind};
pub use crate::{state::Profile, State};
use chrono::Utc;
use std::path::PathBuf;
use tracing::{info, trace};

View File

@@ -1,9 +1,9 @@
//! Theseus profile management interface
use crate::event::LoadingBarType;
use crate::event::emit::{
emit_loading, init_loading, loading_try_for_each_concurrent,
};
use crate::event::LoadingBarType;
use crate::pack::install_from::{
EnvType, PackDependency, PackFile, PackFileHash, PackFormat,
};
@@ -12,10 +12,10 @@ use crate::state::{
ProfileFile, ProfileInstallStage, ProjectType, SideType,
};
use crate::event::{emit::emit_profile, ProfilePayloadType};
use crate::event::{ProfilePayloadType, emit::emit_profile};
use crate::util::fetch;
use crate::util::io::{self, IOError};
pub use crate::{state::Profile, State};
pub use crate::{State, state::Profile};
use async_zip::tokio::write::ZipFileWriter;
use async_zip::{Compression, ZipEntryBuilder};
use serde_json::json;
@@ -831,7 +831,7 @@ pub async fn create_mrpack_json(
return Err(crate::ErrorKind::OtherError(
"Loader version mismatch".to_string(),
)
.into())
.into());
}
};
dependencies

View File

@@ -1,13 +1,13 @@
use crate::state::CacheBehaviour;
use crate::{
LoadingBarType,
event::{
emit::{emit_profile, init_loading},
ProfilePayloadType,
emit::{emit_profile, init_loading},
},
pack::{self, install_from::generate_pack_from_version_id},
profile::get,
state::ProfileInstallStage,
LoadingBarType,
};
use futures::try_join;
@@ -24,9 +24,9 @@ pub async fn update_managed_modrinth_version(
})?;
let unmanaged_err = || {
crate::ErrorKind::InputError(
format!("Profile at {profile_path} is not a managed modrinth pack, or has been disconnected."),
)
crate::ErrorKind::InputError(format!(
"Profile at {profile_path} is not a managed modrinth pack, or has been disconnected."
))
};
// Extract modrinth pack information, if appropriate
@@ -58,9 +58,9 @@ pub async fn repair_managed_modrinth(profile_path: &str) -> crate::Result<()> {
})?;
let unmanaged_err = || {
crate::ErrorKind::InputError(
format!("Profile at {profile_path} is not a managed modrinth pack, or has been disconnected."),
)
crate::ErrorKind::InputError(format!(
"Profile at {profile_path} is not a managed modrinth pack, or has been disconnected."
))
};
// For repairing specifically, first we remove all installed projects (to ensure we do remove ones that aren't in the pack)

View File

@@ -1,8 +1,8 @@
//! Theseus profile management interface
pub use crate::{
state::{Hooks, MemorySettings, Profile, Settings, WindowSize},
State,
state::{Hooks, MemorySettings, Profile, Settings, WindowSize},
};
/// Gets entire settings

View File

@@ -1,8 +1,8 @@
//! Theseus tag management interface
use crate::state::CachedEntry;
pub use crate::{
state::{Category, DonationPlatform, GameVersion, Loader},
State,
state::{Category, DonationPlatform, GameVersion, Loader},
};
/// Get category tags

View File

@@ -3,13 +3,13 @@ use crate::launcher::get_loader_version_from_profile;
use crate::profile::get_full_path;
use crate::state::attached_world_data::AttachedWorldData;
use crate::state::{
attached_world_data, server_join_log, Profile, ProfileInstallStage,
Profile, ProfileInstallStage, attached_world_data, server_join_log,
};
pub use crate::util::server_ping::{
ServerGameProfile, ServerPlayers, ServerStatus, ServerVersion,
};
use crate::util::{io, server_ping};
use crate::{launcher, Error, ErrorKind, Result, State};
use crate::{Error, ErrorKind, Result, State, launcher};
use async_walkdir::WalkDir;
use async_zip::{Compression, ZipEntryBuilder};
use chrono::{DateTime, Local, TimeZone, Utc};
@@ -743,8 +743,8 @@ pub async fn remove_server_from_profile(
}
mod servers_data {
use crate::util::io;
use crate::Result;
use crate::util::io;
use serde::{Deserialize, Serialize};
use std::path::Path;

View File

@@ -161,7 +161,7 @@ pub fn emit_loading(
let display_frac = loading_bar.current / loading_bar.total;
let opt_display_frac = if display_frac >= 1.0 {
None // by convention, when its done, we submit None
// any further updates will be ignored (also sending None)
// any further updates will be ignored (also sending None)
} else {
Some(display_frac)
};

View File

@@ -4,8 +4,8 @@ use crate::launcher::parse_rules;
use crate::profile::QuickPlayType;
use crate::{
event::{
emit::{emit_loading, loading_try_for_each_concurrent},
LoadingBarId,
emit::{emit_loading, loading_try_for_each_concurrent},
},
state::State,
util::{fetch::*, io, platform::OsExt},

View File

@@ -9,7 +9,7 @@ use crate::state::{
Credentials, JavaVersion, ProcessMetadata, ProfileInstallStage,
};
use crate::util::io;
use crate::{process, state as st, State};
use crate::{State, process, state as st};
use chrono::Utc;
use daedalus as d;
use daedalus::minecraft::{LoggingSide, RuleAction, VersionInfo};
@@ -65,13 +65,11 @@ pub fn parse_rule(
use d::minecraft::{Rule, RuleAction};
let res = match rule {
Rule {
os: Some(ref os), ..
} => {
Rule { os: Some(os), .. } => {
crate::util::platform::os_rule(os, java_version, minecraft_updated)
}
Rule {
features: Some(ref features),
features: Some(features),
..
} => {
!features.is_demo_user.unwrap_or(true)

View File

@@ -21,8 +21,8 @@ mod state;
pub use api::*;
pub use error::*;
pub use event::{
emit::emit_loading, emit::init_loading, EventState, LoadingBar,
LoadingBarType,
EventState, LoadingBar, LoadingBarType, emit::emit_loading,
emit::init_loading,
};
pub use logger::start_logger;
pub use state::State;

View File

@@ -1,6 +1,6 @@
use crate::config::{META_URL, MODRINTH_API_URL, MODRINTH_API_URL_V3};
use crate::state::ProjectType;
use crate::util::fetch::{fetch_json, sha1_async, FetchSemaphore};
use crate::util::fetch::{FetchSemaphore, fetch_json, sha1_async};
use chrono::{DateTime, Utc};
use dashmap::DashSet;
use reqwest::Method;
@@ -1285,7 +1285,7 @@ impl CachedEntry {
if let Some(values) =
filtered_keys.iter_mut().find(|x| {
x.0 .0 == loaders_key && x.0 .1 == game_version
x.0.0 == loaders_key && x.0.1 == game_version
})
{
values.1.push(hash.to_string());

View File

@@ -1,8 +1,8 @@
//! Theseus directory information
use crate::LoadingBarType;
use crate::event::emit::{emit_loading, init_loading};
use crate::state::{JavaVersion, Profile, Settings};
use crate::util::fetch::IoSemaphore;
use crate::LoadingBarType;
use dashmap::DashSet;
use std::path::{Path, PathBuf};
use std::sync::Arc;

View File

@@ -1,13 +1,13 @@
use std::sync::{atomic::AtomicBool, Arc};
use std::sync::{Arc, atomic::AtomicBool};
use discord_rich_presence::{
activity::{Activity, Assets},
DiscordIpc, DiscordIpcClient,
activity::{Activity, Assets},
};
use tokio::sync::RwLock;
use crate::state::Profile;
use crate::State;
use crate::state::Profile;
pub struct DiscordGuard {
client: Arc<RwLock<DiscordIpcClient>>,

View File

@@ -1,32 +1,33 @@
use crate::config::{MODRINTH_API_URL_V3, MODRINTH_SOCKET_URL};
use crate::data::ModrinthCredentials;
use crate::event::emit::emit_friend;
use crate::event::FriendPayload;
use crate::event::emit::emit_friend;
use crate::state::tunnel::InternalTunnelSocket;
use crate::state::{ProcessManager, Profile, TunnelSocket};
use crate::util::fetch::{fetch_advanced, fetch_json, FetchSemaphore};
use crate::util::fetch::{FetchSemaphore, fetch_advanced, fetch_json};
use ariadne::networking::message::{
ClientToServerMessage, ServerToClientMessage,
};
use ariadne::users::{UserId, UserStatus};
use async_tungstenite::tokio::{connect_async, ConnectStream};
use async_tungstenite::tungstenite::client::IntoClientRequest;
use async_tungstenite::tungstenite::Message;
use async_tungstenite::WebSocketStream;
use async_tungstenite::tokio::{ConnectStream, connect_async};
use async_tungstenite::tungstenite::Message;
use async_tungstenite::tungstenite::client::IntoClientRequest;
use bytes::Bytes;
use chrono::{DateTime, Utc};
use dashmap::DashMap;
use either::Either;
use futures::stream::SplitSink;
use futures::{SinkExt, StreamExt};
use reqwest::header::HeaderValue;
use reqwest::Method;
use reqwest::header::HeaderValue;
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::ops::Deref;
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::tcp::OwnedReadHalf;
use tokio::net::TcpStream;
use tokio::net::tcp::OwnedReadHalf;
use tokio::sync::{Mutex, RwLock};
use uuid::Uuid;
@@ -204,7 +205,10 @@ impl FriendsSocket {
}
}
Err(e) => {
tracing::error!("Error handling message from websocket server: {:?}", e);
tracing::error!(
"Error handling message from websocket server: {:?}",
e
);
}
}
}
@@ -258,7 +262,7 @@ impl FriendsSocket {
last_ping = Utc::now();
let mut write = state.friends_socket.write.write().await;
if let Some(write) = write.as_mut() {
let _ = write.send(Message::Ping(Vec::new())).await;
let _ = write.send(Message::Ping(Bytes::new())).await;
}
}

View File

@@ -1,9 +1,9 @@
use crate::event::emit::{emit_profile, emit_warning};
use crate::event::ProfilePayloadType;
use crate::event::emit::{emit_profile, emit_warning};
use crate::state::{DirectoryInfo, ProfileInstallStage, ProjectType};
use futures::{channel::mpsc::channel, SinkExt, StreamExt};
use futures::{SinkExt, StreamExt, channel::mpsc::channel};
use notify::{RecommendedWatcher, RecursiveMode};
use notify_debouncer_mini::{new_debouncer, DebounceEventResult, Debouncer};
use notify_debouncer_mini::{DebounceEventResult, Debouncer, new_debouncer};
use std::time::Duration;
use tokio::sync::RwLock;

View File

@@ -9,7 +9,7 @@ use crate::state::{
MemorySettings, ModrinthCredentials, Profile, ProfileInstallStage,
TeamMember, Theme, VersionFile, WindowSize,
};
use crate::util::fetch::{read_json, IoSemaphore};
use crate::util::fetch::{IoSemaphore, read_json};
use chrono::{DateTime, Utc};
use p256::ecdsa::SigningKey;
use p256::pkcs8::DecodePrivateKey;
@@ -250,9 +250,11 @@ where
.metadata
.game_version
.clone(),
loaders: vec![mod_loader
.as_str()
.to_string()],
loaders: vec![
mod_loader
.as_str()
.to_string(),
],
update_version_id:
update_version.id.clone(),
},

View File

@@ -1,7 +1,7 @@
use crate::util::fetch::REQWEST_CLIENT;
use crate::ErrorKind;
use base64::prelude::{BASE64_STANDARD, BASE64_URL_SAFE_NO_PAD};
use crate::util::fetch::REQWEST_CLIENT;
use base64::Engine;
use base64::prelude::{BASE64_STANDARD, BASE64_URL_SAFE_NO_PAD};
use byteorder::BigEndian;
use chrono::{DateTime, Duration, TimeZone, Utc};
use dashmap::DashMap;
@@ -9,10 +9,10 @@ use futures::TryStreamExt;
use p256::ecdsa::signature::Signer;
use p256::ecdsa::{Signature, SigningKey, VerifyingKey};
use p256::pkcs8::{DecodePrivateKey, EncodePrivateKey, LineEnding};
use rand::rngs::OsRng;
use rand::Rng;
use reqwest::header::HeaderMap;
use rand::rngs::OsRng;
use reqwest::Response;
use reqwest::header::HeaderMap;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::json;
@@ -1201,6 +1201,6 @@ fn get_date_header(headers: &HeaderMap) -> DateTime<Utc> {
fn generate_oauth_challenge() -> String {
let mut rng = rand::thread_rng();
let bytes: Vec<u8> = (0..64).map(|_| rng.gen::<u8>()).collect();
let bytes: Vec<u8> = (0..64).map(|_| rng.r#gen::<u8>()).collect();
bytes.iter().map(|byte| format!("{byte:02x}")).collect()
}

View File

@@ -111,7 +111,9 @@ impl State {
/// Get the current launcher state, waiting for initialization
pub async fn get() -> crate::Result<Arc<Self>> {
if !LAUNCHER_STATE.initialized() {
tracing::error!("Attempted to get state before it is initialized - this should never happen!");
tracing::error!(
"Attempted to get state before it is initialized - this should never happen!"
);
while !LAUNCHER_STATE.initialized() {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
}

View File

@@ -1,6 +1,6 @@
use crate::config::{MODRINTH_API_URL, MODRINTH_URL};
use crate::state::{CacheBehaviour, CachedEntry};
use crate::util::fetch::{fetch_advanced, FetchSemaphore};
use crate::util::fetch::{FetchSemaphore, fetch_advanced};
use chrono::{DateTime, Duration, TimeZone, Utc};
use dashmap::DashMap;
use futures::TryStreamExt;

View File

@@ -4,8 +4,8 @@ use crate::profile;
use crate::util::io::IOError;
use chrono::{DateTime, TimeZone, Utc};
use dashmap::DashMap;
use quick_xml::events::Event;
use quick_xml::Reader;
use quick_xml::events::Event;
use serde::Deserialize;
use serde::Serialize;
use std::fs::OpenOptions;
@@ -345,7 +345,10 @@ impl Process {
&current_content,
)
{
tracing::error!("Failed to write throwable to log file: {}", e);
tracing::error!(
"Failed to write throwable to log file: {}",
e
);
}
}
}

View File

@@ -2,10 +2,10 @@ use super::settings::{Hooks, MemorySettings, WindowSize};
use crate::profile::get_full_path;
use crate::state::server_join_log::JoinLogEntry;
use crate::state::{
cache_file_hash, CacheBehaviour, CachedEntry, CachedFileHash,
CacheBehaviour, CachedEntry, CachedFileHash, cache_file_hash,
};
use crate::util;
use crate::util::fetch::{write_cached_icon, FetchSemaphore, IoSemaphore};
use crate::util::fetch::{FetchSemaphore, IoSemaphore, write_cached_icon};
use crate::util::io::{self};
use chrono::{DateTime, TimeDelta, TimeZone, Utc};
use dashmap::DashMap;

View File

@@ -1,5 +1,5 @@
use crate::state::friends::{TunnelSockets, WriteSocket};
use crate::state::FriendsSocket;
use crate::state::friends::{TunnelSockets, WriteSocket};
use ariadne::networking::message::ClientToServerMessage;
use std::net::SocketAddr;
use std::sync::Arc;

View File

@@ -1,8 +1,8 @@
//! Functions for fetching infromation from the Internet
use super::io::{self, IOError};
use crate::config::{MODRINTH_API_URL, MODRINTH_API_URL_V3};
use crate::event::emit::emit_loading;
use crate::event::LoadingBarId;
use crate::event::emit::emit_loading;
use bytes::Bytes;
use lazy_static::lazy_static;
use reqwest::Method;

View File

@@ -10,8 +10,8 @@ use tokio::task::JoinError;
use crate::State;
#[cfg(target_os = "windows")]
use winreg::{
enums::{HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, KEY_WOW64_64KEY},
RegKey,
enums::{HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, KEY_WOW64_64KEY},
};
// Entrypoint function (Windows)

View File

@@ -1,5 +1,5 @@
use crate::error::Result;
use crate::ErrorKind;
use crate::error::Result;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;
use std::time::Duration;

View File

@@ -1,12 +1,12 @@
[package]
name = "ariadne"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
thiserror = "2.0.12"
uuid = { version = "1.2.2", features = ["v4", "fast-rng", "serde"] }
serde_bytes = "0.11"
rand = "0.8.5"

View File

@@ -33,7 +33,7 @@ pub fn random_base62_rng_range<R: rand::RngCore>(
) -> u64 {
use rand::Rng;
assert!(n_min > 0 && n_max <= 11 && n_min <= n_max);
// gen_range is [low, high): max value is `MULTIPLES[n] - 1`,
// random_range is [low, high): max value is `MULTIPLES[n] - 1`,
// which is n characters long when encoded
rng.gen_range(MULTIPLES[n_min - 1]..MULTIPLES[n_max])
}