use crate::minecraft::fabric::FabricVersionData;
use crate::minecraft::models::VersionData;
use crate::minecraft::{
build_classpath, build_game_args, build_jvm_args, build_logging_arg, combine_launch_parts,
ArgumentReplacements, LaunchOptions,
};
use crate::utils::Platform;
use std::path::Path;
use std::process::Command;
#[cfg_attr(doc_cfg, doc(cfg(feature = "fabric")))]
#[allow(clippy::too_many_arguments)]
#[instrument(
name = "build_launch_command",
level = "trace",
skip_all,
fields(
game_version = version_data.id,
fabric_version = fabric_version_data.id,
launch_options,
minecraft_path,
libraries_path,
assets_path,
natives_path,
log_configs_path,
)
)]
pub fn build_fabric_launch_command(
version_data: &VersionData,
fabric_version_data: &FabricVersionData,
launch_options: &LaunchOptions,
minecraft_path: impl AsRef<Path>,
libraries_path: impl AsRef<Path>,
assets_path: impl AsRef<Path>,
natives_path: impl AsRef<Path>,
log_configs_path: impl AsRef<Path>,
) -> Command {
trace!("Build classpath");
let mut classpath = build_classpath(version_data, &minecraft_path, &libraries_path);
extend_classpath(&mut classpath, fabric_version_data, &libraries_path);
trace!("Create argument replacements");
let argument_replacements = ArgumentReplacements::build(
launch_options,
version_data,
classpath,
minecraft_path.as_ref().to_string_lossy().to_string(),
assets_path.as_ref().to_string_lossy().to_string(),
natives_path.as_ref().to_string_lossy().to_string(),
);
trace!("Build JVM arguments");
let mut jvm_args = build_jvm_args(version_data, &argument_replacements, launch_options);
extend_jvm_args(&mut jvm_args, fabric_version_data, &argument_replacements);
trace!("Build game arguments");
let mut game_args = build_game_args(version_data, &argument_replacements, launch_options);
extend_game_args(&mut game_args, fabric_version_data, &argument_replacements);
trace!("Build log argument");
let log_arg = build_logging_arg(version_data, &log_configs_path);
trace!("Build command");
combine_launch_parts(
launch_options.java_executable.clone(),
minecraft_path,
jvm_args,
game_args,
log_arg,
fabric_version_data.main_class.clone(),
launch_options.environment_variables.clone(),
)
}
fn extend_classpath(
classpath: &mut String,
fabric_version_data: &FabricVersionData,
libraries_path: impl AsRef<Path>,
) {
let classes = fabric_version_data
.libraries
.iter()
.map(|l| l.jar_path(&libraries_path))
.map(|p| p.to_string_lossy().to_string())
.collect::<Vec<_>>();
let classes = classes.join(&Platform::current().classpath_seperator().to_string());
classpath.push(Platform::current().classpath_seperator());
classpath.push_str(&classes);
}
fn extend_jvm_args(
jvm_args: &mut Vec<String>,
fabric_version_data: &FabricVersionData,
argument_replacements: &ArgumentReplacements,
) {
if let Some(args) = &fabric_version_data.arguments {
for argument in args.jvm_arguments() {
jvm_args.push(argument_replacements.replace(argument.clone()));
}
}
}
fn extend_game_args(
game_args: &mut Vec<String>,
fabric_version_data: &FabricVersionData,
argument_replacements: &ArgumentReplacements,
) {
if let Some(args) = &fabric_version_data.arguments {
for argument in args.game_arguments() {
game_args.push(argument_replacements.replace(argument.clone()));
}
}
}