From 0523a2125527b6f59ad779bc9710f022043628f9 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 11 Aug 2026 11:19:50 -0400 Subject: [PATCH 1/2] refactor(lib): Add path separator helpers to PathUtil --- Core/Libraries/Include/Lib/PathUtil.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Core/Libraries/Include/Lib/PathUtil.h b/Core/Libraries/Include/Lib/PathUtil.h index cf1ce769d91..eddade82485 100644 --- a/Core/Libraries/Include/Lib/PathUtil.h +++ b/Core/Libraries/Include/Lib/PathUtil.h @@ -23,6 +23,29 @@ #include "BaseType.h" #include +inline char getNativePathSeparator() +{ +#ifdef _WIN32 + return '\\'; +#else + return '/'; +#endif +} + +inline const char* getLastPathSeparator(const char* path) +{ + const char* forward = strrchr(path, '/'); + const char* backward = strrchr(path, '\\'); + return !forward ? backward : (!backward || forward > backward ? forward : backward); +} + +inline const wchar_t* getLastPathSeparator(const wchar_t* path) +{ + const wchar_t* forward = wcsrchr(path, L'/'); + const wchar_t* backward = wcsrchr(path, L'\\'); + return !forward ? backward : (!backward || forward > backward ? forward : backward); +} + inline const char* getExtension(const char* path) { const char* lastDot = strrchr(path, '.'); @@ -32,7 +55,7 @@ inline const char* getExtension(const char* path) return nullptr; } - const char* lastSeparator = maxPtr(strrchr(path, '/'), strrchr(path, '\\')); + const char* lastSeparator = getLastPathSeparator(path); // Check if the dot is contained in the filename if (lastSeparator && lastDot < lastSeparator) @@ -52,7 +75,7 @@ inline const wchar_t* getExtension(const wchar_t* path) return nullptr; } - const wchar_t* lastSeparator = maxPtr(wcsrchr(path, L'/'), wcsrchr(path, L'\\')); + const wchar_t* lastSeparator = getLastPathSeparator(path); // Check if the dot is contained in the filename if (lastSeparator && lastDot < lastSeparator) From 7fb08ab4bb8c92b28cc65ac2accca292f4d1808c Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 11 Aug 2026 11:20:07 -0400 Subject: [PATCH 2/2] bugfix(network): Build map transfer paths with the platform separator --- .../Source/GameNetwork/FileTransfer.cpp | 57 ++++++++----------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/Core/GameEngine/Source/GameNetwork/FileTransfer.cpp b/Core/GameEngine/Source/GameNetwork/FileTransfer.cpp index 5d9cc7dfe64..9ef6e256032 100644 --- a/Core/GameEngine/Source/GameNetwork/FileTransfer.cpp +++ b/Core/GameEngine/Source/GameNetwork/FileTransfer.cpp @@ -34,6 +34,7 @@ #include "GameClient/Shell.h" #include "GameNetwork/FileTransfer.h" #include "GameNetwork/networkutil.h" +#include "Lib/PathUtil.h" //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- @@ -137,7 +138,7 @@ static Bool doFileTransfer( AsciiString filename, MapTransferLoadScreen *ls, Int AsciiString GetBasePathFromPath( AsciiString path ) { - const char *s = path.reverseFind('\\'); + const char *s = getLastPathSeparator(path.str()); if (s) { Int len = s - path.str(); @@ -153,7 +154,7 @@ AsciiString GetBasePathFromPath( AsciiString path ) AsciiString GetFileFromPath( AsciiString path ) { - const char *s = path.reverseFind('\\'); + const char *s = getLastPathSeparator(path.str()); if (s) return s+1; return path; @@ -183,59 +184,51 @@ AsciiString GetBaseFileFromFile( AsciiString fname ) return AsciiString::TheEmptyString; } +static AsciiString GetFileInMapDirectory( const AsciiString &mapPath, const AsciiString &filename ) +{ + AsciiString base = GetBasePathFromPath(mapPath); + if (base.isEmpty()) + { + return filename; + } + + const char *separator = getLastPathSeparator(mapPath.str()); + AsciiString path; + path.format("%s%c%s", base.str(), separator ? *separator : getNativePathSeparator(), filename.str()); + return path; +} + AsciiString GetPreviewFromMap( AsciiString path ) { AsciiString fname = GetBaseFileFromFile(GetFileFromPath(path)); - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\%s.tga", base.str(), fname.str()); - return out; + AsciiString preview; + preview.format("%s.tga", fname.str()); + return GetFileInMapDirectory(path, preview); } AsciiString GetINIFromMap( AsciiString path ) { - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\map.ini", base.str()); - return out; + return GetFileInMapDirectory(path, "map.ini"); } AsciiString GetStrFileFromMap( AsciiString path ) { - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\map.str", base.str()); - return out; + return GetFileInMapDirectory(path, "map.str"); } AsciiString GetSoloINIFromMap( AsciiString path ) { - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\solo.ini", base.str()); - return out; + return GetFileInMapDirectory(path, "solo.ini"); } AsciiString GetAssetUsageFromMap( AsciiString path ) { - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\assetusage.txt", base.str()); - return out; + return GetFileInMapDirectory(path, "assetusage.txt"); } AsciiString GetReadmeFromMap( AsciiString path ) { - AsciiString base = GetBasePathFromPath(path); - - AsciiString out; - out.format("%s\\readme.txt", base.str()); - return out; + return GetFileInMapDirectory(path, "readme.txt"); } //-------------------------------------------------------------------------------------