summaryrefslogtreecommitdiffstats
path: root/src/launcher/runner.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/launcher/runner.rs')
-rw-r--r--src/launcher/runner.rs105
1 files changed, 88 insertions, 17 deletions
diff --git a/src/launcher/runner.rs b/src/launcher/runner.rs
index 8d12197..4d07f20 100644
--- a/src/launcher/runner.rs
+++ b/src/launcher/runner.rs
@@ -1,27 +1,34 @@
use std::borrow::Cow;
-use crate::launcher::Launch;
-use crate::launcher::strsub::SubFunc;
+use std::ffi::OsString;
+use std::iter;
+use crate::version::{CompleteVersion, FeatureMatcher};
+use super::rules::CompatCheck;
+use super::strsub::{self, SubFunc};
+use super::LaunchInfo;
-impl<'k, 'rep, 'l: 'rep> SubFunc<'k, 'rep> for &'rep Launch<'l> {
- fn substitute(self, key: &'k str) -> Option<Cow<'rep, str>> {
+#[derive(Clone, Copy)]
+struct LaunchArgSub<'a: 'l, 'l, F: FeatureMatcher>(&'a LaunchInfo<'l, F>);
+
+impl<'rep, 'l, F: FeatureMatcher> SubFunc<'rep> for LaunchArgSub<'rep, 'l, F> {
+ fn substitute(&self, key: &str) -> Option<Cow<'rep, str>> {
match key {
- "assets_index_name" => self.asset_index_name.as_ref().map(|s| Cow::Borrowed(s.as_str())),
- "assets_root" => Some(self.launcher.assets.get_home().to_string_lossy()),
+ "assets_index_name" => self.0.asset_index_name.as_ref().map(|s| Cow::Borrowed(s.as_str())),
+ "assets_root" => Some(self.0.launcher.assets.get_home().to_string_lossy()),
"auth_access_token" => Some(Cow::Borrowed("-")), // TODO
"auth_player_name" => Some(Cow::Borrowed("Player")), // TODO
"auth_session" => Some(Cow::Borrowed("-")), // TODO
"auth_uuid" => Some(Cow::Borrowed("00000000-0000-0000-0000-000000000000")), // TODO
"auth_xuid" => Some(Cow::Borrowed("00000000-0000-0000-0000-000000000000")), // TODO
- "classpath" => Some(Cow::Borrowed(self.classpath.as_str())), // TODO
+ "classpath" => Some(Cow::Borrowed(self.0.classpath.as_str())), // TODO
"classpath_separator" => None, // FIXME
- "game_assets" => self.virtual_assets_path.as_ref().map(|s| s.to_string_lossy()),
- "game_directory" => Some(self.instance_home.to_string_lossy()),
+ "game_assets" => self.0.virtual_assets_path.as_ref().map(|s| s.to_string_lossy()),
+ "game_directory" => Some(self.0.instance_home.to_string_lossy()),
"language" => Some(Cow::Borrowed("en-us")), // ???
"launcher_name" => Some(Cow::Borrowed("ozone (olauncher 3)")), // TODO
"launcher_version" => Some(Cow::Borrowed("yeah")), // TODO
- "library_directory" => Some(self.launcher.libraries.home.to_string_lossy()),
- "natives_directory" => Some(self.natives_path.to_string_lossy()),
- "primary_jar" => self.client_jar.as_ref().map(|p| p.to_string_lossy()),
+ "library_directory" => Some(self.0.launcher.libraries.home.to_string_lossy()),
+ "natives_directory" => Some(self.0.natives_path.to_string_lossy()),
+ "primary_jar" => self.0.client_jar.as_ref().map(|p| p.to_string_lossy()),
"quickPlayMultiplayer" => None, // TODO
"quickPlayPath" => None, // TODO
"quickPlayRealms" => None, // TODO
@@ -31,17 +38,81 @@ impl<'k, 'rep, 'l: 'rep> SubFunc<'k, 'rep> for &'rep Launch<'l> {
"user_properties" => Some(Cow::Borrowed("{}")), // TODO
"user_property_map" => Some(Cow::Borrowed("[]")), // TODO
"user_type" => Some(Cow::Borrowed("legacy")), // TODO
- "version_name" => Some(Cow::Borrowed(&self.version_id.as_ref())),
- "version_type" => self.version_type.as_ref().map(|s| Cow::Borrowed(s.to_str())),
+ "version_name" => Some(Cow::Borrowed(&self.0.version_id.as_ref())),
+ "version_type" => self.0.version_type.as_ref().map(|s| Cow::Borrowed(s.to_str())),
_ => {
if let Some(asset_key) = key.strip_prefix("asset=") {
- return self.asset_index.as_ref()
+ return self.0.asset_index.as_ref()
.map_or(None, |idx| idx.objects.get(asset_key))
- .map(|obj| Cow::Owned(self.launcher.assets.get_object_path(obj).to_string_lossy().into_owned()))
+ .map(|obj| Cow::Owned(self.0.launcher.assets.get_object_path(obj).to_string_lossy().into_owned()))
}
None
}
}
}
-} \ No newline at end of file
+}
+
+#[derive(Clone, Copy)]
+pub enum ArgumentType {
+ JVM,
+ Game
+}
+
+struct OptionalIterator<I>
+where
+ I: Iterator
+{
+ opt: Option<I>
+}
+
+impl<I: Iterator> Iterator for OptionalIterator<I> {
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.opt {
+ Some(ref mut i) => i.next(),
+ None => None
+ }
+ }
+}
+
+impl<II: IntoIterator> From<Option<II>> for OptionalIterator<II::IntoIter> {
+ fn from(opt: Option<II>) -> Self {
+ OptionalIterator {
+ opt: opt.map(IntoIterator::into_iter)
+ }
+ }
+}
+
+pub fn build_arguments<'l, F: FeatureMatcher>(launch: &LaunchInfo<'l, F>, version: &CompleteVersion, arg_type: ArgumentType) -> Vec<OsString> {
+ let sub = LaunchArgSub(launch);
+ let system_info = &launch.launcher.system_info;
+
+ if let Some(arguments) = version.arguments.as_ref().map_or(None, |args| match arg_type {
+ ArgumentType::JVM => args.jvm.as_ref(),
+ ArgumentType::Game => args.game.as_ref()
+ }) {
+ arguments.iter()
+ .flat_map(|wa| OptionalIterator::from(wa.rules_apply(system_info, launch.feature_matcher).ok().map(|_| &wa.value)))
+ .map(|s| OsString::from(strsub::replace_string(s, &sub).into_owned())).collect()
+ } else if let Some(arguments) = version.minecraft_arguments.as_ref() {
+ match arg_type {
+ ArgumentType::JVM => {
+ todo!()
+ }
+ ArgumentType::Game => {
+ arguments.split(' ')
+ .chain(iter::once("--demo")
+ .take_while(|_| launch.feature_matcher.matches("is_demo_user")))
+ .chain(iter::once(["--width", "${resolution_width}", "--height", "${resolution_height}"])
+ .take_while(|_| launch.feature_matcher.matches("has_custom_resolution"))
+ .flatten())
+ .map(|s| OsString::from(strsub::replace_string(s, &sub).into_owned()))
+ .collect()
+ }
+ }
+ } else {
+ Vec::default()
+ }
+}