cobble_core/minecraft/launch/
command.rs

1use crate::minecraft::launch::ArgumentReplacements;
2use crate::minecraft::launch::{
3    build_classpath, build_game_args, build_jvm_args, build_logging_arg,
4};
5use crate::minecraft::models::VersionData;
6use crate::minecraft::LaunchOptions;
7use std::path::Path;
8use std::process::Command;
9
10/// Builds the launch command for Minecraft.
11/// The game needs to be installed to launch.
12#[instrument(
13    name = "build_launch_command",
14    level = "trace",
15    skip_all,
16    fields(
17        version = version_data.id,
18        launch_options,
19        minecraft_path,
20        libraries_path,
21        assets_path,
22        natives_path,
23        log_configs_path,
24    )
25)]
26pub fn build_launch_command(
27    version_data: &VersionData,
28    launch_options: &LaunchOptions,
29    minecraft_path: impl AsRef<Path>,
30    libraries_path: impl AsRef<Path>,
31    assets_path: impl AsRef<Path>,
32    natives_path: impl AsRef<Path>,
33    log_configs_path: impl AsRef<Path>,
34) -> Command {
35    // Classpath
36    trace!("Build classpath");
37    let classpath = build_classpath(version_data, &minecraft_path, &libraries_path);
38
39    // Argument replacements
40    trace!("Create argument replacements");
41    let argument_replacements = ArgumentReplacements::build(
42        launch_options,
43        version_data,
44        classpath,
45        minecraft_path.as_ref().to_string_lossy().to_string(),
46        assets_path.as_ref().to_string_lossy().to_string(),
47        natives_path.as_ref().to_string_lossy().to_string(),
48    );
49
50    // Arguments
51    trace!("Build JVM arguments");
52    let jvm_args = build_jvm_args(version_data, &argument_replacements, launch_options);
53    trace!("Build game arguments");
54    let game_args = build_game_args(version_data, &argument_replacements, launch_options);
55
56    // Logging config
57    trace!("Build log argument");
58    let log_arg = build_logging_arg(version_data, &log_configs_path);
59
60    trace!("Build command");
61    combine_launch_parts(
62        launch_options.java_executable.clone(),
63        minecraft_path,
64        jvm_args,
65        game_args,
66        log_arg,
67        version_data.main_class.clone(),
68        launch_options.environment_variables.clone(),
69    )
70}
71
72pub(crate) fn combine_launch_parts(
73    java_exec: String,
74    minecraft_path: impl AsRef<Path>,
75    jvm_args: Vec<String>,
76    game_args: Vec<String>,
77    log_argument: Option<String>,
78    main_class: String,
79    env_vars: Vec<(String, Option<String>)>,
80) -> Command {
81    let mut command = Command::new(java_exec);
82
83    command.current_dir(minecraft_path);
84    command.args(jvm_args);
85
86    if let Some(log_arg) = log_argument {
87        command.arg(log_arg);
88    }
89
90    command.arg(main_class);
91    command.args(game_args);
92
93    command.envs(
94        env_vars
95            .into_iter()
96            .map(|(k, v)| (k, v.unwrap_or_default())),
97    );
98
99    command
100}