Merge pull request #29 from ModOrganizer2/dev/format-and-gh-actions

This commit is contained in:
Mikaël Capelle
2024-06-09 13:42:44 +02:00
committed by GitHub
20 changed files with 506 additions and 453 deletions
+41
View File
@@ -0,0 +1,41 @@
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 2
---
Language: Cpp
DeriveLineEnding: false
UseCRLF: true
DerivePointerAlignment: false
PointerAlignment: Left
AlignConsecutiveAssignments: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Empty
AlwaysBreakTemplateDeclarations: Yes
AccessModifierOffset: -2
AlignTrailingComments: true
SpacesBeforeTrailingComments: 2
NamespaceIndentation: Inner
MaxEmptyLinesToKeep: 1
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true
ColumnLimit: 88
ForEachMacros: ['Q_FOREACH', 'foreach']
+1
View File
@@ -0,0 +1 @@
130524f58eb58daa22e87727563254ce0025a35b
+7
View File
@@ -0,0 +1,7 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.cpp text eol=crlf
*.h text eol=crlf
+16
View File
@@ -0,0 +1,16 @@
name: Build Skyrim Plugin
on:
push:
branches: master
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
runs-on: windows-2022
steps:
- name: Build Skyrim Plugin
uses: ModOrganizer2/build-with-mob-action@master
with:
mo2-dependencies: cmake_common uibase game_gamebryo
+16
View File
@@ -0,0 +1,16 @@
name: Lint Skyrim Plugin
on:
push:
pull_request:
types: [opened, synchronize, reopened]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check format
uses: ModOrganizer2/check-formatting-action@master
with:
check-path: "."
-40
View File
@@ -1,40 +0,0 @@
version: 1.0.{build}
skip_branch_with_pr: true
image: Visual Studio 2019
environment:
WEBHOOK_URL:
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1Vbg57wBaeLhi49uGjxPw5GVujHku6kxN6ab89zhbS5GVeluR76GM83IbKV4Sh7udXzoYZZdg6YudtYHzdhCgUeiedpswbuczTq9ceIkkfSEWZuh/lMAAVVwvcGsJAnoPFw=
build_script:
- pwsh: >-
$ErrorActionPreference = 'Stop'
git clone --depth=1 --no-single-branch https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella
New-Item -ItemType Directory -Path c:\projects\modorganizer-build
cd c:\projects\modorganizer-umbrella
($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH -eq $null) ? ($branch = $env:APPVEYOR_REPO_BRANCH) : ($branch = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH)
git checkout $(git show-ref --verify --quiet refs/remotes/origin/${branch} || echo '-b') ${branch}
C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True ${env:APPVEYOR_PROJECT_NAME}
if($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode ) }
artifacts:
- path: vsbuild\src\RelWithDebInfo\game_skyrim.dll
name: game_skyrim_dll
- path: vsbuild\src\RelWithDebInfo\game_skyrim.pdb
name: game_skyrim_pdb
- path: vsbuild\src\RelWithDebInfo\game_skyrim.lib
name: game_skyrim_lib
on_success:
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
- ps: ./send.ps1 success $env:WEBHOOK_URL
on_failure:
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stdout.log
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stderr.log
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
- ps: ./send.ps1 failure $env:WEBHOOK_URL
+51 -41
View File
@@ -1,20 +1,20 @@
#include "gameskyrim.h"
#include "skyrimbsainvalidation.h"
#include "skyrimscriptextender.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 <gamebryolocalsavegames.h>
#include <gamebryogameplugins.h>
#include <gamebryounmanagedmods.h>
#include <gamebryolocalsavegames.h>
#include <gamebryosavegameinfo.h>
#include <gamebryounmanagedmods.h>
#include <QCoreApplication>
#include <QDebug>
@@ -33,11 +33,9 @@
using namespace MOBase;
GameSkyrim::GameSkyrim()
{
}
GameSkyrim::GameSkyrim() {}
bool GameSkyrim::init(IOrganizer *moInfo)
bool GameSkyrim::init(IOrganizer* moInfo)
{
if (!GameGamebryo::init(moInfo)) {
return false;
@@ -48,7 +46,8 @@ bool GameSkyrim::init(IOrganizer *moInfo)
registerFeature(dataArchives);
registerFeature(std::make_shared<SkyrimBSAInvalidation>(dataArchives.get(), this));
registerFeature(std::make_shared<GamebryoSaveGameInfo>(this));
registerFeature(std::make_shared<GamebryoLocalSavegames>(myGamesPath(), "skyrim.ini"));
registerFeature(
std::make_shared<GamebryoLocalSavegames>(myGamesPath(), "skyrim.ini"));
registerFeature(std::make_shared<SkyrimModDataChecker>(this));
registerFeature(std::make_shared<SkyrimModDataContent>(m_Organizer->gameFeatures()));
registerFeature(std::make_shared<SkyrimGamePlugins>(moInfo));
@@ -65,14 +64,18 @@ QString GameSkyrim::gameName() const
QList<ExecutableInfo> GameSkyrim::executables() const
{
return QList<ExecutableInfo>()
<< ExecutableInfo("SKSE", findInGameFolder(m_Organizer->gameFeatures()->gameFeature<MOBase::ScriptExtender>()->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")
;
<< ExecutableInfo("SKSE",
findInGameFolder(m_Organizer->gameFeatures()
->gameFeature<MOBase::ScriptExtender>()
->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<ExecutableForcedLoadSetting> GameSkyrim::executableForcedLoads() const
@@ -108,20 +111,22 @@ MOBase::VersionInfo GameSkyrim::version() const
QList<PluginSetting> GameSkyrim::settings() const
{
QList<PluginSetting> results;
results.push_back(PluginSetting("sse_downloads", "allow Skyrim SE downloads", QVariant(false)));
results.push_back(
PluginSetting("sse_downloads", "allow Skyrim SE downloads", QVariant(false)));
return results;
}
void GameSkyrim::initializeProfile(const QDir &path, ProfileSettings settings) const
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");
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");
}
@@ -152,7 +157,7 @@ QString GameSkyrim::steamAPPId() const
QStringList GameSkyrim::primaryPlugins() const
{
return { "skyrim.esm", "update.esm" };
return {"skyrim.esm", "update.esm"};
}
QString GameSkyrim::binaryName() const
@@ -173,33 +178,37 @@ QString GameSkyrim::gameNexusName() const
QStringList GameSkyrim::validShortNames() const
{
QStringList results;
if (m_Organizer->pluginSetting(name(), "sse_downloads").toBool())
{
results.push_back( "SkyrimSE" );
if (m_Organizer->pluginSetting(name(), "sse_downloads").toBool()) {
results.push_back("SkyrimSE");
}
return results;
}
QStringList GameSkyrim::iniFiles() const
{
return { "skyrim.ini", "skyrimprefs.ini" };
return {"skyrim.ini", "skyrimprefs.ini"};
}
QStringList GameSkyrim::DLCPlugins() const
{
return { "Dawnguard.esm", "Dragonborn.esm", "HearthFires.esm",
"HighResTexturePack01.esp", "HighResTexturePack02.esp", "HighResTexturePack03.esp" };
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)
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)
VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName)
{
DWORD handle = 0UL;
DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
if (size == 0) {
throw std::runtime_error("failed to determine file version info size");
}
@@ -210,7 +219,7 @@ VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
throw std::runtime_error("failed to determine file version info");
}
void *versionInfoPtr = nullptr;
void* versionInfoPtr = nullptr;
UINT versionInfoLength = 0;
if (!::VerQueryValue(buffer.data(), L"\\", &versionInfoPtr, &versionInfoLength)) {
throw std::runtime_error("failed to determine file version");
@@ -219,24 +228,25 @@ VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
return *static_cast<VS_FIXEDFILEINFO*>(versionInfoPtr);
}
}
} // namespace
IPluginGame::LoadOrderMechanism GameSkyrim::loadOrderMechanism() const
{
try {
std::wstring fileName = gameDirectory().absoluteFilePath(binaryName()).toStdWString().c_str();
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
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) {
} catch (const std::exception& e) {
qCritical() << "TESV.exe is invalid: " << e.what();
}
return LoadOrderMechanism::FileTime;
}
int GameSkyrim::nexusModOrganizerID() const
{
return 0;
+55 -56
View File
@@ -1,56 +1,55 @@
#ifndef GAMESKYRIM_H
#define GAMESKYRIM_H
#include "gamegamebryo.h"
#include <QObject>
#include <QtGlobal>
class GameSkyrim : public GameGamebryo
{
Q_OBJECT
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
Q_PLUGIN_METADATA(IID "org.tannin.GameSkyrim" FILE "gameskyrim.json")
#endif
public:
GameSkyrim();
virtual bool init(MOBase::IOrganizer *moInfo) override;
public: // IPluginGame interface
virtual QString gameName() const override;
virtual QList<MOBase::ExecutableInfo> executables() const override;
virtual QList<MOBase::ExecutableForcedLoadSetting> executableForcedLoads() const override;
virtual void initializeProfile(const QDir &path, ProfileSettings settings) const override;
virtual QString steamAPPId() const override;
virtual QStringList primaryPlugins() const override;
virtual QString binaryName() const override;
virtual QString gameShortName() const override;
virtual QString gameNexusName() const override;
virtual QStringList validShortNames() const override;
virtual QStringList iniFiles() const override;
virtual QStringList DLCPlugins() const override;
virtual LoadOrderMechanism loadOrderMechanism() const override;
virtual int nexusModOrganizerID() const override;
virtual int nexusGameID() const override;
public: // IPlugin interface
virtual QString name() const override;
virtual QString localizedName() const override;
virtual QString author() const override;
virtual QString description() const override;
virtual MOBase::VersionInfo version() const override;
virtual QList<MOBase::PluginSetting> settings() const override;
protected:
virtual QString savegameExtension() const override;
virtual QString savegameSEExtension() const override;
virtual std::shared_ptr<const GamebryoSaveGame> makeSaveGame(QString filepath) const override;
};
#endif // GAMESKYRIM_H
#ifndef GAMESKYRIM_H
#define GAMESKYRIM_H
#include "gamegamebryo.h"
#include <QObject>
#include <QtGlobal>
class GameSkyrim : public GameGamebryo
{
Q_OBJECT
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
Q_PLUGIN_METADATA(IID "org.tannin.GameSkyrim" FILE "gameskyrim.json")
#endif
public:
GameSkyrim();
virtual bool init(MOBase::IOrganizer* moInfo) override;
public: // IPluginGame interface
virtual QString gameName() const override;
virtual QList<MOBase::ExecutableInfo> executables() const override;
virtual QList<MOBase::ExecutableForcedLoadSetting>
executableForcedLoads() const override;
virtual void initializeProfile(const QDir& path,
ProfileSettings settings) const override;
virtual QString steamAPPId() const override;
virtual QStringList primaryPlugins() const override;
virtual QString binaryName() const override;
virtual QString gameShortName() const override;
virtual QString gameNexusName() const override;
virtual QStringList validShortNames() const override;
virtual QStringList iniFiles() const override;
virtual QStringList DLCPlugins() const override;
virtual LoadOrderMechanism loadOrderMechanism() const override;
virtual int nexusModOrganizerID() const override;
virtual int nexusGameID() const override;
public: // IPlugin interface
virtual QString name() const override;
virtual QString localizedName() const override;
virtual QString author() const override;
virtual QString description() const override;
virtual MOBase::VersionInfo version() const override;
virtual QList<MOBase::PluginSetting> settings() const override;
protected:
virtual QString savegameExtension() const override;
virtual QString savegameSEExtension() const override;
virtual std::shared_ptr<const GamebryoSaveGame>
makeSaveGame(QString filepath) const override;
};
#endif // GAMESKYRIM_H
+16 -16
View File
@@ -1,16 +1,16 @@
#include "skyrimbsainvalidation.h"
SkyrimBSAInvalidation::SkyrimBSAInvalidation(MOBase::DataArchives *dataArchives, MOBase::IPluginGame const *game)
: GamebryoBSAInvalidation(dataArchives, "skyrim.ini", game)
{
}
QString SkyrimBSAInvalidation::invalidationBSAName() const
{
return "Skyrim - Invalidation.bsa";
}
unsigned long SkyrimBSAInvalidation::bsaVersion() const
{
return 0x68;
}
#include "skyrimbsainvalidation.h"
SkyrimBSAInvalidation::SkyrimBSAInvalidation(MOBase::DataArchives* dataArchives,
MOBase::IPluginGame const* game)
: GamebryoBSAInvalidation(dataArchives, "skyrim.ini", game)
{}
QString SkyrimBSAInvalidation::invalidationBSAName() const
{
return "Skyrim - Invalidation.bsa";
}
unsigned long SkyrimBSAInvalidation::bsaVersion() const
{
return 0x68;
}
+20 -23
View File
@@ -1,23 +1,20 @@
#ifndef SKYRIMBSAINVALIDATION_H
#define SKYRIMBSAINVALIDATION_H
#include "gamebryobsainvalidation.h"
#include "skyrimdataarchives.h"
#include <memory>
class SkyrimBSAInvalidation : public GamebryoBSAInvalidation
{
public:
SkyrimBSAInvalidation(MOBase::DataArchives *dataArchives, MOBase::IPluginGame const *game);
private:
virtual QString invalidationBSAName() const override;
virtual unsigned long bsaVersion() const override;
};
#endif // SKYRIMBSAINVALIDATION_H
#ifndef SKYRIMBSAINVALIDATION_H
#define SKYRIMBSAINVALIDATION_H
#include "gamebryobsainvalidation.h"
#include "skyrimdataarchives.h"
#include <memory>
class SkyrimBSAInvalidation : public GamebryoBSAInvalidation
{
public:
SkyrimBSAInvalidation(MOBase::DataArchives* dataArchives,
MOBase::IPluginGame const* game);
private:
virtual QString invalidationBSAName() const override;
virtual unsigned long bsaVersion() const override;
};
#endif // SKYRIMBSAINVALIDATION_H
+46 -49
View File
@@ -1,49 +1,46 @@
#include "skyrimdataarchives.h"
#include <utility.h>
SkyrimDataArchives::SkyrimDataArchives(const QDir &myGamesDir) :
GamebryoDataArchives(myGamesDir)
{
}
QStringList SkyrimDataArchives::vanillaArchives() const
{
return { "Skyrim - Misc.bsa"
, "Skyrim - Shaders.bsa"
, "Skyrim - Textures.bsa"
, "HighResTexturePack01.bsa"
, "HighResTexturePack02.bsa"
, "HighResTexturePack03.bsa"
, "Skyrim - Interface.bsa"
, "Skyrim - Animations.bsa"
, "Skyrim - Meshes.bsa"
, "Skyrim - Sounds.bsa"
, "Skyrim - Voices.bsa"
, "Skyrim - VoicesExtra.bsa" };
}
QStringList SkyrimDataArchives::archives(const MOBase::IProfile *profile) const
{
QStringList result;
QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini") : m_LocalGameDir.absoluteFilePath("skyrim.ini");
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList"));
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList2"));
return result;
}
void SkyrimDataArchives::writeArchiveList(MOBase::IProfile *profile, const QStringList &before)
{
QString list = before.join(", ");
QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini") : m_LocalGameDir.absoluteFilePath("skyrim.ini");
if (list.length() > 255) {
int splitIdx = list.lastIndexOf(",", 256);
setArchivesToKey(iniFile, "SResourceArchiveList", list.mid(0, splitIdx));
setArchivesToKey(iniFile, "SResourceArchiveList2", list.mid(splitIdx + 2));
} else {
setArchivesToKey(iniFile, "SResourceArchiveList", list);
}
}
#include "skyrimdataarchives.h"
#include <utility.h>
SkyrimDataArchives::SkyrimDataArchives(const QDir& myGamesDir)
: GamebryoDataArchives(myGamesDir)
{}
QStringList SkyrimDataArchives::vanillaArchives() const
{
return {"Skyrim - Misc.bsa", "Skyrim - Shaders.bsa",
"Skyrim - Textures.bsa", "HighResTexturePack01.bsa",
"HighResTexturePack02.bsa", "HighResTexturePack03.bsa",
"Skyrim - Interface.bsa", "Skyrim - Animations.bsa",
"Skyrim - Meshes.bsa", "Skyrim - Sounds.bsa",
"Skyrim - Voices.bsa", "Skyrim - VoicesExtra.bsa"};
}
QStringList SkyrimDataArchives::archives(const MOBase::IProfile* profile) const
{
QStringList result;
QString iniFile = profile->localSettingsEnabled()
? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini")
: m_LocalGameDir.absoluteFilePath("skyrim.ini");
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList"));
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList2"));
return result;
}
void SkyrimDataArchives::writeArchiveList(MOBase::IProfile* profile,
const QStringList& before)
{
QString list = before.join(", ");
QString iniFile = profile->localSettingsEnabled()
? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini")
: m_LocalGameDir.absoluteFilePath("skyrim.ini");
if (list.length() > 255) {
int splitIdx = list.lastIndexOf(",", 256);
setArchivesToKey(iniFile, "SResourceArchiveList", list.mid(0, splitIdx));
setArchivesToKey(iniFile, "SResourceArchiveList2", list.mid(splitIdx + 2));
} else {
setArchivesToKey(iniFile, "SResourceArchiveList", list);
}
}
+25 -28
View File
@@ -1,28 +1,25 @@
#ifndef SKYRIMDATAARCHIVES_H
#define SKYRIMDATAARCHIVES_H
#include <gamebryodataarchives.h>
#include <iprofile.h>
#include <QString>
#include <QStringList>
#include <QDir>
class SkyrimDataArchives : public GamebryoDataArchives
{
public:
SkyrimDataArchives(const QDir &myGamesDir);
public:
virtual QStringList vanillaArchives() const override;
virtual QStringList archives(const MOBase::IProfile *profile) const override;
private:
virtual void writeArchiveList(MOBase::IProfile *profile, const QStringList &before) override;
};
#endif // SKYRIMDATAARCHIVES_H
#ifndef SKYRIMDATAARCHIVES_H
#define SKYRIMDATAARCHIVES_H
#include <QDir>
#include <QString>
#include <QStringList>
#include <gamebryodataarchives.h>
#include <iprofile.h>
class SkyrimDataArchives : public GamebryoDataArchives
{
public:
SkyrimDataArchives(const QDir& myGamesDir);
public:
virtual QStringList vanillaArchives() const override;
virtual QStringList archives(const MOBase::IProfile* profile) const override;
private:
virtual void writeArchiveList(MOBase::IProfile* profile,
const QStringList& before) override;
};
#endif // SKYRIMDATAARCHIVES_H
+80 -78
View File
@@ -1,44 +1,44 @@
#include "skyrimgameplugins.h"
#include <safewritefile.h>
#include <report.h>
#include <ipluginlist.h>
#include <report.h>
#include <safewritefile.h>
#include <scopeguard.h>
#include <QDir>
#include <QStringList>
#include <QStringEncoder>
#include <QStringList>
using MOBase::IOrganizer;
using MOBase::IPluginGame;
using MOBase::IPluginList;
using MOBase::IOrganizer;
using MOBase::SafeWriteFile;
using MOBase::reportError;
using MOBase::SafeWriteFile;
SkyrimGamePlugins::SkyrimGamePlugins(IOrganizer *organizer)
SkyrimGamePlugins::SkyrimGamePlugins(IOrganizer* organizer)
: GamebryoGamePlugins(organizer)
{}
void SkyrimGamePlugins::readPluginLists(MOBase::IPluginList *pluginList) {
QString loadOrderPath =
organizer()->profile()->absolutePath() + "/loadorder.txt";
QString pluginsPath = organizer()->profile()->absolutePath() + "/plugins.txt";
void SkyrimGamePlugins::readPluginLists(MOBase::IPluginList* pluginList)
{
QString loadOrderPath = organizer()->profile()->absolutePath() + "/loadorder.txt";
QString pluginsPath = organizer()->profile()->absolutePath() + "/plugins.txt";
bool loadOrderIsNew = !m_LastRead.isValid() ||
!QFileInfo(loadOrderPath).exists() ||
QFileInfo(loadOrderPath).lastModified() > m_LastRead;
bool pluginsIsNew = !m_LastRead.isValid() ||
QFileInfo(pluginsPath).lastModified() > m_LastRead;
bool loadOrderIsNew = !m_LastRead.isValid() || !QFileInfo(loadOrderPath).exists() ||
QFileInfo(loadOrderPath).lastModified() > m_LastRead;
bool pluginsIsNew =
!m_LastRead.isValid() || QFileInfo(pluginsPath).lastModified() > m_LastRead;
if (pluginsIsNew && !loadOrderIsNew) {
// If the plugins is new but not loadorder, we must reparse the load order from the plugin files
// If the plugins is new but not loadorder, we must reparse the load order from the
// plugin files
//removed because returned loadorder was incorrect and did not account for plugins that were already disabled before.
// removed because returned loadorder was incorrect and did not account for plugins
// that were already disabled before.
/*QStringList loadOrder = readPluginList(pluginList);
pluginList->setLoadOrder(loadOrder);*/
//Fix me: we are ignoring order changes in plugins.txt favouring loadorder.txt in all cases (plugins.txt shuld have precedence)
// Fix me: we are ignoring order changes in plugins.txt favouring loadorder.txt in
// all cases (plugins.txt shuld have precedence)
QStringList loadOrder = readLoadOrderList(pluginList, loadOrderPath);
pluginList->setLoadOrder(loadOrder);
readPluginList(pluginList);
@@ -52,70 +52,72 @@ void SkyrimGamePlugins::readPluginLists(MOBase::IPluginList *pluginList) {
m_LastRead = QDateTime::currentDateTime();
}
//TODO: return value is incorrect and should be ignored (it's not currently used
QStringList SkyrimGamePlugins::readPluginList(MOBase::IPluginList *pluginList)
// TODO: return value is incorrect and should be ignored (it's not currently used
QStringList SkyrimGamePlugins::readPluginList(MOBase::IPluginList* pluginList)
{
QStringList plugins = pluginList->pluginNames();
QStringList primaryPlugins = organizer()->managedGame()->primaryPlugins();
QStringList loadOrder(plugins);
QStringList plugins = pluginList->pluginNames();
QStringList primaryPlugins = organizer()->managedGame()->primaryPlugins();
QStringList loadOrder(plugins);
for (const QString &pluginName : primaryPlugins) {
if (pluginList->state(pluginName) != IPluginList::STATE_MISSING) {
pluginList->setState(pluginName, IPluginList::STATE_ACTIVE);
}
for (const QString& pluginName : primaryPlugins) {
if (pluginList->state(pluginName) != IPluginList::STATE_MISSING) {
pluginList->setState(pluginName, IPluginList::STATE_ACTIVE);
}
}
// Do not sort the primary plugins. Their load order should be locked as defined in
// "primaryPlugins".
const QStringList pluginsClone(plugins);
for (QString plugin : pluginsClone) {
if (primaryPlugins.contains(plugin, Qt::CaseInsensitive))
plugins.removeAll(plugin);
}
// Determine plugin active state by the plugins.txt file.
bool pluginsTxtExists = true;
QString filePath = organizer()->profile()->absolutePath() + "/plugins.txt";
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
pluginsTxtExists = false;
}
ON_BLOCK_EXIT([&]() {
qDebug("close %s", qUtf8Printable(filePath));
file.close();
});
if (file.size() == 0) {
// MO stores at least a header in the file. if it's completely empty the
// file is broken
pluginsTxtExists = false;
}
if (pluginsTxtExists) {
while (!file.atEnd()) {
QByteArray line = file.readLine();
QString pluginName;
if ((line.size() > 0) && (line.at(0) != '#')) {
pluginName = QStringEncoder(QStringConverter::Encoding::System)
.encode(line.trimmed().constData());
}
if (pluginName.size() > 0) {
pluginList->setState(pluginName, IPluginList::STATE_ACTIVE);
plugins.removeAll(pluginName);
// we already have the old loadorder and we ignore the positions in plugins.txt
// (needs fix) loadOrder.append(pluginName);
}
}
// Do not sort the primary plugins. Their load order should be locked as defined in "primaryPlugins".
const QStringList pluginsClone(plugins);
for (QString plugin : pluginsClone) {
if (primaryPlugins.contains(plugin, Qt::CaseInsensitive))
plugins.removeAll(plugin);
file.close();
// we removed each plugin found in the file, so what's left are inactive mods
for (const QString& pluginName : plugins) {
pluginList->setState(pluginName, IPluginList::STATE_INACTIVE);
}
// Determine plugin active state by the plugins.txt file.
bool pluginsTxtExists = true;
QString filePath = organizer()->profile()->absolutePath() + "/plugins.txt";
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
pluginsTxtExists = false;
} else {
for (const QString& pluginName : plugins) {
pluginList->setState(pluginName, IPluginList::STATE_INACTIVE);
}
ON_BLOCK_EXIT([&]() {
qDebug("close %s", qUtf8Printable(filePath));
file.close();
});
}
if (file.size() == 0) {
// MO stores at least a header in the file. if it's completely empty the
// file is broken
pluginsTxtExists = false;
}
if (pluginsTxtExists) {
while (!file.atEnd()) {
QByteArray line = file.readLine();
QString pluginName;
if ((line.size() > 0) && (line.at(0) != '#')) {
pluginName = QStringEncoder(QStringConverter::Encoding::System).encode(line.trimmed().constData());
}
if (pluginName.size() > 0) {
pluginList->setState(pluginName, IPluginList::STATE_ACTIVE);
plugins.removeAll(pluginName);
//we already have the old loadorder and we ignore the positions in plugins.txt (needs fix)
//loadOrder.append(pluginName);
}
}
file.close();
// we removed each plugin found in the file, so what's left are inactive mods
for (const QString &pluginName : plugins) {
pluginList->setState(pluginName, IPluginList::STATE_INACTIVE);
}
} else {
for (const QString &pluginName : plugins) {
pluginList->setState(pluginName, IPluginList::STATE_INACTIVE);
}
}
return loadOrder;
return loadOrder;
}
+6 -8
View File
@@ -1,25 +1,23 @@
#ifndef _SKYRIMGAMEPLUGINS_H
#define _SKYRIMGAMEPLUGINS_H
#include <gamebryogameplugins.h>
#include <iplugingame.h>
#include <imoinfo.h>
#include <iplugingame.h>
#include <map>
class SkyrimGamePlugins : public GamebryoGamePlugins
{
public:
SkyrimGamePlugins(MOBase::IOrganizer *organizer);
SkyrimGamePlugins(MOBase::IOrganizer* organizer);
virtual void readPluginLists(MOBase::IPluginList *pluginList) override;
virtual void readPluginLists(MOBase::IPluginList* pluginList) override;
protected:
virtual QStringList readPluginList(MOBase::IPluginList *pluginList) override;
virtual QStringList readPluginList(MOBase::IPluginList* pluginList) override;
private:
std::map<QString, QByteArray> m_LastSaveHash;
std::map<QString, QByteArray> m_LastSaveHash;
};
#endif // _SKYRIMSEGAMEPLUGINS_H
#endif // _SKYRIMSEGAMEPLUGINS_H
+33 -13
View File
@@ -9,22 +9,42 @@ public:
using GamebryoModDataChecker::GamebryoModDataChecker;
protected:
virtual const FileNameSet& possibleFolderNames() const override {
static FileNameSet result{
"fonts", "interface", "menus", "meshes", "music", "scripts", "shaders",
"sound", "strings", "textures", "trees", "video", "facegen", "materials",
"skse", "distantlod", "asi", "Tools", "MCM", "distantland", "mits",
"dllplugins", "SkyProc Patchers", "CalienteTools", "NetScriptFramework",
"shadersfx", "Nemesis_Engine"
};
virtual const FileNameSet& possibleFolderNames() const override
{
static FileNameSet result{"fonts",
"interface",
"menus",
"meshes",
"music",
"scripts",
"shaders",
"sound",
"strings",
"textures",
"trees",
"video",
"facegen",
"materials",
"skse",
"distantlod",
"asi",
"Tools",
"MCM",
"distantland",
"mits",
"dllplugins",
"SkyProc Patchers",
"CalienteTools",
"NetScriptFramework",
"shadersfx",
"Nemesis_Engine"};
return result;
}
virtual const FileNameSet& possibleFileExtensions() const override {
static FileNameSet result{
"esp", "esm", "bsa", "modgroups", "ini"
};
virtual const FileNameSet& possibleFileExtensions() const override
{
static FileNameSet result{"esp", "esm", "bsa", "modgroups", "ini"};
return result;
}
};
#endif // SKYRIM_MODATACHECKER_H
#endif // SKYRIM_MODATACHECKER_H
+3 -4
View File
@@ -5,11 +5,10 @@
#include <ifiletree.h>
// Skyrim does not need any change from the default feature:
class SkyrimModDataContent : public GamebryoModDataContent {
class SkyrimModDataContent : public GamebryoModDataContent
{
public:
using GamebryoModDataContent::GamebryoModDataContent;
};
#endif // SKYRIM_MODDATACONTENT_H
#endif // SKYRIM_MODDATACONTENT_H
+46 -50
View File
@@ -4,77 +4,73 @@
#include "gameskyrim.h"
SkyrimSaveGame::SkyrimSaveGame(QString const& fileName, GameSkyrim const* game) :
GamebryoSaveGame(fileName, game)
SkyrimSaveGame::SkyrimSaveGame(QString const& fileName, GameSkyrim const* game)
: GamebryoSaveGame(fileName, game)
{
FileWrapper file(getFilepath(), "TESV_SAVEGAME");
FileWrapper file(getFilepath(), "TESV_SAVEGAME");
FILETIME ftime;
fetchInformationFields(file, m_SaveNumber, m_PCName, m_PCLevel, m_PCLocation, ftime);
FILETIME ftime;
fetchInformationFields(file, m_SaveNumber, m_PCName, m_PCLevel, m_PCLocation, ftime);
//A file time is a 64-bit value that represents the number of 100-nanosecond
//intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).
//So we need to convert that to something useful
SYSTEMTIME ctime;
::FileTimeToSystemTime(&ftime, &ctime);
setCreationTime(ctime);
// A file time is a 64-bit value that represents the number of 100-nanosecond
// intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal
// Time (UTC). So we need to convert that to something useful
SYSTEMTIME ctime;
::FileTimeToSystemTime(&ftime, &ctime);
setCreationTime(ctime);
}
void SkyrimSaveGame::fetchInformationFields(FileWrapper& file,
unsigned long& saveNumber,
QString& playerName,
unsigned short& playerLevel,
QString& playerLocation,
FILETIME& creationTime) const
void SkyrimSaveGame::fetchInformationFields(
FileWrapper& file, unsigned long& saveNumber, QString& playerName,
unsigned short& playerLevel, QString& playerLocation, FILETIME& creationTime) const
{
file.skip<unsigned long>(); // header size
file.skip<unsigned long>(); // header version
file.read(saveNumber);
file.skip<unsigned long>(); // header size
file.skip<unsigned long>(); // header version
file.read(saveNumber);
file.read(playerName);
file.read(playerName);
unsigned long temp;
file.read(temp);
playerLevel = static_cast<unsigned short>(temp);
unsigned long temp;
file.read(temp);
playerLevel = static_cast<unsigned short>(temp);
file.setPluginStringFormat(GamebryoSaveGame::StringFormat::LOCAL8BIT);
file.read(playerLocation);
file.setPluginStringFormat(GamebryoSaveGame::StringFormat::UTF8);
file.setPluginStringFormat(GamebryoSaveGame::StringFormat::LOCAL8BIT);
file.read(playerLocation);
file.setPluginStringFormat(GamebryoSaveGame::StringFormat::UTF8);
QString timeOfDay;
file.read(timeOfDay);
QString timeOfDay;
file.read(timeOfDay);
QString race;
file.read(race); // race name (i.e. BretonRace)
QString race;
file.read(race); // race name (i.e. BretonRace)
file.skip<unsigned short>(); // Player gender (0 = male)
file.skip<float>(2); // experience gathered, experience required
file.skip<unsigned short>(); // Player gender (0 = male)
file.skip<float>(2); // experience gathered, experience required
file.read(creationTime);
file.read(creationTime);
}
std::unique_ptr<GamebryoSaveGame::DataFields> SkyrimSaveGame::fetchDataFields() const
{
FileWrapper file(getFilepath(), "TESV_SAVEGAME");
std::unique_ptr<DataFields> fields = std::make_unique<DataFields>();
FileWrapper file(getFilepath(), "TESV_SAVEGAME");
std::unique_ptr<DataFields> fields = std::make_unique<DataFields>();
{
QString dummyName, dummyLocation;
unsigned short dummyLevel;
unsigned long dummySaveNumber;
FILETIME dummyTime;
{
QString dummyName, dummyLocation;
unsigned short dummyLevel;
unsigned long dummySaveNumber;
FILETIME dummyTime;
fetchInformationFields(file, dummySaveNumber, dummyName, dummyLevel,
dummyLocation, dummyTime);
}
fetchInformationFields(file, dummySaveNumber, dummyName, dummyLevel, dummyLocation,
dummyTime);
}
fields->Screenshot = file.readImage();
fields->Screenshot = file.readImage();
file.skip<unsigned char>(); // form version
file.skip<unsigned long>(); // plugin info size
file.skip<unsigned char>(); // form version
file.skip<unsigned long>(); // plugin info size
fields->Plugins = file.readPlugins();
fields->Plugins = file.readPlugins();
return fields;
return fields;
}
+9 -10
View File
@@ -5,26 +5,25 @@
#include <Windows.h>
namespace MOBase { class IPluginGame; }
namespace MOBase
{
class IPluginGame;
}
class GameSkyrim;
class SkyrimSaveGame : public GamebryoSaveGame
{
public:
SkyrimSaveGame(QString const &fileName, GameSkyrim const *game);
SkyrimSaveGame(QString const& fileName, GameSkyrim const* game);
protected:
// Fetch easy-to-access information.
void fetchInformationFields(FileWrapper& wrapper,
unsigned long& saveNumber,
QString& playerName,
unsigned short& playerLevel,
QString& playerLocation,
FILETIME& creationTime) const;
void fetchInformationFields(FileWrapper& wrapper, unsigned long& saveNumber,
QString& playerName, unsigned short& playerLevel,
QString& playerLocation, FILETIME& creationTime) const;
std::unique_ptr<DataFields> fetchDataFields() const override;
};
#endif // SKYRIMSAVEGAME_H
#endif // SKYRIMSAVEGAME_H
+18 -19
View File
@@ -1,19 +1,18 @@
#include "skyrimscriptextender.h"
#include <QString>
#include <QStringList>
SkyrimScriptExtender::SkyrimScriptExtender(GameGamebryo const *game) :
GamebryoScriptExtender(game)
{
}
QString SkyrimScriptExtender::BinaryName() const
{
return "skse_loader.exe";
}
QString SkyrimScriptExtender::PluginPath() const
{
return "skse/plugins";
}
#include "skyrimscriptextender.h"
#include <QString>
#include <QStringList>
SkyrimScriptExtender::SkyrimScriptExtender(GameGamebryo const* game)
: GamebryoScriptExtender(game)
{}
QString SkyrimScriptExtender::BinaryName() const
{
return "skse_loader.exe";
}
QString SkyrimScriptExtender::PluginPath() const
{
return "skse/plugins";
}
+17 -18
View File
@@ -1,18 +1,17 @@
#ifndef SKYRIMSCRIPTEXTENDER_H
#define SKYRIMSCRIPTEXTENDER_H
#include "gamebryoscriptextender.h"
class GameGamebryo;
class SkyrimScriptExtender : public GamebryoScriptExtender
{
public:
SkyrimScriptExtender(const GameGamebryo *game);
virtual QString BinaryName() const override;
virtual QString PluginPath() const override;
};
#endif // SKYRIMSCRIPTEXTENDER_H
#ifndef SKYRIMSCRIPTEXTENDER_H
#define SKYRIMSCRIPTEXTENDER_H
#include "gamebryoscriptextender.h"
class GameGamebryo;
class SkyrimScriptExtender : public GamebryoScriptExtender
{
public:
SkyrimScriptExtender(const GameGamebryo* game);
virtual QString BinaryName() const override;
virtual QString PluginPath() const override;
};
#endif // SKYRIMSCRIPTEXTENDER_H