cobble_core/instance/
loader_mods.rs

1use crate::error::CobbleResult;
2use crate::minecraft::{load_loader_mods, parse_loader_mod, LoaderMod};
3use crate::Instance;
4use std::path::{Path, PathBuf};
5use tokio::fs::create_dir_all;
6
7impl Instance {
8    /// Path to the .minecraft/mods folder.
9    #[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
10    pub fn loader_mods_path(&self) -> PathBuf {
11        let mut loader_mods_path = self.dot_minecraft_path();
12        loader_mods_path.push("mods");
13        loader_mods_path
14    }
15
16    /// Loads all log files from this instance.
17    #[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
18    pub async fn load_loader_mods(&self) -> CobbleResult<Vec<LoaderMod>> {
19        load_loader_mods(self.loader_mods_path()).await
20    }
21
22    /// Adds a loader mod.
23    ///
24    /// Returns `None` when `src` is not a valid resourcepack.
25    #[instrument(name = "add_loader_mod", level = "trace", skip_all, fields(src))]
26    #[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
27    pub async fn add_loader_mod(&self, src: impl AsRef<Path>) -> CobbleResult<Option<LoaderMod>> {
28        trace!("Validating src...");
29        if parse_loader_mod(PathBuf::from(src.as_ref()))
30            .await?
31            .is_none()
32        {
33            return Ok(None);
34        }
35
36        trace!("Building new path for loader_mod");
37        let file_name = src
38            .as_ref()
39            .file_name()
40            .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "Path ends with '..'"))?;
41        let mut loader_mod_path = self.loader_mods_path();
42        loader_mod_path.push(file_name);
43        tracing::Span::current().record("dest", loader_mod_path.to_string_lossy().to_string());
44
45        if let Some(parent) = loader_mod_path.parent() {
46            trace!("Creating mods folder...");
47            create_dir_all(parent).await?;
48        }
49
50        trace!("Copying loader mod...");
51        tokio::fs::copy(src, &loader_mod_path).await?;
52
53        trace!("Parsing new loader mod...");
54        let loader_mod = parse_loader_mod(loader_mod_path).await?;
55        Ok(loader_mod)
56    }
57}