diff --git a/SporeModLoader/SporeModLoader.cpp b/SporeModLoader/SporeModLoader.cpp index d176ed7..9b31a68 100644 --- a/SporeModLoader/SporeModLoader.cpp +++ b/SporeModLoader/SporeModLoader.cpp @@ -23,17 +23,21 @@ bool SporeModLoader::Initialize() try { Logger::Clear(); - - for (const auto& path : { Path::GetCoreLibsPath(), Path::GetModLibsPath() }) + + + for (const auto& paths : { Path::GetCoreLibsPaths(), Path::GetModLibsPaths() }) { - if (!std::filesystem::is_directory(path)) + for (const auto& path : paths) { - std::wstring errorMessage; - errorMessage = L"\""; - errorMessage += path.wstring(); - errorMessage += L"\" doesn't exist!"; - UI::ShowErrorMessage(errorMessage); - throw std::exception(); + if (!std::filesystem::exists(path)) + { + std::wstring errorMessage; + errorMessage = L"\""; + errorMessage += path.wstring(); + errorMessage += L"\" doesn't exist!"; + UI::ShowErrorMessage(errorMessage); + throw std::exception(); + } } } @@ -53,7 +57,7 @@ bool SporeModLoader::LoadCoreLibs() try { Logger::AddMessage(L"SporeModLoader::LoadCoreLibs()"); - if (!Library::LoadAllInPath(Path::GetCoreLibsPath())) + if (!Library::LoadAll(Path::GetCoreLibsPaths())) { throw std::exception(); } @@ -73,7 +77,7 @@ bool SporeModLoader::LoadModLibs() try { Logger::AddMessage(L"SporeModLoader::LoadModLibs()"); - if (!Library::LoadAllInPath(Path::GetModLibsPath())) + if (!Library::LoadAll(Path::GetModLibsPaths())) { throw std::exception(); } diff --git a/SporeModLoader/SporeModLoaderHelpers.cpp b/SporeModLoader/SporeModLoaderHelpers.cpp index 2c136db..a240502 100644 --- a/SporeModLoader/SporeModLoaderHelpers.cpp +++ b/SporeModLoader/SporeModLoaderHelpers.cpp @@ -56,8 +56,12 @@ std::filesystem::path Path::GetLogFilePath(void) return logFilePath; } -std::filesystem::path Path::GetCoreLibsPath(void) +std::vector Path::GetCoreLibsPaths(void) { + std::vector coreLibsPaths; + std::string legacyLibFile; + std::filesystem::path legacyLibPath; + std::filesystem::path coreLibPath; std::filesystem::path coreLibsPath; coreLibsPath = GetModLoaderPath(); @@ -70,31 +74,93 @@ std::filesystem::path Path::GetCoreLibsPath(void) throw std::exception(); case Game::GameVersion::Origin_1_5_1: + case Game::GameVersion::Origin_March2017: + UI::ShowErrorMessage(L"Unsupported Spore version!"); + throw std::exception(); + case Game::GameVersion::GogOrSteam_1_5_1: UI::ShowErrorMessage(L"Update Spore to the latest version!"); throw std::exception(); - case Game::GameVersion::Origin_March2017: case Game::GameVersion::GogOrSteam_March2017: - coreLibsPath += "\\march2017"; + coreLibsPath += "\\march2017\\"; + legacyLibFile = "SporeModAPI-steam_patched.dll"; break; case Game::GameVersion::Disk_1_5_1: - coreLibsPath += "\\disk"; + coreLibsPath += "\\disk\\"; + legacyLibFile = "SporeModAPI-disk.dll"; break; } - return coreLibsPath; + coreLibPath = coreLibsPath; + coreLibPath += "SporeModAPI.dll"; + + legacyLibPath = coreLibsPath; + legacyLibPath += legacyLibFile; + + coreLibsPaths.push_back(coreLibPath); + coreLibsPaths.push_back(legacyLibPath); + + return coreLibsPaths; } -std::filesystem::path Path::GetModLibsPath(void) +std::vector Path::GetModLibsPaths(void) { + std::vector modLibsPaths; std::filesystem::path modLibsPath; + Game::GameVersion gameVersion; + std::vector excludePostfixes; modLibsPath = GetModLoaderPath(); modLibsPath += "\\ModLibs"; - return modLibsPath; + // we have to create an exclusion list + // for the postfixes for the mod dlls + // due to support for the legacy ModAPI DLLs + // where games shipped a dll with either the + // -steam, -steam_patched or -disk postfix + gameVersion = Game::GetCurrentVersion(); + if (gameVersion == Game::GameVersion::GogOrSteam_March2017) + { + excludePostfixes.push_back("-steam.dll"); + excludePostfixes.push_back("-disk.dll"); + } + else + { + excludePostfixes.push_back("-steam.dll"); + excludePostfixes.push_back("-steam_patched.dll"); + } + + for (const auto& entry : std::filesystem::recursive_directory_iterator(modLibsPath)) + { + // skip non-files & non-dlls + if (!entry.is_regular_file() || + !entry.path().has_extension() || + entry.path().extension() != ".dll") + { + continue; + } + + // ensure we have an allowed postfix + bool skipLib = false; + for (const auto& postFix : excludePostfixes) + { + if (entry.path().filename().string().ends_with(postFix)) + { + skipLib = true; + break; + } + } + + + if (!skipLib) + { + modLibsPaths.push_back(entry.path()); + } + } + + return modLibsPaths; } void Logger::Clear(void) @@ -137,24 +203,16 @@ void UI::ShowErrorMessage(std::wstring message) MessageBoxW(nullptr, message.c_str(), L"SporeModLoader", MB_OK | MB_ICONERROR); } -bool Library::LoadAllInPath(std::filesystem::path path) +bool Library::LoadAll(std::vector paths) { - for (const auto& entry : std::filesystem::recursive_directory_iterator(path)) + for (const auto& path : paths) { - // skip non-files & non-dlls - if (!entry.is_regular_file() || - !entry.path().has_extension() || - entry.path().extension() != ".dll") - { - continue; - } - // attempt to load library - bool ret = LoadLibraryW(entry.path().wstring().c_str()) != nullptr; + bool ret = LoadLibraryW(path.wstring().c_str()) != nullptr; std::wstring logMessage; logMessage = L"LoadLibraryW(\""; - logMessage += entry.path().wstring(); + logMessage += path.wstring(); logMessage += L"\") == "; logMessage += std::to_wstring((ret ? 1 : GetLastError())); Logger::AddMessage(logMessage); @@ -163,7 +221,7 @@ bool Library::LoadAllInPath(std::filesystem::path path) { std::wstring errorMessage; errorMessage = L"LoadLibraryW(\""; - errorMessage += entry.path().wstring(); + errorMessage += path.wstring(); errorMessage += L"\") Failed!"; UI::ShowErrorMessage(errorMessage); return false; diff --git a/SporeModLoader/SporeModLoaderHelpers.hpp b/SporeModLoader/SporeModLoaderHelpers.hpp index 475907b..0d20106 100644 --- a/SporeModLoader/SporeModLoaderHelpers.hpp +++ b/SporeModLoader/SporeModLoaderHelpers.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace SporeModLoaderHelpers { @@ -33,14 +34,14 @@ namespace SporeModLoaderHelpers std::filesystem::path GetLogFilePath(void); /// - /// Returns path to the core libs + /// Returns paths to the core libs /// - std::filesystem::path GetCoreLibsPath(void); + std::vector GetCoreLibsPaths(void); /// - /// Returns path to the mod libs + /// Returns paths to the mod libs /// - std::filesystem::path GetModLibsPath(void); + std::vector GetModLibsPaths(void); } namespace Logger @@ -67,9 +68,9 @@ namespace SporeModLoaderHelpers namespace Library { /// - /// Loads all DLL files that are in path + /// Loads all specified DLL files /// - bool LoadAllInPath(std::filesystem::path path); + bool LoadAll(std::vector paths); } namespace Game