summaryrefslogtreecommitdiffstats
path: root/src/launcher.rs
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2025-01-20 04:33:28 -0600
committerLibravatar bigfoot547 <[email protected]>2025-01-20 04:33:28 -0600
commitb317a8a652d2e3a48c8b9f4940c7933d3802cfc3 (patch)
treeec06208dd483d17eb7c764587c7629e4e4f0d100 /src/launcher.rs
parentget rid of wacky closure business (diff)
it runs the game
Diffstat (limited to 'src/launcher.rs')
-rw-r--r--src/launcher.rs58
1 files changed, 42 insertions, 16 deletions
diff --git a/src/launcher.rs b/src/launcher.rs
index a21a422..f148653 100644
--- a/src/launcher.rs
+++ b/src/launcher.rs
@@ -12,7 +12,7 @@ use std::borrow::Cow;
use std::cmp::min;
use std::env::consts::{ARCH, OS};
use std::error::Error;
-use std::ffi::OsStr;
+use std::ffi::{OsStr, OsString};
use std::fmt::{Display, Formatter};
use std::io::ErrorKind;
use std::io::ErrorKind::AlreadyExists;
@@ -39,6 +39,7 @@ use assets::{AssetError, AssetRepository};
use crate::util::{self, FileVerifyError, IntegrityError};
pub use settings::*;
+pub use runner::run_the_game;
use crate::assets::AssetIndex;
use crate::launcher::runner::ArgumentType;
use crate::launcher::strsub::SubFunc;
@@ -115,6 +116,7 @@ pub enum LaunchError {
LoadVersion(Box<dyn Error>),
ResolveVersion(VersionResolveError),
IncompatibleVersion(IncompatibleError),
+ MissingMainClass,
// library errors
LibraryDirError(PathBuf, io::Error),
@@ -146,6 +148,7 @@ impl Display for LaunchError {
LaunchError::LoadVersion(e) => write!(f, "error loading remote version: {e}"),
LaunchError::ResolveVersion(e) => write!(f, "error resolving remote version: {e}"),
LaunchError::IncompatibleVersion(e) => e.fmt(f),
+ LaunchError::MissingMainClass => f.write_str("main class not specified"),
LaunchError::LibraryDirError(path, e) => write!(f, "failed to create library directory {}: {}", path.display(), e),
LaunchError::LibraryVerifyError(e) => write!(f, "failed to verify library: {}", e),
LaunchError::LibraryDownloadError => f.write_str("library download failed (see above logs for details)"), // TODO: booo this sucks
@@ -198,10 +201,24 @@ struct LaunchInfo<'l, F: FeatureMatcher> {
asset_index: Option<AssetIndex>
}
-struct FMTrivial;
-impl FeatureMatcher for FMTrivial {
- fn matches(&self, _feature: &str) -> bool {
- false
+#[derive(Debug)]
+pub struct Launch {
+ jvm_args: Vec<OsString>,
+ game_args: Vec<OsString>,
+ main_class: String,
+ instance_path: PathBuf
+}
+
+struct ProfileFeatureMatcher<'prof> {
+ profile: &'prof Profile
+}
+
+impl FeatureMatcher for ProfileFeatureMatcher<'_> {
+ fn matches(&self, feature: &str) -> bool {
+ match feature {
+ "has_custom_resolution" => self.profile.get_resolution().is_some(),
+ _ => false
+ }
}
}
@@ -246,10 +263,6 @@ impl Launcher {
lib.natives.as_ref().map_or(None, |n| n.get(&self.system_info.os)).map(|s| s.as_str())
}
- fn get_feature_matcher(&self) -> &impl FeatureMatcher {
- &FMTrivial
- }
-
async fn ensure_file(&self, path: &Path, dlinfo: &DownloadInfo) -> Result<(), LaunchError> {
// verify the file
match util::verify_file(path, dlinfo.size, dlinfo.sha1).await {
@@ -374,7 +387,7 @@ impl Launcher {
Ok(strsub::replace_string(config.client.argument.as_str(), &PathSub(path.as_ref())).to_string())
}
- pub async fn prepare_launch(&self, version_id: &ProfileVersion, instance: &Instance) -> Result<(), LaunchError> {
+ pub async fn prepare_launch(&self, profile: &Profile, instance: &Instance) -> Result<Launch, LaunchError> {
/* tasks 2 l;aunch the gayme!!!! :3
* - java runtime
* - normal process (good research, past figboot :3)
@@ -399,6 +412,9 @@ impl Launcher {
* - launch the game
* - build argument list and whatnot also
*/
+ let feature_matcher = ProfileFeatureMatcher { profile };
+ let version_id = profile.get_version();
+
let Some(version_id) = self.versions.get_profile_version_id(version_id) else {
// idk how common this use case actually is
warn!("Can't use latest release/snapshot profiles while offline!");
@@ -429,7 +445,7 @@ impl Launcher {
};
let ver = self.versions.resolve_version(ver.as_ref()).await.map_err(|e| LaunchError::ResolveVersion(e))?;
- ver.rules_apply(&self.system_info, self.get_feature_matcher()).map_err(|e| LaunchError::IncompatibleVersion(e))?;
+ ver.rules_apply(&self.system_info, &feature_matcher).map_err(|e| LaunchError::IncompatibleVersion(e))?;
info!("Resolved launch version {}!", ver.id);
@@ -438,7 +454,7 @@ impl Launcher {
let mut downloads = Vec::new();
for lib in ver.libraries.values() {
- if lib.rules_apply(&self.system_info, self.get_feature_matcher()).is_err() {
+ if lib.rules_apply(&self.system_info, &feature_matcher).is_err() {
continue;
}
@@ -548,12 +564,12 @@ impl Launcher {
info!("Deriving launch arguments");
let info = LaunchInfo {
launcher: self,
- feature_matcher: self.get_feature_matcher(),
+ feature_matcher: &feature_matcher,
asset_index_name: asset_idx_name.map(|s| s.to_owned()),
classpath,
virtual_assets_path: game_assets,
- instance_home: inst_home,
+ instance_home: inst_home.clone(),
natives_path: natives_dir,
client_jar: client_jar_path,
version_id: ver.id.to_string(),
@@ -561,10 +577,20 @@ impl Launcher {
asset_index: asset_idx
};
- let jvm_args = runner::build_arguments(&info, ver.as_ref(), ArgumentType::JVM);
+ let Some(ref main_class) = ver.main_class else {
+ return Err(LaunchError::MissingMainClass);
+ };
+
+ // yuck
+ let jvm_args = profile.iter_arguments().map(OsString::from).chain(runner::build_arguments(&info, ver.as_ref(), ArgumentType::JVM).drain(..)).collect();
let game_args = runner::build_arguments(&info, ver.as_ref(), ArgumentType::Game);
- todo!()
+ Ok(Launch {
+ jvm_args,
+ game_args,
+ main_class: main_class.to_string(),
+ instance_path: inst_home
+ })
}
}