Skip to content

Commit

Permalink
PackageManager: Read the Paths values inside the system ini file for …
Browse files Browse the repository at this point in the history
…package searching and utilise PackageRemap section of the same ini if available
  • Loading branch information
LupertEverett authored and dpjudas committed Dec 31, 2023
1 parent 0e06809 commit c4192c2
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 19 deletions.
116 changes: 98 additions & 18 deletions SurrealEngine/Package/PackageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,9 @@ PackageManager::PackageManager(const GameLaunchInfo& launchInfo) : launchInfo(la
}

LoadIntFiles();
LoadPackageRemaps();
ScanForMaps();

// TODO: parse game ini for this info
ScanFolder("Maps", "*.unr");
ScanFolder("Maps", "*.dx"); // Deus Ex
if (IsUnreal1())
ScanFolder("Maps/UPak", "*.unr");
ScanFolder("Music", "*.umx");
ScanFolder("Sounds", "*.uax");
ScanFolder("System", "*.u");
ScanFolder("Textures", "*.utx");
ScanPaths();

InitPropertyOffsets(this);

Expand All @@ -95,16 +87,23 @@ Package* PackageManager::GetPackage(const NameString& name)
if (package)
return package.get();

auto it = packageFilenames.find(name);
// TODO: Is this how PackageRemap really works?
// There is no documentation of it anywhere it seems
NameString remapped_name = name;

auto remap_it = packageRemaps.find(name.ToString());
if (remap_it != packageRemaps.end())
{
remapped_name = NameString(remap_it->second);
}

auto it = packageFilenames.find(remapped_name);
if (it != packageFilenames.end())
{
package = std::make_unique<Package>(this, name, it->second);
package = std::make_unique<Package>(this, remapped_name, it->second);
}
else
{
// TODO: Read things from the PackageRemap section of the .ini, perhaps?
if (IsUnrealTournament() && name == "UnrealI")
return GetPackage("UnrealShare");
throw std::runtime_error("Could not find package " + name.ToString());
}

Expand Down Expand Up @@ -137,12 +136,51 @@ void PackageManager::ScanForMaps()
}
}

void PackageManager::ScanFolder(const std::string& name, const std::string& search)
void PackageManager::ScanFolder(const std::string& packagedir, const std::string& search)
{
std::string packagedir = FilePath::combine(launchInfo.folder, name);
for (std::string filename : Directory::files(FilePath::combine(packagedir, search)))
{
packageFilenames[NameString(FilePath::remove_extension(filename))] = FilePath::combine(packagedir, filename);
// Do not add the package again if it exists
// This is useful for example when you have HD textures installed in a different folder
// And you wish to load them instead of the original ones
auto it = packageFilenames.find(NameString(FilePath::remove_extension(filename)));
if (it == packageFilenames.end())
packageFilenames[NameString(FilePath::remove_extension(filename))] = FilePath::combine(packagedir, filename);
}
}

void PackageManager::ScanPaths()
{
auto paths = GetIniValues("system", "Core.System", "Paths");

for (auto& current_path : paths)
{
// Get the filename
std::string filename = FilePath::last_component(current_path);
current_path = FilePath::remove_last_component(current_path);

// Paths are relative from the System folder the executable (and the ini file) is in
// So we should start from there
auto resulting_root_path = FilePath::combine(launchInfo.folder, "System");

auto first_component = FilePath::first_component(current_path);

while (first_component == ".." || first_component == ".")
{
if (first_component == "..")
{
// "Go one directory up" as many as the amount of ".."s in the current_path
resulting_root_path = FilePath::remove_last_component(resulting_root_path);
}

current_path = FilePath::remove_first_component(current_path);
first_component = FilePath::first_component(current_path);
}

// Combine everything
auto final_path = FilePath::combine(resulting_root_path, current_path);

ScanFolder(final_path, filename);
}
}

Expand Down Expand Up @@ -232,6 +270,22 @@ UClass* PackageManager::FindClass(const NameString& name)
}
}

std::vector<NameString> PackageManager::GetIniKeysFromSection(NameString iniName, const NameString& sectionName)
{
if (iniName == "system" || iniName == "System")
iniName = launchInfo.gameName;
else if (iniName == "user")
iniName = "User";

auto& ini = iniFiles[iniName];
if (!ini)
{
ini = std::make_unique<IniFile>(FilePath::combine(launchInfo.folder, "System/" + iniName.ToString() + ".ini"));
}

return ini->GetKeys(sectionName);
}

std::string PackageManager::GetIniValue(NameString iniName, const NameString& sectionName, const NameString& keyName)
{
if (iniName == "system" || iniName == "System")
Expand All @@ -248,6 +302,32 @@ std::string PackageManager::GetIniValue(NameString iniName, const NameString& se
return ini->GetValue(sectionName, keyName);
}

std::vector<std::string> PackageManager::GetIniValues(NameString iniName, const NameString& sectionName, const NameString& keyName)
{
if (iniName == "system" || iniName == "System")
iniName = launchInfo.gameName;
else if (iniName == "user")
iniName = "User";

auto& ini = iniFiles[iniName];
if (!ini)
{
ini = std::make_unique<IniFile>(FilePath::combine(launchInfo.folder, "System/" + iniName.ToString() + ".ini"));
}

return ini->GetValues(sectionName, keyName);
}

void PackageManager::LoadPackageRemaps()
{
auto remap_keys = GetIniKeysFromSection("system", "PackageRemap");

for (auto& key : remap_keys)
{
packageRemaps[key.ToString()] = GetIniValue("system", "PackageRemap", key);
}
}

void PackageManager::LoadIntFiles()
{
std::string systemdir = FilePath::combine(launchInfo.folder, "System");
Expand Down
7 changes: 6 additions & 1 deletion SurrealEngine/Package/PackageManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,23 @@ class PackageManager

UClass* FindClass(const NameString& name);

std::vector<NameString> GetIniKeysFromSection(NameString iniName, const NameString& sectionName);
std::string GetIniValue(NameString iniName, const NameString& sectionName, const NameString& keyName);
std::vector<std::string> GetIniValues(NameString iniName, const NameString& sectionName, const NameString& keyName);
std::string Localize(NameString packageName, const NameString& sectionName, const NameString& keyName);

std::vector<IntObject>& GetIntObjects(const NameString& metaclass);
const std::vector<std::string>& GetMaps() const { return maps; }

private:
void LoadIntFiles();
void LoadPackageRemaps();
std::map<NameString, std::string> ParseIntPublicValue(const std::string& value);

void ScanForMaps();

void ScanFolder(const std::string& name, const std::string& search);
void ScanFolder(const std::string& packagedir, const std::string& search);
void ScanPaths();

void DelayLoadNow();

Expand All @@ -67,6 +71,7 @@ class PackageManager
std::map<NameString, std::unique_ptr<Package>> packages;
std::map<NameString, std::unique_ptr<IniFile>> iniFiles;
std::map<NameString, std::unique_ptr<IniFile>> intFiles;
std::map<std::string, std::string> packageRemaps;

std::map<NameString, std::vector<IntObject>> IntObjects;

Expand Down

0 comments on commit c4192c2

Please sign in to comment.