From 277cdf67b0c440c4518ba675891c7217f68bd06c Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Fri, 17 Dec 2021 21:16:42 -0500 Subject: [PATCH 01/20] * Feature: Initial secure VFS implementation with asset import capability. --- Engine/source/T3D/assets/assetImporter.cpp | 52 +++++++++++-- Engine/source/core/volume.cpp | 27 +++++++ Engine/source/core/volume.h | 4 + Engine/source/persistence/taml/taml.cpp | 7 +- Engine/source/platform/platformVolume.cpp | 30 ++++++++ Engine/source/platformPOSIX/posixVolume.cpp | 2 + Engine/source/platformWin32/winVolume.cpp | 2 + .../source/windowManager/sdl/sdlWindowMgr.cpp | 76 +++++++++++++++++++ .../source/windowManager/sdl/sdlWindowMgr.h | 18 +++++ .../utility/scripts/helperFunctions.tscript | 2 +- Tools/CMake/torque3d.cmake | 5 +- Tools/CMake/torqueConfig.h.in | 5 +- 12 files changed, 220 insertions(+), 10 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 7c0bda9ae..221e776dd 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2660,8 +2660,16 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) char qualifiedFromFile[2048]; char qualifiedToFile[2048]; +#ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); +#else + dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); + dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); + + dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); + dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); +#endif newAsset->setAssetName(assetName); newAsset->setImageFileName(imageFileName.c_str()); @@ -2697,7 +2705,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) { bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile); - if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport)) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str()); activityLog.push_back(importLogBuffer); @@ -2725,7 +2733,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) char qualifiedFromFile[2048]; +#ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); +#else + dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); + dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); +#endif newAsset->setAssetName(assetName); newAsset->setScriptFile(scriptName.c_str()); @@ -3000,11 +3013,22 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) char qualifiedFromCSFile[2048]; char qualifiedToCSFile[2048]; +#ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); - Platform::makeFullPathName(originalConstructorPath.c_str(), qualifiedFromCSFile, sizeof(qualifiedFromCSFile)); Platform::makeFullPathName(constructorPath.c_str(), qualifiedToCSFile, sizeof(qualifiedToCSFile)); +#else + dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); + dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); + dMemset(qualifiedFromCSFile, 0x00, sizeof(qualifiedFromCSFile)); + dMemset(qualifiedToCSFile, 0x00, sizeof(qualifiedToCSFile)); + + dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); + dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); + dMemcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), originalConstructorPath.size()); + dMemcpy(qualifiedToCSFile, constructorPath.c_str(), constructorPath.size()); +#endif newAsset->setAssetName(assetName); newAsset->setShapeFile(shapeFileName.c_str()); @@ -3086,7 +3110,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) { bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile); - if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport)) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromFile); activityLog.push_back(importLogBuffer); @@ -3097,7 +3121,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) { if (Platform::isFile(qualifiedFromCSFile)) { - if (!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport)) + if (!Torque::FS::CopyFile(qualifiedFromCSFile, qualifiedToCSFile, !isReimport)) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile); activityLog.push_back(importLogBuffer); @@ -3289,8 +3313,16 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) char qualifiedFromFile[2048]; char qualifiedToFile[2048]; +#ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); +#else + dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); + dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); + + dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); + dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); +#endif newAsset->setAssetName(assetName); newAsset->setSoundFile(imageFileName.c_str()); @@ -3316,7 +3348,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) { bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile); - if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport)) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str()); activityLog.push_back(importLogBuffer); @@ -3345,8 +3377,16 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt char qualifiedFromFile[2048]; char qualifiedToFile[2048]; +#ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); +#else + dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); + dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); + + dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); + dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); +#endif newAsset->setAssetName(assetName); newAsset->setAnimationFile(imageFileName.c_str()); @@ -3372,7 +3412,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt { bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile); - if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport)) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str()); activityLog.push_back(importLogBuffer); diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index d056ee331..570dcc2cd 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -500,6 +500,28 @@ Path MountSystem::_normalize(const Path& path) return po; } +bool MountSystem::copyFile(const Path& source, const Path& destination, bool noOverwrite) +{ + // Exit out early if we're not overriding + if (isFile(destination) && noOverwrite) + { + return true; + } + + FileRef sourceFile = openFile(source, FS::File::AccessMode::Read); + const U64 sourceFileSize = sourceFile->getSize(); + + void* writeBuffer = dMalloc(sourceFileSize); + sourceFile->read(writeBuffer, sourceFileSize); + + FileRef destinationFile = openFile(destination, FS::File::AccessMode::Write); + const bool success = destinationFile->write(writeBuffer, sourceFileSize) == sourceFileSize; + + dFree(writeBuffer); + + return success; +} + FileRef MountSystem::createFile(const Path& path) { Path np = _normalize(path); @@ -909,6 +931,11 @@ FileRef CreateFile(const Path &path) return sgMountSystem.createFile(path); } +bool CopyFile(const Path& source, const Path& destination, bool noOverwrite) +{ + return sgMountSystem.copyFile(source, destination, noOverwrite); +} + DirectoryRef CreateDirectory(const Path &path) { return sgMountSystem.createDirectory(path); diff --git a/Engine/source/core/volume.h b/Engine/source/core/volume.h index 18112322f..627fdb58a 100644 --- a/Engine/source/core/volume.h +++ b/Engine/source/core/volume.h @@ -335,6 +335,7 @@ public: virtual ~MountSystem() {} FileRef createFile(const Path& path); + bool copyFile(const Path& source, const Path& destination, bool noOverwrite); DirectoryRef createDirectory(const Path& path, FileSystemRef fs = NULL); virtual bool createPath(const Path& path); @@ -538,6 +539,9 @@ DirectoryRef OpenDirectory(const Path &file); ///@ingroup VolumeSystem FileRef CreateFile(const Path &file); +/// Copy a file from one location to another. +bool CopyFile(const Path& source, const Path& destination, bool noOverride); + /// Create a directory. /// The directory object is returned in a closed state. ///@ingroup VolumeSystem diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index b05b0d8bc..114466e39 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -212,8 +212,13 @@ ImplementEnumType(_TamlFormatMode, AssertFatal(pSimObject != NULL, "Cannot write a NULL object."); AssertFatal(pFilename != NULL, "Cannot write to a NULL filename."); - // Expand the file-name into the file-path buffer. + // Expand the file-name into the file-path buffer unless we're a secure VFS +#ifndef TORQUE_SECURE_VFS Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename); +#else + dMemset(mFilePathBuffer, 0x00, sizeof(mFilePathBuffer)); + dMemcpy(mFilePathBuffer, pFilename, dStrlen(pFilename)); +#endif FileStream stream; diff --git a/Engine/source/platform/platformVolume.cpp b/Engine/source/platform/platformVolume.cpp index 5f0595ef0..dccd52f0d 100644 --- a/Engine/source/platform/platformVolume.cpp +++ b/Engine/source/platform/platformVolume.cpp @@ -20,6 +20,7 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "console/console.h" #include "platform/platform.h" #if defined(TORQUE_OS_WIN) @@ -30,6 +31,7 @@ #include "platform/platformVolume.h" #include "core/util/zip/zipVolume.h" +#include "core/memVolume.h" using namespace Torque; using namespace Torque::FS; @@ -48,6 +50,34 @@ bool MountDefaults() if ( !mounted ) return false; +#ifdef TORQUE_SECURE_VFS + // Set working directory to where the executable is + StringTableEntry executablePath = Platform::getExecutablePath(); + SetCwd(executablePath); + + // FIXME: Should we use the asset path here as well? + mounted = Mount("/", createNativeFS(executablePath)); + if (!mounted) + { + return false; + } +#endif + + // Always mount the data dir so scripts work in either configuration. This is used for eg. preferences storage. + Path dataDirectory = Platform::getUserDataDirectory(); + Path appDataDirectory; + appDataDirectory.setPath(dataDirectory.getFileName()); + dataDirectory.appendPath(appDataDirectory); + + dataDirectory.setFileName(TORQUE_APP_NAME); + + Con::errorf("RAW DATA: %s", dataDirectory.getFullPath().c_str()); + mounted = Mount("data", Platform::FS::createNativeFS(dataDirectory.getFullPath())); + if (!mounted) + { + return false; + } + #ifndef TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM // Note that the VirtualMountSystem must be enabled in volume.cpp for zip support to work. return MountZips("game"); diff --git a/Engine/source/platformPOSIX/posixVolume.cpp b/Engine/source/platformPOSIX/posixVolume.cpp index d06dccd13..3a1067aa6 100644 --- a/Engine/source/platformPOSIX/posixVolume.cpp +++ b/Engine/source/platformPOSIX/posixVolume.cpp @@ -595,6 +595,7 @@ String Platform::FS::getAssetDir() /// file systems. bool Platform::FS::InstallFileSystems() { +#ifndef TORQUE_SECURE_VFS Platform::FS::Mount( "/", Platform::FS::createNativeFS( String() ) ); // Setup the current working dir. @@ -611,6 +612,7 @@ bool Platform::FS::InstallFileSystems() // Mount the home directory if (char* home = getenv("HOME")) Platform::FS::Mount( "home", Platform::FS::createNativeFS(home) ); +#endif return true; } diff --git a/Engine/source/platformWin32/winVolume.cpp b/Engine/source/platformWin32/winVolume.cpp index 5d168ac95..779a5d7b9 100644 --- a/Engine/source/platformWin32/winVolume.cpp +++ b/Engine/source/platformWin32/winVolume.cpp @@ -758,6 +758,7 @@ String Platform::FS::getAssetDir() /// file systems. bool Platform::FS::InstallFileSystems() { +#ifndef TORQUE_SECURE_VFS WCHAR buffer[1024]; // [8/24/2009 tomb] This stops Windows from complaining about drives that have no disks in @@ -792,6 +793,7 @@ bool Platform::FS::InstallFileSystems() wd += '/'; Platform::FS::SetCwd(wd); +#endif return true; } diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp index 4a00294c8..f86e09a09 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp @@ -22,6 +22,8 @@ #include "windowManager/sdl/sdlWindowMgr.h" #include "platformSDL/sdlInputManager.h" +#include "platform/platformVolume.h" +#include "core/util/path.h" #include "gfx/gfxDevice.h" #include "core/util/journal/process.h" #include "core/strings/unicode.h" @@ -35,6 +37,26 @@ void sdl_CloseSplashWindow(void* hinst); #ifdef TORQUE_SDL +#ifdef TORQUE_SECURE_VFS +PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo() +{ +} + +PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo(String rootName, Torque::FS::FileSystemRef fileSystem) : mRootName(rootName), mDragAndDropFS(fileSystem) +{ + if (!Torque::FS::Mount(rootName, fileSystem)) + { + Con::errorf("Could not mount drag and drop FS!"); + } +} + +PlatformWindowManagerSDL::DragAndDropFSInfo::~DragAndDropFSInfo() +{ +// FIXME: Cleanup - we can't simply do this unmount due to the way the hash mapping works +// Torque::FS::Unmount(mDragAndDropFS); +} +#endif + PlatformWindowManager * CreatePlatformWindowManager() { return new PlatformWindowManagerSDL(); @@ -427,7 +449,61 @@ void PlatformWindowManagerSDL::_process() if (!Platform::isDirectory(fileName) && !Platform::isFile(fileName)) break; +#ifdef TORQUE_SECURE_VFS + // Determine what the directory is so we can mount it + Torque::Path targetDirectory = Torque::Path(fileName); + + // If we're dropping a file, strip off file information - otherwise if a directory mount it directly + if (Platform::isFile(fileName)) + { + targetDirectory.setExtension(""); + targetDirectory.setFileName(""); + } + const String directoryName = targetDirectory.getDirectory(targetDirectory.getDirectoryCount() - 1); + + auto dropFSMount = mActiveDragAndDropFSByPath.find(targetDirectory); + if (dropFSMount == mActiveDragAndDropFSByPath.end()) + { + Torque::FS::FileSystemRef newMount = Platform::FS::createNativeFS(targetDirectory.getFullPath()); + + // Search for an unused root in case we have duplicate names + U32 rootCounter = 1; + String chosenRootName = directoryName; + auto search = mActiveDragAndDropByRoot.find(chosenRootName); + while (search != mActiveDragAndDropByRoot.end()) + { + char buffer[32]; + dSprintf(buffer, 32, "%u", rootCounter); + chosenRootName = directoryName + buffer; + + search = mActiveDragAndDropByRoot.find(chosenRootName); + } + + mActiveDragAndDropFSByPath[targetDirectory] = DragAndDropFSInfo(directoryName, newMount); + mActiveDragAndDropFSByPath[chosenRootName] = mActiveDragAndDropFSByPath[targetDirectory]; + } + + DragAndDropFSInfo& filesystemInformation = mActiveDragAndDropFSByPath[targetDirectory]; + + // Load source file information + Torque::Path sourceFile = fileName; + + // Build a reference to the file in VFS + Torque::Path targetFile; + targetFile.setRoot(filesystemInformation.mRootName); + targetFile.setPath("/"); + + // Only copy file & extension information if we're dropping a file + if (Platform::isFile(fileName)) + { + targetFile.setFileName(sourceFile.getFileName()); + targetFile.setExtension(sourceFile.getExtension()); + } + + Con::executef("onDropFile", StringTable->insert(targetFile.getFullPath())); +#else Con::executef("onDropFile", StringTable->insert(fileName)); +#endif SDL_free(fileName); // Free dropped_filedir memory break; diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.h b/Engine/source/windowManager/sdl/sdlWindowMgr.h index 45cd3bfe3..c5456e50d 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.h +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.h @@ -27,6 +27,7 @@ #include "gfx/gfxStructs.h" #include "windowManager/sdl/sdlWindow.h" #include "core/util/tVector.h" +#include "core/volume.h" struct SDL_Window; class FileDialog; // TODO SDL REMOVE @@ -57,6 +58,18 @@ public: RAW_INPUT = 2 /// < We only want raw input. }; +#ifdef TORQUE_SECURE_VFS + struct DragAndDropFSInfo + { + String mRootName; + Torque::FS::FileSystemRef mDragAndDropFS; + + DragAndDropFSInfo(); + DragAndDropFSInfo(String rootName, Torque::FS::FileSystemRef fileSystem); + ~DragAndDropFSInfo(); + }; +#endif + protected: friend class PlatformWindowSDL; friend class FileDialog; // TODO SDL REMOVE @@ -97,6 +110,11 @@ protected: /// After it is handled, it will return to state NONE. KeyboardInputState mInputState; +#ifdef TORQUE_SECURE_VFS + HashMap mActiveDragAndDropByRoot; + HashMap mActiveDragAndDropFSByPath; +#endif + public: PlatformWindowManagerSDL(); ~PlatformWindowManagerSDL(); diff --git a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript index 98d616529..0743b149e 100644 --- a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript +++ b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript @@ -175,7 +175,7 @@ function getUserPath() function getPrefpath() { - $prefPath = getUserPath() @ "/preferences"; + $prefPath = "data:/preferences"; return $prefPath; } diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index 2f5a0b6ac..f018d7d76 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -169,6 +169,9 @@ if(NOT MSVC AND NOT APPLE) # handle single-configuration generator mark_as_advanced(TORQUE_ADDITIONAL_LINKER_FLAGS) endif() +option(TORQUE_SECURE_VFS "Secure VFS configuration. Arbitrary script access to file system will be heavily restricted." OFF) +mark_as_advanced(TORQUE_SECURE_VFS) + option(TORQUE_MULTITHREAD "Multi Threading" ON) mark_as_advanced(TORQUE_MULTITHREAD) @@ -999,4 +1002,4 @@ if(TORQUE_SDL) else() set_target_properties(SDL2 PROPERTIES FOLDER ${TORQUE_LIBS_FOLDER_NAME}) endif() -endif() \ No newline at end of file +endif() diff --git a/Tools/CMake/torqueConfig.h.in b/Tools/CMake/torqueConfig.h.in index 9e045b1d5..449e12614 100644 --- a/Tools/CMake/torqueConfig.h.in +++ b/Tools/CMake/torqueConfig.h.in @@ -50,6 +50,9 @@ /// Define me if you want path case insensitivity support in ZIP files. #cmakedefine TORQUE_ZIP_PATH_CASE_INSENSITIVE +/// Define me if you want to enable secure VFS support. +#cmakedefine TORQUE_SECURE_VFS + /// Define me if you want to enable multithreading support. #cmakedefine TORQUE_MULTITHREAD @@ -225,4 +228,4 @@ #endif /// Password to use when opening encrypted zip files. Change this to whatever the password is for your zips. -#define DEFAULT_ZIP_PASSWORD "@TORQUE_APP_PASSWORD@" \ No newline at end of file +#define DEFAULT_ZIP_PASSWORD "@TORQUE_APP_PASSWORD@" From 948bc43d858de52500db30a191f267fe316fb75d Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sat, 18 Dec 2021 03:56:11 -0500 Subject: [PATCH 02/20] * Feature: Augment VFS file information with creation times & update some console functions to use VFS. --- Engine/source/console/fileSystemFunctions.cpp | 30 ++++++------------- Engine/source/core/memVolume.cpp | 7 +++-- Engine/source/core/util/zip/zipVolume.cpp | 3 ++ Engine/source/core/volume.cpp | 12 ++++++++ Engine/source/core/volume.h | 2 ++ Engine/source/platformPOSIX/posixVolume.cpp | 1 + Engine/source/platformWin32/winVolume.cpp | 4 +++ 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index eea26a984..34fd77bc5 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -530,8 +530,12 @@ DefineEngineFunction(fileSize, S32, ( const char* fileName ),, "@ingroup FileSystem") { - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName); - return Platform::getFileSize( sgScriptFilenameBuffer ); + StrongRefPtr node = Torque::FS::GetFileNode(fileName); + if (node.isValid()) + { + return node->getSize(); + } + return -1; } DefineEngineFunction( fileModifiedTime, String, ( const char* fileName ),, @@ -609,13 +613,7 @@ DefineEngineFunction(fileDelete, bool, ( const char* path ),, "@return True if file was successfully deleted\n" "@ingroup FileSystem") { - static char fileName[1024]; - static char sandboxFileName[1024]; - - Con::expandScriptFilename( fileName, sizeof( fileName ), path ); - Platform::makeFullPathName(fileName, sandboxFileName, sizeof(sandboxFileName)); - - return dFileDelete(sandboxFileName); + return Torque::FS::Remove(path); } @@ -830,13 +828,7 @@ DefineEngineFunction( pathCopy, bool, ( const char* fromFile, const char* toFile "@note Only present in a Tools build of Torque.\n" "@ingroup FileSystem") { - char qualifiedFromFile[ 2048 ]; - char qualifiedToFile[ 2048 ]; - - Platform::makeFullPathName( fromFile, qualifiedFromFile, sizeof( qualifiedFromFile ) ); - Platform::makeFullPathName( toFile, qualifiedToFile, sizeof( qualifiedToFile ) ); - - return dPathCopy( qualifiedFromFile, qualifiedToFile, noOverwrite ); + return Torque::FS::CopyFile(fromFile, toFile, noOverwrite); } //----------------------------------------------------------------------------- @@ -876,11 +868,7 @@ DefineEngineFunction( createPath, bool, ( const char* path ),, "@note Only present in a Tools build of Torque.\n" "@ingroup FileSystem" ) { - static char pathName[1024]; - - Con::expandScriptFilename( pathName, sizeof( pathName ), path ); - - return Platform::createPath( pathName ); + return Torque::FS::CreatePath(path); } #endif // TORQUE_TOOLS diff --git a/Engine/source/core/memVolume.cpp b/Engine/source/core/memVolume.cpp index 56d53174f..31cbd76dd 100644 --- a/Engine/source/core/memVolume.cpp +++ b/Engine/source/core/memVolume.cpp @@ -46,7 +46,8 @@ namespace Torque mBuffer = dMalloc(mBufferSize); dMemset(mBuffer, 0, mBufferSize); mModified = Time::getCurrentTime(); - mLastAccess = mModified; + mLastAccess = mModified; + mCreated = mModified; mFileSystem = fs; } @@ -62,6 +63,7 @@ namespace Torque attr->size = mFileSize; attr->mtime = mModified; attr->atime = mLastAccess; + attr->ctime = mCreated; return true; } @@ -81,6 +83,7 @@ namespace Torque U32 mBufferSize; // This is the size of the memory buffer >= mFileSize U32 mFileSize; // This is the size of the "file" <= mBufferSize Time mModified; // Last modified + Time mCreated; // When Created Time mLastAccess; // Last access MemFileSystem* mFileSystem; }; @@ -508,4 +511,4 @@ namespace Torque } } // Namespace Mem -} // Namespace Torque \ No newline at end of file +} // Namespace Torque diff --git a/Engine/source/core/util/zip/zipVolume.cpp b/Engine/source/core/util/zip/zipVolume.cpp index d56c9471e..6fe6edb37 100644 --- a/Engine/source/core/util/zip/zipVolume.cpp +++ b/Engine/source/core/util/zip/zipVolume.cpp @@ -86,6 +86,7 @@ public: // use the mod time for both mod and access time, since we only have mod time in the CD attr->mtime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); attr->atime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); + attr->ctime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); attr->size = mZipEntry->mCD.mUncompressedSize; return true; @@ -197,6 +198,7 @@ public: // use the mod time for both mod and access time, since we only have mod time in the CD attr->mtime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); attr->atime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); + attr->ctime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate); attr->size = mZipEntry->mCD.mUncompressedSize; return true; @@ -291,6 +293,7 @@ public: ZipArchive::ZipEntry* zipEntry = mArchive->getRoot(); attr->mtime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate); attr->atime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate); + attr->ctime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate); attr->size = zipEntry->mCD.mUncompressedSize; return true; diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index 570dcc2cd..a0a4570d7 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -273,6 +273,18 @@ Time FileNode::getModifiedTime() return attrs.mtime; } +Time FileNode::getCreatedTime() +{ + Attributes attrs; + + bool success = getAttributes(&attrs); + + if (!success) + return Time(); + + return attrs.ctime; +} + U64 FileNode::getSize() { Attributes attrs; diff --git a/Engine/source/core/volume.h b/Engine/source/core/volume.h index 627fdb58a..4766439c6 100644 --- a/Engine/source/core/volume.h +++ b/Engine/source/core/volume.h @@ -114,6 +114,7 @@ public: String name; ///< File/Directory name Time mtime; ///< Last modified time Time atime; ///< Last access time + Time ctime; ///< Creation Time U64 size; }; @@ -128,6 +129,7 @@ public: // Convenience routines - may be overridden for optimal access virtual Time getModifiedTime(); ///< @note This will return Time() on failure + virtual Time getCreatedTime(); ///< @note This will return Time() on failure virtual U64 getSize(); ///< @note This will return 0 on failure virtual U32 getChecksum(); ///< @note This will return 0 on failure diff --git a/Engine/source/platformPOSIX/posixVolume.cpp b/Engine/source/platformPOSIX/posixVolume.cpp index 3a1067aa6..b50a226e3 100644 --- a/Engine/source/platformPOSIX/posixVolume.cpp +++ b/Engine/source/platformPOSIX/posixVolume.cpp @@ -135,6 +135,7 @@ static void copyStatAttributes(const struct stat& info, FileNode::Attributes* at attr->size = info.st_size; attr->mtime = UnixTimeToTime(info.st_mtime); attr->atime = UnixTimeToTime(info.st_atime); + attr->ctime = UnixTimeToTime(info.st_ctime); } diff --git a/Engine/source/platformWin32/winVolume.cpp b/Engine/source/platformWin32/winVolume.cpp index 779a5d7b9..0271ff96b 100644 --- a/Engine/source/platformWin32/winVolume.cpp +++ b/Engine/source/platformWin32/winVolume.cpp @@ -143,6 +143,10 @@ static void _CopyStatAttributes(const WIN32_FIND_DATAW& info, FileNode::Attribut attr->atime = Win32FileTimeToTime( info.ftLastAccessTime.dwLowDateTime, info.ftLastAccessTime.dwHighDateTime); + + attr->ctime = Win32FileTimeToTime( + info.ftCreationTime.dwLowDateTime, + info.ftCreationTime.dwHighDateTime); } From cbe7ee13d64ee39126bd6ccf7624e3ff996b0c5b Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sat, 18 Dec 2021 23:37:49 -0500 Subject: [PATCH 03/20] * Adjustment: Change several filesystem functions to use the VFS. * Feature: Initial implementation of a VFS dump directories function. --- Engine/source/console/fileSystemFunctions.cpp | 44 +++---- Engine/source/core/memVolume.h | 2 +- Engine/source/core/util/zip/zipVolume.h | 2 +- Engine/source/core/volume.cpp | 111 ++++++++++++++++-- Engine/source/core/volume.h | 13 +- 5 files changed, 130 insertions(+), 42 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index 34fd77bc5..7a9ffeb23 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -368,15 +368,11 @@ DefineEngineFunction(getFileCRC, S32, ( const char* fileName ),, "@ingroup FileSystem") { - String cleanfilename(Torque::Path::CleanSeparators(fileName)); - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str()); - - Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); - Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode( givenPath ); + Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode( fileName ); if ( fileRef == NULL ) { - Con::errorf("getFileCRC() - could not access file: [%s]", givenPath.getFullPath().c_str() ); + Con::errorf("getFileCRC() - could not access file: [%s]", fileName ); return -1; } @@ -391,11 +387,7 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),, "@ingroup FileSystem") { - String cleanfilename(Torque::Path::CleanSeparators(fileName)); - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str()); - - Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); - return Torque::FS::IsFile(givenPath); + return Torque::FS::IsFile(fileName); } DefineEngineFunction(isScriptFile, bool, (const char* fileName), , @@ -406,11 +398,7 @@ DefineEngineFunction(isScriptFile, bool, (const char* fileName), , "@ingroup FileSystem") { - String cleanfilename(Torque::Path::CleanSeparators(fileName)); - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str()); - - Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); - return Torque::FS::IsScriptFile(givenPath.getFullPath()); + return Torque::FS::IsScriptFile(fileName); } DefineEngineFunction( IsDirectory, bool, ( const char* directory ),, @@ -423,11 +411,7 @@ DefineEngineFunction( IsDirectory, bool, ( const char* directory ),, "@ingroup FileSystem") { - String dir(Torque::Path::CleanSeparators(directory)); - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), dir.c_str()); - - Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); - return Torque::FS::IsDirectory( givenPath ); + return Torque::FS::IsDirectory( directory ); } DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),, @@ -438,14 +422,7 @@ DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),, "@ingroup FileSystem") { - String filename(Torque::Path::CleanSeparators(fileName)); - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), filename.c_str()); - - Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); - Torque::FS::FileSystemRef fs = Torque::FS::GetFileSystem(givenPath); - Torque::Path path = fs->mapTo(givenPath); - - return !Torque::FS::IsReadOnly(path); + return !Torque::FS::IsReadOnly(fileName); } DefineEngineFunction(startFileChangeNotifications, void, (),, @@ -840,7 +817,11 @@ DefineEngineFunction( getCurrentDirectory, String, (),, "@see getWorkingDirectory()" "@ingroup FileSystem") { +#ifdef TORQUE_SECURE_VFS + return Torque::FS::GetCwd(); +#else return Platform::getCurrentDirectory(); +#endif } //----------------------------------------------------------------------------- @@ -853,8 +834,11 @@ DefineEngineFunction( setCurrentDirectory, bool, ( const char* path ),, "@note Only present in a Tools build of Torque.\n" "@ingroup FileSystem") { +#ifdef TORQUE_SECURE_VFS + return Torque::FS::SetCwd(path); +#else return Platform::setCurrentDirectory( StringTable->insert( path ) ); - +#endif } //----------------------------------------------------------------------------- diff --git a/Engine/source/core/memVolume.h b/Engine/source/core/memVolume.h index 0a20fa84f..bc45bcec2 100644 --- a/Engine/source/core/memVolume.h +++ b/Engine/source/core/memVolume.h @@ -129,4 +129,4 @@ namespace Torque } // Namespace } // Namespace -#endif \ No newline at end of file +#endif diff --git a/Engine/source/core/util/zip/zipVolume.h b/Engine/source/core/util/zip/zipVolume.h index 6f949df5e..db1a7faab 100644 --- a/Engine/source/core/util/zip/zipVolume.h +++ b/Engine/source/core/util/zip/zipVolume.h @@ -75,4 +75,4 @@ private: } -#endif \ No newline at end of file +#endif diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index a0a4570d7..090dc43f7 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -255,6 +255,64 @@ File::~File() {} Directory::Directory() {} Directory::~Directory() {} +bool Directory::dump(Vector& out) +{ + const Path sourcePath = getName(); + + FileNode::Attributes currentAttributes; + while (read(¤tAttributes)) + { + Path currentPath = sourcePath; + currentPath.appendPath(currentPath.getFileName()); + currentPath.setFileName(currentAttributes.name); + + out.push_back(currentPath); + } + + return true; +} + +bool Directory::dumpFiles(Vector& out) +{ + const Path sourcePath = getName(); + + FileNode::Attributes currentAttributes; + while (read(¤tAttributes)) + { + Path currentPath = sourcePath; + currentPath.appendPath(currentPath.getFileName()); + currentPath.setFileName(currentAttributes.name); + + if (IsFile(currentPath)) + { + out.push_back(currentPath); + } + } + + return true; +} + +bool Directory::dumpDirectories(Vector& out) +{ + const Path sourcePath = getName(); + + FileNode::Attributes currentAttributes; + while (read(¤tAttributes)) + { + Path currentPath = sourcePath; + currentPath.appendPath(currentPath.getFileName()); + currentPath.setFileName(currentAttributes.name); + + const bool result = IsDirectory(currentPath); + if (result) + { + out.push_back(currentPath); + } + } + + return true; +} + FileNode::FileNode() : mChecksum(0) @@ -534,6 +592,39 @@ bool MountSystem::copyFile(const Path& source, const Path& destination, bool noO return success; } +bool MountSystem::_dumpDirectories(DirectoryRef directory, Vector& directories, S32 depth, bool noBasePath, S32 currentDepth, const Path& basePath) +{ + Vector directoryPaths; + if (!directory->dumpDirectories(directoryPaths)) + { + return false; + } + + for (U32 iteration = 0; iteration < directoryPaths.size(); ++iteration) + { + directories.push_back(StringTable->insert(directoryPaths[iteration].getFullPath().c_str(), true)); + + if (currentDepth <= depth) + { + DirectoryRef nextDirectory = OpenDirectory(directoryPaths[iteration]); + _dumpDirectories(nextDirectory, directories, depth, noBasePath, currentDepth + 1, basePath); + } + } + + return true; +} + +bool MountSystem::dumpDirectories(const Path& path, Vector& directories, S32 depth, bool noBasePath) +{ + if (!isDirectory(path)) + { + return false; + } + + DirectoryRef sourceDirectory = openDirectory(path); + return _dumpDirectories(sourceDirectory, directories, depth, noBasePath, 0, path); +} + FileRef MountSystem::createFile(const Path& path) { Path np = _normalize(path); @@ -830,22 +921,19 @@ bool MountSystem::isDirectory(const Path& path, FileSystemRef fsRef) { FileNode::Attributes attr; + bool result = false; if (fsRef.isNull()) { - if (getFileAttributes(path,&attr)) - return attr.flags & FileNode::Directory; - return false; + if (getFileAttributes(path, &attr)) + result = (attr.flags & FileNode::Directory) != 0; } else { FileNodeRef fnRef = fsRef->resolve(path); - if (fnRef.isNull()) - return false; - - if (fnRef->getAttributes(&attr)) - return attr.flags & FileNode::Directory; - return false; + if (!fnRef.isNull() && fnRef->getAttributes(&attr)) + result = (attr.flags & FileNode::Directory) != 0; } + return result; } bool MountSystem::isReadOnly(const Path& path) @@ -948,6 +1036,11 @@ bool CopyFile(const Path& source, const Path& destination, bool noOverwrite) return sgMountSystem.copyFile(source, destination, noOverwrite); } +bool DumpDirectories(const Path& path, Vector& directories, S32 depth, bool noBasePath) +{ + return sgMountSystem.dumpDirectories(path, directories, depth, noBasePath); +} + DirectoryRef CreateDirectory(const Path &path) { return sgMountSystem.createDirectory(path); diff --git a/Engine/source/core/volume.h b/Engine/source/core/volume.h index 4766439c6..d6369660e 100644 --- a/Engine/source/core/volume.h +++ b/Engine/source/core/volume.h @@ -203,7 +203,11 @@ public: // Functions virtual bool open() = 0; virtual bool close() = 0; - virtual bool read(Attributes*) = 0; + virtual bool read(Attributes*) = 0; + + bool dump(Vector& out); + bool dumpFiles(Vector& out); + bool dumpDirectories(Vector& out); }; typedef WeakRefPtr DirectoryPtr; @@ -338,6 +342,8 @@ public: FileRef createFile(const Path& path); bool copyFile(const Path& source, const Path& destination, bool noOverwrite); + bool dumpDirectories(const Path& path, Vector& directories, S32 depth, bool noBasePath); + DirectoryRef createDirectory(const Path& path, FileSystemRef fs = NULL); virtual bool createPath(const Path& path); @@ -377,6 +383,8 @@ public: void startFileChangeNotifications(); void stopFileChangeNotifications(); +private: + bool _dumpDirectories(DirectoryRef directory, Vector& directories, S32 depth, bool noBasePath, S32 currentDepth, const Path& basePath); protected: virtual void _log(const String& msg); @@ -544,6 +552,9 @@ FileRef CreateFile(const Path &file); /// Copy a file from one location to another. bool CopyFile(const Path& source, const Path& destination, bool noOverride); +/// Retrieve list of directories in the specified directory. +bool DumpDirectories(const Path& path, Vector& directories, S32 depth, bool noBasePath); + /// Create a directory. /// The directory object is returned in a closed state. ///@ingroup VolumeSystem From 66f93369958261bf10d4ba4a59ee04fd2bd59ef5 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sun, 19 Dec 2021 00:28:15 -0500 Subject: [PATCH 04/20] * Adjustment: Tweak the asset importer to use the Torque VFS functions. --- Engine/source/T3D/assets/assetImporter.cpp | 38 +++++++++---------- Engine/source/console/fileSystemFunctions.cpp | 10 +++++ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 221e776dd..3b19984f9 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1400,7 +1400,7 @@ void AssetImportConfig::loadSISFile(Torque::Path filePath) String settingsFile = settingsFilePath + "/" + fileExtension + ".sis"; FileObject* fileObj = new FileObject(); - if (Platform::isFile(settingsFile)) + if (Torque::FS::IsFile(settingsFile)) { if (!fileObj->readMemory(settingsFile.c_str())) { @@ -2074,7 +2074,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m if (fullFilePath.isNotEmpty()) { - if (!Platform::isFile(fullFilePath.c_str())) + if (!Torque::FS::IsFile(fullFilePath.c_str())) { //could be a stale path reference, such as if it was downloaded elsewhere. Trim to just the filename and see //if we can find it there @@ -2086,7 +2086,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m if(filePath.getPath().isEmpty()) fullFilePath = shapePathBase + "/" + fullFilePath; - if (Platform::isFile(fullFilePath.c_str())) + if (Torque::FS::IsFile(fullFilePath.c_str())) { filePath = Torque::Path(fullFilePath); } @@ -2203,7 +2203,7 @@ void AssetImporter::validateAsset(AssetImportObject* assetItem) } } - if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Platform::isFile(assetItem->filePath.getFullPath().c_str())) + if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Torque::FS::IsFile(assetItem->filePath.getFullPath().c_str())) { assetItem->status = "Error"; assetItem->statusType = "MissingFile"; @@ -2667,8 +2667,8 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); - dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); + dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); + dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); #endif newAsset->setAssetName(assetName); @@ -2737,7 +2737,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); #else dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); + dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); #endif newAsset->setAssetName(assetName); @@ -2817,7 +2817,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) FileObject* file = new FileObject(); file->registerObject(); - if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile)) + if (activeImportConfig->UseExistingMaterials && Torque::FS::IsFile(qualifiedFromFile)) { //Now write the script file containing our material out //There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old @@ -3024,10 +3024,10 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) dMemset(qualifiedFromCSFile, 0x00, sizeof(qualifiedFromCSFile)); dMemset(qualifiedToCSFile, 0x00, sizeof(qualifiedToCSFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); - dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); - dMemcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), originalConstructorPath.size()); - dMemcpy(qualifiedToCSFile, constructorPath.c_str(), constructorPath.size()); + dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); + dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); + dMemcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), std::min(originalConstructorPath.size(), sizeof(qualifiedFromCSFile))); + dMemcpy(qualifiedToCSFile, constructorPath.c_str(), std::min(constructorPath.size(), sizeof(qualifiedToCSFile))); #endif newAsset->setAssetName(assetName); @@ -3119,7 +3119,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) if (!isInPlace) { - if (Platform::isFile(qualifiedFromCSFile)) + if (Torque::FS::IsFile(qualifiedFromCSFile)) { if (!Torque::FS::CopyFile(qualifiedFromCSFile, qualifiedToCSFile, !isReimport)) { @@ -3138,7 +3138,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) else { //We're doing an in-place import, so double check we've already got a constructor file in the expected spot - if (Platform::isFile(qualifiedFromCSFile)) + if (Torque::FS::IsFile(qualifiedFromCSFile)) { //Yup, found it, we're good to go makeNewConstructor = false; @@ -3151,7 +3151,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) Torque::Path constrFilePath = qualifiedFromCSFile; constrFilePath.setExtension("cs"); - if (Platform::isFile(constrFilePath.getFullPath().c_str())) + if (Torque::FS::IsFile(constrFilePath.getFullPath().c_str())) { //Yup, found it, we're good to go makeNewConstructor = false; @@ -3320,8 +3320,8 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); - dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); + dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); + dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); #endif newAsset->setAssetName(assetName); @@ -3384,8 +3384,8 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), originalPath.size()); - dMemcpy(qualifiedToFile, assetPath.c_str(), assetPath.size()); + dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); + dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); #endif newAsset->setAssetName(assetName); diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index 7a9ffeb23..11a286e22 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -455,7 +455,13 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), { // Grab the full path. char fullpath[1024]; + +#ifdef TORQUE_SECURE_VFS + dMemset(fullpath, 0x00, sizeof(fullpath)); + dMemcpy(fullpath, path, dStrlen(path)); +#else Platform::makeFullPathName(String::compare(path, "/") == 0 ? "" : path, fullpath, sizeof(fullpath)); +#endif //dSprintf(fullpath, 511, "%s/%s", Platform::getWorkingDirectory(), path); @@ -469,7 +475,11 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), // Dump the directories. Vector directories; +#ifdef TORQUE_SECURE_VFS + Torque::FS::DumpDirectories(fullpath, directories, depth, true); +#else Platform::dumpDirectories(fullpath, directories, depth, true); +#endif if( directories.empty() ) return ""; From 7665076b19210230c40a27eee348354368f4de47 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sun, 19 Dec 2021 00:54:11 -0500 Subject: [PATCH 05/20] * Cleanup: Minor cleanup of test code and an unused include. --- Engine/source/platform/platformVolume.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Engine/source/platform/platformVolume.cpp b/Engine/source/platform/platformVolume.cpp index dccd52f0d..c14347496 100644 --- a/Engine/source/platform/platformVolume.cpp +++ b/Engine/source/platform/platformVolume.cpp @@ -31,7 +31,6 @@ #include "platform/platformVolume.h" #include "core/util/zip/zipVolume.h" -#include "core/memVolume.h" using namespace Torque; using namespace Torque::FS; @@ -71,7 +70,6 @@ bool MountDefaults() dataDirectory.setFileName(TORQUE_APP_NAME); - Con::errorf("RAW DATA: %s", dataDirectory.getFullPath().c_str()); mounted = Mount("data", Platform::FS::createNativeFS(dataDirectory.getFullPath())); if (!mounted) { From 46b8c3d15ded542d1d1c78e89d5e77310b2be782 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sun, 19 Dec 2021 01:18:52 -0500 Subject: [PATCH 06/20] * BugFix: Correct the VFS dumpDirectories function not honoring noBasePath properly. --- Engine/source/core/volume.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index 090dc43f7..3f4b79c42 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -602,8 +602,23 @@ bool MountSystem::_dumpDirectories(DirectoryRef directory, Vectorinsert(directoryPaths[iteration].getFullPath().c_str(), true)); + const Path& directoryPath = directoryPaths[iteration]; + String directoryPathString = directoryPath.getFullPath().c_str(); + if (noBasePath) + { + Path newDirectoryPath; + for (U32 iteration = basePath.getDirectoryCount() + 1; iteration < directoryPath.getDirectoryCount(); ++iteration) + { + newDirectoryPath.appendPath(directoryPath.getDirectory(iteration)); + } + + newDirectoryPath.setFileName(directoryPath.getFileName()); + newDirectoryPath.setExtension(directoryPath.getExtension()); + directoryPathString = newDirectoryPath.getFullPathWithoutRoot(); + } + + directories.push_back(StringTable->insert(directoryPathString, true)); if (currentDepth <= depth) { DirectoryRef nextDirectory = OpenDirectory(directoryPaths[iteration]); From b63122ea76f40496e2e73c2b5ca5ee12933ab502 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sun, 19 Dec 2021 01:51:19 -0500 Subject: [PATCH 07/20] * BugFix: Corrections to the VFS dumpDirectories function to properly honor the depth parameter. --- Engine/source/core/volume.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index 3f4b79c42..5e58ad452 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -608,9 +608,13 @@ bool MountSystem::_dumpDirectories(DirectoryRef directory, Vector basePath.getDirectoryCount()) + { + newDirectoryPath.setPath(newDirectoryPath.getPath() + "/"); + } + newDirectoryPath.setPath(newDirectoryPath.getPath() + directoryPath.getDirectory(iteration)); } newDirectoryPath.setFileName(directoryPath.getFileName()); @@ -621,7 +625,9 @@ bool MountSystem::_dumpDirectories(DirectoryRef directory, Vectorinsert(directoryPathString, true)); if (currentDepth <= depth) { - DirectoryRef nextDirectory = OpenDirectory(directoryPaths[iteration]); + const String subdirectoryPath = directoryPath.getFullPath() + "/"; + + DirectoryRef nextDirectory = OpenDirectory(subdirectoryPath); _dumpDirectories(nextDirectory, directories, depth, noBasePath, currentDepth + 1, basePath); } } @@ -637,7 +643,7 @@ bool MountSystem::dumpDirectories(const Path& path, Vector& di } DirectoryRef sourceDirectory = openDirectory(path); - return _dumpDirectories(sourceDirectory, directories, depth, noBasePath, 0, path); + return _dumpDirectories(sourceDirectory, directories, depth, noBasePath, 1, path); } FileRef MountSystem::createFile(const Path& path) From 0e93373824c9dcb3d7f086adf91a10c849fb8c3e Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 20 Dec 2021 19:26:32 -0500 Subject: [PATCH 08/20] * BugFix: When querying against root with Torque::FS::DumpDirectories, correctly return directories with their path. * Adjustment: Add commenting to some of the new programming. * Adjustment: Tweak fileCreatedTime and fileModifiedTime functions to use the VFS. --- Engine/source/console/fileSystemFunctions.cpp | 44 +++++++++---------- Engine/source/core/util/timeClass.cpp | 25 +++++++++++ Engine/source/core/util/timeClass.h | 6 ++- Engine/source/core/volume.cpp | 12 ++++- Engine/source/platform/platformVolume.cpp | 7 +-- .../source/windowManager/sdl/sdlWindowMgr.cpp | 14 ++++-- .../source/windowManager/sdl/sdlWindowMgr.h | 3 ++ 7 files changed, 77 insertions(+), 34 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index 11a286e22..c9a0f5ae2 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -532,20 +532,20 @@ DefineEngineFunction( fileModifiedTime, String, ( const char* fileName ),, "@return Formatted string (OS specific) containing modified time, \"9/3/2010 12:33:47 PM\" for example\n" "@ingroup FileSystem") { - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName); + Torque::FS::FileNodeRef node = Torque::FS::GetFileNode(fileName); - FileTime ft = {0}; - Platform::getFileTimes( sgScriptFilenameBuffer, NULL, &ft ); + if (node) + { + Platform::LocalTime lt = node->getModifiedTime().toLocalTime(); - Platform::LocalTime lt = {0}; - Platform::fileToLocalTime( ft, < ); - - String fileStr = Platform::localTimeToString( lt ); - - char *buffer = Con::getReturnBuffer( fileStr.size() ); - dStrcpy( buffer, fileStr, fileStr.size() ); - - return buffer; + String fileStr = Platform::localTimeToString(lt); + + char *buffer = Con::getReturnBuffer(fileStr.size()); + dStrcpy(buffer, fileStr, fileStr.size()); + + return buffer; + } + return ""; } DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),, @@ -555,20 +555,20 @@ DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),, "@return Formatted string (OS specific) containing created time, \"9/3/2010 12:33:47 PM\" for example\n" "@ingroup FileSystem") { - Con::expandScriptFilename( sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName ); + Torque::FS::FileNodeRef node = Torque::FS::GetFileNode(fileName); - FileTime ft = {0}; - Platform::getFileTimes( sgScriptFilenameBuffer, &ft, NULL ); + if (node) + { + Platform::LocalTime lt = node->getCreatedTime().toLocalTime(); - Platform::LocalTime lt = {0}; - Platform::fileToLocalTime( ft, < ); + String fileStr = Platform::localTimeToString(lt); - String fileStr = Platform::localTimeToString( lt ); + char *buffer = Con::getReturnBuffer(fileStr.size()); + dStrcpy(buffer, fileStr, fileStr.size()); - char *buffer = Con::getReturnBuffer( fileStr.size() ); - dStrcpy( buffer, fileStr, fileStr.size() ); - - return buffer; + return buffer; + } + return ""; } DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* fileB), ("", ""), diff --git a/Engine/source/core/util/timeClass.cpp b/Engine/source/core/util/timeClass.cpp index 98c60e882..b30c36d66 100644 --- a/Engine/source/core/util/timeClass.cpp +++ b/Engine/source/core/util/timeClass.cpp @@ -195,4 +195,29 @@ void Time::get(S32 *pyear, S32 *pmonth, S32 *pday, S32 *phour, S32 *pminute, S32 *pmicrosecond = time % OneSecond; } +Platform::LocalTime Time::toLocalTime() +{ + Platform::LocalTime result; + result.isdst = false; + + S32 year; + S32 month; + S32 day; + S32 hour; + S32 minute; + S32 second; + S32 microsecond; + + get(&year, &month, &day, &hour, &minute, &second, µsecond); + result.year = year - 1900; + result.month = month - 1; + result.yearday = day; + result.hour = hour; + result.min = minute; + result.sec = second; + result.monthday = day % 32; + result.weekday = day % 7; + return result; +} + } // Namespace diff --git a/Engine/source/core/util/timeClass.h b/Engine/source/core/util/timeClass.h index af9fe09fa..cfee70a86 100644 --- a/Engine/source/core/util/timeClass.h +++ b/Engine/source/core/util/timeClass.h @@ -26,7 +26,9 @@ #ifndef _TORQUE_TYPES_H_ #include "platform/types.h" #endif - +#ifndef _PLATFORM_H_ +#include "platform/platform.h" +#endif #if defined(TORQUE_COMPILER_VISUALC) #define TORQUE_CONSTANT_S64(a) (a##I64) @@ -105,6 +107,8 @@ public: S64 getMicroseconds() const; S64 getInternalRepresentation() const; + Platform::LocalTime toLocalTime(); + private: class Tester { diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index 5e58ad452..f4338c692 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -600,17 +600,24 @@ bool MountSystem::_dumpDirectories(DirectoryRef directory, Vector basePath.getDirectoryCount()) + if (iteration > basePathDirectoryCount) { newDirectoryPath.setPath(newDirectoryPath.getPath() + "/"); } @@ -622,6 +629,7 @@ bool MountSystem::_dumpDirectories(DirectoryRef directory, Vectorinsert(directoryPathString, true)); if (currentDepth <= depth) { diff --git a/Engine/source/platform/platformVolume.cpp b/Engine/source/platform/platformVolume.cpp index c14347496..c7778b363 100644 --- a/Engine/source/platform/platformVolume.cpp +++ b/Engine/source/platform/platformVolume.cpp @@ -50,12 +50,7 @@ bool MountDefaults() return false; #ifdef TORQUE_SECURE_VFS - // Set working directory to where the executable is - StringTableEntry executablePath = Platform::getExecutablePath(); - SetCwd(executablePath); - - // FIXME: Should we use the asset path here as well? - mounted = Mount("/", createNativeFS(executablePath)); + mounted = Mount("/", createNativeFS(path)); if (!mounted) { return false; diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp index f86e09a09..68def351a 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp @@ -52,8 +52,7 @@ PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo(String rootName, PlatformWindowManagerSDL::DragAndDropFSInfo::~DragAndDropFSInfo() { -// FIXME: Cleanup - we can't simply do this unmount due to the way the hash mapping works -// Torque::FS::Unmount(mDragAndDropFS); + } #endif @@ -88,6 +87,15 @@ PlatformWindowManagerSDL::PlatformWindowManagerSDL() PlatformWindowManagerSDL::~PlatformWindowManagerSDL() { + // Unmount all drag and drop FS mounts + for (auto iteration = mActiveDragAndDropFSByPath.begin(); iteration != mActiveDragAndDropFSByPath.end(); ++iteration) + { + auto&& mapping = *iteration; + Torque::FS::Unmount(mapping.value.mDragAndDropFS); + } + mActiveDragAndDropByRoot.clear(); + mActiveDragAndDropFSByPath.clear(); + // Kill all our windows first. while(mWindowListHead) // The destructors update the list, so this works just fine. @@ -473,7 +481,7 @@ void PlatformWindowManagerSDL::_process() while (search != mActiveDragAndDropByRoot.end()) { char buffer[32]; - dSprintf(buffer, 32, "%u", rootCounter); + dSprintf(buffer, sizeof(buffer), "%u", rootCounter); chosenRootName = directoryName + buffer; search = mActiveDragAndDropByRoot.find(chosenRootName); diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.h b/Engine/source/windowManager/sdl/sdlWindowMgr.h index c5456e50d..fc2ae4969 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.h +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.h @@ -111,7 +111,10 @@ protected: KeyboardInputState mInputState; #ifdef TORQUE_SECURE_VFS + /// Used to check if a root is already used when generating root names. HashMap mActiveDragAndDropByRoot; + + /// Used to keep track of what mounts are handling a given path. HashMap mActiveDragAndDropFSByPath; #endif From abb4e558dca835ae760150d0b2c50730d5d5ffd0 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Tue, 21 Dec 2021 02:15:16 -0500 Subject: [PATCH 09/20] * Adjustment: Rework the TORQUE_SECURE_VFS paths in the assetImporter to use dStrcpy instead of manual memory management. --- Engine/source/T3D/assets/assetImporter.cpp | 37 +++++++--------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 3b19984f9..695945649 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2664,11 +2664,8 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); #else - dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - - dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); - dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); + dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile)); + dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile)); #endif newAsset->setAssetName(assetName); @@ -2736,8 +2733,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) #ifndef TORQUE_SECURE_VFS Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); #else - dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); + dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile)); #endif newAsset->setAssetName(assetName); @@ -3019,15 +3015,10 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalConstructorPath.c_str(), qualifiedFromCSFile, sizeof(qualifiedFromCSFile)); Platform::makeFullPathName(constructorPath.c_str(), qualifiedToCSFile, sizeof(qualifiedToCSFile)); #else - dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - dMemset(qualifiedFromCSFile, 0x00, sizeof(qualifiedFromCSFile)); - dMemset(qualifiedToCSFile, 0x00, sizeof(qualifiedToCSFile)); - - dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); - dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); - dMemcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), std::min(originalConstructorPath.size(), sizeof(qualifiedFromCSFile))); - dMemcpy(qualifiedToCSFile, constructorPath.c_str(), std::min(constructorPath.size(), sizeof(qualifiedToCSFile))); + dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile)); + dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile)); + dStrcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), sizeof(qualifiedFromCSFile)); + dStrcpy(qualifiedToCSFile, constructorPath.c_str(), sizeof(qualifiedToCSFile)); #endif newAsset->setAssetName(assetName); @@ -3317,11 +3308,8 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); #else - dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - - dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); - dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); + dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile)); + dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile)); #endif newAsset->setAssetName(assetName); @@ -3381,11 +3369,8 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); #else - dMemset(qualifiedFromFile, 0x00, sizeof(qualifiedFromFile)); - dMemset(qualifiedToFile, 0x00, sizeof(qualifiedToFile)); - - dMemcpy(qualifiedFromFile, originalPath.c_str(), std::min(originalPath.size(), sizeof(qualifiedFromFile))); - dMemcpy(qualifiedToFile, assetPath.c_str(), std::min(assetPath.size(), sizeof(qualifiedToFile))); + dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile)); + dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile)); #endif newAsset->setAssetName(assetName); From 9cf6c42fa1c6facdbdf807a9478c0d1af0a053a5 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Tue, 21 Dec 2021 14:52:31 -0500 Subject: [PATCH 10/20] * Adjustment: Tweak more manual memory management to use dStrcpy and use the VFS for directory queries always now. --- Engine/source/console/fileSystemFunctions.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index c9a0f5ae2..bbeddaca4 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -457,8 +457,7 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), char fullpath[1024]; #ifdef TORQUE_SECURE_VFS - dMemset(fullpath, 0x00, sizeof(fullpath)); - dMemcpy(fullpath, path, dStrlen(path)); + dStrcpy(fullpath, path, sizeof(fullpath)); #else Platform::makeFullPathName(String::compare(path, "/") == 0 ? "" : path, fullpath, sizeof(fullpath)); #endif @@ -475,11 +474,7 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), // Dump the directories. Vector directories; -#ifdef TORQUE_SECURE_VFS Torque::FS::DumpDirectories(fullpath, directories, depth, true); -#else - Platform::dumpDirectories(fullpath, directories, depth, true); -#endif if( directories.empty() ) return ""; From ba07e6c6d7280bda93e31f18ccbe004576ca038d Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 08:08:43 -0400 Subject: [PATCH 11/20] * Cleanup: Remove the partial editor tools integration from the TORQUE_SECURE_VFS implementation in preference for developers building mod tools builds instead. --- .../source/windowManager/sdl/sdlWindowMgr.cpp | 82 ------------------- .../source/windowManager/sdl/sdlWindowMgr.h | 21 ----- 2 files changed, 103 deletions(-) diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp index 68def351a..dad0686d9 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp @@ -37,25 +37,6 @@ void sdl_CloseSplashWindow(void* hinst); #ifdef TORQUE_SDL -#ifdef TORQUE_SECURE_VFS -PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo() -{ -} - -PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo(String rootName, Torque::FS::FileSystemRef fileSystem) : mRootName(rootName), mDragAndDropFS(fileSystem) -{ - if (!Torque::FS::Mount(rootName, fileSystem)) - { - Con::errorf("Could not mount drag and drop FS!"); - } -} - -PlatformWindowManagerSDL::DragAndDropFSInfo::~DragAndDropFSInfo() -{ - -} -#endif - PlatformWindowManager * CreatePlatformWindowManager() { return new PlatformWindowManagerSDL(); @@ -87,15 +68,6 @@ PlatformWindowManagerSDL::PlatformWindowManagerSDL() PlatformWindowManagerSDL::~PlatformWindowManagerSDL() { - // Unmount all drag and drop FS mounts - for (auto iteration = mActiveDragAndDropFSByPath.begin(); iteration != mActiveDragAndDropFSByPath.end(); ++iteration) - { - auto&& mapping = *iteration; - Torque::FS::Unmount(mapping.value.mDragAndDropFS); - } - mActiveDragAndDropByRoot.clear(); - mActiveDragAndDropFSByPath.clear(); - // Kill all our windows first. while(mWindowListHead) // The destructors update the list, so this works just fine. @@ -457,61 +429,7 @@ void PlatformWindowManagerSDL::_process() if (!Platform::isDirectory(fileName) && !Platform::isFile(fileName)) break; -#ifdef TORQUE_SECURE_VFS - // Determine what the directory is so we can mount it - Torque::Path targetDirectory = Torque::Path(fileName); - - // If we're dropping a file, strip off file information - otherwise if a directory mount it directly - if (Platform::isFile(fileName)) - { - targetDirectory.setExtension(""); - targetDirectory.setFileName(""); - } - const String directoryName = targetDirectory.getDirectory(targetDirectory.getDirectoryCount() - 1); - - auto dropFSMount = mActiveDragAndDropFSByPath.find(targetDirectory); - if (dropFSMount == mActiveDragAndDropFSByPath.end()) - { - Torque::FS::FileSystemRef newMount = Platform::FS::createNativeFS(targetDirectory.getFullPath()); - - // Search for an unused root in case we have duplicate names - U32 rootCounter = 1; - String chosenRootName = directoryName; - auto search = mActiveDragAndDropByRoot.find(chosenRootName); - while (search != mActiveDragAndDropByRoot.end()) - { - char buffer[32]; - dSprintf(buffer, sizeof(buffer), "%u", rootCounter); - chosenRootName = directoryName + buffer; - - search = mActiveDragAndDropByRoot.find(chosenRootName); - } - - mActiveDragAndDropFSByPath[targetDirectory] = DragAndDropFSInfo(directoryName, newMount); - mActiveDragAndDropFSByPath[chosenRootName] = mActiveDragAndDropFSByPath[targetDirectory]; - } - - DragAndDropFSInfo& filesystemInformation = mActiveDragAndDropFSByPath[targetDirectory]; - - // Load source file information - Torque::Path sourceFile = fileName; - - // Build a reference to the file in VFS - Torque::Path targetFile; - targetFile.setRoot(filesystemInformation.mRootName); - targetFile.setPath("/"); - - // Only copy file & extension information if we're dropping a file - if (Platform::isFile(fileName)) - { - targetFile.setFileName(sourceFile.getFileName()); - targetFile.setExtension(sourceFile.getExtension()); - } - - Con::executef("onDropFile", StringTable->insert(targetFile.getFullPath())); -#else Con::executef("onDropFile", StringTable->insert(fileName)); -#endif SDL_free(fileName); // Free dropped_filedir memory break; diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.h b/Engine/source/windowManager/sdl/sdlWindowMgr.h index fc2ae4969..45cd3bfe3 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.h +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.h @@ -27,7 +27,6 @@ #include "gfx/gfxStructs.h" #include "windowManager/sdl/sdlWindow.h" #include "core/util/tVector.h" -#include "core/volume.h" struct SDL_Window; class FileDialog; // TODO SDL REMOVE @@ -58,18 +57,6 @@ public: RAW_INPUT = 2 /// < We only want raw input. }; -#ifdef TORQUE_SECURE_VFS - struct DragAndDropFSInfo - { - String mRootName; - Torque::FS::FileSystemRef mDragAndDropFS; - - DragAndDropFSInfo(); - DragAndDropFSInfo(String rootName, Torque::FS::FileSystemRef fileSystem); - ~DragAndDropFSInfo(); - }; -#endif - protected: friend class PlatformWindowSDL; friend class FileDialog; // TODO SDL REMOVE @@ -110,14 +97,6 @@ protected: /// After it is handled, it will return to state NONE. KeyboardInputState mInputState; -#ifdef TORQUE_SECURE_VFS - /// Used to check if a root is already used when generating root names. - HashMap mActiveDragAndDropByRoot; - - /// Used to keep track of what mounts are handling a given path. - HashMap mActiveDragAndDropFSByPath; -#endif - public: PlatformWindowManagerSDL(); ~PlatformWindowManagerSDL(); From 93a4f8780c71fe692daa92233d7c2cda4652bda0 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 08:20:46 -0400 Subject: [PATCH 12/20] * BugFix: Correct simple incorrect references after changing Platform::isFile to Torque::FS::isFile in the asset importer. --- Engine/source/T3D/assets/assetImporter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 997aa0163..2cba87d3f 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2819,7 +2819,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -2882,7 +2882,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) newAsset->setAssetName(assetName); - if (!isReimport && Torque::FS::isFile(qualifiedFromFile)) + if (!isReimport && Torque::FS::IsFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3072,7 +3072,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3352,7 +3352,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3413,7 +3413,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS:::isFile(qualifiedFromFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } From 59cf242a7a053d802f3fea6c5043c64cd3c5105a Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 10:32:39 -0400 Subject: [PATCH 13/20] * BugFix: Fix the data:/ VFS not being mounted if the root directory didn't already exist. --- Engine/source/platform/platformVolume.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Engine/source/platform/platformVolume.cpp b/Engine/source/platform/platformVolume.cpp index c7778b363..d7e4813ab 100644 --- a/Engine/source/platform/platformVolume.cpp +++ b/Engine/source/platform/platformVolume.cpp @@ -59,15 +59,18 @@ bool MountDefaults() // Always mount the data dir so scripts work in either configuration. This is used for eg. preferences storage. Path dataDirectory = Platform::getUserDataDirectory(); - Path appDataDirectory; - appDataDirectory.setPath(dataDirectory.getFileName()); - dataDirectory.appendPath(appDataDirectory); + Path appDataDirectory = Path::Join(dataDirectory.getFullPath().c_str(), '/', TORQUE_APP_NAME); - dataDirectory.setFileName(TORQUE_APP_NAME); + // Ensure the root of the data directory exists before trying to mount data VFS + if (!Platform::FS::IsDirectory(appDataDirectory) && !Platform::FS::CreateDirectory(appDataDirectory)) + { + // NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution + } - mounted = Mount("data", Platform::FS::createNativeFS(dataDirectory.getFullPath())); + mounted = Mount("data", Platform::FS::createNativeFS(appDataDirectory.getFullPath())); if (!mounted) { + // NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution return false; } From 3dafdef5da344870750c840444adca7707380eb4 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 10:53:01 -0400 Subject: [PATCH 14/20] * BugFix: Mount home:/ to refer to Torque's original Documents/ output for eg. prefs while leaving data:/ as an option for those that may want it. --- Engine/source/platform/platformVolume.cpp | 21 +++++++++++++++++-- .../utility/scripts/helperFunctions.tscript | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Engine/source/platform/platformVolume.cpp b/Engine/source/platform/platformVolume.cpp index d7e4813ab..556a57f37 100644 --- a/Engine/source/platform/platformVolume.cpp +++ b/Engine/source/platform/platformVolume.cpp @@ -57,9 +57,12 @@ bool MountDefaults() } #endif - // Always mount the data dir so scripts work in either configuration. This is used for eg. preferences storage. +#ifndef TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM + // Always mount the data & home dir so scripts work in either configuration. This is used for eg. preferences storage. Path dataDirectory = Platform::getUserDataDirectory(); Path appDataDirectory = Path::Join(dataDirectory.getFullPath().c_str(), '/', TORQUE_APP_NAME); + Path homeDirectory = Platform::getUserHomeDirectory(); + Path appHomeDirectory = Path::Join(homeDirectory.getFullPath().c_str(), '/', TORQUE_APP_NAME); // Ensure the root of the data directory exists before trying to mount data VFS if (!Platform::FS::IsDirectory(appDataDirectory) && !Platform::FS::CreateDirectory(appDataDirectory)) @@ -67,6 +70,13 @@ bool MountDefaults() // NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution } + // Ensure the root of the home directory exists before trying to mount home VFS + if (!Platform::FS::IsDirectory(appHomeDirectory) && !Platform::FS::CreateDirectory(appHomeDirectory)) + { + // NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution + } + + // data:/ points to a directory that is usually buried someplace harder to reach on OS mounted = Mount("data", Platform::FS::createNativeFS(appDataDirectory.getFullPath())); if (!mounted) { @@ -74,7 +84,14 @@ bool MountDefaults() return false; } -#ifndef TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM + // home:/ refers to your Documents/ folder which is easier to reach than the data:/ mount + mounted = Mount("home", Platform::FS::createNativeFS(appHomeDirectory.getFullPath())); + if (!mounted) + { + // NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution + return false; + } + // Note that the VirtualMountSystem must be enabled in volume.cpp for zip support to work. return MountZips("game"); #else diff --git a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript index 0743b149e..1c8538867 100644 --- a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript +++ b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.tscript @@ -175,7 +175,7 @@ function getUserPath() function getPrefpath() { - $prefPath = "data:/preferences"; + $prefPath = "home:/preferences"; return $prefPath; } From a390e0d8d549c6cce8a0e3fdd4680e4742b1099f Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 11:43:43 -0400 Subject: [PATCH 15/20] * BugFix: Correct script function 'compareFileTimes' not going through the VFS when making the comparisons. --- Engine/source/console/fileSystemFunctions.cpp | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index eee38f414..bf9c0ae63 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -584,17 +584,33 @@ DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* file "@return S32. If value is 1, then fileA is newer. If value is -1, then fileB is newer. If value is 0, they are equal.\n" "@ingroup FileSystem") { - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileA); + Torque::FS::FileNodeRef nodeA = Torque::FS::GetFileNode(fileA); + Torque::FS::FileNodeRef nodeB = Torque::FS::GetFileNode(fileB); - FileTime fileATime = { 0 }; - Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileATime); + // Can't do anything if either file doesn't exist + if (!nodeA || !nodeB) + { + return 0; + } - Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileB); + Torque::FS::FileNode::Attributes fileAAttributes; + Torque::FS::FileNode::Attributes fileABttributes; - FileTime fileBTime = { 0 }; - Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileBTime); + // If retrieval of attributes fails, we can't compare + if (!nodeA->getAttributes(&fileAAttributes) || !nodeB->getAttributes(&fileABttributes)) + { + return 0; + } - return Platform::compareFileTimes(fileATime, fileBTime); + if (fileAAttributes.mtime > fileABttributes.mtime) + { + return 1; + } + else if (fileAAttributes.mtime < fileABttributes.mtime) + { + return -1; + } + return 0; } DefineEngineFunction(fileDelete, bool, ( const char* path ),, From 1cd2b3ead98d53cf7fd21540a9fa3573daa83502 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 11:45:05 -0400 Subject: [PATCH 16/20] * BugFix: Correct a small typo in the script function 'compareFileTimes'. --- Engine/source/console/fileSystemFunctions.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index bf9c0ae63..cabb0b8d7 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -594,19 +594,19 @@ DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* file } Torque::FS::FileNode::Attributes fileAAttributes; - Torque::FS::FileNode::Attributes fileABttributes; + Torque::FS::FileNode::Attributes fileBAttributes; // If retrieval of attributes fails, we can't compare - if (!nodeA->getAttributes(&fileAAttributes) || !nodeB->getAttributes(&fileABttributes)) + if (!nodeA->getAttributes(&fileAAttributes) || !nodeB->getAttributes(&fileBAttributes)) { return 0; } - if (fileAAttributes.mtime > fileABttributes.mtime) + if (fileAAttributes.mtime > fileBAttributes.mtime) { return 1; } - else if (fileAAttributes.mtime < fileABttributes.mtime) + else if (fileAAttributes.mtime < fileBAttributes.mtime) { return -1; } From 0a45fac224db12eb09246ab10fe77a5b30683005 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 12:02:58 -0400 Subject: [PATCH 17/20] * BugFix: Switch a few raw platform calls in reflectionProbe.cpp to the VFS. --- Engine/source/T3D/lighting/reflectionProbe.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 1715ac758..bbb6cd90b 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -327,15 +327,15 @@ void ReflectionProbe::handleDeleteAction() if (mReflectionModeType != StaticCubemap) { String prefilPath = getPrefilterMapPath(); - if (Platform::isFile(prefilPath)) + if (Torque::FS::IsFile(prefilPath)) { - Platform::fileDelete(prefilPath); + Torque::FS::Remove(prefilPath); } String irrPath = getIrradianceMapPath(); - if (Platform::isFile(irrPath)) + if (Torque::FS::IsFile(irrPath)) { - Platform::fileDelete(irrPath); + Torque::FS::Remove(irrPath); } } From bd3a990140469b26b4b47ebb2ad11d6e8dfe315b Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 13 Jun 2022 12:21:06 -0400 Subject: [PATCH 18/20] * BugFix: Correct the 'gotoWebPage' function not using the VFS. --- Engine/source/console/consoleFunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index 4b43518e5..b17909184 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -2157,7 +2157,7 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),, // the bogus url, and hope for the best. String addr; - if( Platform::isFile( address ) || Platform::isDirectory( address ) ) + if( Torque::FS::IsFile( address ) || Torque::FS::IsDirectory( address ) ) { #ifdef TORQUE2D_TOOLS_FIXME addr = String::ToString( "file://%s", address ); From 2a865d387aeb5eb65b3dd926d286829dfe0db261 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Thu, 16 Jun 2022 18:46:25 -0400 Subject: [PATCH 19/20] * BugFix: When loading sound assets, don't resolve the absolute path. --- Engine/source/sfx/sfxProfile.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Engine/source/sfx/sfxProfile.cpp b/Engine/source/sfx/sfxProfile.cpp index ab3bc44ab..92c79e9e0 100644 --- a/Engine/source/sfx/sfxProfile.cpp +++ b/Engine/source/sfx/sfxProfile.cpp @@ -284,10 +284,7 @@ bool SFXProfile::_preloadBuffer() Resource& SFXProfile::getResource() { - char buf[1024]; - FileName fullFilename = String(Platform::makeFullPathName(mFilename, buf, sizeof(buf))); - - if (!mResource && SFXResource::exists(fullFilename)) + if (!mResource && SFXResource::exists(mFilename)) mResource = SFXResource::load(mFilename); else mResource = NULL; From 35b348f93cdec2cf56bd311e99abccbe7773d058 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Thu, 16 Jun 2022 19:04:43 -0400 Subject: [PATCH 20/20] * Adjustment: Change Platform::makeFullPathName to use "game:/" as cwd if none is specified. --- Engine/source/platform/platformFileIO.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Engine/source/platform/platformFileIO.cpp b/Engine/source/platform/platformFileIO.cpp index b4076a232..66d562cae 100644 --- a/Engine/source/platform/platformFileIO.cpp +++ b/Engine/source/platform/platformFileIO.cpp @@ -328,8 +328,13 @@ char * Platform::makeFullPathName(const char *path, char *buffer, U32 size, cons // [rene, 05/05/2008] Based on overall file handling in Torque, it does not seem to make // that much sense to me to base things off the current working directory here. + #ifndef TORQUE_SCECURE_VFS if(cwd == NULL) cwd = Con::isCurrentScriptToolScript() ? Platform::getMainDotCsDir() : Platform::getCurrentDirectory(); + #else + if (cwd == NULL) + cwd = "game:/"; + #endif dStrncpy(buffer, cwd, size); buffer[size-1] = 0;