#include "gameskyrim.h" #include "skyrimbsainvalidation.h" #include "skyrimdataarchives.h" #include "skyrimgameplugins.h" #include "skyrimmoddatachecker.h" #include "skyrimmoddatacontent.h" #include "skyrimsavegame.h" #include "skyrimscriptextender.h" #include "executableinfo.h" #include "pluginsetting.h" #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include #endif #include #include #include #include #include using namespace MOBase; GameSkyrim::GameSkyrim() {} bool GameSkyrim::init(IOrganizer* moInfo) { if (!GameGamebryo::init(moInfo)) { return false; } auto dataArchives = std::make_shared(this); registerFeature(std::make_shared(this)); registerFeature(dataArchives); registerFeature(std::make_shared(dataArchives.get(), this)); registerFeature(std::make_shared(this)); registerFeature(std::make_shared(this, "Skyrim.ini")); registerFeature(std::make_shared(this)); registerFeature(std::make_shared(m_Organizer->gameFeatures())); registerFeature(std::make_shared(moInfo)); registerFeature(std::make_shared(this)); return true; } QString GameSkyrim::gameName() const { return "Skyrim"; } QList GameSkyrim::executables() const { return QList() << ExecutableInfo("SKSE", findInGameFolder(m_Organizer->gameFeatures() ->gameFeature() ->loaderName())) << ExecutableInfo("SBW", findInGameFolder("SBW.exe")) << ExecutableInfo("Skyrim", findInGameFolder(binaryName())) << ExecutableInfo("Skyrim Launcher", findInGameFolder(getLauncherName())) << ExecutableInfo("BOSS", findInGameFolder("BOSS/BOSS.exe")) << ExecutableInfo("LOOT", QFileInfo(getLootPath())) .withArgument("--game=\"Skyrim\"") << ExecutableInfo("Creation Kit", findInGameFolder("CreationKit.exe")) .withSteamAppId("202480"); } QList GameSkyrim::executableForcedLoads() const { return QList(); } QString GameSkyrim::name() const { return "Skyrim Support Plugin"; } QString GameSkyrim::localizedName() const { return tr("Skyrim Support Plugin"); } QString GameSkyrim::author() const { return "Tannin & MO2 Team"; } QString GameSkyrim::description() const { return tr("Adds support for the game Skyrim"); } MOBase::VersionInfo GameSkyrim::version() const { return VersionInfo(1, 6, 1, VersionInfo::RELEASE_FINAL); } QList GameSkyrim::settings() const { QList results; results.push_back( PluginSetting("sse_downloads", "allow Skyrim SE downloads", QVariant(false))); return results; } void GameSkyrim::initializeProfile(const QDir& path, ProfileSettings settings) const { if (settings.testFlag(IPluginGame::MODS)) { copyToProfile(localAppFolder() + "/Skyrim", path, "plugins.txt"); } if (settings.testFlag(IPluginGame::CONFIGURATION)) { if (settings.testFlag(IPluginGame::PREFER_DEFAULTS) || !QFileInfo(myGamesPath() + "/Skyrim.ini").exists()) { copyToProfile(gameDirectory().absolutePath(), path, "Skyrim_default.ini", "Skyrim.ini"); } else { copyToProfile(myGamesPath(), path, "Skyrim.ini"); } copyToProfile(myGamesPath(), path, "SkyrimPrefs.ini"); } } QString GameSkyrim::savegameExtension() const { return "ess"; } QString GameSkyrim::savegameSEExtension() const { return "skse"; } std::shared_ptr GameSkyrim::makeSaveGame(QString filepath) const { return std::make_shared(filepath, this); } QString GameSkyrim::steamAPPId() const { return "72850"; } QStringList GameSkyrim::primaryPlugins() const { return {"skyrim.esm", "update.esm"}; } QString GameSkyrim::binaryName() const { return "TESV.exe"; } QString GameSkyrim::gameShortName() const { return "Skyrim"; } QString GameSkyrim::gameNexusName() const { return "skyrim"; } QStringList GameSkyrim::validShortNames() const { QStringList results; if (m_Organizer->pluginSetting(name(), "sse_downloads").toBool()) { results.push_back("SkyrimSE"); } return results; } QStringList GameSkyrim::iniFiles() const { return {"Skyrim.ini", "SkyrimPrefs.ini"}; } QStringList GameSkyrim::DLCPlugins() const { return {"Dawnguard.esm", "Dragonborn.esm", "HearthFires.esm", "HighResTexturePack01.esp", "HighResTexturePack02.esp", "HighResTexturePack03.esp"}; } namespace { // Note: This is ripped off from shared/util. And in an upcoming move, the fomod // installer requires something similar. I suspect I should abstract this out // into gamebryo (or lower level) #ifdef _WIN32 VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName) { DWORD handle = 0UL; DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle); if (size == 0) { throw std::runtime_error("failed to determine file version info size"); } std::vector buffer(size); handle = 0UL; if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.data())) { throw std::runtime_error("failed to determine file version info"); } void* versionInfoPtr = nullptr; UINT versionInfoLength = 0; if (!::VerQueryValue(buffer.data(), L"\\", &versionInfoPtr, &versionInfoLength)) { throw std::runtime_error("failed to determine file version"); } return *static_cast(versionInfoPtr); } #endif } // namespace IPluginGame::LoadOrderMechanism GameSkyrim::loadOrderMechanism() const { #ifdef _WIN32 try { std::wstring fileName = gameDirectory().absoluteFilePath(binaryName()).toStdWString().c_str(); VS_FIXEDFILEINFO versionInfo = ::GetFileVersion(fileName); if ((versionInfo.dwFileVersionMS > 0x10004) || // version >= 1.5.x? ((versionInfo.dwFileVersionMS == 0x10004) && (versionInfo.dwFileVersionLS >= 0x1A0000))) { // version >= ?.4.26 return LoadOrderMechanism::PluginsTxt; } } catch (const std::exception& e) { qCritical() << "TESV.exe is invalid: " << e.what(); } #endif return LoadOrderMechanism::FileTime; } int GameSkyrim::nexusModOrganizerID() const { return 0; } int GameSkyrim::nexusGameID() const { return 110; }