aboutsummaryrefslogtreecommitdiff
path: root/libs/game_bethesda/src/gamebryo/gamegamebryo.h
blob: 78ac1d41317adccc1de52493d584046397de7144 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#ifndef GAMEGAMEBRYO_H
#define GAMEGAMEBRYO_H

#include "iplugingame.h"

class BSAInvalidation;
class DataArchives;
class LocalSavegames;
class SaveGameInfo;
class BSAInvalidation;
class LocalSavegames;
class ScriptExtender;
class GamePlugins;
class UnmanagedMods;

#include <QObject>
#include <QString>
#ifdef _WIN32
#include <ShlObj.h>
#include <dbghelp.h>
#endif
#include <ipluginfilemapper.h>
#include <iplugingame.h>
#include <memory>

#include "gamebryosavegame.h"
#include "igamefeatures.h"

class GameGamebryo : public MOBase::IPluginGame, public MOBase::IPluginFileMapper
{
  Q_OBJECT
  Q_INTERFACES(MOBase::IPlugin MOBase::IPluginGame MOBase::IPluginFileMapper)

  friend class GamebryoScriptExtender;
  friend class GamebryoSaveGameInfo;
  friend class GamebryoSaveGameInfoWidget;
  friend class GamebryoSaveGame;

  /**
   * Some Bethesda games do not have a valid file version but a valid product
   * version. If the file version starts with FALLBACK_GAME_VERSION, the product
   * version will be tried.
   */
  static constexpr const char* FALLBACK_GAME_VERSION = "1.0.0";

public:
  GameGamebryo();

  void detectGame() override;
  bool init(MOBase::IOrganizer* moInfo) override;

public:  // IPluginGame interface
  // getName
  // initializeProfile
  virtual std::vector<std::shared_ptr<const MOBase::ISaveGame>>
  listSaves(QDir folder) const override;

  virtual bool isInstalled() const override;
  virtual QIcon gameIcon() const override;
  virtual QDir gameDirectory() const override;
  virtual QDir dataDirectory() const override;
  // secondaryDataDirectories
  virtual void setGamePath(const QString& path) override;
  virtual QDir documentsDirectory() const override;
  virtual QDir savesDirectory() const override;
  // executables
  // steamAPPId
  // primaryPlugins
  // enabledPlugins
  // gameVariants
  virtual void setGameVariant(const QString& variant) override;
  virtual QString binaryName() const override;
  // gameShortName
  // primarySources
  // validShortNames
  // iniFiles
  // DLCPlugins
  // CCPlugins
  virtual LoadOrderMechanism loadOrderMechanism() const override;
  virtual SortMechanism sortMechanism() const override;
  // nexusModOrganizerID
  // nexusGameID
  virtual bool looksValid(QDir const&) const override;
  virtual QString gameVersion() const override;
  virtual QString getLauncherName() const override;

public:  // IPluginFileMapper interface
  virtual MappingType mappings() const;

public:  // Other (e.g. for game features)
  QString myGamesPath() const;

  // Returns the folder name used by the game under AppData/Local
  // (e.g. "FalloutNV", "Skyrim Special Edition").  Defaults to the
  // My Games subfolder name.  Override in games where these differ
  // (e.g. Enderal uses lowercase "enderal" in AppData but "Enderal"
  // in My Games).
  virtual QString localAppName() const;

protected:
  // Retrieve the saves extension for the game.
  virtual QString savegameExtension() const   = 0;
  virtual QString savegameSEExtension() const = 0;

  // Create a save game.
  virtual std::shared_ptr<const GamebryoSaveGame>
  makeSaveGame(QString filepath) const = 0;

  QFileInfo findInGameFolder(const QString& relativePath) const;
  QString selectedVariant() const;

  static QString localAppFolder();
  // Arguably this shouldn't really be here but every gamebryo program seems to
  // use it
  static QString getLootPath();

  // This function is not terribly well named as it copies exactly where it's told
  // to, irrespective of whether it's in the profile...
  static void copyToProfile(const QString& sourcePath, const QDir& destinationDirectory,
                            const QString& sourceFileName);

  static void copyToProfile(const QString& sourcePath, const QDir& destinationDirectory,
                            const QString& sourceFileName,
                            const QString& destinationFileName);

  virtual QString identifyGamePath() const;

  virtual bool prepareIni(const QString& exec);

public:
  // Ensure all game INI files exist with adequate content in the given
  // base path. On Linux, seeds missing/stub INIs from the game's default
  // INI templates and creates case-matching symlinks if needed.
  void ensureIniFilesExist(const QString& basePath);

protected:

#ifdef _WIN32
  static std::unique_ptr<BYTE[]> getRegValue(HKEY key, LPCWSTR path, LPCWSTR value,
                                             DWORD flags, LPDWORD type);

  static QString findInRegistry(HKEY baseKey, LPCWSTR path, LPCWSTR value);

  static QString getKnownFolderPath(REFKNOWNFOLDERID folderId, bool useDefault);

  static QString getSpecialPath(const QString& name);
#endif

  WORD getArch(QString const& program) const;

  static QString determineMyGamesPath(const QString& gameName);

  static QString parseEpicGamesLocation(const QStringList& manifests);

  static QString parseSteamLocation(const QString& appid, const QString& directoryName);

public:  // Cross-platform INI file utilities (used by game features)
  // Read a value from a Bethesda-style INI file using QSettings
  static QString readIniValue(const QString& iniFile, const QString& section,
                              const QString& key, const QString& defaultValue = QString());

protected:
  void registerFeature(std::shared_ptr<MOBase::GameFeature> feature);

protected:
  // to access organizer for game features, avoid having to pass it to all saves since
  // we already pass the game
  friend class GamebryoSaveGame;

  QString m_GamePath;
  QString m_MyGamesPath;
  QString m_GameVariant;
  MOBase::IOrganizer* m_Organizer;
};

#endif  // GAMEGAMEBRYO_H