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
use crate::error::CobbleResult;
use crate::minecraft::{load_loader_mods, parse_loader_mod, LoaderMod};
use crate::Instance;
use std::path::{Path, PathBuf};
use tokio::fs::create_dir_all;
impl Instance {
#[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
pub fn loader_mods_path(&self) -> PathBuf {
let mut loader_mods_path = self.dot_minecraft_path();
loader_mods_path.push("mods");
loader_mods_path
}
#[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
pub async fn load_loader_mods(&self) -> CobbleResult<Vec<LoaderMod>> {
load_loader_mods(self.loader_mods_path()).await
}
#[instrument(name = "add_loader_mod", level = "trace", skip_all, fields(src))]
#[cfg_attr(doc_cfg, doc(cfg(feature = "loader-mods")))]
pub async fn add_loader_mod(&self, src: impl AsRef<Path>) -> CobbleResult<Option<LoaderMod>> {
trace!("Validating src...");
if parse_loader_mod(PathBuf::from(src.as_ref()))
.await?
.is_none()
{
return Ok(None);
}
trace!("Building new path for loader_mod");
let file_name = src
.as_ref()
.file_name()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "Path ends with '..'"))?;
let mut loader_mod_path = self.loader_mods_path();
loader_mod_path.push(file_name);
tracing::Span::current().record("dest", loader_mod_path.to_string_lossy().to_string());
if let Some(parent) = loader_mod_path.parent() {
trace!("Creating mods folder...");
create_dir_all(parent).await?;
}
trace!("Copying loader mod...");
tokio::fs::copy(src, &loader_mod_path).await?;
trace!("Parsing new loader mod...");
let loader_mod = parse_loader_mod(loader_mod_path).await?;
Ok(loader_mod)
}
}