|
- use std::collections::HashSet;
- use std::env::{current_dir, current_exe};
- use std::fs::File;
- use std::ops::Deref;
-
- use log::info;
-
- use vfs::{
- impls::{overlay::OverlayFS, physical::PhysicalFS},
- VfsPath,
- };
- use vfs_zip::ZipReadOnly as ZipFS;
-
- use crate::Error;
-
- #[derive(Clone)]
- pub struct Vfs(pub VfsPath);
-
- impl Vfs {
- pub fn new() -> Result<Self, Error> {
- let dirs = vec![
- current_exe()
- .ok()
- .as_ref()
- .and_then(|p| p.parent())
- .map(|p| p.to_owned()),
- current_exe()
- .ok()
- .as_ref()
- .and_then(|p| p.parent())
- .map(|p| p.join("space-crush")),
- current_dir().ok(),
- current_dir().ok().map(|p| p.join("space-crush")),
- ]
- .into_iter()
- .filter_map(|d| d);
-
- let mut paths = HashSet::new();
- let mut layers = Vec::new();
-
- for dir in dirs.clone() {
- if paths.insert(dir.clone()) {
- info!("Adding layer to VFS: {}", dir.display());
-
- let layer = VfsPath::new(PhysicalFS::new(dir));
-
- layers.push(layer);
- }
- }
-
- for dir in dirs {
- let path = dir.join("resources.bin");
- if path.is_file() && paths.insert(path.to_owned()) {
- info!("Adding layer to VFS: {}", dir.display());
-
- let zip = File::open(path)?;
- let layer = VfsPath::new(ZipFS::new_relaxed(zip)?);
-
- layers.push(layer);
- }
- }
-
- Ok(Self(VfsPath::new(OverlayFS::new(&layers))))
- }
- }
-
- impl Deref for Vfs {
- type Target = VfsPath;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
- }
|