Merge pull request #24 from ModOrganizer2/Develop

Stage for Release 2.2.0
This commit is contained in:
LostDragonist
2019-05-03 21:09:18 -05:00
committed by GitHub
9 changed files with 115 additions and 24 deletions
-6
View File
@@ -11,12 +11,6 @@ SET(DEPENDENCIES_DIR CACHE PATH "")
# hint to find qt in dependencies path
LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake)
FILE(GLOB_RECURSE PYTHON_ROOT ${DEPENDENCIES_DIR}/Python*/pyconfig.h.in)
GET_FILENAME_COMPONENT(PYTHON_ROOT ${PYTHON_ROOT} DIRECTORY)
FILE(GLOB_RECURSE SIP_ROOT ${DEPENDENCIES_DIR}/sip-*/siplib/sip.h)
GET_FILENAME_COMPONENT(SIP_ROOT ${SIP_ROOT} DIRECTORY)
# need to install python
IF(EXISTS "${PYTHON_ROOT}/PCbuild/python27.dll")
INSTALL(FILES ${PYTHON_ROOT}/PCbuild/python27.dll DESTINATION bin)
+36
View File
@@ -0,0 +1,36 @@
version: 1.0.{build}
skip_branch_with_pr: true
image: Visual Studio 2017
environment:
WEBHOOK_URL:
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1Vbg57wBaeLhi49uGjxPw5GVujHku6kxN6ab89zhbS5GVeluR76GM83IbKV4Sh7udXzoYZZdg6YudtYHzdhCgUeiedpswbuczTq9ceIkkfSEWZuh/lMAAVVwvcGsJAnoPFw=
build_script:
- cmd: >-
git clone --depth=1 --branch=%APPVEYOR_REPO_BRANCH% https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella 2> $null
mkdir c:\projects\modorganizer-build -type directory
cd c:\projects\modorganizer-umbrella
C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True %APPVEYOR_PROJECT_NAME%
artifacts:
- path: vsbuild\src\proxy\RelWithDebInfo\plugin_python.dll
name: plugin_python_dll
- path: vsbuild\src\proxy\RelWithDebInfo\plugin_python.pdb
name: plugin_python_pdb
- path: vsbuild\src\proxy\RelWithDebInfo\plugin_python.lib
name: plugin_python_lib
- path: vsbuild\src\runner\RelWithDebInfo\pythonrunner.dll
name: pythonrunner_dll
- path: vsbuild\src\runner\RelWithDebInfo\pythonrunner.pdb
name: pythonrunner_pdb
- path: vsbuild\src\runner\RelWithDebInfo\pythonrunner.lib
name: pythonrunner_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: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
- ps: ./send.ps1 failure $env:WEBHOOK_URL
+5 -4
View File
@@ -13,6 +13,7 @@ SET(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
FIND_PACKAGE(Qt5Widgets REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
#QT5_WRAP_UI(${PROJ_NAME}_UIHDRS ${${PROJ_NAME}_FORMS})
SET(Boost_USE_STATIC_LIBS ON)
@@ -24,7 +25,7 @@ IF (Boost_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
ENDIF (Boost_FOUND)
SET(default_project_path "${CMAKE_SOURCE_DIR}/../..")
SET(default_project_path "${DEPENDENCIES_DIR}/modorganizer_super")
GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH)
SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects")
@@ -33,15 +34,15 @@ SET(lib_path "${project_path}/../../install/libs")
ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
INCLUDE_DIRECTORIES(${project_path}/uibase/src
${project_path}/plugin_python/src/runner/
${PYTHON_ROOT}/Include
${PYTHON_ROOT}/PC)
${CMAKE_SOURCE_DIR}/src/runner/
${PYTHON_ROOT}/Include)
LINK_DIRECTORIES(${lib_path})
ADD_LIBRARY(${PROJ_NAME} SHARED ${${PROJ_NAME}_HDRS} ${${PROJ_NAME}_SRCS} ${${PROJ_NAME}_UIHDRS})
TARGET_LINK_LIBRARIES(${PROJ_NAME}
Qt5::Widgets
Qt5::Network
${Boost_LIBRARIES}
uibase)
+2 -2
View File
@@ -171,7 +171,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
return true;
} else {
DWORD error = ::GetLastError();
qCritical("Failed to load python runner (%s): %s", qPrintable(m_TempRunnerFile), qPrintable(windowsErrorString(error)));
qCritical("Failed to load python runner (%s): %s", qUtf8Printable(m_TempRunnerFile), qUtf8Printable(windowsErrorString(error)));
if (error == ERROR_MOD_NOT_FOUND) {
m_LoadFailure = FAIL_MISSINGDEPENDENCIES;
}
@@ -196,7 +196,7 @@ QString ProxyPython::description() const
VersionInfo ProxyPython::version() const
{
return VersionInfo(2, 0, 0, VersionInfo::RELEASE_FINAL);
return VersionInfo(2, 0, 1, VersionInfo::RELEASE_FINAL);
}
bool ProxyPython::isActive() const
+4 -4
View File
@@ -15,6 +15,7 @@ SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
ADD_DEFINITIONS(-DQT_NO_KEYWORDS)
FIND_PACKAGE(Qt5Widgets REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
#QT5_WRAP_UI(${PROJ_NAME}_UIHDRS ${${PROJ_NAME}_FORMS})
FIND_PACKAGE(Qt5LinguistTools)
QT5_CREATE_TRANSLATION(${PROJ_NAME}_translations_qm ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/${PROJ_NAME}_en.ts)
@@ -28,7 +29,7 @@ IF (Boost_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
ENDIF (Boost_FOUND)
SET(default_project_path "${CMAKE_SOURCE_DIR}/..")
SET(default_project_path "${DEPENDENCIES_DIR}/modorganizer_super")
GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH)
SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects")
@@ -37,17 +38,16 @@ SET(lib_path "${project_path}/../../install/libs")
INCLUDE_DIRECTORIES(${project_path}/uibase/src
${project_path}/game_features/src
${PYTHON_ROOT}/Include
${SIP_ROOT}
${PYTHON_ROOT}/PC)
LINK_DIRECTORIES(${lib_path}
${PYTHON_ROOT}/PCbuild
${Boost_LIBRARY_DIRS}
${SIP_ROOT})
${Boost_LIBRARY_DIRS})
ADD_LIBRARY(${PROJ_NAME} SHARED ${${PROJ_NAME}_HDRS} ${${PROJ_NAME}_SRCS} ${${PROJ_NAME}_translations_qm})
TARGET_LINK_LIBRARIES(${PROJ_NAME}
Qt5::Widgets
Qt5::Network
uibase)
ADD_DEFINITIONS(-DPYTHONRUNNER_LIBRARY)
+5
View File
@@ -178,6 +178,11 @@ QList<MOBase::ExecutableInfo> IPluginGameWrapper::executables() const
return basicWrapperFunctionImplementation<IPluginGameWrapper, QList<MOBase::ExecutableInfo>>(this, "executables");
}
QList<MOBase::ExecutableForcedLoadSetting> IPluginGameWrapper::executableForcedLoads() const
{
return basicWrapperFunctionImplementation<IPluginGameWrapper, QList<MOBase::ExecutableForcedLoadSetting>>(this, "executableForcedLoads");
}
QString IPluginGameWrapper::steamAPPId() const
{
return basicWrapperFunctionImplementation<IPluginGameWrapper, QString>(this, "steamAPPId");
+1
View File
@@ -101,6 +101,7 @@ public:
virtual QDir documentsDirectory() const override;
virtual QDir savesDirectory() const override;
virtual QList<MOBase::ExecutableInfo> executables() const override;
virtual QList<MOBase::ExecutableForcedLoadSetting> executableForcedLoads() const override;
virtual QString steamAPPId() const override;
virtual QStringList primaryPlugins() const override;
virtual QStringList gameVariants() const override;
+21 -3
View File
@@ -73,7 +73,7 @@ struct QString_to_python_str
{
static PyObject *convert(const QString &str) {
// It's safer to explicitly convert to unicode as if we don't, this can return either str or unicode without it being easy to know which to expect
bpy::object pyStr = bpy::object(str.toUtf8().constData());
bpy::object pyStr = bpy::object(qUtf8Printable(str));
if (SIPBytes_Check(pyStr.ptr()))
pyStr = pyStr.attr("decode")("utf-8");
return bpy::incref(pyStr.ptr());
@@ -960,6 +960,7 @@ BOOST_PYTHON_MODULE(mobase)
.def("downloadsPath", bpy::pure_virtual(&IOrganizer::downloadsPath))
.def("overwritePath", bpy::pure_virtual(&IOrganizer::overwritePath))
.def("basePath", bpy::pure_virtual(&IOrganizer::basePath))
.def("modsPath", bpy::pure_virtual(&IOrganizer::modsPath))
.def("appVersion", bpy::pure_virtual(&IOrganizer::appVersion))
.def("getMod", bpy::pure_virtual(&IOrganizer::getMod), bpy::return_value_policy<bpy::reference_existing_object>())
.def("createMod", bpy::pure_virtual(&IOrganizer::createMod), bpy::return_value_policy<bpy::reference_existing_object>())
@@ -981,7 +982,7 @@ BOOST_PYTHON_MODULE(mobase)
.def("pluginList", bpy::pure_virtual(&IOrganizer::pluginList), bpy::return_value_policy<bpy::reference_existing_object>())
.def("modList", bpy::pure_virtual(&IOrganizer::modList), bpy::return_value_policy<bpy::reference_existing_object>())
.def("profile", bpy::pure_virtual(&IOrganizer::profile), bpy::return_value_policy<bpy::reference_existing_object>())
.def("startApplication", bpy::pure_virtual(&IOrganizer::startApplication), ((bpy::arg("args")=QStringList()), (bpy::arg("cwd")=""), (bpy::arg("profile")="")), bpy::return_value_policy<bpy::return_by_value>())
.def("startApplication", bpy::pure_virtual(&IOrganizer::startApplication), ((bpy::arg("args")=QStringList()), (bpy::arg("cwd")=""), (bpy::arg("profile")=""), (bpy::arg("forcedCustomOverwrite")=""), (bpy::arg("ignoreCustomOverwrite")=false)), bpy::return_value_policy<bpy::return_by_value>())
//.def("waitForApplication", bpy::pure_virtual(&IOrganizer::waitForApplication), (bpy::arg("exitCode")=nullptr), bpy::return_value_policy<bpy::return_by_value>())
// Use wrapped version
.def("waitForApplication", waitForApplication)
@@ -1069,6 +1070,7 @@ BOOST_PYTHON_MODULE(mobase)
.def("addCategory", bpy::pure_virtual(&IModInterface::addCategory))
.def("removeCategory", bpy::pure_virtual(&IModInterface::removeCategory))
.def("categories", bpy::pure_virtual(&IModInterface::categories))
.def("setGameName", bpy::pure_virtual(&IModInterface::setGameName))
.def("setName", bpy::pure_virtual(&IModInterface::setName))
.def("remove", bpy::pure_virtual(&IModInterface::remove))
;
@@ -1093,6 +1095,12 @@ BOOST_PYTHON_MODULE(mobase)
QFlags_from_python_obj<IPluginList::PluginState>();
Functor0_converter<void>(); // converter for the onRefreshed-callback
bpy::enum_<IPluginList::PluginState>("PluginState")
.value("missing", IPluginList::STATE_MISSING)
.value("inactive", IPluginList::STATE_INACTIVE)
.value("active", IPluginList::STATE_ACTIVE)
;
bpy::class_<IPluginListWrapper, boost::noncopyable>("IPluginList")
.def("state", bpy::pure_virtual(&MOBase::IPluginList::state))
.def("priority", bpy::pure_virtual(&MOBase::IPluginList::priority))
@@ -1111,6 +1119,16 @@ BOOST_PYTHON_MODULE(mobase)
QFlags_from_python_obj<IModList::ModState>();
Functor2_converter<void, const QString&, IModList::ModStates>(); // converter for the onModStateChanged-callback
bpy::enum_<IModList::ModState>("ModState")
.value("exists", IModList::STATE_EXISTS)
.value("active", IModList::STATE_ACTIVE)
.value("essential", IModList::STATE_ESSENTIAL)
.value("empty", IModList::STATE_EMPTY)
.value("endorsed", IModList::STATE_ENDORSED)
.value("valid", IModList::STATE_VALID)
.value("alternate", IModList::STATE_ALTERNATE)
;
bpy::class_<IModListWrapper, boost::noncopyable>("IModList")
.def("displayName", bpy::pure_virtual(&MOBase::IModList::displayName))
.def("allMods", bpy::pure_virtual(&MOBase::IModList::allMods))
@@ -1392,7 +1410,7 @@ QList<QObject*> PythonRunner::instantiate(const QString &pluginName)
return interfaceList;
} catch (const bpy::error_already_set&) {
qWarning("failed to run python script \"%s\"", qPrintable(pluginName));
qWarning("failed to run python script \"%s\"", qUtf8Printable(pluginName));
reportPythonError();
}
return QList<QObject*>();
+41 -5
View File
@@ -63,8 +63,8 @@ public:
{ m_Wrapped->requestFiles(gameName, modID, userData); }
void requestFileInfo(QString gameName, int modID, int fileID, QVariant userData)
{ m_Wrapped->requestFileInfo(gameName, modID, fileID, userData); }
void requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData)
{ m_Wrapped->requestToggleEndorsement(gameName, modID, endorse, userData); }
void requestToggleEndorsement(QString gameName, int modID, QString modVersion, bool endorse, QVariant userData)
{ m_Wrapped->requestToggleEndorsement(gameName, modID, modVersion, endorse, userData); }
void onFilesAvailable(boost::python::object callback) {
m_FilesAvailableHandler = callback;
@@ -94,6 +94,14 @@ public:
Qt::UniqueConnection);
}
void onTrackingToggled(boost::python::object callback) {
m_TrackingToggledHandler = callback;
connect(m_Wrapped, SIGNAL(trackingToggled(int,QVariant,bool)),
this, SLOT(trackingToggled(int,QVariant,bool)),
Qt::UniqueConnection);
}
void onRequestFailed(boost::python::object callback) {
m_FailedHandler = callback;
connect(m_Wrapped, SIGNAL(requestFailed(int,int,QVariant,QString)),
@@ -180,6 +188,26 @@ private Q_SLOTS:
}
}
void trackingToggled(int modID, QVariant userData, bool tracked)
{
try {
if (m_TrackingToggledHandler.is_none()) {
qCritical("no handler connected");
return;
}
try {
GILock lock;
m_TrackingToggledHandler(modID, userData, tracked);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
} catch (const std::exception &e) {
qCritical("failed to report event: %s", e.what());
} catch (...) {
qCritical("failed to report event");
}
}
void requestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage)
{
try {
@@ -197,6 +225,7 @@ private:
boost::python::object m_DescriptionAvailableHandler;
boost::python::object m_FileInfoHandler;
boost::python::object m_EndorsementToggledHandler;
boost::python::object m_TrackingToggledHandler;
boost::python::object m_FailedHandler;
};
@@ -228,6 +257,10 @@ struct IOrganizerWrapper : MOBase::IOrganizer,
{
return this->get_override("basePath")();
}
virtual QString modsPath() const override
{
return this->get_override("modsPath")();
}
virtual MOBase::VersionInfo appVersion() const override
{
return this->get_override("appVersion")();
@@ -323,9 +356,11 @@ struct IOrganizerWrapper : MOBase::IOrganizer,
virtual HANDLE startApplication(const QString &executable,
const QStringList &args = QStringList(),
const QString &cwd = "",
const QString &profile = "") override
const QString &profile = "",
const QString &forcedCustomOverwrite = "",
bool ignoreCustomOverwrite = false) override
{
return reinterpret_cast<HANDLE>(this->get_override("startApplication")(executable, args, cwd, profile).as<size_t>());
return reinterpret_cast<HANDLE>(this->get_override("startApplication")(executable, args, cwd, profile, forcedCustomOverwrite, ignoreCustomOverwrite).as<size_t>());
}
virtual bool waitForApplication(HANDLE handle,
LPDWORD exitCode = nullptr) const override
@@ -387,7 +422,7 @@ struct IModRepositoryBridgeWrapper: MOBase::IModRepositoryBridge, boost::python:
virtual void requestFiles(QString gameName, int modID, QVariant userData) { this->get_override("requestFiles")(gameName, modID, userData); }
virtual void requestFileInfo(QString gameName, int modID, int fileID, QVariant userData) { this->get_override("requestFileInfo")(gameName, modID, fileID, userData); }
virtual void requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData) { this->get_override("requestDownloadURL")(gameName, modID, fileID, userData); }
virtual void requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData) { this->get_override("requestToggleEndorsement")(gameName, modID, endorse, userData); }
virtual void requestToggleEndorsement(QString gameName, int modID, QString modVersion, bool endorse, QVariant userData) { this->get_override("requestToggleEndorsement")(gameName, modID, endorse, userData); }
};
struct IInstallationManagerWrapper: MOBase::IInstallationManager, boost::python::wrapper<MOBase::IInstallationManager>
@@ -408,6 +443,7 @@ struct IModInterfaceWrapper: MOBase::IModInterface, boost::python::wrapper<MOBas
virtual void setNexusID(int nexusID) override { this->get_override("setNexusID")(nexusID); }
virtual void setInstallationFile(const QString &fileName) override { this->get_override("setInstallationFile")(fileName); }
virtual void addNexusCategory(int categoryID) override { this->get_override("addNexusCategory")(categoryID); }
virtual void setGameName(const QString &gameName) override { this->get_override("setGameName")(gameName); }
virtual bool setName(const QString &name) override { return this->get_override("setName")(name); }
virtual bool remove() override { return this->get_override("remove")(); }
virtual void addCategory(const QString &categoryName) override { this->get_override("addCategory")(categoryName); }