minecraft_java_rs_core/game/
lwjgl_native.rs1use serde::Deserialize;
2
3use crate::error::LaunchError;
4use crate::models::minecraft::{Library, MinecraftVersionJson};
5
6macro_rules! lwjgl_bytes {
17 ($arch:literal, $ver:literal) => {
18 include_bytes!(concat!(
19 "../../assets/LWJGL/",
20 $arch,
21 "/",
22 $ver,
23 ".json"
24 ))
25 .as_ref()
26 };
27}
28
29fn arm_lwjgl_data(arch: &str, version: &str) -> Option<&'static [u8]> {
32 let version = if version.contains("2.9") { "2.9.4" } else { version };
34
35 match (arch, version) {
36 ("aarch64", "2.9.4") => Some(lwjgl_bytes!("aarch64", "2.9.4")),
37 ("aarch64", "3.1.2") => Some(lwjgl_bytes!("aarch64", "3.1.2")),
38 ("aarch64", "3.2.2") => Some(lwjgl_bytes!("aarch64", "3.2.2")),
39 ("aarch64", "3.3.1") => Some(lwjgl_bytes!("aarch64", "3.3.1")),
40 ("aarch64", "3.3.2") => Some(lwjgl_bytes!("aarch64", "3.3.2")),
41 ("aarch", "2.9.4") => Some(lwjgl_bytes!("aarch", "2.9.4")),
42 ("aarch", "3.3.1") => Some(lwjgl_bytes!("aarch", "3.3.1")),
43 _ => None,
44 }
45}
46
47pub fn process_json(version: &mut MinecraftVersionJson) -> Result<(), LaunchError> {
58 let mapped_arch = match std::env::consts::ARCH {
59 "aarch64" => "aarch64",
60 "arm" => "aarch",
61 _ => return Ok(()), };
63
64 let version_jinput = find_version(&version.libraries, &["net.java.jinput:jinput-platform:", "net.java.jinput:jinput:"]);
66 let version_lwjgl = find_version(&version.libraries, &["org.lwjgl:lwjgl:", "org.lwjgl.lwjgl:lwjgl:"]);
67
68 if version_jinput.is_some() {
70 version.libraries.retain(|lib| !lib.name.contains("jinput"));
71 }
72
73 if let Some(lwjgl_ver) = version_lwjgl {
75 version.libraries.retain(|lib| !lib.name.contains("lwjgl"));
76
77 match arm_lwjgl_data(mapped_arch, &lwjgl_ver) {
78 Some(bytes) => {
79 let set: LwjglLibrarySet = serde_json::from_slice(bytes)?;
80 version.libraries.extend(set.libraries);
81 }
82 None => {
83 }
87 }
88 }
89
90 Ok(())
91}
92
93fn find_version(libs: &[Library], prefixes: &[&str]) -> Option<String> {
98 libs.iter()
99 .find(|lib| prefixes.iter().any(|p| lib.name.starts_with(p)))
100 .and_then(|lib| lib.name.split(':').last())
101 .map(|v| v.to_string())
102}
103
104#[derive(Deserialize)]
106struct LwjglLibrarySet {
107 libraries: Vec<Library>,
108}
109
110#[cfg(test)]
113mod tests {
114 use super::*;
115
116 fn make_lib(name: &str) -> Library {
117 Library {
118 name: name.to_string(),
119 rules: None,
120 natives: None,
121 downloads: None,
122 url: None,
123 loader: None,
124 }
125 }
126
127 fn libs(names: &[&str]) -> Vec<Library> {
128 names.iter().map(|n| make_lib(n)).collect()
129 }
130
131 #[test]
132 fn find_version_returns_last_colon_segment() {
133 let l = libs(&["org.lwjgl:lwjgl:3.3.1", "org.lwjgl:lwjgl-opengl:3.3.1"]);
134 assert_eq!(find_version(&l, &["org.lwjgl:lwjgl:"]), Some("3.3.1".into()));
135 }
136
137 #[test]
138 fn find_version_returns_none_when_absent() {
139 let l = libs(&["com.example:something:1.0"]);
140 assert_eq!(find_version(&l, &["org.lwjgl:lwjgl:"]), None);
141 }
142
143 #[test]
144 fn find_version_matches_multiple_prefixes() {
145 let l = libs(&["org.lwjgl.lwjgl:lwjgl:2.9.4"]);
146 let v = find_version(&l, &["org.lwjgl:lwjgl:", "org.lwjgl.lwjgl:lwjgl:"]);
147 assert_eq!(v, Some("2.9.4".into()));
148 }
149
150 #[test]
151 fn arm_lwjgl_data_normalises_29x() {
152 assert!(arm_lwjgl_data("aarch64", "2.9.0").is_some());
154 assert!(arm_lwjgl_data("aarch64", "2.9.1").is_some());
155 assert!(arm_lwjgl_data("aarch64", "2.9.4").is_some());
156 }
157
158 #[test]
159 fn arm_lwjgl_data_returns_none_for_unknown() {
160 assert!(arm_lwjgl_data("aarch64", "4.0.0").is_none());
161 assert!(arm_lwjgl_data("x86_64", "3.3.1").is_none());
162 }
163
164 #[test]
165 fn process_json_noop_on_current_arch() {
166 if matches!(std::env::consts::ARCH, "aarch64" | "arm") {
168 return; }
170
171 let mut version = MinecraftVersionJson {
172 id: "1.20.4".into(),
173 version_type: "release".into(),
174 assets: None,
175 asset_index: None,
176 downloads: None,
177 libraries: libs(&["org.lwjgl:lwjgl:3.3.1", "org.lwjgl:lwjgl-opengl:3.3.1"]),
178 arguments: None,
179 minecraft_arguments: None,
180 java_version: None,
181 main_class: None,
182 has_natives: false,
183 };
184
185 let original_count = version.libraries.len();
186 process_json(&mut version).unwrap();
187 assert_eq!(version.libraries.len(), original_count);
189 }
190}