aboutsummaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2021-11-06 22:25:23 +0100
committerDaniel Schadt <kingdread@gmx.de>2021-11-06 22:25:23 +0100
commit834a2d4f8a7dbd0e9eb14573c4340eb41af04738 (patch)
treebebd06cc13104fb8e77dc313f2f2ee862eb94a32 /src/game.rs
downloadmodderbaas-834a2d4f8a7dbd0e9eb14573c4340eb41af04738.tar.gz
modderbaas-834a2d4f8a7dbd0e9eb14573c4340eb41af04738.tar.bz2
modderbaas-834a2d4f8a7dbd0e9eb14573c4340eb41af04738.zip
Initial commit
This is the inital commit of a somewhat working version.
Diffstat (limited to 'src/game.rs')
-rw-r--r--src/game.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/game.rs b/src/game.rs
new file mode 100644
index 0000000..f323212
--- /dev/null
+++ b/src/game.rs
@@ -0,0 +1,67 @@
+use std::{
+ fmt,
+ path::{Path, PathBuf},
+};
+
+use super::{
+ error::{Error, Result},
+ minemod::{self, MineMod},
+ scan,
+};
+
+/// Represents an on-disk Minetest game.
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Game {
+ path: PathBuf,
+}
+
+impl Game {
+ /// Open the given directory as a Minetest game.
+ ///
+ /// Note that the path may be relative, but only to the parent directory of the actual game.
+ /// This is because Minetest uses the game's directory name to identify the game
+ /// ([`Game::technical_name`]), so we need this information.
+ pub fn open<P: AsRef<Path>>(path: P) -> Result<Game> {
+ Game::open_path(path.as_ref())
+ }
+
+ fn open_path(path: &Path) -> Result<Game> {
+ if path.file_name().is_none() {
+ return Err(Error::InvalidGameDir(path.into()));
+ }
+ let conf = path.join("game.conf");
+ if !conf.is_file() {
+ return Err(Error::InvalidGameDir(path.into()));
+ }
+
+ Ok(Game { path: path.into() })
+ }
+
+ /// Returns the technical name of this game.
+ ///
+ /// This is the name that is used by minetest to identify the game.
+ pub fn technical_name(&self) -> String {
+ self.path
+ .file_name()
+ .expect("Somebody constructed an invalid `Game`")
+ .to_str()
+ .expect("Non-UTF8 directory encountered")
+ .into()
+ }
+
+ /// Returns all mods that this game provides.
+ pub fn mods(&self) -> Result<Vec<MineMod>> {
+ let path = self.path.join("mods");
+ let mut mods = vec![];
+ for container in scan(&path, |p| minemod::open_mod_or_pack(p))? {
+ mods.extend(container.mods()?);
+ }
+ Ok(mods)
+ }
+}
+
+impl fmt::Display for Game {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.technical_name())
+ }
+}