Skip to content

Commit a4fa456

Browse files
committed
Enhance ArchiveFileSystem: Add sortedByName option to loadIntoDirectoryTree and refactor community patch loading logic
Signed-off-by: tintinhamans <5984296+tintinhamans@users.noreply.github.com>
1 parent 123d592 commit a4fa456

3 files changed

Lines changed: 39 additions & 9 deletions

File tree

Core/GameEngine/Include/Common/ArchiveFileSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class ArchiveFileSystem : public SubsystemInterface
162162

163163
ArchivedDirectoryInfoResult getArchivedDirectoryInfo(const Char* directory);
164164

165-
virtual void loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite = FALSE); ///< load the archive file's header information and apply it to the global archive directory tree.
165+
virtual void loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite = FALSE, Bool sortedByName = FALSE); ///< load the archive file's header information and apply it to the global archive directory tree. sortedByName inserts by archive filename order (addon number convention), ignoring overwrite.
166166

167167
ArchiveFileMap m_archiveFileMap;
168168
ArchivedDirectoryInfo m_rootDirectory;

Core/GameEngine/Source/Common/System/ArchiveFileSystem.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "Common/ArchiveFile.h"
5050
#include "Common/ArchiveFileSystem.h"
5151
#include "Common/AsciiString.h"
52+
#include "Common/LocalFileSystem.h"
5253
#include "Common/PerfTimer.h"
5354
#include "../NGMP_include.h"
5455
#include "../OnlineServices_Init.h"
@@ -94,6 +95,15 @@ ArchiveFileSystem *TheArchiveFileSystem = nullptr;
9495
// Private Functions
9596
//----------------------------------------------------------------------------
9697

98+
static AsciiString getBaseFilename(const AsciiString& path)
99+
{
100+
const char* str = path.str();
101+
const char* p1 = strrchr(str, '\\');
102+
const char* p2 = strrchr(str, '/');
103+
const char* sep = (p1 == nullptr) ? p2 : ((p2 == nullptr) ? p1 : ((p1 > p2) ? p1 : p2));
104+
return sep ? AsciiString(sep + 1) : path;
105+
}
106+
97107

98108

99109
//----------------------------------------------------------------------------
@@ -117,7 +127,7 @@ ArchiveFileSystem::~ArchiveFileSystem()
117127
}
118128
}
119129

120-
void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite)
130+
void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite, Bool sortedByName)
121131
{
122132

123133
FilenameList filenameList;
@@ -157,7 +167,16 @@ void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool ove
157167
}
158168

159169
ArchivedFileLocationMap::iterator fileIt;
160-
if (overwrite)
170+
if (sortedByName)
171+
{
172+
// Insert by case-insensitive archive filename, matching game folder load order where the alphabetically first archive wins.
173+
const AsciiString baseName = getBaseFilename(archiveFile->getName());
174+
std::pair<ArchivedFileLocationMap::iterator, ArchivedFileLocationMap::iterator> range = dirInfo->m_files.equal_range(token);
175+
fileIt = range.first;
176+
while (fileIt != range.second && getBaseFilename(fileIt->second->getName()).compareNoCase(baseName) <= 0)
177+
++fileIt;
178+
}
179+
else if (overwrite)
161180
{
162181
// When overwriting, try place the new value at the beginning of the key list.
163182
fileIt = dirInfo->m_files.find(token);
@@ -218,9 +237,20 @@ void ArchiveFileSystem::loadMods()
218237
// load community data patch BIG
219238
if (NGMP_OnlineServicesManager::Settings.DataPacks_UseCommunityPatch())
220239
{
221-
std::string strSettingsFileDir = std::format("{}/GeneralsOnlineGameData/", TheGlobalData->getPath_UserData().str());
222-
bool bLoaded = TheArchiveFileSystem->loadBigFilesFromDirectory(strSettingsFileDir.c_str(), "500_900_CommunityPatch_CoreINI.big", TRUE);
223-
NetworkLog(ELogVerbosity::LOG_RELEASE, "Loaded community patch: %d", bLoaded);
240+
std::string strBigPath = std::format("{}GeneralsOnlineGameData/500_900_CommunityPatch_CoreINI.big", TheGlobalData->getPath_UserData().str());
241+
bool bLoaded = false;
242+
if (TheLocalFileSystem->doesFileExist(strBigPath.c_str()))
243+
{
244+
ArchiveFile* archiveFile = openArchiveFile(strBigPath.c_str());
245+
if (archiveFile != nullptr)
246+
{
247+
// Sorted by filename so the patch respects the addon number order of BIGs in the game folder.
248+
loadIntoDirectoryTree(archiveFile, FALSE, TRUE);
249+
m_archiveFileMap[AsciiString(strBigPath.c_str())] = archiveFile;
250+
bLoaded = true;
251+
}
252+
}
253+
NetworkLog(ELogVerbosity::LOG_RELEASE, "Loaded community patch (%s): %d", strBigPath.c_str(), bLoaded);
224254
}
225255
#endif
226256

GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,9 @@ void GameEngine::init()
528528
// special-case: parse command-line parameters after loading global data
529529
CommandLine::parseCommandLineForEngineInit();
530530

531+
// NGMP_CHANGE: Init our settings before loadMods, which reads DataPacks_UseCommunityPatch. Needs TheGlobalData for the user data path.
532+
NGMP_OnlineServicesManager::Settings.Initialize();
533+
531534
TheArchiveFileSystem->loadMods();
532535

533536
// doesn't require resets so just create a single instance here.
@@ -826,9 +829,6 @@ void GameEngine::init()
826829

827830
HideControlBar();
828831

829-
// NGMP_CHANGE: Init our settings
830-
NGMP_OnlineServicesManager::Settings.Initialize();
831-
832832
m_discordRichPresence = new GeneralsOnlineDiscordRPC();
833833
m_discordRichPresence->Initialize();
834834
}

0 commit comments

Comments
 (0)