summaryrefslogtreecommitdiffstats
path: root/src/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'src/launcher')
-rw-r--r--src/launcher/runner.rs70
-rw-r--r--src/launcher/settings.rs42
2 files changed, 77 insertions, 35 deletions
diff --git a/src/launcher/runner.rs b/src/launcher/runner.rs
index 4d07f20..8c7af3d 100644
--- a/src/launcher/runner.rs
+++ b/src/launcher/runner.rs
@@ -1,13 +1,14 @@
use std::borrow::Cow;
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
use std::iter;
-use crate::version::{CompleteVersion, FeatureMatcher};
+use std::process::Command;
+use crate::version::{CompleteVersion, FeatureMatcher, OperatingSystem};
use super::rules::CompatCheck;
use super::strsub::{self, SubFunc};
-use super::LaunchInfo;
+use super::{Launch, LaunchInfo};
#[derive(Clone, Copy)]
-struct LaunchArgSub<'a: 'l, 'l, F: FeatureMatcher>(&'a LaunchInfo<'l, F>);
+struct LaunchArgSub<'a, '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>> {
@@ -59,32 +60,6 @@ pub enum ArgumentType {
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;
@@ -94,13 +69,31 @@ pub fn build_arguments<'l, F: FeatureMatcher>(launch: &LaunchInfo<'l, F>, versio
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)))
+ .filter(|wa| wa.rules_apply(system_info, launch.feature_matcher).is_ok())
+ .flat_map(|wa| &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!()
- }
+ [
+ "-Djava.library.path=${natives_directory}",
+ "-Dminecraft.launcher.brand=${launcher_name}",
+ "-Dminecraft.launcher.version=${launcher_version}",
+ "-Dminecraft.client.jar=${primary_jar}",
+ "-cp",
+ "${classpath}"
+ ].into_iter()
+ .chain(iter::once("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump")
+ .take_while(|_| system_info.os == OperatingSystem::Windows))
+ .chain(iter::once(["-Dos.name=Windows 10", "-Dos.version=10.0"])
+ .take_while(|_| launch.feature_matcher.matches("__ozone_win10_hack"))
+ .flatten())
+ .chain(iter::once(["-Xdock:icon=${asset=icons/minecraft.icns}", "-Xdock:name=Minecraft"])
+ .take_while(|_| system_info.os == OperatingSystem::MacOS)
+ .flatten())
+ .map(|s| OsString::from(strsub::replace_string(s, &sub).into_owned()))
+ .collect()
+ },
ArgumentType::Game => {
arguments.split(' ')
.chain(iter::once("--demo")
@@ -116,3 +109,14 @@ pub fn build_arguments<'l, F: FeatureMatcher>(launch: &LaunchInfo<'l, F>, versio
Vec::default()
}
}
+
+pub fn run_the_game(launch: &Launch) -> Result<(), Box<dyn std::error::Error>> {
+ Command::new("/usr/lib/jvm/java-8-openjdk-amd64/bin/java")
+ .args(launch.jvm_args.iter()
+ .map(|o| o.as_os_str())
+ .chain(iter::once(OsStr::new(launch.main_class.as_str())))
+ .chain(launch.game_args.iter().map(|o| o.as_os_str())))
+ .current_dir(launch.instance_path.as_path()).spawn()?.wait()?;
+
+ Ok(())
+}
diff --git a/src/launcher/settings.rs b/src/launcher/settings.rs
index 5a96589..29d9220 100644
--- a/src/launcher/settings.rs
+++ b/src/launcher/settings.rs
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::error::Error;
+use std::ffi::{OsStr, OsString};
use std::fmt::{Display, Formatter};
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
@@ -140,11 +141,28 @@ pub enum ProfileVersion {
Specific(String)
}
+#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
+pub struct Resolution {
+ width: u32,
+ height: u32
+}
+
+impl Default for Resolution {
+ fn default() -> Self {
+ Resolution { width: 864, height: 480 }
+ }
+}
+
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Profile {
game_version: ProfileVersion,
java_runtime: Option<String>,
- instance: String // ugly that this is a string instead of reference to an Instance but whatever I'm lazy
+ instance: String, // ugly that this is a string instead of reference to an Instance but whatever I'm lazy
+
+ #[serde(default)]
+ jvm_arguments: Vec<OsString>,
+
+ resolution: Option<Resolution>
}
impl<P: AsRef<Path>> From<P> for Instance {
@@ -165,12 +183,24 @@ impl Instance {
}
}
+const DEF_JVM_ARGUMENTS: [&'static str; 7] = [
+ "-Xmx2G",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseG1GC",
+ "-XX:G1NewSizePercent=20",
+ "-XX:G1ReservePercent=20",
+ "-XX:MaxGCPauseMillis=50",
+ "-XX:G1HeapRegionSize=32M"
+];
+
impl Profile {
fn new(instance_name: &str) -> Self {
Self {
game_version: ProfileVersion::LatestRelease,
java_runtime: None,
- instance: instance_name.into()
+ instance: instance_name.into(),
+ jvm_arguments: DEF_JVM_ARGUMENTS.iter().map(OsString::from).collect(),
+ resolution: None
}
}
@@ -181,4 +211,12 @@ impl Profile {
pub fn get_instance_name(&self) -> &str {
&self.instance
}
+
+ pub fn iter_arguments(&self) -> impl Iterator<Item = &OsString> {
+ self.jvm_arguments.iter()
+ }
+
+ pub fn get_resolution(&self) -> Option<Resolution> {
+ self.resolution
+ }
}