mirror of
https://github.com/ModOrganizer2/modorganizer-plugin_python.git
synced 2026-07-27 14:03:33 -07:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceab36e5f0 | ||
|
|
e158038cfc |
@@ -11,6 +11,8 @@
|
||||
#include <QtPlugin>
|
||||
#include <QDirIterator>
|
||||
#include <QWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QCoreApplication>
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
@@ -85,8 +87,16 @@ typedef IPythonRunner* (*CreatePythonRunner_func)(const MOBase::IOrganizer *moIn
|
||||
bool ProxyPython::init(IOrganizer *moInfo)
|
||||
{
|
||||
m_MOInfo = moInfo;
|
||||
if (!m_MOInfo->pluginSetting(name(), "enabled").toBool()) {
|
||||
m_LoadFailure = FAIL_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_LoadFailure = FAIL_OTHER;
|
||||
if (QCoreApplication::applicationDirPath().contains(';')) {
|
||||
m_LoadFailure = FAIL_SEMICOLON;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString();
|
||||
|
||||
@@ -95,7 +105,6 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll");
|
||||
m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str());
|
||||
if (m_RunnerLib != NULL) {
|
||||
@@ -103,7 +112,28 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
if (CreatePythonRunner == NULL) {
|
||||
throw MyException("embedded dll is invalid: " + windowsErrorString(::GetLastError()));
|
||||
}
|
||||
if (m_MOInfo->persistent(name(), "tryInit", false).toBool()) {
|
||||
if (pythonPath.isEmpty()) {
|
||||
m_LoadFailure = FAIL_PYTHONDETECTION;
|
||||
} else {
|
||||
m_LoadFailure = FAIL_WRONGPYTHONPATH;
|
||||
}
|
||||
if (QMessageBox::question(parentWidget(), tr("Python Initialization failed"),
|
||||
tr("On a previous start the Python Plugin failed to initialize.\n"
|
||||
"Either the value in Settings->Plugins->ProxyPython->plugin_dir is set incorrectly or it is empty and auto-detection doesn't work "
|
||||
"for whatever reason.\n"
|
||||
"Do you want to try initializing python again (at the risk of another crash)?\n"
|
||||
"Suggestion: Select \"no\", and click the warning sign for further help. Afterwards you have to re-enable the python plugin."),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
|
||||
m_MOInfo->setPluginSetting(name(), "enabled", false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_MOInfo->setPersistent(name(), "tryInit", true);
|
||||
m_Runner = CreatePythonRunner(moInfo, pythonPath);
|
||||
m_MOInfo->setPersistent(name(), "tryInit", false);
|
||||
|
||||
if (m_Runner != NULL) {
|
||||
m_LoadFailure = FAIL_NONE;
|
||||
} else {
|
||||
@@ -137,7 +167,7 @@ QString ProxyPython::description() const
|
||||
|
||||
VersionInfo ProxyPython::version() const
|
||||
{
|
||||
return VersionInfo(1, 1, 1, VersionInfo::RELEASE_FINAL);
|
||||
return VersionInfo(1, 2, 0, VersionInfo::RELEASE_FINAL);
|
||||
}
|
||||
|
||||
bool ProxyPython::isActive() const
|
||||
@@ -149,6 +179,7 @@ QList<PluginSetting> ProxyPython::settings() const
|
||||
{
|
||||
QList<PluginSetting> result;
|
||||
result.push_back(PluginSetting("python_dir", "Path to your python installation. Leave empty for auto-detection", ""));
|
||||
result.push_back(PluginSetting("enabled", "Set to true to enable support for python plugins", true));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -183,8 +214,12 @@ std::vector<unsigned int> ProxyPython::activeProblems() const
|
||||
result.push_back(PROBLEM_PYTHONMISSING);
|
||||
} else if (m_LoadFailure == FAIL_WRONGPYTHONPATH) {
|
||||
result.push_back(PROBLEM_WRONGPYTHONPATH);
|
||||
} else if (m_LoadFailure == FAIL_PYTHONDETECTION) {
|
||||
result.push_back(PROBLEM_PYTHONDETECTION);
|
||||
} else if (m_LoadFailure == FAIL_INITFAIL) {
|
||||
result.push_back(PROBLEM_INITFAIL);
|
||||
} else if (m_LoadFailure == FAIL_SEMICOLON) {
|
||||
result.push_back(PROBLEM_SEMICOLON);
|
||||
} else if (m_Runner != NULL) {
|
||||
if (!m_Runner->isPythonInstalled()) {
|
||||
// don't know how this could happen but wth
|
||||
@@ -213,6 +248,12 @@ QString ProxyPython::shortDescription(unsigned int key) const
|
||||
case PROBLEM_INITFAIL: {
|
||||
return tr("Initializing Python failed");
|
||||
} break;
|
||||
case PROBLEM_PYTHONDETECTION: {
|
||||
return tr("Python auto-detection failed");
|
||||
} break;
|
||||
case PROBLEM_SEMICOLON: {
|
||||
return tr("ModOrganizer path contains a semicolon");
|
||||
} break;
|
||||
default:
|
||||
throw MyException(tr("invalid problem key %1").arg(key));
|
||||
}
|
||||
@@ -231,16 +272,27 @@ QString ProxyPython::fullDescription(unsigned int key) const
|
||||
case PROBLEM_PYTHONWRONGVERSION: {
|
||||
return tr("Your installed python version has a different version than 2.7. "
|
||||
"Some MO plugins may not work.<br>"
|
||||
"If you have multiple versions of python installed you may have to configure the path to 2.7 "
|
||||
"If you have multiple versions of python installed you may have to configure the path to 2.7 (32 bit) "
|
||||
"in the settings dialog.<br>"
|
||||
"This is only required to use some extended functionality in MO, you do not need Python to play the game.");
|
||||
} break;
|
||||
case PROBLEM_WRONGPYTHONPATH: {
|
||||
return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 installation.");
|
||||
return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
|
||||
} break;
|
||||
case PROBLEM_PYTHONDETECTION: {
|
||||
return tr("The auto-detection of the python path failed. I don't know why this would happen but you can try to fix it "
|
||||
"by setting python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
|
||||
} break;
|
||||
case PROBLEM_INITFAIL: {
|
||||
return tr("Sorry, I don't know any details. Most likely your python installation is not supported.");
|
||||
} break;
|
||||
case PROBLEM_SEMICOLON: {
|
||||
return tr("The path to Mod Organizer (%1) contains a semicolon. <br>"
|
||||
"While this is legal on NTFS drives there is a lot of software that doesn't handle it correctly.<br>"
|
||||
"Unfortunately MO depends on libraries that seem to fall into that group.<br>"
|
||||
"As a result the python plugin can't be loaded.<br>"
|
||||
"The only solution I can offer is to remove the semicolon / move MO to a path without a semicolon.").arg(QCoreApplication::applicationDirPath());
|
||||
} break;
|
||||
default:
|
||||
throw MyException(tr("invalid problem key %1").arg(key));
|
||||
}
|
||||
@@ -251,9 +303,11 @@ bool ProxyPython::hasGuidedFix(unsigned int key) const
|
||||
return (key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION);
|
||||
}
|
||||
|
||||
void ProxyPython::startGuidedFix(unsigned int) const
|
||||
void ProxyPython::startGuidedFix(unsigned int key) const
|
||||
{
|
||||
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
|
||||
if ((key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION)) {
|
||||
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,19 +52,23 @@ private:
|
||||
static const unsigned int PROBLEM_PYTHONWRONGVERSION = 2;
|
||||
static const unsigned int PROBLEM_WRONGPYTHONPATH = 3;
|
||||
static const unsigned int PROBLEM_INITFAIL = 4;
|
||||
static const unsigned int PROBLEM_PYTHONDETECTION = 5;
|
||||
static const unsigned int PROBLEM_SEMICOLON = 6;
|
||||
static const char *s_DownloadPythonURL;
|
||||
|
||||
const MOBase::IOrganizer *m_MOInfo;
|
||||
MOBase::IOrganizer *m_MOInfo;
|
||||
QString m_TempRunnerFile;
|
||||
HMODULE m_RunnerLib;
|
||||
IPythonRunner *m_Runner;
|
||||
|
||||
enum {
|
||||
FAIL_NONE,
|
||||
FAIL_SEMICOLON,
|
||||
FAIL_NOTINIT,
|
||||
FAIL_MISSINGDEPENDENCIES,
|
||||
FAIL_INITFAIL,
|
||||
FAIL_WRONGPYTHONPATH,
|
||||
FAIL_PYTHONDETECTION,
|
||||
FAIL_OTHER
|
||||
} m_LoadFailure;
|
||||
|
||||
|
||||
@@ -572,6 +572,9 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
.def("removeMod", bpy::pure_virtual(&MOBase::IOrganizer::removeMod))
|
||||
.def("modDataChanged", bpy::pure_virtual(&MOBase::IOrganizer::modDataChanged))
|
||||
.def("pluginSetting", bpy::pure_virtual(&IOrganizer::pluginSetting))
|
||||
.def("setPluginSetting", bpy::pure_virtual(&IOrganizer::pluginSetting))
|
||||
.def("persistent", bpy::pure_virtual(&IOrganizer::persistent))
|
||||
.def("setPersistent", bpy::pure_virtual(&IOrganizer::setPersistent))
|
||||
.def("pluginDataPath", bpy::pure_virtual(&IOrganizer::pluginDataPath))
|
||||
.def("installMod", bpy::pure_virtual(&IOrganizer::installMod))
|
||||
.def("downloadManager", bpy::pure_virtual(&IOrganizer::downloadManager), bpy::return_value_policy<bpy::reference_existing_object>());
|
||||
@@ -642,10 +645,12 @@ bool PythonRunner::initPython(const QString &pythonPath)
|
||||
|
||||
Py_SetProgramName(argv0);
|
||||
PyImport_AppendInittab("mobase", &initmobase);
|
||||
Py_Initialize();
|
||||
|
||||
Py_InitializeEx(0);
|
||||
if (!Py_IsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PySys_SetArgv(0, &argv0);
|
||||
|
||||
bpy::object main_module = bpy::import("__main__");
|
||||
|
||||
@@ -133,6 +133,9 @@ struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOr
|
||||
virtual bool removeMod(MOBase::IModInterface *mod) { return this->get_override("removeMod")(mod); }
|
||||
virtual void modDataChanged(MOBase::IModInterface *mod) { this->get_override("modDataChanged")(mod); }
|
||||
virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const { return this->get_override("pluginSetting")(pluginName, key); }
|
||||
virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) { this->get_override("setPluginSetting")(pluginName, key, value); }
|
||||
virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const { return this->get_override("persistent")(pluginName, key, def); }
|
||||
virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true) { this->get_override("setPersistent")(pluginName, key, value, sync); }
|
||||
virtual QString pluginDataPath() const { return this->get_override("pluginDataPath")(); }
|
||||
virtual void installMod(const QString &fileName) { this->get_override("installMod")(fileName); }
|
||||
virtual MOBase::IDownloadManager *downloadManager() { return this->get_override("downloadManager")(); }
|
||||
|
||||
Reference in New Issue
Block a user