From e6a87a17987de5d8e462634777df31e2cae5c1a6 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 4 Nov 2020 20:57:50 -0500 Subject: added IPlugin::registered() removed useless dummy interfaces because init() isn't called anymore python plugins currently broken because init() isn't called on them fixed create instance dialog being shown on startup even if portable instance existed display a message when the last instance can't be found fixed instance manager dialog failing to open the portable instance --- src/plugincontainer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugincontainer.h') diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 07363ee7..bfbf1fa8 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -168,7 +168,7 @@ private: QObject* as_qobject(MOBase::IPlugin* plugin) const; - bool verifyPlugin(MOBase::IPlugin *plugin); + bool initPlugin(MOBase::IPlugin *plugin); void registerGame(MOBase::IPluginGame *game); bool registerPlugin(QObject *pluginObj, const QString &fileName); bool unregisterPlugin(QObject *pluginObj, const QString &fileName); -- cgit v1.3.1 From dc9de3696519fab6403c386a48c84cd6781ab99c Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 4 Nov 2020 22:50:51 -0500 Subject: call init() on proxy plugins OrganizerProxy now handles a null OrganizerCore, used for proxy plugins changed appVersion() and pluginDataPath() so they don't need OrganizerCore --- src/organizercore.cpp | 2 +- src/organizercore.h | 2 +- src/organizerproxy.cpp | 206 +++++++++++++++++++++++++++++++++++++++--------- src/plugincontainer.cpp | 34 +++++++- src/plugincontainer.h | 2 +- 5 files changed, 205 insertions(+), 41 deletions(-) (limited to 'src/plugincontainer.h') diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 550f61d4..d01aab96 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -758,7 +758,7 @@ void OrganizerCore::setPersistent(const QString &pluginName, const QString &key, m_Settings.plugins().setPersistent(pluginName, key, value, sync); } -QString OrganizerCore::pluginDataPath() const +QString OrganizerCore::pluginDataPath() { return qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()) + "/data"; diff --git a/src/organizercore.h b/src/organizercore.h index 1452bf08..80b89a43 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -314,7 +314,7 @@ public: void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value); QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def) const; void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync); - QString pluginDataPath() const; + static QString pluginDataPath(); virtual MOBase::IModInterface *installMod(const QString &fileName, bool reinstallation, ModInfo::Ptr currentMod, const QString &initModName); QString resolvePath(const QString &fileName) const; QStringList listDirectories(const QString &directoryName) const; diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index 45efc00c..5fa1f4ef 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -9,6 +9,7 @@ #include "modlistproxy.h" #include "pluginlistproxy.h" #include "proxyutils.h" +#include "shared/util.h" #include #include @@ -21,10 +22,17 @@ OrganizerProxy::OrganizerProxy(OrganizerCore* organizer, PluginContainer* plugin : m_Proxied(organizer) , m_PluginContainer(pluginContainer) , m_Plugin(plugin) - , m_DownloadManagerProxy(std::make_unique(this, organizer->downloadManager())) - , m_ModListProxy(std::make_unique(this, organizer->modList())) - , m_PluginListProxy(std::make_unique(this, organizer->pluginList())) { + if (m_Proxied) { + m_DownloadManagerProxy = std::make_unique( + this, m_Proxied->downloadManager()); + + m_ModListProxy = std::make_unique( + this, m_Proxied->modList()); + + m_PluginListProxy = std::make_unique( + this, m_Proxied->pluginList()); + } } IModRepositoryBridge *OrganizerProxy::createNexusBridge() const @@ -34,83 +42,133 @@ IModRepositoryBridge *OrganizerProxy::createNexusBridge() const QString OrganizerProxy::profileName() const { - return m_Proxied->profileName(); + if (m_Proxied) { + return m_Proxied->profileName(); + } else { + return {}; + } } QString OrganizerProxy::profilePath() const { - return m_Proxied->profilePath(); + if (m_Proxied) { + return m_Proxied->profilePath(); + } else { + return {}; + } } QString OrganizerProxy::downloadsPath() const { - return m_Proxied->downloadsPath(); + if (m_Proxied) { + return m_Proxied->downloadsPath(); + } else { + return {}; + } } QString OrganizerProxy::overwritePath() const { - return m_Proxied->overwritePath(); + if (m_Proxied) { + return m_Proxied->overwritePath(); + } else { + return {}; + } } QString OrganizerProxy::basePath() const { - return m_Proxied->basePath(); + if (m_Proxied) { + return m_Proxied->basePath(); + } else { + return {}; + } } QString OrganizerProxy::modsPath() const { - return m_Proxied->modsPath(); + if (m_Proxied) { + return m_Proxied->modsPath(); + } else { + return {}; + } } VersionInfo OrganizerProxy::appVersion() const { - return m_Proxied->appVersion(); + return createVersionInfo(); } IPluginGame *OrganizerProxy::getGame(const QString &gameName) const { - return m_Proxied->getGame(gameName); + if (m_Proxied) { + return m_Proxied->getGame(gameName); + } else { + return nullptr; + } } IModInterface *OrganizerProxy::createMod(MOBase::GuessedValue &name) { - return m_Proxied->createMod(name); + if (m_Proxied) { + return m_Proxied->createMod(name); + } else { + return nullptr; + } } void OrganizerProxy::modDataChanged(IModInterface *mod) { - m_Proxied->modDataChanged(mod); + if (m_Proxied) { + m_Proxied->modDataChanged(mod); + } } QVariant OrganizerProxy::pluginSetting(const QString &pluginName, const QString &key) const { - return m_Proxied->pluginSetting(pluginName, key); + if (m_Proxied) { + return m_Proxied->pluginSetting(pluginName, key); + } else { + return {}; + } } void OrganizerProxy::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) { - m_Proxied->setPluginSetting(pluginName, key, value); + if (m_Proxied) { + m_Proxied->setPluginSetting(pluginName, key, value); + } } QVariant OrganizerProxy::persistent(const QString &pluginName, const QString &key, const QVariant &def) const { - return m_Proxied->persistent(pluginName, key, def); + if (m_Proxied) { + return m_Proxied->persistent(pluginName, key, def); + } else { + return {}; + } } void OrganizerProxy::setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync) { - m_Proxied->setPersistent(pluginName, key, value, sync); + if (m_Proxied) { + m_Proxied->setPersistent(pluginName, key, value, sync); + } } QString OrganizerProxy::pluginDataPath() const { - return m_Proxied->pluginDataPath(); + return OrganizerCore::pluginDataPath(); } HANDLE OrganizerProxy::startApplication( const QString& exe, const QStringList& args, const QString &cwd, const QString& profile, const QString &overwrite, bool ignoreOverwrite) { + if (!m_Proxied) { + return INVALID_HANDLE_VALUE; + } + log::debug( "a plugin has requested to start an application:\n" " . executable: '{}'\n" @@ -135,6 +193,10 @@ HANDLE OrganizerProxy::startApplication( bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const { + if (!m_Proxied) { + return false; + } + const auto pid = ::GetProcessId(handle); log::debug( @@ -170,31 +232,53 @@ bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const void OrganizerProxy::refresh(bool saveChanges) { - m_Proxied->refresh(saveChanges); + if (m_Proxied) { + m_Proxied->refresh(saveChanges); + } } IModInterface *OrganizerProxy::installMod(const QString &fileName, const QString &nameSuggestion) { - return m_Proxied->installMod(fileName, false, nullptr, nameSuggestion); + if (m_Proxied) { + return m_Proxied->installMod(fileName, false, nullptr, nameSuggestion); + } else { + return nullptr; + } } QString OrganizerProxy::resolvePath(const QString &fileName) const { - return m_Proxied->resolvePath(fileName); + if (m_Proxied) { + return m_Proxied->resolvePath(fileName); + } else { + return {}; + } } QStringList OrganizerProxy::listDirectories(const QString &directoryName) const { - return m_Proxied->listDirectories(directoryName); + if (m_Proxied) { + return m_Proxied->listDirectories(directoryName); + } else { + return {}; + } } QStringList OrganizerProxy::findFiles(const QString &path, const std::function &filter) const { - return m_Proxied->findFiles(path, filter); + if (m_Proxied) { + return m_Proxied->findFiles(path, filter); + } else { + return {}; + } } QStringList OrganizerProxy::findFiles(const QString& path, const QStringList& globFilters) const { + if (!m_Proxied) { + return {}; + } + QList> patterns; for (auto& gfilter : globFilters) { patterns.append(GlobPattern(gfilter)); @@ -211,12 +295,20 @@ QStringList OrganizerProxy::findFiles(const QString& path, const QStringList& gl QStringList OrganizerProxy::getFileOrigins(const QString &fileName) const { - return m_Proxied->getFileOrigins(fileName); + if (m_Proxied) { + return m_Proxied->getFileOrigins(fileName); + } else { + return {}; + } } QList OrganizerProxy::findFileInfos(const QString &path, const std::function &filter) const { - return m_Proxied->findFileInfos(path, filter); + if (m_Proxied) { + return m_Proxied->findFileInfos(path, filter); + } else { + return {}; + } } MOBase::IDownloadManager *OrganizerProxy::downloadManager() const @@ -236,54 +328,94 @@ MOBase::IModList *OrganizerProxy::modList() const MOBase::IProfile *OrganizerProxy::profile() const { - return m_Proxied->currentProfile(); + if (m_Proxied) { + return m_Proxied->currentProfile(); + } else { + return nullptr; + } } MOBase::IPluginGame const *OrganizerProxy::managedGame() const { - return m_Proxied->managedGame(); + if (m_Proxied) { + return m_Proxied->managedGame(); + } else { + return nullptr; + } } // CALLBACKS bool OrganizerProxy::onAboutToRun(const std::function& func) { - return m_Proxied->onAboutToRun(MOShared::callIfPluginActive(this, func, true)); + if (m_Proxied) { + return m_Proxied->onAboutToRun(MOShared::callIfPluginActive(this, func, true)); + } else { + return false; + } } bool OrganizerProxy::onFinishedRun(const std::function& func) { - return m_Proxied->onFinishedRun(MOShared::callIfPluginActive(this, func)); + if (m_Proxied) { + return m_Proxied->onFinishedRun(MOShared::callIfPluginActive(this, func)); + } else { + return false; + } } bool OrganizerProxy::onUserInterfaceInitialized(std::function const& func) { - // Always call this one to allow plugin to initialize themselves even when not active: - return m_Proxied->onUserInterfaceInitialized(func); + if (m_Proxied) { + // Always call this one to allow plugin to initialize themselves even when not active: + return m_Proxied->onUserInterfaceInitialized(func); + } else { + return false; + } } bool OrganizerProxy::onProfileCreated(std::function const& func) { - return m_Proxied->onProfileCreated(MOShared::callIfPluginActive(this, func)); + if (m_Proxied) { + return m_Proxied->onProfileCreated(MOShared::callIfPluginActive(this, func)); + } else { + return false; + } } bool OrganizerProxy::onProfileRenamed(std::function const& func) { - return m_Proxied->onProfileRenamed(MOShared::callIfPluginActive(this, func)); + if (m_Proxied) { + return m_Proxied->onProfileRenamed(MOShared::callIfPluginActive(this, func)); + } else { + return false; + } } bool OrganizerProxy::onProfileRemoved(std::function const& func) { - return m_Proxied->onProfileRemoved(MOShared::callIfPluginActive(this, func)); + if (m_Proxied) { + return m_Proxied->onProfileRemoved(MOShared::callIfPluginActive(this, func)); + } else { + return false; + } } bool OrganizerProxy::onProfileChanged(std::function const& func) { - return m_Proxied->onProfileChanged(MOShared::callIfPluginActive(this, func)); + if (m_Proxied) { + return m_Proxied->onProfileChanged(MOShared::callIfPluginActive(this, func)); + } else { + return false; + } } bool OrganizerProxy::onPluginSettingChanged(std::function const& func) { - // Always call this one, otherwise plugin cannot detect they are being enabled / disabled: - return m_Proxied->onPluginSettingChanged(func); + if (m_Proxied) { + // Always call this one, otherwise plugin cannot detect they are being enabled / disabled: + return m_Proxied->onPluginSettingChanged(func); + } else { + return false; + } } diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 0c71e491..3ad3da21 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -171,6 +171,22 @@ QObject* PluginContainer::as_qobject(MOBase::IPlugin* plugin) const bool PluginContainer::initPlugin(IPlugin *plugin) { + // when MO has no instance loaded, `init()` is not called on plugins, except + // for proxy plugins + // + // proxy plugins are given an OrganizerProxy that has a null OrganizerCore, + // so there's not a lot it can do, but it can return some information; the + // majority of its functions are no-ops + // + // so initPlugin() (this function) is called for all plugins except proxies, + // and does not call init() if m_Organizer is null; initProxyPlugin() below + // is called only for proxy plugins and will call init() with the crippled + // OrganizerProxy + // + // note that after proxies are initialized, instantiate() is called for all + // the plugins they've discovered, but as for regular plugins, init() won't be + // called on them if m_OrganizerCore is null + if (plugin == nullptr) { return false; } @@ -187,6 +203,22 @@ bool PluginContainer::initPlugin(IPlugin *plugin) return true; } +bool PluginContainer::initProxyPlugin(IPlugin *plugin) +{ + // see initPlugin() above for info + + if (plugin == nullptr) { + return false; + } + + if (!plugin->init(new OrganizerProxy(m_Organizer, this, plugin))) { + log::warn("proxy plugin failed to initialize"); + return false; + } + + return true; +} + void PluginContainer::registerGame(IPluginGame *game) { @@ -272,7 +304,7 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) } { // proxy plugins IPluginProxy *proxy = qobject_cast(plugin); - if (initPlugin(proxy)) { + if (initProxyPlugin(proxy)) { bf::at_key(m_Plugins).push_back(proxy); QStringList pluginNames = proxy->pluginList( QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath())); diff --git a/src/plugincontainer.h b/src/plugincontainer.h index bfbf1fa8..2b39726b 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -169,9 +169,9 @@ private: bool initPlugin(MOBase::IPlugin *plugin); + bool initProxyPlugin(MOBase::IPlugin *plugin); void registerGame(MOBase::IPluginGame *game); bool registerPlugin(QObject *pluginObj, const QString &fileName); - bool unregisterPlugin(QObject *pluginObj, const QString &fileName); OrganizerCore *m_Organizer; -- cgit v1.3.1