Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Core/GameEngine/Include/Common/ArchiveFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class ArchiveFileSystem : public SubsystemInterface

ArchivedDirectoryInfoResult getArchivedDirectoryInfo(const Char* directory);

virtual void loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite = FALSE); ///< load the archive file's header information and apply it to the global archive directory tree.
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.

ArchiveFileMap m_archiveFileMap;
ArchivedDirectoryInfo m_rootDirectory;
Expand Down
40 changes: 35 additions & 5 deletions Core/GameEngine/Source/Common/System/ArchiveFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "Common/ArchiveFile.h"
#include "Common/ArchiveFileSystem.h"
#include "Common/AsciiString.h"
#include "Common/LocalFileSystem.h"
#include "Common/PerfTimer.h"
#include "../NGMP_include.h"
#include "../OnlineServices_Init.h"
Expand Down Expand Up @@ -94,6 +95,15 @@ ArchiveFileSystem *TheArchiveFileSystem = nullptr;
// Private Functions
//----------------------------------------------------------------------------

static AsciiString getBaseFilename(const AsciiString& path)
{
const char* str = path.str();
const char* p1 = strrchr(str, '\\');
const char* p2 = strrchr(str, '/');
const char* sep = (p1 == nullptr) ? p2 : ((p2 == nullptr) ? p1 : ((p1 > p2) ? p1 : p2));
return sep ? AsciiString(sep + 1) : path;
}



//----------------------------------------------------------------------------
Expand All @@ -117,7 +127,7 @@ ArchiveFileSystem::~ArchiveFileSystem()
}
}

void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite)
void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool overwrite, Bool sortedByName)
{

FilenameList filenameList;
Expand Down Expand Up @@ -157,7 +167,16 @@ void ArchiveFileSystem::loadIntoDirectoryTree(ArchiveFile *archiveFile, Bool ove
}

ArchivedFileLocationMap::iterator fileIt;
if (overwrite)
if (sortedByName)
{
// Insert by case-insensitive archive filename, matching game folder load order where the alphabetically first archive wins.
const AsciiString baseName = getBaseFilename(archiveFile->getName());
std::pair<ArchivedFileLocationMap::iterator, ArchivedFileLocationMap::iterator> range = dirInfo->m_files.equal_range(token);
fileIt = range.first;
while (fileIt != range.second && getBaseFilename(fileIt->second->getName()).compareNoCase(baseName) <= 0)
++fileIt;
}
else if (overwrite)
{
// When overwriting, try place the new value at the beginning of the key list.
fileIt = dirInfo->m_files.find(token);
Expand Down Expand Up @@ -218,9 +237,20 @@ void ArchiveFileSystem::loadMods()
// load community data patch BIG
if (NGMP_OnlineServicesManager::Settings.DataPacks_UseCommunityPatch())
{
std::string strSettingsFileDir = std::format("{}/GeneralsOnlineGameData/", TheGlobalData->getPath_UserData().str());
bool bLoaded = TheArchiveFileSystem->loadBigFilesFromDirectory(strSettingsFileDir.c_str(), "500_900_CommunityPatch_CoreINI.big", TRUE);
NetworkLog(ELogVerbosity::LOG_RELEASE, "Loaded community patch: %d", bLoaded);
std::string strBigPath = std::format("{}GeneralsOnlineGameData/500_900_CommunityPatch_CoreINI.big", TheGlobalData->getPath_UserData().str());
bool bLoaded = false;
if (TheLocalFileSystem->doesFileExist(strBigPath.c_str()))
{
ArchiveFile* archiveFile = openArchiveFile(strBigPath.c_str());
if (archiveFile != nullptr)
{
// Sorted by filename so the patch respects the addon number order of BIGs in the game folder.
loadIntoDirectoryTree(archiveFile, FALSE, TRUE);
m_archiveFileMap[AsciiString(strBigPath.c_str())] = archiveFile;
bLoaded = true;
}
}
NetworkLog(ELogVerbosity::LOG_RELEASE, "Loaded community patch (%s): %d", strBigPath.c_str(), bLoaded);
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ void GameEngine::init()
// special-case: parse command-line parameters after loading global data
CommandLine::parseCommandLineForEngineInit();

// NGMP_CHANGE: Init our settings before loadMods, which reads DataPacks_UseCommunityPatch. Needs TheGlobalData for the user data path.
NGMP_OnlineServicesManager::Settings.Initialize();

TheArchiveFileSystem->loadMods();

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

HideControlBar();

// NGMP_CHANGE: Init our settings
NGMP_OnlineServicesManager::Settings.Initialize();

m_discordRichPresence = new GeneralsOnlineDiscordRPC();
m_discordRichPresence->Initialize();
}
Expand Down
Loading