diff --git a/lib/filesystem/AdapterLoaders.cpp b/lib/filesystem/AdapterLoaders.cpp index 86d41a009..bd35ef59c 100644 --- a/lib/filesystem/AdapterLoaders.cpp +++ b/lib/filesystem/AdapterLoaders.cpp @@ -56,6 +56,18 @@ std::unordered_set CMappedFileLoader::getFilteredFiles(std::functi return foundID; } +std::string CMappedFileLoader::getFullFileURI(const ResourcePath& resourceName) const +{ + return CResourceHandler::get()->getFullFileURI(fileList.at(resourceName)); +} + +std::time_t CMappedFileLoader::getLastWriteTime(const ResourcePath& resourceName) const +{ + return CResourceHandler::get()->getLastWriteTime(fileList.at(resourceName)); +} + + + CFilesystemList::CFilesystemList() { } @@ -176,7 +188,29 @@ bool CFilesystemList::removeLoader(ISimpleResourceLoader * loader) return true; } } + + return false; } +std::string CFilesystemList::getFullFileURI(const ResourcePath& resourceName) const +{ + for (const auto& loader : boost::adaptors::reverse(loaders)) + if (loader->existsResource(resourceName)) + return loader->getFullFileURI(resourceName); + + throw std::runtime_error("Resource with name " + resourceName.getName() + " and type " + + EResTypeHelper::getEResTypeAsString(resourceName.getType()) + " wasn't found."); +} + +std::time_t CFilesystemList::getLastWriteTime(const ResourcePath& resourceName) const +{ + for (const auto& loader : boost::adaptors::reverse(loaders)) + if (loader->existsResource(resourceName)) + return loader->getLastWriteTime(resourceName); + + throw std::runtime_error("Resource with name " + resourceName.getName() + " and type " + + EResTypeHelper::getEResTypeAsString(resourceName.getType()) + " wasn't found."); +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/filesystem/AdapterLoaders.h b/lib/filesystem/AdapterLoaders.h index f9b7380f0..3b31cc1be 100644 --- a/lib/filesystem/AdapterLoaders.h +++ b/lib/filesystem/AdapterLoaders.h @@ -44,6 +44,8 @@ public: std::optional getResourceName(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override {} std::unordered_set getFilteredFiles(std::function filter) const override; + std::string getFullFileURI(const ResourcePath& resourceName) const override; + std::time_t getLastWriteTime(const ResourcePath& resourceName) const override; private: /** A list of files in this map @@ -77,6 +79,8 @@ public: std::unordered_set getFilteredFiles(std::function filter) const override; bool createResource(const std::string & filename, bool update = false) override; std::vector getResourcesWithName(const ResourcePath & resourceName) const override; + std::string getFullFileURI(const ResourcePath& resourceName) const override; + std::time_t getLastWriteTime(const ResourcePath& resourceName) const override; /** * Adds a resource loader to the loaders list diff --git a/lib/filesystem/CArchiveLoader.cpp b/lib/filesystem/CArchiveLoader.cpp index a571d559f..b4af2fee0 100644 --- a/lib/filesystem/CArchiveLoader.cpp +++ b/lib/filesystem/CArchiveLoader.cpp @@ -15,6 +15,7 @@ #include "CCompressedStream.h" #include "CBinaryReader.h" +#include "../texts/TextOperations.h" VCMI_LIB_NAMESPACE_BEGIN @@ -240,6 +241,19 @@ void CArchiveLoader::extractToFolder(const std::string & outputSubFolder, const extractToFolder(outputSubFolder, *inputStream, entry, absolute); } + +std::string CArchiveLoader::getFullFileURI(const ResourcePath& resourceName) const +{ + auto relativePath = TextOperations::Utf8TofilesystemPath(resourceName.getName()); + auto path = boost::filesystem::canonical(archive) / relativePath; + return TextOperations::filesystemPathToUtf8(path); +} + +std::time_t CArchiveLoader::getLastWriteTime(const ResourcePath& resourceName) const +{ + return boost::filesystem::last_write_time(archive); +} + boost::filesystem::path createExtractedFilePath(const std::string & outputSubFolder, const std::string & entryName, bool absolute) { boost::filesystem::path extractionFolderPath = absolute ? outputSubFolder : VCMIDirs::get().userExtractedPath() / outputSubFolder; diff --git a/lib/filesystem/CArchiveLoader.h b/lib/filesystem/CArchiveLoader.h index d8797d7a5..1cdb99df6 100644 --- a/lib/filesystem/CArchiveLoader.h +++ b/lib/filesystem/CArchiveLoader.h @@ -70,6 +70,8 @@ public: void extractToFolder(const std::string & outputSubFolder, CInputStream & fileStream, const ArchiveEntry & entry, bool absolute = false) const; /** Extracts one archive entry to the specified subfolder. Used for Images, Sprites, etc */ void extractToFolder(const std::string & outputSubFolder, const std::string & mountPoint, ArchiveEntry entry, bool absolute = false) const; + std::string getFullFileURI(const ResourcePath& resourceName) const override; + std::time_t getLastWriteTime(const ResourcePath& resourceName) const override; private: /** diff --git a/lib/filesystem/CFilesystemLoader.cpp b/lib/filesystem/CFilesystemLoader.cpp index 34f09f1d8..a29e69440 100644 --- a/lib/filesystem/CFilesystemLoader.cpp +++ b/lib/filesystem/CFilesystemLoader.cpp @@ -198,4 +198,17 @@ std::unordered_map CFilesystemLoader::lis return fileList; } +std::string CFilesystemLoader::getFullFileURI(const ResourcePath& resourceName) const +{ + auto filePath = getResourceName(resourceName); + auto path = boost::filesystem::canonical(*filePath); + return TextOperations::filesystemPathToUtf8(path); +} + +std::time_t CFilesystemLoader::getLastWriteTime(const ResourcePath& resourceName) const +{ + auto resourcePath = getResourceName(resourceName); + return boost::filesystem::last_write_time(*resourcePath); +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/filesystem/CFilesystemLoader.h b/lib/filesystem/CFilesystemLoader.h index ec75c62a0..0b0f8661e 100644 --- a/lib/filesystem/CFilesystemLoader.h +++ b/lib/filesystem/CFilesystemLoader.h @@ -41,6 +41,8 @@ public: std::optional getResourceName(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override; std::unordered_set getFilteredFiles(std::function filter) const override; + std::string getFullFileURI(const ResourcePath& resourceName) const override; + std::time_t getLastWriteTime(const ResourcePath& resourceName) const override; private: /** The base directory which is scanned and indexed. */ diff --git a/lib/filesystem/CZipLoader.cpp b/lib/filesystem/CZipLoader.cpp index dad7943c1..2e9555a5a 100644 --- a/lib/filesystem/CZipLoader.cpp +++ b/lib/filesystem/CZipLoader.cpp @@ -11,6 +11,7 @@ #include "CZipLoader.h" #include "../ScopeGuard.h" +#include "../texts/TextOperations.h" VCMI_LIB_NAMESPACE_BEGIN @@ -120,6 +121,19 @@ std::unordered_set CZipLoader::getFilteredFiles(std::function filter) const override {} std::unordered_set getFilteredFiles(std::function filter) const override; + std::string getFullFileURI(const ResourcePath& resourceName) const override; + std::time_t getLastWriteTime(const ResourcePath& resourceName) const override; }; class DLL_LINKAGE ZipArchive : boost::noncopyable diff --git a/lib/filesystem/ISimpleResourceLoader.h b/lib/filesystem/ISimpleResourceLoader.h index 06b7c9a65..6f0b87214 100644 --- a/lib/filesystem/ISimpleResourceLoader.h +++ b/lib/filesystem/ISimpleResourceLoader.h @@ -106,6 +106,10 @@ public: return std::vector(1, this); return std::vector(); } + + virtual std::string getFullFileURI(const ResourcePath& resourceName) const = 0; + + virtual std::time_t getLastWriteTime(const ResourcePath& resourceName) const = 0; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/mapping/CMapInfo.cpp b/lib/mapping/CMapInfo.cpp index 3bc1b42ab..b33be7c96 100644 --- a/lib/mapping/CMapInfo.cpp +++ b/lib/mapping/CMapInfo.cpp @@ -38,11 +38,6 @@ CMapInfo::CMapInfo() CMapInfo::~CMapInfo() = default; -std::string CMapInfo::getFullFileURI(const ResourcePath & file) const -{ - auto path = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(file)); - return TextOperations::filesystemPathToUtf8(path); -} void CMapInfo::mapInit(const std::string & fname) { @@ -50,9 +45,9 @@ void CMapInfo::mapInit(const std::string & fname) CMapService mapService; ResourcePath resource = ResourcePath(fname, EResType::MAP); originalFileURI = resource.getOriginalName(); - fullFileURI = getFullFileURI(resource); + fullFileURI = CResourceHandler::get()->getFullFileURI(resource); mapHeader = mapService.loadMapHeader(resource); - lastWrite = boost::filesystem::last_write_time(*CResourceHandler::get()->getResourceName(resource)); + lastWrite = CResourceHandler::get()->getLastWriteTime(resource); date = TextOperations::getFormattedDateTimeLocal(lastWrite); countPlayers(); } @@ -71,9 +66,9 @@ void CMapInfo::saveInit(const ResourcePath & file) fileURI = file.getName(); originalFileURI = file.getOriginalName(); - fullFileURI = getFullFileURI(file); + fullFileURI = CResourceHandler::get()->getFullFileURI(file); countPlayers(); - lastWrite = boost::filesystem::last_write_time(*CResourceHandler::get()->getResourceName(file)); + lastWrite = CResourceHandler::get()->getLastWriteTime(file); date = TextOperations::getFormattedDateTimeLocal(lastWrite); // We absolutely not need this data for lobby and server will read it from save @@ -85,7 +80,7 @@ void CMapInfo::campaignInit() { ResourcePath resource = ResourcePath(fileURI, EResType::CAMPAIGN); originalFileURI = resource.getOriginalName(); - fullFileURI = getFullFileURI(resource); + fullFileURI = CResourceHandler::get()->getFullFileURI(resource); campaign = CampaignHandler::getHeader(fileURI); lastWrite = boost::filesystem::last_write_time(*CResourceHandler::get()->getResourceName(resource)); date = TextOperations::getFormattedDateTimeLocal(lastWrite); diff --git a/lib/mapping/CMapInfo.h b/lib/mapping/CMapInfo.h index bc9e5fd17..64340956b 100644 --- a/lib/mapping/CMapInfo.h +++ b/lib/mapping/CMapInfo.h @@ -48,7 +48,6 @@ public: CMapInfo &operator=(CMapInfo &&other) = delete; CMapInfo &operator=(const CMapInfo &other) = delete; - std::string getFullFileURI(const ResourcePath& file) const; void mapInit(const std::string & fname); void saveInit(const ResourcePath & file); void campaignInit();