/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Got rid of unzip usage, now using ZipDir for much more effective // memory usage (~3-6 times less memory, and no allocator overhead) // to keep the directory of the zip file; better overall effectiveness and // more readable and manageable code, made the connection to Streaming Engine #ifndef CRYINCLUDE_CRYSYSTEM_CRYPAK_H #define CRYINCLUDE_CRYSYSTEM_CRYPAK_H #pragma once #include <ICryPak.h> #include <CryThread.h> #include "IMiniLog.h" #include "ZipDir.h" #include "MTSafeAllocator.h" #include "StlUtils.h" #include "PakVars.h" #include <VectorMap.h> #include "IPerfHud.h" #include "System.h" #include <unordered_map> // remove after https://issues.labcollab.net/browse/LMBR-17710 is resolved #include <AzCore/std/parallel/mutex.h> #include <AzCore/std/parallel/lock.h> #include <AzCore/std/smart_ptr/unique_ptr.h> #include <AzCore/std/smart_ptr/shared_ptr.h> #include <AzCore/IO/CompressionBus.h> class CCryPak; namespace AzFramework { class AssetBundleManifest; class AssetRegistry; } // this is the header in the cache of the file data struct CCachedFileData : public _i_reference_target_t { CCachedFileData (class CCryPak* pPak, ZipDir::Cache* pZip, unsigned int nArchiveFlags, ZipDir::FileEntry* pFileEntry, const char* szFilename); ~CCachedFileData(); // return the data in the file, or NULL if error // by default, if bRefreshCache is true, and the data isn't in the cache already, // the cache is refreshed. Otherwise, it returns whatever cache is (NULL if the data isn't cached yet) // decompress and decrypt can be harmlessly set to true if you want the data back decrypted/decompressed. // set them to false only if you want to operate on the raw data while its still encrypted/compressed. void* GetData(bool bRefreshCache = true, bool decompress = true, bool decrypt = true); // Uncompress file data directly to provided memory. bool GetDataTo(void* pFileData, int nDataSize, bool bDecompress = true); // Return number of copied bytes, or -1 if did not read anything int64 ReadData(void* pBuffer, int64 nFileOffset, int64 nReadSize); ILINE ZipDir::Cache* GetZip(){return m_pZip; } ILINE ZipDir::FileEntry* GetFileEntry() {return m_pFileEntry; } /* // the memory needs to be allocated out of a MT-safe heap here void * __cdecl operator new (size_t size) { return g_pPakHeap->Alloc(size, "CCachedFileData::new"); } void * __cdecl operator new (size_t size, const std::nothrow_t ¬hrow) { return g_pPakHeap->Alloc(size, "CCachedFileData::new(std::nothrow)"); } void __cdecl operator delete (void *p) { g_pPakHeap->Free(p); }; */ unsigned GetFileDataOffset() { return m_pZip->GetFileDataOffset(m_pFileEntry); } size_t sizeofThis() const { return sizeof(*this) + (m_pFileData && m_pFileEntry ? m_pFileEntry->desc.lSizeUncompressed : 0); } void GetMemoryUsage(ICrySizer* pSizer) const { pSizer->AddObject(m_pZip); pSizer->AddObject(m_pFileEntry); } // need to overload addref and release to prevent a race condition in virtual void AddRef(); virtual void Release(); public: void* m_pFileData; // the zip file in which this file is opened ZipDir::CachePtr m_pZip; unsigned int m_nArchiveFlags; // the file entry : if this is NULL, the entry is free and all the other fields are meaningless ZipDir::FileEntry* m_pFileEntry; class CCryPak* m_pPak; #ifdef _DEBUG string m_sDebugFilename; #endif // file I/O guard: guarantees thread-safe decompression operation and safe allocation CryCriticalSection m_csDecompressDecryptLock; private: CCachedFileData(const CCachedFileData&); CCachedFileData& operator = (const CCachedFileData&); }; TYPEDEF_AUTOPTR(CCachedFileData); typedef CCachedFileData_AutoPtr CCachedFileDataPtr; ////////////////////////////////////////////////////////////////////////// struct CCachedFileRawData { void* m_pCachedData; CCachedFileRawData(int nAlloc); ~CCachedFileRawData(); }; // an (inside zip) emultated open file struct CZipPseudoFile { CZipPseudoFile() { Construct(); } ~CZipPseudoFile() { } enum { _O_COMMIT_FLUSH_MODE = 1 << 31, _O_DIRECT_OPERATION = 1 << 30 }; // this object must be constructed before usage // nFlags is a combination of _O_... flags void Construct(CCachedFileData* pFileData = NULL, unsigned nFlags = 0); // this object needs to be freed manually when the CryPak shuts down.. void Destruct(); CCachedFileData* GetFile() {return m_pFileData; } long FTell() {return m_nCurSeek; } unsigned GetFileSize() { return GetFile() ? GetFile()->GetFileEntry()->desc.lSizeUncompressed : 0; } int FSeek (long nOffset, int nMode); size_t FRead(void* pDest, size_t nSize, size_t nCount, AZ::IO::HandleType fileHandle); size_t FReadAll(void* pDest, size_t nFileSize, AZ::IO::HandleType fileHandle); void* GetFileData(size_t& nFileSize, AZ::IO::HandleType fileHandle); int FEof(); char* FGets(char* pBuf, int n); int Getc(); int Ungetc(int c); uint64 GetModificationTime() { return m_pFileData->GetFileEntry()->GetModificationTime(); } const char* GetArchivePath() { return m_pFileData->GetZip()->GetFilePath(); } void GetMemoryUsage(ICrySizer* pSizer) const { pSizer->AddObject(m_pFileData); } protected: unsigned long m_nCurSeek; CCachedFileDataPtr m_pFileData; // nFlags is a combination of _O_... flags unsigned m_nFlags; }; struct CIStringOrder { bool operator () (const string& left, const string& right) const { return _stricmp(left.c_str(), right.c_str()) < 0; } }; class CCryPakFindData : public _reference_target_t { public: // the directory wildcard must already be adjusted CCryPakFindData (); bool empty() const; bool Fetch(_finddata_t* pfd); virtual void Scan(CCryPak* pPak, const char* szDir, bool bAllowUseFS = false); size_t sizeofThis() const; void GetMemoryUsage(ICrySizer* pSizer) const; protected: void ScanFS(CCryPak* pPak, const char* szDir); void ScanZips(CCryPak* pPak, const char* szDir); struct FileDesc { unsigned nAttrib; unsigned nSize; time_t tAccess; time_t tCreate; time_t tWrite; FileDesc (struct _finddata_t* fd); FileDesc (struct __finddata64_t* fd); FileDesc (ZipDir::FileEntry* fe); // default initialization is as a directory entry FileDesc (); void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/} }; typedef std::map<string, FileDesc, CIStringOrder> FileMap; FileMap m_mapFiles; }; TYPEDEF_AUTOPTR(CCryPakFindData); ////////////////////////////////////////////////////////////////////// class CCryPak : public ICryPak , public ISystemEventListener , public AZ::IO::CompressionBus::Handler { friend class CReadStream; friend struct CCachedFileData; static const uint32_t s_compressionTag = static_cast<uint32_t>('Z') << 24 | static_cast<uint32_t>('C') << 16 | static_cast<uint32_t>('R') << 8 | static_cast<uint32_t>('Y'); // the array of pseudo-files : emulated files in the virtual zip file system // the handle to the file is its index inside this array. // some of the entries can be free. The entries need to be destructed manually CryReadModifyLock m_csOpenFiles; typedef std::vector<CZipPseudoFile*> ZipPseudoFileArray; ZipPseudoFileArray m_arrOpenFiles; // the array of file datas; they are relatively self-contained and can // read and cache the file data on-demand. It's up to the clients // to use caching or access the zips directly CryReadModifyLock m_csCachedFiles; typedef std::vector<CCachedFileData*> CachedFileDataSet; CachedFileDataSet m_setCachedFiles; // Swith to AZStd::unordered_map after https://issues.labcollab.net/browse/LMBR-17710 is resolved // This is a cached data for the FGetCachedFileData call. struct CachedRawDataEntry { AZStd::unique_ptr<CCachedFileRawData> m_data; size_t m_fileSize = 0; }; using CachedFileRawDataSet = std::unordered_map<AZ::IO::HandleType, CachedRawDataEntry>; CachedFileRawDataSet m_cachedFileRawDataSet; // For m_pCachedFileRawDataSet AZStd::mutex m_cachedFileRawDataMutex; using RawDataCacheLockGuard = AZStd::lock_guard<decltype(m_cachedFileRawDataMutex)>; // The F* emulation functions critical sectio: protects all F* functions // that don't have a chance to be called recursively (to avoid deadlocks) CryReadModifyLock m_csMain; // open zip cache objects that can be reused. They're self-[un]registered // they're sorted by the path and typedef std::vector<ICryArchive*> ArchiveArray; ArchiveArray m_arrArchives; //Pak file comment data. Supplied in key=value pairs in the zip archive file comment typedef VectorMap<string, string> TCommentDataMap; typedef std::pair<string, string> TCommentDataPair; // the array of opened caches - they get destructed by themselves (these are auto-pointers, see the ZipDir::Cache documentation) struct PackDesc { string strBindRoot; // the zip binding root WITH the trailing native slash string strFileName; // the zip file name (with path) - very useful for debugging so please don't remove bool m_containsLevelPak = false; // indicates whether this pak has level.pak inside it or not TCommentDataMap m_commentData; //VectorMap of key=value pairs from the zip archive comments const char* GetFullPath() const {return pZip->GetFilePath(); } ICryArchive_AutoPtr pArchive; ZipDir::CachePtr pZip; size_t sizeofThis() { return strBindRoot.capacity() + strFileName.capacity() + pZip->GetSize(); } void GetMemoryUsage(ICrySizer* pSizer) const { pSizer->AddObject(strBindRoot); pSizer->AddObject(strFileName); pSizer->AddObject(pArchive); pSizer->AddObject(pZip); pSizer->AddObject(m_containsLevelPak); } }; typedef std::vector<PackDesc, stl::STLGlobalAllocator<PackDesc> > ZipArray; CryReadModifyLock m_csZips; ZipArray m_arrZips; friend class CCryPakFindData; protected: CryReadModifyLock m_csFindData; typedef std::set<CCryPakFindData_AutoPtr> CryPakFindDataSet; CryPakFindDataSet m_setFindData; // given the source relative path, constructs the full path to the file according to the flags const char* AdjustFileNameImpl(const char* src, char* dst, size_t dstSize, unsigned nFlags, bool skipMods) override; // LY Bundle Management // Handle our initial LY Canonical "Bundles" which contain manifest info and update our Asset Registry as // Loaded and Unloaded bool OpenBundle(ZipDir::CachePtr zipEntry); bool CloseBundle(ZipDir::CachePtr zipEntry); // Retrieve the manifest from the Bundle if it exists AZStd::unique_ptr<AzFramework::AssetBundleManifest> LoadManifest(ZipDir::CachePtr zipEntry) const; // Retrieve the Catalog name from the bundle AZStd::string GetCatalogName(AZStd::unique_ptr<const AzFramework::AssetBundleManifest>& bundleManifest) const; private: IMiniLog* m_pLog; // the root: "C:\MasterCD\" string m_strDataRoot; string m_strDataRootWithSlash; bool m_bInstalledToHDD; // this is the list of MOD subdirectories that will be prepended to the actual relative file path // they all have trailing forward slash. "" means the root dir std::vector<string> m_arrMods; ////////////////////////////////////////////////////////////////////////// // Opened files collector. ////////////////////////////////////////////////////////////////////////// ICryPak::ERecordFileOpenList m_eRecordFileOpenList; typedef std::set<string, stl::less_stricmp<string> > RecordedFilesSet; RecordedFilesSet m_recordedFilesSet; _smart_ptr<IResourceList> m_pEngineStartupResourceList; _smart_ptr<IResourceList> m_pLevelResourceList; _smart_ptr<IResourceList> m_pNextLevelResourceList; _smart_ptr<ICustomMemoryHeap> m_pInMemoryPaksCPUHeap; ITimer* m_pITimer; float m_fFileAcessTime; // Time used to perform file operations std::vector<ICryPakFileAcesssSink*> m_FileAccessSinks; // useful for gathering file access statistics const PakVars* m_pPakVars; bool m_bLvlRes; // if asset tracking is enabled for GetResourceList() - all assets since executable start are recorded bool m_bGameFolderWritable; bool m_disableRuntimeFileAccess[2]; //threads which we don't want to access files from during the game threadID m_mainThreadId; threadID m_renderThreadId; CryFixedStringT<128> m_sLocalizationFolder; CryFixedStringT<128> m_sLocalizationRoot; ////////////////////////////////////////////////////////////////////////// private: bool InitPack(const char* szBasePath, unsigned nFlags = FLAGS_PATH_REAL); const char* AdjustFileNameInternal(const char* src, char* dst, size_t dstSize, unsigned nFlags); /** * Currently access to PseudoFile operations are not thread safe, as we touch variable like m_nCurSeek * without any synchronization. There is also the assumption that only one thread at a time will open/read/close * a single file in a PAK, multiple threads can open different files in a PAK. If requirements change (or turns out this is a bug in CryPAK) * we can add readwrite lock inside the CZipPseudoFile and we can pass a second argument lockForOperation where we can lock * the file specific lock while getting a handle. This way you can safely execute the operation. This is no done by default * because the API implies that this is not the intended use case. e.g. FSeek and FRead are separate operations, if you have multiple threads * reading data, they can both execute FSeek/FRead and unless we lock the operation set, this will not work. */ CZipPseudoFile* GetPseudoFile(AZ::IO::HandleType fileHandle) const; public: // this is the start of indexation of pseudofiles: // to the actual index , this offset is added to get the valid handle enum { g_nPseudoFileIdxOffset = 1 }; // this defines which slash will be kept internally #if AZ_LEGACY_CRYSYSTEM_TRAIT_CRYPAK_POSIX enum { g_cNativeSlash = '/', g_cNonNativeSlash = '\\' }; #else enum { g_cNativeSlash = '\\', g_cNonNativeSlash = '/' }; #endif // makes the path lower-case (if requested) and removes the duplicate and non native slashes // may make some other fool-proof stuff // may NOT write beyond the string buffer (may not make it longer) // returns: the pointer to the ending terminator \0 static char* BeautifyPath(char* dst, bool bMakeLowercase); static void RemoveRelativeParts(char* dst); CCryPak(IMiniLog* pLog, PakVars* pPakVars, const bool bLvlRes, const IGameStartup* pGameStartup); ~CCryPak(); const PakVars* GetPakVars() const {return m_pPakVars; } public: // --------------------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // ISystemEventListener implementation. ////////////////////////////////////////////////////////////////////////// virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); ////////////////////////////////////////////////////////////////////////// //@{ CompressionBus Handler implementation. void FindCompressionInfo(bool& found, AZ::IO::CompressionInfo& info, const AZStd::string_view filename) override; //@} ICryPak::PakInfo* GetPakInfo(); void FreePakInfo (PakInfo*); // Set from outside if game folder is writable void SetGameFolderWritable(bool bWritable); void SetLog(IMiniLog* pLog); //! adds a mod to the list of mods void AddMod(const char* szMod); //! removes a mod from the list of mods void RemoveMod(const char* szMod); //! returns indexed mod path, or NULL if out of range virtual const char* GetMod(int index); //! Processes an alias command line containing multiple aliases. void ParseAliases(const char* szCommandLine); //! adds or removes an alias from the list - if bAdd set to false will remove it void SetAlias(const char* szName, const char* szAlias, bool bAdd); //! gets an alias from the list, if any exist. //! if bReturnSame==true, it will return the input name if an alias doesn't exist. Otherwise returns NULL const char* GetAlias(const char* szName, bool bReturnSame = true); // Set the localization folder virtual void SetLocalizationFolder(const char* sLocalizationFolder); virtual const char* GetLocalizationFolder() const { return m_sLocalizationFolder.c_str(); } virtual const char* GetLocalizationRoot() const { return m_sLocalizationRoot.c_str(); } // Only returns useful results on a dedicated server at present - and only if the pak is already opened void GetCachedPakCDROffsetSize(const char* szName, uint32& offset, uint32& size); //! Puts the memory statistics into the given sizer object //! According to the specifications in interface ICrySizer void GetMemoryStatistics(ICrySizer* pSizer); // lock all the operations virtual void Lock(); virtual void Unlock(); // open the physical archive file - creates if it doesn't exist // returns NULL if it's invalid or can't open the file virtual ICryArchive* OpenArchive (const char* szPath, const char* bindRoot = nullptr, unsigned int nFlags = 0, IMemoryBlock* pData = 0); // returns the path to the archive in which the file was opened virtual const char* GetFileArchivePath(AZ::IO::HandleType fileHandle); void Register (CCachedFileData* p) { // actually, registration may only happen when the set is already locked, but for generality.. AUTO_MODIFYLOCK(m_csCachedFiles); m_setCachedFiles.push_back(p); } void Unregister (CCachedFileData* p) { AUTO_MODIFYLOCK(m_csCachedFiles); stl::find_and_erase(m_setCachedFiles, p); } // Get access to the special memory heap used to preload pak files into memory. ICustomMemoryHeap* GetInMemoryPakHeap(); ////////////////////////////////////////////////////////////////////////// //! Return pointer to pool if available virtual void* PoolMalloc(size_t size); //! Free pool virtual void PoolFree(void* p); virtual IMemoryBlock* PoolAllocMemoryBlock(size_t nSize, const char* sUsage, size_t nAlign); // interface ICryPak --------------------------------------------------------------------------- virtual void RegisterFileAccessSink(ICryPakFileAcesssSink* pSink); virtual void UnregisterFileAccessSink(ICryPakFileAcesssSink* pSink); virtual bool GetLvlResStatus() const { return m_bLvlRes; } virtual bool Init (const char* szBasePath); virtual void Release(); virtual bool IsInstalledToHDD(const char* acFilePath = 0) const; void SetInstalledToHDD(bool bValue); virtual bool OpenPack(const char* pName, unsigned nFlags = 0, IMemoryBlock* pData = 0, CryFixedStringT<ICryPak::g_nMaxPath>* pFullPath = NULL, bool addLevels = true); virtual bool OpenPack(const char* szBindRoot, const char* pName, unsigned nFlags = 0, IMemoryBlock* pData = 0, CryFixedStringT<ICryPak::g_nMaxPath>* pFullPath = NULL, bool addLevels = true); // after this call, the file will be unlocked and closed, and its contents won't be used to search for files virtual bool ClosePack(const char* pName, unsigned nFlags = 0); virtual bool OpenPacks(const char* pWildcard, unsigned nFlags = 0, std::vector< CryFixedStringT<ICryPak::g_nMaxPath> >* pFullPaths = NULL); virtual bool OpenPacks(const char* szBindRoot, const char* pWildcard, unsigned nFlags = 0, std::vector< CryFixedStringT<ICryPak::g_nMaxPath> >* pFullPaths = NULL); bool OpenPackCommon(const char* szBindRoot, const char* pName, unsigned int nPakFlags, IMemoryBlock* pData = 0, bool addLevels = true); bool OpenPacksCommon(const char* szDir, const char* pWildcardIn, char* cWork, int nPakFlags, std::vector< CryFixedStringT<ICryPak::g_nMaxPath> >* pFullPaths = NULL, bool addLevels = true); // closes pack files by the path and wildcard virtual bool ClosePacks(const char* pWildcard, unsigned nFlags = 0); //returns if a pak exists matching the wildcard virtual bool FindPacks(const char* pWildcardIn); // prevent access to specific pak files bool SetPacksAccessible(bool bAccessible, const char* pWildcard, unsigned nFlags = 0); bool SetPackAccessible(bool bAccessible, const char* pName, unsigned nFlags = 0); void SetPacksAccessibleForLevel(const char* sLevelName); // Remount the packs to another file system typedef bool (* CBShouldPackReOpen)(const char* filePath); int RemountPacks(DynArray<AZ::IO::HandleType>& outHandlesToClose, CBShouldPackReOpen shouldPackReOpen); //ReOpen pak file - used for devices when pak is successfully cached to HDD bool ReOpenPack(const char* pPath); // returns the file modification time virtual uint64 GetModificationTime(AZ::IO::HandleType fileHandle); // this function gets the file data for the given file, if found. // The file data object may be created in this function, // and it's important that the autoptr is returned: another thread may release the existing // cached data before the function returns // the path must be absolute normalized lower-case with forward-slashes CCachedFileDataPtr GetFileData(const char* szName, unsigned int& nArchiveFlags, ZipDir::CachePtr* pZip = 0); CCachedFileDataPtr GetFileData(const char* szName){unsigned int archiveFlags; return GetFileData(szName, archiveFlags); } // Get the data for a file by name within an archive if it exists CCachedFileDataPtr GetFileData(ZipDir::CachePtr pZip, const char* szName); //! Return the Manifest from a bundle, if it exists AZStd::shared_ptr<AzFramework::AssetBundleManifest> GetBundleManifest(ZipDir::CachePtr pZip); AZStd::shared_ptr<AzFramework::AssetRegistry> GetBundleCatalog(ZipDir::CachePtr pZip, const AZStd::string& catalogName); //! Checks the archive for any levels and returns a list of levels folder. //! We check for levels by searching for the level.pak file. AZStd::vector<AZStd::string> ScanForLevels(ZipDir::CachePtr pZip); // Return cached file data for entries inside pak file. CCachedFileDataPtr GetOpenedFileDataInZip(AZ::IO::HandleType file); // tests if the given file path refers to an existing file inside registered (opened) packs // the path must be absolute normalized lower-case with forward-slashes bool WillOpenFromPak(const char* szPath); ZipDir::FileEntry* FindPakFileEntry(const char* szPath, unsigned int& nArchiveFlags, ZipDir::CachePtr* pZip = 0, bool bSkipInMemoryPaks = false); ZipDir::FileEntry* FindPakFileEntry(const char* szPath){unsigned int flags; return FindPakFileEntry(szPath, flags); } virtual bool LoadPakToMemory(const char* pName, EInMemoryPakLocation nLoadPakToMemory, IMemoryBlock* pMemoryBlock = NULL); virtual void LoadPaksToMemory(int nMaxPakSize, bool bLoadToMemory); virtual const char* GetDirectoryDelimiter() const; virtual AZ::IO::HandleType FOpen(const char* pName, const char* mode, unsigned nPathFlags = 0); virtual AZ::IO::HandleType FOpen(const char* pName, const char* mode, char* szFileGamePath, int nLen); virtual size_t FReadRaw(void* data, size_t length, size_t elems, AZ::IO::HandleType handle); virtual size_t FReadRawAll(void* data, size_t nFileSize, AZ::IO::HandleType handle); virtual void* FGetCachedFileData(AZ::IO::HandleType handle, size_t& nFileSize); virtual size_t FWrite(const void* data, size_t length, size_t elems, AZ::IO::HandleType handle); virtual size_t FSeek(AZ::IO::HandleType handle, long seek, int mode); virtual long FTell(AZ::IO::HandleType handle); virtual int FFlush(AZ::IO::HandleType handle); virtual int FClose(AZ::IO::HandleType handle); virtual intptr_t FindFirst(const char* pDir, _finddata_t* fd, unsigned int nPathFlags = 0, bool bAllOwUseFileSystem = false); virtual int FindNext(intptr_t handle, _finddata_t* fd); virtual int FindClose(intptr_t handle); virtual int FEof(AZ::IO::HandleType handle); virtual char* FGets(char*, int, AZ::IO::HandleType); virtual int Getc(AZ::IO::HandleType); virtual int Ungetc(int c, AZ::IO::HandleType); virtual int FPrintf(AZ::IO::HandleType handle, const char* format, ...) PRINTF_PARAMS(3, 4); virtual size_t FGetSize(AZ::IO::HandleType fileHandle); virtual size_t FGetSize(const char* sFilename, bool bAllowUseFileSystem = false); virtual bool IsInPak(AZ::IO::HandleType handle); virtual bool RemoveFile(const char* pName); // remove file from FS (if supported) virtual bool RemoveDir(const char* pName); // remove directory from FS (if supported) virtual bool IsAbsPath(const char* pPath); virtual CCryPakFindData* CreateFindData(); virtual bool CopyFileOnDisk(const char* source, const char* dest, bool bFailIfExist); virtual bool IsFileExist(const char* sFilename, EFileSearchLocation fileLocation = eFileLocation_Any); virtual bool IsFolder(const char* sPath); virtual bool IsFileCompressed(const char* filename); virtual ICryPak::SignedFileSize GetFileSizeOnDisk(const char* filename); // creates a directory virtual bool MakeDir (const char* szPath, bool bGamePathMapping = false); // returns the current game directory, with trailing slash (or empty string if it's right in MasterCD) // this is used to support Resource Compiler which doesn't have access to this interface: // in case all the contents is located in a subdirectory of MasterCD, this string is the subdirectory name with slash //virtual const char* GetGameDir(); void Register (ICryArchive* pArchive); void Unregister (ICryArchive* pArchive); ICryArchive* FindArchive (const char* szFullPath); const ICryArchive* FindArchive (const char* szFullPath) const; // compresses the raw data into raw data. The buffer for compressed data itself with the heap passed. Uses method 8 (deflate) // returns one of the Z_* errors (Z_OK upon success) // MT-safe int RawCompress (const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel = -1); // Uncompresses raw (without wrapping) data that is compressed with method 8 (deflated) in the Zip file // returns one of the Z_* errors (Z_OK upon success) // This function just mimics the standard uncompress (with modification taken from unzReadCurrentFile) // with 2 differences: there are no 16-bit checks, and // it initializes the inflation to start without waiting for compression method byte, as this is the // way it's stored into zip file int RawUncompress (void* pUncompressed, unsigned long* pDestSize, const void* pCompressed, unsigned long nSrcSize); ////////////////////////////////////////////////////////////////////////// // Files opening recorder. ////////////////////////////////////////////////////////////////////////// void RecordFileOpen(ERecordFileOpenList eMode); ICryPak::ERecordFileOpenList GetRecordFileOpenList(); void RecordFile(AZ::IO::HandleType in, const char* szFilename); void CheckFileAccess(const char* szFilename); virtual IResourceList* GetResourceList(ERecordFileOpenList eList); virtual void SetResourceList(ERecordFileOpenList eList, IResourceList* pResourceList); virtual uint32 ComputeCRC(const char* szPath, uint32 nFileOpenFlags = 0); virtual bool ComputeMD5(const char* szPath, unsigned char* md5, uint32 nFileOpenFlags = 0, bool useDirectFileAccess = false); int ComputeCachedPakCDR_CRC(ZipDir::CachePtr pInZip); virtual int ComputeCachedPakCDR_CRC(const char* filename, bool useCryFile /*=true*/, IMemoryBlock* pData /*=NULL*/); void OnMissingFile (const char* szPath); virtual void DisableRuntimeFileAccess(bool status) { m_disableRuntimeFileAccess[0] = status; m_disableRuntimeFileAccess[1] = status; } virtual bool DisableRuntimeFileAccess(bool status, threadID threadId); virtual bool CheckFileAccessDisabled(const char* name, const char* mode); void LogFileAccessCallStack(const char* name, const char* nameFull, const char* mode); virtual void SetRenderThreadId(threadID renderThreadId) { m_renderThreadId = renderThreadId; } // missing file -> count of missing files CryCriticalSection m_csMissingFiles; typedef std::map<string, uint32, std::less<string> > MissingFileMap; MissingFileMap m_mapMissingFiles; bool m_warnedCryMissingFilesDeprecated = false; friend struct SAutoCollectFileAcessTime; std::set< uint32, std::less<uint32>, stl::STLGlobalAllocator<uint32> > m_filesCachedOnHDD; // gets the current pak priority virtual int GetPakPriority(); virtual uint64 GetFileOffsetOnMedia(const char* szName); virtual EStreamSourceMediaType GetFileMediaType(const char* szName); EStreamSourceMediaType GetMediaType(ZipDir::Cache* pCache, unsigned int nArchiveFlags); virtual void CreatePerfHUDWidget(); #if AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM private: intptr_t m_HandleSource; std::map<intptr_t, CCryPakFindData* > m_Handles; #endif //PerfHUD Widget for tracking open pak files: class CPakFileWidget : public ICryPerfHUDWidget { public: CPakFileWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud, CCryPak* pPak); ~CPakFileWidget() {} virtual void Reset() {} virtual void Update(); virtual bool ShouldUpdate() { return !m_pTable->IsHidden(); } virtual void LoadBudgets(XmlNodeRef perfXML) {} virtual void SaveStats(XmlNodeRef statsXML) {} virtual void Enable(int mode) { m_pTable->Hide(false); } virtual void Disable() { m_pTable->Hide(true); } protected: minigui::IMiniTable* m_pTable; CCryPak* m_pPak; }; CPakFileWidget* m_pWidget; }; namespace CryPakInternal { // Utility function to de-alias pak file opening and file-within-pak opening // if the file specified was an absolute path but it points at one of the aliases, de-alias it and replace it with that alias. // this works around problems where the level editor is in control but still mounts asset packs (ie, level.pak mounted as @assets@) // it is assumed that the path is already converted to forward slashes, lowcased, and normalized AZ::Outcome<string, AZStd::string> ConvertAbsolutePathToAliasedPath(const char* sourcePath, const char* aliasToLookFor = "@devassets@", const char* aliasToReplaceWith = "@assets@"); } #endif // CRYINCLUDE_CRYSYSTEM_CRYPAK_H