23 #include "pluginloader.h"
25 #include "configuration/doomseekerconfig.h"
26 #include "ini/inisection.h"
27 #include "ini/inivariable.h"
29 #include "plugins/engineplugin.h"
30 #include "serverapi/masterclient.h"
31 #include "strings.hpp"
35 #include <QScopedPointer>
38 DClass<PluginLoader::Plugin>
43 QScopedPointer<QLibrary> library;
45 static bool isForbiddenPlugin(QString file)
47 return QFileInfo(file).fileName().toLower().contains(
"vavoom");
53 PluginLoader::Plugin::Plugin(
unsigned int type, QString file)
60 gLog << QObject::tr(
"Skipping loading of forbidden plugin: %1").arg(file);
65 d->library.reset(
new QLibrary(file));
66 if (d->library->load())
68 auto doomSeekerABI = (
unsigned int (*)())(d->library->resolve(
"doomSeekerABI"));
69 if (!doomSeekerABI || doomSeekerABI() != DOOMSEEKER_ABI_VERSION)
73 if (doomSeekerABI !=
nullptr)
76 "plugin ABI version mismatch; plugin: %1, Doomseeker: %2").arg(
77 doomSeekerABI()).arg(DOOMSEEKER_ABI_VERSION);
81 reason = QObject::tr(
"plugin doesn't report its ABI version");
83 gLog << QObject::tr(
"Cannot load plugin %1, reason: %2.").arg(file, reason);
88 auto doomSeekerInit = (
EnginePlugin * (*)())(d->library->resolve(
"doomSeekerInit"));
89 if (doomSeekerInit ==
nullptr)
95 d->info = doomSeekerInit();
96 if (!info()->data()->valid)
102 gLog << QObject::tr(
"Loaded plugin: \"%1\"!").arg(info()->data()->name);
107 gLog << QObject::tr(
"Failed to open plugin: %1").arg(file);
108 gLog << QString(
"Last error was: %1").arg(d->library->errorString());
112 PluginLoader::Plugin::~Plugin()
119 return (
void *) d->library->resolve(func);
127 void PluginLoader::Plugin::initConfig()
131 IniSection cfgSection = gConfig.iniSectionForPlugin(
info()->data()->name);
132 info()->setConfig(cfgSection);
136 bool PluginLoader::Plugin::isValid()
const
138 return d->library !=
nullptr && d->library->isLoaded();
141 void PluginLoader::Plugin::unload()
151 QString pluginsDirectory;
152 QList<PluginLoader::Plugin *> plugins;
162 for (
const QString &dir : directories)
164 d->pluginsDirectory = dir;
172 gLog << QObject::tr(
"Failed to locate plugins.");
176 PluginLoader::~PluginLoader()
178 qDeleteAll(d->plugins);
183 qDeleteAll(d->plugins);
189 if (staticInstance !=
nullptr)
191 delete staticInstance;
192 staticInstance =
nullptr;
196 bool PluginLoader::filesInDir()
198 gLog << QString(
"Attempting to load plugins from directory: %1").arg(d->pluginsDirectory);
199 QDir dir(d->pluginsDirectory);
205 QStringList windowsNamesFilter;
206 windowsNamesFilter <<
"*.dll";
207 dir.setNameFilters(windowsNamesFilter);
209 for (
const QString &entry : dir.entryList(QDir::Files))
212 Plugin *
plugin =
new Plugin(d->type, pluginFilePath);
213 if (plugin->isValid())
214 d->plugins << plugin;
233 if (staticInstance !=
nullptr)
235 qDebug() <<
"Attempting to re-init PluginLoader";
239 staticInstance =
new PluginLoader(MAKEID(
'E',
'N',
'G',
'N'), directories);
246 plugin->initConfig();
252 assert(staticInstance !=
nullptr);
253 return staticInstance;
258 return d->plugins.size();
261 const QList<PluginLoader::Plugin *> &PluginLoader::plugins()
const
268 return d->plugins[index];
281 QString mangledName = QString(name).replace(
" ",
"");
282 for (
int i = 0; i < d->plugins.size(); ++i)
284 QString mangledCandidate = QString(d->plugins[i]->info()->data()->name).replace(
" ",
"");
285 if (mangledName.compare(mangledCandidate) == 0)
296 d->pluginsDirectory = pluginsDirectory;
303 return d->plugins[index];