Skip to main content

minecraft_java_rs_core/models/
minecraft.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::utils::platform::LibraryRule;
6
7// ── Mojang version manifest ──────────────────────────────────────────────────
8// Fetched from launchermeta.mojang.com/mc/game/version_manifest_v2.json
9
10#[derive(Debug, Clone, Deserialize)]
11pub struct MojangVersionManifest {
12    pub latest: LatestVersions,
13    pub versions: Vec<VersionEntry>,
14}
15
16#[derive(Debug, Clone, Deserialize)]
17pub struct LatestVersions {
18    pub release: String,
19    pub snapshot: String,
20}
21
22#[derive(Debug, Clone, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct VersionEntry {
25    pub id: String,
26    #[serde(rename = "type")]
27    pub version_type: String,
28    pub url: String,
29    pub time: String,
30    pub release_time: String,
31}
32
33// ── Per-version JSON (e.g. 1.20.1.json) ─────────────────────────────────────
34
35#[derive(Debug, Clone, Deserialize, Serialize)]
36#[serde(rename_all = "camelCase")]
37pub struct MinecraftVersionJson {
38    pub id: String,
39    #[serde(rename = "type")]
40    pub version_type: String,
41    pub assets: Option<String>,
42    pub asset_index: Option<AssetIndexRef>,
43    pub downloads: Option<VersionDownloads>,
44    #[serde(default)]
45    pub libraries: Vec<Library>,
46    pub main_class: Option<String>,
47    pub java_version: Option<JavaVersionInfo>,
48    // Legacy format (pre-1.13): space-separated arg string
49    pub minecraft_arguments: Option<String>,
50    // Modern format (1.13+): structured args
51    pub arguments: Option<Arguments>,
52    // Runtime field: true when native JARs were found and extracted.
53    // Not present in Mojang JSON; stored in our game_data.json.
54    #[serde(rename = "nativesList", default)]
55    pub has_natives: bool,
56}
57
58#[derive(Debug, Clone, Deserialize, Serialize)]
59#[serde(rename_all = "camelCase")]
60pub struct AssetIndexRef {
61    pub id: String,
62    pub sha1: String,
63    pub size: u64,
64    pub total_size: Option<u64>,
65    pub url: String,
66}
67
68#[derive(Debug, Clone, Deserialize, Serialize)]
69pub struct VersionDownloads {
70    pub client: DownloadArtifact,
71    pub server: Option<DownloadArtifact>,
72    pub client_mappings: Option<DownloadArtifact>,
73    pub server_mappings: Option<DownloadArtifact>,
74}
75
76#[derive(Debug, Clone, Deserialize, Serialize)]
77pub struct DownloadArtifact {
78    pub sha1: String,
79    pub size: u64,
80    pub url: String,
81}
82
83#[derive(Debug, Clone, Deserialize, Serialize)]
84#[serde(rename_all = "camelCase")]
85pub struct JavaVersionInfo {
86    pub component: Option<String>,
87    pub major_version: Option<u32>,
88}
89
90// ── Arguments ────────────────────────────────────────────────────────────────
91
92#[derive(Debug, Clone, Deserialize, Serialize)]
93pub struct Arguments {
94    pub game: Option<Vec<GameArgEntry>>,
95    // JVM args can also be conditional objects with rules
96    pub jvm: Option<Vec<serde_json::Value>>,
97}
98
99/// Modern (1.13+) game argument: either a plain string or a conditional object.
100/// Conditional objects are dropped during argument construction (same as JS).
101#[derive(Debug, Clone, Deserialize, Serialize)]
102#[serde(untagged)]
103pub enum GameArgEntry {
104    Plain(String),
105    Conditional(serde_json::Value),
106}
107
108// ── Library ──────────────────────────────────────────────────────────────────
109
110#[derive(Debug, Clone, Deserialize, Serialize)]
111pub struct Library {
112    pub name: String,
113    /// OS/feature rules from Mojang. Evaluated by `utils::platform::skip_library`.
114    pub rules: Option<Vec<LibraryRule>>,
115    /// Maps OS names to native classifier suffixes (e.g. `"linux" → "natives-linux"`).
116    pub natives: Option<HashMap<String, String>>,
117    pub downloads: Option<LibraryDownloads>,
118    /// Base repository URL — used by Fabric/Quilt loader libraries (not in Mojang JSON).
119    #[serde(default)]
120    pub url: Option<String>,
121    /// Loader root path — injected at runtime when building loader classpath.
122    /// Not present in Mojang JSON; set by the loader installer.
123    #[serde(default)]
124    pub loader: Option<String>,
125}
126
127#[derive(Debug, Clone, Deserialize, Serialize)]
128pub struct LibraryDownloads {
129    pub artifact: Option<ArtifactInfo>,
130    /// Keyed by classifier string (e.g. `"natives-linux-aarch64"`).
131    pub classifiers: Option<HashMap<String, ArtifactInfo>>,
132}
133
134#[derive(Debug, Clone, Deserialize, Serialize)]
135pub struct ArtifactInfo {
136    pub sha1: Option<String>,
137    pub size: Option<u64>,
138    /// Relative Maven path (e.g. `"net/minecraftforge/forge/1.19-41.0.63/forge-1.19-41.0.63.jar"`).
139    pub path: Option<String>,
140    pub url: String,
141}
142
143// ── Asset index ──────────────────────────────────────────────────────────────
144
145/// Content of the asset index JSON (fetched from `assetIndex.url`).
146#[derive(Debug, Clone, Deserialize)]
147pub struct AssetIndexData {
148    pub objects: HashMap<String, AssetObject>,
149}
150
151#[derive(Debug, Clone, Deserialize)]
152pub struct AssetObject {
153    pub hash: String,
154    pub size: u64,
155}
156
157/// Resolved bundle entry produced by the game/* modules.
158#[derive(Debug, Clone, Deserialize, Serialize)]
159#[serde(tag = "kind", rename_all = "camelCase")]
160pub enum AssetItem {
161    /// A file whose content is known at resolve-time — written verbatim to disk
162    /// without downloading (e.g. `assets/indexes/<id>.json`,
163    /// `versions/<id>/<id>.json`).
164    CFile { path: String, content: String },
165    /// A regular downloadable file verified by SHA-1.
166    Asset {
167        path: String,
168        sha1: String,
169        size: u64,
170        url: String,
171    },
172    /// A native JAR (`.dll`/`.so`/`.dylib` bundle) — downloaded like `Asset`
173    /// but then extracted to `versions/<id>/natives/` by `extract_natives`.
174    NativeAsset {
175        path: String,
176        sha1: String,
177        size: u64,
178        url: String,
179    },
180}
181
182// ── Authenticator ────────────────────────────────────────────────────────────
183
184#[derive(Debug, Clone, Deserialize, Serialize)]
185#[serde(rename_all = "camelCase")]
186pub struct Authenticator {
187    pub access_token: String,
188    pub name: String,
189    pub uuid: String,
190    #[serde(default)]
191    pub xbox_account: Option<XboxAccount>,
192    #[serde(default)]
193    pub user_properties: Option<String>,
194    #[serde(default)]
195    pub client_id: Option<String>,
196    #[serde(default)]
197    pub client_token: Option<String>,
198}
199
200#[derive(Debug, Clone, Deserialize, Serialize)]
201pub struct XboxAccount {
202    pub xuid: String,
203}
204