cobble_core/minecraft/models/
launch_arguments.rs

1use crate::minecraft::models::Rule;
2use crate::utils::Either;
3use serde::{Deserialize, Serialize};
4
5/// Game and JVM arguments.
6#[derive(Clone, Debug, Deserialize, Serialize)]
7pub struct LaunchArguments {
8    /// Game arguments
9    pub game: Vec<Argument>,
10    /// JVM arguments
11    pub jvm: Vec<Argument>,
12}
13
14impl LaunchArguments {
15    /// Gets all JVM arguments and also filters out some arguments that are not needed.
16    pub fn jvm_arguments(&self) -> Vec<String> {
17        Self::collect_args(&self.jvm)
18    }
19
20    /// Gets all game arguments and also filters out some arguments that are not needed.
21    pub fn game_arguments(&self) -> Vec<String> {
22        Self::collect_args(&self.game)
23    }
24
25    /// Collects all arguments and checks wether they are needed by checking defined rules.
26    fn collect_args(args: &[Argument]) -> Vec<String> {
27        let mut arguments = vec![];
28
29        for argument in args {
30            match argument {
31                Argument::Simple(simple_argument) => {
32                    if check_skip_argument(simple_argument) {
33                        continue;
34                    }
35
36                    arguments.push(simple_argument.to_string());
37                }
38                Argument::Complex(complex_arg) => {
39                    if !complex_arg.check_use() {
40                        continue;
41                    }
42
43                    let values = complex_arg
44                        .value()
45                        .into_iter()
46                        .filter(|arg| !check_skip_argument(arg));
47
48                    arguments.extend(values);
49                }
50            }
51        }
52
53        arguments
54    }
55}
56
57/// An argument that can be just a string, or a complex one that has rules defined.
58#[derive(Clone, Debug, Serialize, Deserialize)]
59#[serde(untagged)]
60pub enum Argument {
61    /// Simple argument
62    Simple(String),
63    /// Complex argument with defined rules
64    Complex(ComplexArgument),
65}
66
67/// Complex arguments that can define rules for usage.
68#[derive(Clone, Debug, Deserialize, Serialize)]
69pub struct ComplexArgument {
70    /// The rules of this argument.
71    #[serde(alias = "compatibilityRules")]
72    pub rules: Vec<Rule>,
73    /// Argument itself.
74    /// Can be a single string or multiple ones.
75    pub value: Either<String, Vec<String>>,
76}
77
78impl ComplexArgument {
79    /// Checks if the arguments needs to be used on the current executing machine.
80    pub fn check_use(&self) -> bool {
81        for rule in &self.rules {
82            if !rule.allows() {
83                return false;
84            }
85        }
86
87        true
88    }
89
90    /// Extracts the rules into a unified form.
91    pub fn value(&self) -> Vec<String> {
92        match &self.value {
93            Either::Left(val) => vec![val.clone()],
94            Either::Right(x) => x.clone(),
95        }
96    }
97}
98
99fn check_skip_argument(arg: &str) -> bool {
100    matches!(
101        arg,
102        "--clientId" | "--xuid" | "${clientid}" | "${auth_xuid}"
103    )
104}