Merge branch 'master' into issue/344

# Conflicts:
#	src/gameinfoimpl.cpp
#	src/gameinfoimpl.h
#	src/shared/fallout3info.h
#	src/shared/falloutnvinfo.h
#	src/shared/gameinfo.h
#	src/shared/oblivioninfo.h
#	src/shared/skyriminfo.h
This commit is contained in:
Thomas Tanner
2015-12-06 15:49:56 +00:00
71 changed files with 3747 additions and 1396 deletions
+171 -1
View File
@@ -37,6 +37,14 @@ def setup_config_variables():
if 'ZLIBPATH' in os.environ:
zlibpath = os.environ['ZLIBPATH']
git = 'git'
if 'GIT' in os.environ:
git = os.environ['GIT']
mercurial = 'hg'
if 'MERCURIAL' in os.environ:
hg = os.environ['HG']
vars = Variables('scons_configure.py')
vars.AddVariables(
PathVariable('BOOSTPATH', 'Set to point to your boost directory',
@@ -51,7 +59,13 @@ def setup_config_variables():
PathVariable('SEVENZIPPATH', 'Path to 7zip sources', sevenzippath,
PathVariable.PathIsDir),
PathVariable('ZLIBPATH', 'Path to zlib install', zlibpath,
PathVariable.PathIsDir)
PathVariable.PathIsDir),
PathVariable('GIT', 'Path to git executable', git,
PathVariable.PathIsFile),
PathVariable('MERCURIAL', 'Path to hg executable', mercurial,
PathVariable.PathIsFile),
PathVariable('IWYU', 'Path to include-what-you-use executable', None,
PathVariable.PathIsFile)
)
return vars
@@ -231,6 +245,157 @@ def DisableQtModules(self, *modules):
for module in modules:
self['CPPPATH'].remove(os.path.join('$QTDIR', 'include', 'QT' + module))
def setup_IWYU(env):
import SCons.Defaults
import SCons.Builder
original_shared = SCons.Defaults.SharedObjectEmitter
original_static = SCons.Defaults.StaticObjectEmitter
def DoIWYU(env, source, target):
for i in range(len(source)):
s = source[i]
dir, name = os.path.split(str(s)) # I'm sure theres a way of getting this from scons
# Don't bother looking at moc files and 7zip source
if not name.startswith('moc_') and \
not dir.startswith(env['SEVENZIPPATH']):
# Put the .iwyu in the same place as the .obj
targ = os.path.splitext(str(target[i]))[0]
env.Depends(env.IWYU(targ + '.iwyu', s), target[i])
def shared_emitter(target, source, env):
DoIWYU(env, source, target)
return original_shared(target, source, env)
def static_emitter(target, source, env):
DoIWYU(env, source, target)
return original_static(target, source, env)
SCons.Defaults.SharedObjectEmitter = shared_emitter
SCons.Defaults.StaticObjectEmitter = static_emitter
def emitter(target, source, env):
env.Depends(target, env['IWYU_MAPPING_FILE'])
env.Depends(target, env['IWYU_MASSAGE'])
return target, source
def _concat_list(prefixes, list, suffixes, env, f=lambda x: x, target=None, source=None):
""" Creates a new list from 'list' by first interpolating each element
in the list using the 'env' dictionary and then calling f on the
list, and concatenate the 'prefix' and 'suffix' LISTS onto each element of the list.
A trailing space on the last element of 'prefix' or leading space on the
first element of 'suffix' will cause them to be put into separate list
elements rather than being concatenated.
"""
if not list:
return list
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
if l is not None:
list = l
# This bit replaces current concat_ixes
result = []
def process_stringlist(s):
return [ str(env.subst(p, SCons.Subst.SUBST_RAW))
for p in Flatten([s]) if p != '' ]
# ensure that prefix and suffix are strings
prefixes = process_stringlist(prefixes)
prefix = ''
if len(prefixes) != 0:
if prefixes[-1][-1] != ' ':
prefix = prefixes.pop()
suffixes = process_stringlist(suffixes)
suffix = ''
if len(suffixes) != 0:
if suffixes[-1][0] != ' ':
suffix = suffixes.pop(0)
for x in list:
if isinstance(x, SCons.Node.FS.File):
result.append(x)
continue
x = str(x)
if x:
result.append(prefixes)
if prefix:
if x[:len(prefix)] != prefix:
x = prefix + x
result.append(x)
if suffix:
if x[-len(suffix):] != suffix:
result[-1] = result[-1] + suffix
result.append(suffixes)
return result
env['_concat_list'] = _concat_list
# Note to self: command 2>&1 | other command appears to work as I would hope
# except it eats errors
iwyu = SCons.Builder.Builder(
action=[
'$IWYU_MASSAGE $TARGET $IWYU $IWYU_FLAGS $IWYU_MAPPINGS $IWYU_COMCOM $SOURCE'
],
emitter=emitter,
suffix='.iwyu',
src_suffix='.cpp')
env.Append(BUILDERS={'IWYU': iwyu})
# Sigh - IWYU is a right bum as it doesn't recognise /I so I have to
# duplicate most of the usual stuff
env['IWYU_FLAGS'] = [
# This might turn down the output a bit. I hope
'-Xiwyu', '--transitive_includes_only',
# Seem to be needed for a windows build
'-D_MT', '-D_DLL', '-m32',
# This is something to do with clang, windows and boost headers
'-DBOOST_USE_WINDOWS_H',
# There's a lot of this, disabled for now
'-Wno-inconsistent-missing-override',
# Mark boost and Qt headers as system headers to disable a lot of noise.
# I'm sure there has to be a better way than saying 'prefix=Q'
'--system-header-prefix=Q',
'--system-header-prefix=boost/',
# Should be able to get this info from our setup really
'-fmsc-version=1800', '-D_MSC_VER=1800',
# clang and qt don't agree about these because clang says its gcc 4.2
# and QT doesn't realise it's clang
'-DQ_COMPILER_INITIALIZER_LISTS',
'-DQ_COMPILER_DECLTYPE',
'-DQ_COMPILER_VARIADIC_TEMPLATES',
]
if env['CONFIG'] == 'debug':
env['IWYU_FLAGS'] += [ '-D_DEBUG' ]
env['IWYU_DEFPREFIX'] = '-D'
env['IWYU_DEFSUFFIX'] = ''
env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}'
env['IWYU_INCPREFIX'] = '-I'
env['IWYU_INCSUFFIX'] = ''
env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
env['IWYU_PCH_PREFIX'] = '-include' # Amazingly this works without a space
env['IWYU_PCH_SUFFIX'] = ''
env['IWYU_PCHFILES'] = '$( ${_concat(IWYU_PCH_PREFIX, PCHSTOP, IWYU_PCH_SUFFIX, __env__, target=TARGET, source=SOURCE)} $)'
env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $IWYU_PCHFILES $CCPDBFLAGS'
env['IWYU_MAPPING_PREFIX'] = ['-Xiwyu', '--mapping_file=']
env['IWYU_MAPPING_SUFFIX'] = ''
env['IWYU_MAPPINGS'] = '$( ${_concat_list(IWYU_MAPPING_PREFIX, IWYU_MAPPING_FILE, IWYU_MAPPING_SUFFIX, __env__, f=lambda l: [ str(x) for x in l], target=TARGET, source=SOURCE)} $)'
env['IWYU_MAPPING_FILE'] = [
env.File('#/modorganizer/qt5_4.imp'),
env.File('#/modorganizer/win.imp'),
env.File('#/modorganizer/mappings.imp')
]
env['IWYU_MASSAGE'] = env.File('#/modorganizer/massage_messages.py')
# Create base environment
vars = setup_config_variables()
@@ -347,6 +512,11 @@ else:
env.AppendUnique(CPPFLAGS = [ '/O2', '/MD' ])
env.AppendUnique(LINKFLAGS = [ '/OPT:REF', '/OPT:ICF' ])
# Set up include what you use. Add this as an extra compile step. Note it
# doesn't currently generate an output file (use the output instead!).
if 'IWYU' in env:
setup_IWYU(env)
# /OPT:REF removes unreferenced code
# for release, use /OPT:ICF (comdat folding: coalesce identical blocks of code)
+30
View File
@@ -0,0 +1,30 @@
[
# for boost???
# These are probably correct but might need a revisit as if you look at the boost documentation pages, it
# can give you huge lists of alternate includes...
{ symbol: [ "BOOST_FOREACH", "private", "<boost/foreach.hpp>", "public" ] },
{ include: [ "@\"boost/bind/.*\"", "private", "<boost/bind.hpp>", "public" ] },
{ include: [ "@\"boost/algorithm/string/.*\"", "private", "<boost/algorithm/string.hpp>", "public" ] },
{ include: [ "@\"boost/assign/.*\"", "private", "<boost/assign.hpp>", "public" ] },
{ include: [ "@\"boost/filesystem/.*\"", "private", "<boost/filesystem.hpp>", "public" ] },
{ include: [ "@\"boost/format/.*\"", "private", "<boost/format.hpp>", "public" ] },
{ include: [ "@\"boost/function/.*\"", "private", "<boost/function.hpp>", "public" ] },
{ include: [ "@\"boost/local/.*\"", "private", "<boost/locale.hpp>", "public" ] },
{ include: [ "@\"boost/python/.*\"", "private", "<boost/python.hpp>", "public" ] },
{ include: [ "@\"boost/signals2/.*\"", "private", "<boost/signals2.hpp>", "public" ] },
{ include: [ "\"boost/smart_ptr/scoped_array.hpp\"", "private", "<boost/scoped_array.hpp>", "public" ] },
{ include: [ "\"boost/smart_ptr/shared_ptr.hpp\"", "private", "<boost/shared_ptr.hpp>", "public" ] },
# this appears to be excessive
#{ include: [ "@\"boost/thread/.*\"", "private", "<boost/thread.hpp>", "public" ] },
# And this is specific to us
{ include: [ "\"appconfig.inc\"", "private", "\"appconfig.h\"", "public" ] },
]
# Ones I don't yet know how to deal with
#include "boost/fusion/container/vector/vector10_fwd.hpp" // for fusion
#include "boost/iterator/iterator_facade.hpp" // for operator!=
#include "boost/iterator/iterator_facade.hpp"
+116
View File
@@ -0,0 +1,116 @@
import fileinput
import re
import subprocess
import sys
"""
source/organizer/aboutdialog.h should add these lines:
#include <QObject> // for Q_OBJECT, slots
#include <QString> // for QString
class QListWidgetItem;
class QWidget;
source/organizer/aboutdialog.h should remove these lines:
- #include <QListWidgetItem> // lines 25-25
- #include <utility> // lines 28-28
- #include <vector> // lines 27-27
- class DownloadManager; // lines 47-47
The full include-list for source/organizer/aboutdialog.h:
#include <QDialog> // for QDialog
#include <QObject> // for Q_OBJECT, slots
#include <QString> // for QString
#include <map> // for map
class QListWidgetItem;
class QWidget;
namespace Ui { class AboutDialog; } // lines 31-31
---
"""
removing = None
includes = dict
foundline = 0
errors = False
def process_next_line(line, outfile):
""" Read a line of output/error from include-what-you use
Turn clang errors into a form QT creator recognises
Raise warnings for unneeded includes
"""
global removing
global includes
global foundline
global errors
line = line.rstrip()
print >> outfile, line
if removing:
if line == '':
removing = None
print
return
else:
# Really we should stash these so that if we get a 'class xxx' in
# the add lines we can print it here. also we could do the case
# fixing.
m = re.match(r'- #include [<"](.*)[">] +// lines (.*)-', line)
if m:
# If there is an added line with the same class, print it here
print '%s(%s) : warning I0001: Unnecessary include of %s' %\
(removing, m.group(2), m.group(1))
foundline = m.group(1)
else:
m = re.match(r'- (.*) +// lines (.*)-', line)
if m:
print '%s(%s) : warning I0002: '\
'Unnecessary forward ref of %s' %\
(removing, m.group(2), m.group(1))
foundline = m.group(1)
else:
print '********* I got confused **********'
if line.startswith('In file included from'):
line = re.sub(r'^(In file included from)(.*):(\d+):',
r' \2(\3) : \1 here',
line)
# Note; QT Creator seems to be unwilling to let you double click the
# line to select the code in question if you get a string of these, not
# sure why.
elif ': note:' in line:
line = ' ' + re.sub(r':(\d+):\d+: note:', r'(\1) : note:', line)
else:
# Replace clang :line:column: type: with ms (line) : type nnnn:
line = re.sub(r':(\d+):\d+: ([^:]*):', r'(\1) : \2 I1234:', line)
if ' : error I1234:' in line:
errors = True
print line
if line.endswith(' should remove these lines:'):
removing = (line.split(' '))[0]
elif line.endswith(' should add these lines:'):
adding = (line.split(' '))[0]
# also process the other lines
# added lines should come after the first entry with a line number.
outfile = open(sys.argv[1], 'w')
process = subprocess.Popen(sys.argv[2:],
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
process_next_line(output, outfile)
rc = process.poll()
# The return code you get appears to be more to do with the amount of output
# generated than any real error, so instead we should error if any ': error:'
# lines are detected
if errors:
sys.exit(1)
+2478
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -66,7 +66,6 @@ SET(organizer_SRCS
moapplication.cpp
profileinputdialog.cpp
icondelegate.cpp
gameinfoimpl.cpp
csvbuilder.cpp
savetextasdialog.cpp
qtgroupingproxy.cpp
@@ -160,7 +159,6 @@ SET(organizer_HDRS
moapplication.h
profileinputdialog.h
icondelegate.h
gameinfoimpl.h
csvbuilder.h
savetextasdialog.h
qtgroupingproxy.h
+9 -3
View File
@@ -67,7 +67,6 @@ env.Uic(env.Glob('*.ui'))
env.RequireLibraries('uibase', 'shared', 'bsatk', 'esptk')
env.AppendUnique(LIBS = [
'shell32',
'user32',
@@ -96,6 +95,12 @@ env['CPPPATH'] += [
'${BOOSTPATH}',
]
#########################FUDGE###############################
env['CPPPATH'] += [
'../plugins/gameGamebryo',
]
#############################################################
env.AppendUnique(CPPDEFINES = [
'_UNICODE',
'_CRT_SECURE_NO_WARNINGS',
@@ -118,8 +123,9 @@ env.AppendUnique(LINKFLAGS = [
# modeltest is optional and it doesn't compile anyway...
cpp_files = [
x for x in Glob('*.cpp')
if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp'
x for x in env.Glob('*.cpp', source = True)
if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp' and \
not x.name.startswith('moc_') # I think this is a strange bug
]
about_env = env.Clone()
+1 -3
View File
@@ -21,8 +21,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QRegExp>
#include <map>
#include <algorithm>
#include <boost/assign.hpp>
namespace BBCode {
@@ -80,7 +78,7 @@ public:
if (tagName == "color") {
QString color = tagIter->second.first.cap(1);
QString content = tagIter->second.first.cap(2);
if (color.at(0) == "#") {
if (color.at(0) == '#') {
return temp.replace(tagIter->second.first, QString("<font style=\"color: %1;\">%2</font>").arg(color, content));
} else {
auto colIter = m_ColorMap.find(color.toLower());
+2 -4
View File
@@ -18,18 +18,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "browserdialog.h"
#include "ui_browserdialog.h"
#include "browserview.h"
#include "messagedialog.h"
#include "report.h"
#include "persistentcookiejar.h"
#include "json.h"
#include <utility.h>
#include <gameinfo.h>
#include "settings.h"
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QMenu>
+3 -1
View File
@@ -21,9 +21,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define NEXUSVIEW_H
class QEvent;
class QUrl;
class QWidget;
#include <QWebView>
#include <QWebPage>
#include <QTabWidget>
/**
* @brief web view used to display a nexus page
+2 -2
View File
@@ -18,9 +18,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "categories.h"
#include <utility.h>
#include <report.h>
#include <gameinfo.h>
#include <QObject>
#include <QFile>
#include <QDir>
@@ -29,7 +30,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
CategoryFactory* CategoryFactory::s_Instance = nullptr;
+7 -2
View File
@@ -18,10 +18,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "directoryrefresher.h"
#include "iplugingame.h"
#include "utility.h"
#include "report.h"
#include "modinfo.h"
#include <gameinfo.h>
#include <QApplication>
#include <QDir>
#include <QString>
@@ -141,7 +144,9 @@ void DirectoryRefresher::refresh()
m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
std::wstring dataDirectory = GameInfo::instance().getGameDirectory() + L"\\data";
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
// TODO what was the point of having the priority in this tuple? the list is already sorted by priority
+11 -4
View File
@@ -18,18 +18,19 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "downloadmanager.h"
#include "nxmurl.h"
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
#include <gameinfo.h>
#include "iplugingame.h"
#include <nxmurl.h>
#include <taskprogressmanager.h>
#include "utility.h"
#include "json.h"
#include "selectiondialog.h"
#include "bbcode.h"
#include <utility.h>
#include <report.h>
#include <QTimer>
#include <QFileInfo>
#include <QRegExp>
@@ -38,6 +39,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QMessageBox>
#include <QCoreApplication>
#include <QTextDocument>
#include <boost/bind.hpp>
#include <regex>
@@ -448,7 +450,7 @@ void DownloadManager::addNXMDownload(const QString &url)
{
NXMUrl nxmInfo(url);
QString managedGame = ToQString(MOShared::GameInfo::instance().getGameShortName());
QString managedGame = m_ManagedGame->getGameShortName();
qDebug("add nxm download: %s", qPrintable(url));
if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game()));
@@ -1242,13 +1244,14 @@ int DownloadManager::startDownloadURLs(const QStringList &urls)
return m_ActiveDownloads.size() - 1;
}
/* This doesn't appear to be used by anything
int DownloadManager::startDownloadNexusFile(int modID, int fileID)
{
int newID = m_ActiveDownloads.size();
addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(ToQString(MOShared::GameInfo::instance().getGameName())).arg(modID).arg(fileID));
return newID;
}
*/
QString DownloadManager::downloadPath(int id)
{
return getFilePath(id);
@@ -1468,3 +1471,7 @@ void DownloadManager::directoryChanged(const QString&)
refreshList();
}
void DownloadManager::managedGameChanged(MOBase::IPluginGame const *managedGame)
{
m_ManagedGame = managedGame;
}
+6
View File
@@ -35,6 +35,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QFileSystemWatcher>
#include <QSettings>
namespace MOBase { class IPluginGame; }
class NexusInterface;
@@ -328,7 +329,9 @@ public:
virtual int startDownloadURLs(const QStringList &urls);
/* This doesn't appear to be used anywhere
virtual int startDownloadNexusFile(int modID, int fileID);
*/
virtual QString downloadPath(int id);
/**
@@ -414,6 +417,8 @@ public slots:
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
private slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
@@ -501,6 +506,7 @@ private:
QRegExp m_DateExpression;
MOBase::IPluginGame const *m_ManagedGame;
};
+6 -4
View File
@@ -18,16 +18,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "executableslist.h"
#include <gameinfo.h>
#include "iplugingame.h"
#include "utility.h"
#include <QFileInfo>
#include <QDir>
#include <QDebug>
#include "utility.h"
#include <algorithm>
using namespace MOBase;
using namespace MOShared;
ExecutablesList::ExecutablesList()
@@ -38,7 +40,7 @@ ExecutablesList::~ExecutablesList()
{
}
void ExecutablesList::init(IPluginGame *game)
void ExecutablesList::init(IPluginGame const *game)
{
Q_ASSERT(game != nullptr);
m_Executables.clear();
+4 -3
View File
@@ -20,13 +20,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef EXECUTABLESLIST_H
#define EXECUTABLESLIST_H
#include "executableinfo.h"
#include <vector>
#include <QFileInfo>
#include <QMetaType>
#include <gameinfo.h>
#include <iplugingame.h>
namespace MOBase { class IPluginGame; }
/*!
* @brief Information about an executable
@@ -78,7 +79,7 @@ public:
/**
* @brief initialise the list with the executables preconfigured for this game
**/
void init(MOBase::IPluginGame *game);
void init(MOBase::IPluginGame const *game);
/**
* @brief find an executable by its name
-103
View File
@@ -1,103 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gameinfoimpl.h"
#include "gameinfo.h"
#include <utility.h>
#include <QDebug>
#include <QDir>
using namespace MOBase;
using namespace MOShared;
GameInfoImpl::GameInfoImpl()
{
}
IGameInfo::Type GameInfoImpl::type() const
{
switch (GameInfo::instance().getType()) {
case GameInfo::TYPE_OBLIVION: return IGameInfo::TYPE_OBLIVION;
case GameInfo::TYPE_FALLOUT3: return IGameInfo::TYPE_FALLOUT3;
case GameInfo::TYPE_FALLOUTNV: return IGameInfo::TYPE_FALLOUTNV;
case GameInfo::TYPE_SKYRIM: return IGameInfo::TYPE_SKYRIM;
default: throw MyException(QObject::tr("invalid game type %1").arg(GameInfo::instance().getType()));
}
}
QString GameInfoImpl::path() const
{
return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory()));
}
QString GameInfoImpl::binaryName() const
{
return ToQString(GameInfo::instance().getBinaryName());
}
namespace {
QString GetAppVersion(std::wstring const &app_name)
{
DWORD handle;
DWORD info_len = ::GetFileVersionInfoSizeW(app_name.c_str(), &handle);
if (info_len == 0) {
qDebug("GetFileVersionInfoSizeW Error %d", ::GetLastError());
return "";
}
std::vector<char> buff(info_len);
if( ! ::GetFileVersionInfoW(app_name.c_str(), handle, info_len, buff.data())) {
qDebug("GetFileVersionInfoW Error %d", ::GetLastError());
return "";
}
VS_FIXEDFILEINFO *pFileInfo;
UINT buf_len;
if ( ! ::VerQueryValueW(buff.data(), L"\\", reinterpret_cast<LPVOID *>(&pFileInfo), &buf_len)) {
qDebug("VerQueryValueW Error %d", ::GetLastError());
return "";
}
return QString("%1.%2.%3.%4").arg(HIWORD(pFileInfo->dwFileVersionMS))
.arg(LOWORD(pFileInfo->dwFileVersionMS))
.arg(HIWORD(pFileInfo->dwFileVersionLS))
.arg(LOWORD(pFileInfo->dwFileVersionLS));
}
}
QString GameInfoImpl::version() const
{
std::wstring dir = GameInfo::instance().getGameDirectory();
std::wstring exec = GameInfo::instance().getBinaryName();
std::wstring target = L"\\\\?\\" + dir + L"\\" + exec;
return GetAppVersion(target.c_str());
}
QString GameInfoImpl::extenderVersion() const
{
std::wstring dir = GameInfo::instance().getGameDirectory();
std::wstring exec = GameInfo::instance().getExtenderName();
std::wstring target = L"\\\\?\\" + dir + L"\\" + exec;
return GetAppVersion(target.c_str());
}
-41
View File
@@ -1,41 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GAMEINFOIMPL_H
#define GAMEINFOIMPL_H
#include <igameinfo.h>
#include <QString>
class GameInfoImpl : public MOBase::IGameInfo
{
public:
GameInfoImpl();
virtual Type type() const;
virtual QString path() const;
virtual QString binaryName() const;
virtual QString version() const;
virtual QString extenderVersion() const;
};
#endif // GAMEINFOIMPL_H
+1 -1
View File
@@ -21,7 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define HELPER_H
#include <QString>
#include <string>
/**
+5 -2
View File
@@ -18,6 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "installationmanager.h"
#include "utility.h"
#include "report.h"
#include "categories.h"
@@ -32,9 +33,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include <scopeguard.h>
#include <installationtester.h>
#include <gameinfo.h>
#include <utility.h>
#include <scopeguard.h>
#include <QFileInfo>
#include <QLibrary>
#include <QInputDialog>
@@ -42,11 +43,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDir>
#include <QMessageBox>
#include <QSettings>
#include <Shellapi.h>
#include <QPushButton>
#include <QApplication>
#include <QDateTime>
#include <QDirIterator>
#include <Shellapi.h>
#include <boost/assign.hpp>
#include <boost/scoped_ptr.hpp>
+10 -11
View File
@@ -56,7 +56,7 @@ void LoadMechanism::writeHintFile(const QDir &targetDirectory)
}
void LoadMechanism::removeHintFile(QDir &targetDirectory)
void LoadMechanism::removeHintFile(QDir targetDirectory)
{
targetDirectory.remove("mo_path.txt");
}
@@ -64,7 +64,8 @@ void LoadMechanism::removeHintFile(QDir &targetDirectory)
bool LoadMechanism::isDirectLoadingSupported()
{
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
//FIXME: Seriously? isn't there a 'do i need steam' thing?
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
if (game->gameName().compare("oblivion", Qt::CaseInsensitive) == 0) {
// oblivion can be loaded directly if it's not the steam variant
return !game->gameDirectory().exists("steam_api.dll");
@@ -76,13 +77,11 @@ bool LoadMechanism::isDirectLoadingSupported()
bool LoadMechanism::isScriptExtenderSupported()
{
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
// test if there even is an extender for the managed game and if so whether it's installed
return (extender != nullptr)
&& (game->gameDirectory().exists(extender->name() + "_loader.exe")
|| game->gameDirectory().exists(extender->name() + "_steam_loader.dll"));
return extender != nullptr && extender->isInstalled();
}
bool LoadMechanism::isProxyDLLSupported()
@@ -92,7 +91,7 @@ bool LoadMechanism::isProxyDLLSupported()
// plus: the proxy dll hasn't been working for at least the whole 1.12.x versions of MO and
// noone reported it so why maintain an unused feature?
return false;
/* IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
/* IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
return game->gameDirectory().exists(QString::fromStdWString(AppConfig::proxyDLLTarget()));*/
}
@@ -124,7 +123,7 @@ bool LoadMechanism::hashIdentical(const QString &fileNameLHS, const QString &fil
void LoadMechanism::deactivateScriptExtender()
{
try {
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
if (extender == nullptr) {
throw MyException(QObject::tr("game doesn't support a script extender"));
@@ -150,7 +149,7 @@ void LoadMechanism::deactivateScriptExtender()
void LoadMechanism::deactivateProxyDLL()
{
try {
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
@@ -179,7 +178,7 @@ void LoadMechanism::deactivateProxyDLL()
void LoadMechanism::activateScriptExtender()
{
try {
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
if (extender == nullptr) {
throw MyException(QObject::tr("game doesn't support a script extender"));
@@ -219,7 +218,7 @@ void LoadMechanism::activateScriptExtender()
void LoadMechanism::activateProxyDLL()
{
try {
IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));

Some files were not shown because too many files have changed in this diff Show More