From 5dc8d0599701cacf13651bdf00149d82e1032c73 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Tue, 9 Nov 2021 20:59:11 +0100 Subject: support the legacy style of mods Those mods might not have a mod.conf and instead define their dependencies in depends.txt. A lot of mods in mineclone2 for example still do that. --- modderbaas/src/minemod.rs | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/modderbaas/src/minemod.rs b/modderbaas/src/minemod.rs index 456d1c6..6be0ab4 100644 --- a/modderbaas/src/minemod.rs +++ b/modderbaas/src/minemod.rs @@ -51,7 +51,8 @@ impl MineMod { fn open_path(path: &Path) -> Result { let conf = path.join("mod.conf"); - if !conf.is_file() { + let depends = path.join("depends.txt"); + if !conf.is_file() && !depends.is_file() { return Err(Error::InvalidModDir(path.into())); } @@ -70,23 +71,49 @@ impl MineMod { /// Read the mod ID. pub fn mod_id(&self) -> Result { + let fallback = self + .path + .file_name() + .map(|s| s.to_str().expect("Non-UTF8 directory encountered")); + let conf = self.read_conf()?; conf.get("name") + .map(String::as_str) + .or(fallback) .map(Into::into) .ok_or_else(|| Error::InvalidModDir(self.path.clone())) } /// Returns all dependencies of this mod. pub fn dependencies(&self) -> Result> { - let conf = self.read_conf()?; - static EMPTY: String = String::new(); - let depstr = conf.get("depends").unwrap_or(&EMPTY); - Ok(depstr - .split(',') - .map(str::trim) - .filter(|s| !s.is_empty()) - .map(Into::into) - .collect()) + // We could do this with Result combinators and default values, but we also don't want to + // end up swallowing errors (like filesystem errors). Therefore, we do some basic checks + // first and propagate the errors. + if self.path.join("mod.conf").is_file() { + // First try to extract dependencies from mod.conf (the new way) + let conf = self.read_conf()?; + if let Some(depstr) = conf.get("depends") { + return Ok(depstr + .split(',') + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(Into::into) + .collect()); + } + } + + if self.path.join("depends.txt").is_file() { + let depstr = fs::read_to_string(self.path.join("depends.txt"))?; + Ok(depstr + .lines() + .filter(|line| !line.ends_with('?')) + .filter(|s| !s.is_empty()) + .map(str::trim) + .map(Into::into) + .collect()) + } else { + Ok(Vec::new()) + } } /// Copies the mod to the given path. -- cgit v1.2.3