#include "asset_source.h" #include #include #include namespace fs = std::filesystem; namespace mtpack { bool AssetSource::build(const std::string &assets_root, const std::string &pack_dir, const std::string &cache_dir, std::string *err) { if (!m_loose.build(assets_root, fmt::AssetResolver::default_priority(), err)) { return false; } if (!pack_dir.empty()) { int n = m_packs.scan_dir(pack_dir); m_have_packs = n > 0; m_cache = !cache_dir.empty() ? cache_dir : (fs::path(pack_dir) / ".mtcache").string(); } return true; } bool AssetSource::exists(const std::string &vpath) const { if (!m_loose.resolve(vpath).empty()) { return true; } return m_have_packs && m_packs.has(vpath); } bool AssetSource::read(const std::string &vpath, std::vector &out, std::string *err) const { std::string lp = m_loose.resolve(vpath); if (!lp.empty()) { std::ifstream f(lp, std::ios::binary); if (f) { out.assign((std::istreambuf_iterator(f)), std::istreambuf_iterator()); return true; } } if (m_have_packs && m_packs.read(vpath, out, err)) { return true; } if (err && err->empty()) { *err = "not found: " + vpath; } return false; } std::string AssetSource::to_path(const std::string &vpath, std::string *err) const { std::string lp = m_loose.resolve(vpath); if (!lp.empty()) { return lp; } if (!m_have_packs || !m_packs.has(vpath)) { if (err) *err = "not found: " + vpath; return ""; } // extract to cache/, once std::string rel = PackMount::norm(vpath); fs::path dst = fs::path(m_cache) / rel; std::error_code ec; if (fs::exists(dst, ec) && fs::file_size(dst, ec) > 0) { return dst.string(); } std::vector bytes; if (!m_packs.read(vpath, bytes, err)) { return ""; } fs::create_directories(dst.parent_path(), ec); std::ofstream o(dst, std::ios::binary | std::ios::trunc); if (!o) { if (err) *err = "cannot write cache file " + dst.string(); return ""; } o.write(reinterpret_cast(bytes.data()), static_cast(bytes.size())); o.close(); return dst.string(); } } // namespace mtpack