mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
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:
+171
-1
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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
@@ -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
@@ -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());
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
@@ -21,7 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define HELPER_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <string>
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user