From a393e0a2f2c3678a3ea869dc1417fa269f2b1040 Mon Sep 17 00:00:00 2001 From: Filip Wandzio Date: Sat, 24 Jan 2026 08:29:14 +0100 Subject: Resolve audio not loading bug Ensure all assets are downloading for each version Temporarily disable minecraft versions older than 1.8 because of the asset/manifest loading issues Implement basic documentation of modules Implement basic async/multithreading for downloading assets --- src/minecraft/extraction.rs | 116 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 4 deletions(-) (limited to 'src/minecraft/extraction.rs') diff --git a/src/minecraft/extraction.rs b/src/minecraft/extraction.rs index 5175ee0..b58fd2e 100644 --- a/src/minecraft/extraction.rs +++ b/src/minecraft/extraction.rs @@ -1,10 +1,118 @@ +use std::{fs, io, path::Path}; + use log::info; +use zip::ZipArchive; + +use crate::{ + errors::McError, + minecraft::manifests::{Library, Version}, +}; -use crate::errors::McError; pub fn extract_natives( - _cfg: &crate::config::Config, - version: &crate::minecraft::manifests::Version, + cfg: &crate::config::Config, + version: &Version, ) -> Result<(), McError> { - info!("Extracting natives for {}", version.id); + let natives_dir = cfg + .data_dir + .join("minecraft") + .join("versions") + .join(&version.id) + .join("natives"); + + info!("Extracting natives for {} into {:?}", version.id, natives_dir); + + if natives_dir.exists() { + fs::remove_dir_all(&natives_dir)?; + } + fs::create_dir_all(&natives_dir)?; + + for lib in &version.libraries { + if !library_allowed(lib) { + continue; + } + + let natives = match &lib.natives { + | Some(n) => n, + | None => continue, + }; + + let classifier = match natives.get("linux") { + | Some(c) => c, + | None => continue, + }; + + let classifiers = match &lib.downloads.classifiers { + | Some(c) => c, + | None => continue, + }; + + let artifact = match classifiers.get(classifier) { + | Some(a) => a, + | None => continue, + }; + + let jar_path = cfg + .data_dir + .join("minecraft") + .join("libraries") + .join(&artifact.path); + + info!("Extracting natives from {:?}", jar_path); + + extract_zip(&jar_path, &natives_dir)?; + } + + Ok(()) +} + +fn library_allowed(lib: &Library) -> bool { + let rules = match &lib.rules { + | Some(r) => r, + | None => return true, + }; + + let mut allowed = false; + + for rule in rules { + let os_match = match &rule.os { + | Some(os) => os.name == "linux", + | None => true, + }; + + if os_match { + allowed = rule.action == "allow"; + } + } + + allowed +} + +fn extract_zip(jar_path: &Path, out_dir: &Path) -> Result<(), McError> { + let file = fs::File::open(jar_path)?; + let mut zip = ZipArchive::new(file)?; + + for i in 0..zip.len() { + let mut entry = zip.by_index(i)?; + let name = entry.name(); + + if name.starts_with("META-INF/") { + continue; + } + + let out_path = out_dir.join(name); + + if entry.is_dir() { + fs::create_dir_all(&out_path)?; + continue; + } + + if let Some(parent) = out_path.parent() { + fs::create_dir_all(parent)?; + } + + let mut out_file = fs::File::create(&out_path)?; + io::copy(&mut entry, &mut out_file)?; + } + Ok(()) } -- cgit v1.2.3