1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#[cfg(feature = "backup")]
mod backup;
#[cfg(not(feature = "fabric"))]
mod install;
#[cfg(not(feature = "fabric"))]
mod launch;
mod paths;
mod remove;
mod version_data;

// Vanilla features
#[cfg(feature = "log-files")]
mod log_files;
#[cfg(feature = "resourcepacks")]
mod resourcepacks;
#[cfg(feature = "save-games")]
mod save_games;
#[cfg(feature = "screenshots")]
mod screenshots;
#[cfg(feature = "servers")]
mod servers;

// Modded features
#[cfg(feature = "fabric")]
mod fabric;
#[cfg(feature = "loader-mods")]
mod loader_mods;
#[cfg(feature = "shaderpacks")]
mod shaderpacks;

use derive_builder::Builder;
use std::path::PathBuf;
use time::OffsetDateTime;
use uuid::Uuid;

/// A Minecraft instance with defined locations for installing libraries, assets and other game data.
/// An instance enables multiple instances to be installed while sharing common data like assets and libraries.
///
/// An instance can be created using the builder pattern:
///
/// ```rust
/// # use cobble_core::instance::{Instance, InstanceBuilder, InstanceBuilderError};
/// # fn function() -> Result<(), InstanceBuilderError> {
///
/// let instance: Instance = InstanceBuilder::default()
///     .name("Minecraft Instance".to_string())
///     .version("1.18.2".to_string())
///     .instance_path(".".to_string())
///     .libraries_path("./libraries".to_string())
///     .assets_path("./assets".to_string())
///     .build()?;
///
/// # Ok(())
/// # }
/// ```
#[derive(serde::Deserialize, serde::Serialize, Builder, Clone, Debug)]
pub struct Instance {
    /// Instance [`UUID`](uuid::Uuid).
    ///
    /// Defaults to `Uuid::new_v4()`.
    #[builder(default = "Uuid::new_v4()")]
    pub uuid: Uuid,

    /// Name of the instance.
    #[builder(setter(into))]
    pub name: String,

    /// Optional description of the instance.
    #[builder(setter(into, strip_option), default)]
    pub description: Option<String>,

    /// Minecraft version identifier for this instance.
    #[builder(setter(into))]
    pub version: String,

    /// Path for the instance folder.
    /// This path contains the `.minecraft`folder and some other metadata.
    #[builder(setter(into))]
    pub instance_path: PathBuf,

    /// Path for the libraries.
    #[builder(setter(into))]
    pub libraries_path: PathBuf,

    /// Path for the assets.
    #[builder(setter(into))]
    pub assets_path: PathBuf,

    /// Enables fullscreen.
    /// Overwrites the custom window size.
    ///
    /// Defaults to `false`.
    #[builder(default)]
    pub fullscreen: bool,

    /// Enables custom window size.
    /// Takes effect when not launching in fullscreen.
    /// The width and height can be configured with `custom_width` and `custom_height`.
    ///
    /// Defaults to `false`.
    #[builder(default)]
    pub enable_custom_window_size: bool,

    /// Custom game window width.
    /// Used when `enable_custom_window_size` is enabled.
    ///
    /// Defaults to `1280`.
    #[builder(default = "1280")]
    pub custom_width: u32,

    /// Custom game window height.
    /// Used when `enable_custom_window_size` is enabled.
    ///
    /// Defaults to `720`.
    #[builder(default = "720")]
    pub custom_height: u32,

    /// Enables custom JVM memory restrictions.
    /// The minimum and maximum can be configured with `custom_min_memory` and `custom_max_memory`.
    ///
    /// Defaults to `false`.
    #[builder(default)]
    pub enable_custom_memory: bool,

    /// JVM initial heap size in megabytes.
    /// Adds the `-Xms` option to the command.
    /// Gets added before `custom_jvm_args`.
    /// Used when `enable_custom_memory` is enabled.
    ///
    /// Defaults to `1024`.
    #[builder(default = "1024")]
    pub custom_min_memory: u32,

    /// JVM max heap size in megabytes.
    /// Adds the `-Xmx` opti`on to the command.
    /// Gets added before `custom_jvm_args`.
    /// Used when `enable_custom_memory` is enabled.
    ///
    /// Defaults to `2048`.
    #[builder(default = "2048")]
    pub custom_max_memory: u32,

    /// Custom java executable.
    ///
    /// Defaults to `None`.
    #[builder(setter(into, strip_option), default)]
    pub custom_java_executable: Option<String>,

    /// Custom JVM arguments
    ///
    /// Defaults to `None`.
    #[builder(setter(into, strip_option), default)]
    pub custom_jvm_arguments: Option<String>,

    /// Environment variables used for launching the game.
    ///
    /// Defaults to `vec![]`.
    #[builder(default)]
    pub environment_variables: Vec<(String, Option<String>)>,

    /// Flag whether the instance was installed.
    ///
    /// Defaults to `false`.
    #[builder(default)]
    pub installed: bool,

    /// Created timestamp.
    ///
    /// Defaults to `OffsetDateTime::now_utc()`.
    #[builder(default = "OffsetDateTime::now_utc()")]
    #[cfg_attr(feature = "serde", serde(with = "time::serde::rfc3339"))]
    pub created: OffsetDateTime,

    /// Fabric loader version that is used by this instance.
    ///
    /// Defaults to `None`.
    #[cfg_attr(doc_cfg, doc(cfg(feature = "fabric")))]
    #[cfg(feature = "fabric")]
    #[builder(default)]
    #[cfg_attr(feature = "serde", serde(default))]
    pub fabric_version: Option<String>,
}