sourcemod
sourcemod copied to clipboard
[Feature Request] Convert from Valve filesystem search paths
Help us help you
- [x] I have checked that my issue doesn't exist yet.
- [x] I have tried my absolute best to reduce the problem-space and have provided the absolute smallest test-case possible.
- [x] I can always reproduce the issue with the provided description below.
Environment
- Operating System version: Windows 11
- Game/AppID (with version if applicable): hl2dm
- Current SourceMod version: 1.12.0.7031
Description
While reading a file from the custom folder using Valve filesystem is effortless, as soon as you try opening it with a mode that is able to write, the file is not found. As far as I understand, this is a Valve limitation.
For a workaround (and other use cases) I suggest adding a function that either
- Returns all Valve search paths as real paths, so we can iterate over them
- Finds occurrences of a file in Valve FS and returns its real paths.
That way we can open the files for writing with normal filesystem.
Problematic Code (or Steps to Reproduce)
// custom/test/maps/myconfig.txt
OpenFile("maps/myconfig.txt", "r", true); // valid
OpenFile("maps/myconfig.txt", "r+", true); // null
OpenFile("custom/test/maps/myconfig.txt", "r+") // valid
SP workaround:
/**
* This is a workaround for opening existing files, potentially located in the custom folder, with the Valve filesystem, for both reading and writing.
* Normally, opening an existing file with Valve FS using any writable modes ("r+", "a", ..) will only look for files in root game folder.
* This function currently accounts for the custom folder only, other additional Valve search paths are ignored.
*
* https://github.com/alliedmodders/sourcemod/issues/2175
*/
stock File OpenFileEx(const char[] file, const char[] mode, bool use_valve_fs=false, const char[] valve_path_id="GAME")
{
if (use_valve_fs && !StrEqual(mode, "r", false) && !StrEqual(mode, "rb", false) && !StrEqual(mode, "rt", false))
{
char szFullPath[PLATFORM_MAX_PATH];
if (ResolveValveFile(file, szFullPath, sizeof(szFullPath)))
{
return OpenFile(szFullPath, mode);
}
}
return OpenFile(file, mode, use_valve_fs, valve_path_id);
}
/**
* Should only be used as last resort.
*/
stock bool ResolveValveFile(const char[] szFile, char[] szFullPath, int maxLen)
{
DirectoryListing dir = OpenDirectory("custom");
if (dir)
{
char buffer[PLATFORM_MAX_PATH];
FileType ft;
while (dir.GetNext(buffer, sizeof(buffer), ft))
{
if (ft == FileType_Directory && !StrEqual(buffer, ".") && !StrEqual(buffer, ".."))
{
Format(buffer, sizeof(buffer), "custom/%s/%s", buffer, szFile);
if (FileExists(buffer))
{
dir.Close();
Format(szFullPath, maxLen, buffer);
return true;
}
}
}
dir.Close();
}
return false;
}