Add new methods that take std::filesystem::path objects instead of
std::string objects, and which contain the logic, and make the methods
taking std::string objects into thin wrappers around them. The new
methods avoid a repeated conversions to paths, and will replace the old
methods in the public API at some point.
The Microsoft Store installs Fallout 4 DLC to separate directories
outside of the game's install path. The relative paths are fixed: users
cannot customise the install paths (aside from the folder within which
all games are installed on a drive), and renaming the DLC's path or its
Content directory causes an error when trying to launch the game.
The game scans these additional data paths similarly to how it scans
the main data path: it doesn't only load the DLC plugins from their
data paths, it will find non-DLC plugins in them, and DLC plugins can be
moved between them and still be detected. The same is true for BA2
files and other resources.
To support these separate directories:
- GameInterface::IsValidPlugin, GameInterface::LoadPlugins
and GameInterface::SortPlugins() now take plugin paths instead of
plugin filenames. Relative paths are interpreted as relative to the
data path, so the change is backwards-compatible, and absolute paths
are used as given.
- LoadPlugins now checks that all filenames in the given paths are
unique, which was previously required but not enforced.
- When scanning for archives, LOOT now scans the DLC data paths before
scanning the game data path.
- libloadorder and loot-condition-interpreter have been updated to
support the MS Store Fallout 4 DLC paths. libloadorder has built-in
support for the Fallout 4 DLCs specifically, so does not need to be
initialised, while loot-condition-interpreter's support is not
specific and so it's now passed a list of data paths that includes the
Fallout 4 DLC paths when appropriate.
When listing the DLC paths together with the game's main data path, the
order they're listed in matches the order in which the game scans them
for plugins, with the game stopping at the first directory in which it
finds a file it's looking for.
This introduces detection of whether or not a game install comes from
the Microsoft Store: like LOOT and libloadorder, libloot detects this by
looking for an appxmanifest.xml file in the install path.
The new Game::SetAdditionalDataPaths() method may be added to
GameInterface in the future: that hasn't been done yet because adding it
will break the ABI.
So that any data or metadata contradicting master flags will cause
a cyclic interaction error as they did before the plugin graph was split
in 232202c17e.
Most of the existing tests ave been rewritten as PluginGraphTest tests,
because the tests can be simpler, faster, clearer and more tightly
scoped to the functionality that's actually being tested.
For vertices in the plugin graph. This is so that the group and overlap
edges are evaluated in an order that does not depend on the current load
order. Tie-breaking still uses the current load order.
This is necessary because if the group and overlap edges that get added
depend on the current load order, sorting and applying changes the
current load order, so sorting again may give different results even
even though no plugin data or metadata has changed.
Rather than storing them in PluginSortingData, which is now immutable.
This also means the predecessor groups plugins map can use vertices
instead of plugin names, which is a
little simpler.
GCC 8 doesn't support C++17's parallel algorithms, which I'd like to
use, and GCC 10 is the newest major version available from Ubuntu
20.04's repositories.
This commit removes a Linux-only std::filesystem::path constructor test,
which fails due to a thrown exception when compiled with GCC 10. The
failure isn't important, because libloot avoids that particular
constructor: in a sense an exception is a bit better because it would
make any usage more obvious.