diff --git a/src/controllers/commands/CommandController.cpp b/src/controllers/commands/CommandController.cpp index 7268d3356..27e723b99 100644 --- a/src/controllers/commands/CommandController.cpp +++ b/src/controllers/commands/CommandController.cpp @@ -10,6 +10,7 @@ #include "controllers/commands/Command.hpp" #include "controllers/commands/CommandContext.hpp" #include "controllers/commands/CommandModel.hpp" +#include "controllers/plugins/PluginController.hpp" #include "controllers/userdata/UserDataController.hpp" #include "messages/Message.hpp" #include "messages/MessageBuilder.hpp" @@ -3125,6 +3126,10 @@ void CommandController::initialize(Settings &, Paths &paths) return ""; }); + this->registerCommand("lualol", [](const auto &ctx) { + getApp()->plugins->callEvery("test"); + return ""; + }); } void CommandController::save() diff --git a/src/controllers/plugins/PluginController.cpp b/src/controllers/plugins/PluginController.cpp index cefb0dbc1..f63f81fa8 100644 --- a/src/controllers/plugins/PluginController.cpp +++ b/src/controllers/plugins/PluginController.cpp @@ -1,8 +1,12 @@ #include "PluginController.hpp" +#include "Application.hpp" #include "common/QLogging.hpp" +#include "messages/MessageBuilder.hpp" +#include "providers/twitch/TwitchIrcServer.hpp" -#include +#include +#include extern "C" { #include @@ -47,9 +51,63 @@ void PluginController::load(QFileInfo index, QDir pluginDir) qCDebug(chatterinoLua) << "Running lua file" << index; lua_State *l = luaL_newstate(); luaL_openlibs(l); + this->loadChatterinoLib(l); luaL_dofile(l, index.absoluteFilePath().toStdString().c_str()); - lua_close(l); + + auto pluginName = pluginDir.dirName(); + auto plugin = std::make_unique(pluginName, l); + this->plugins.insert({pluginName, std::move(plugin)}); + qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index; +} + +void PluginController::callEvery(const QString &functionName) +{ + for (const auto &[name, plugin] : this->plugins) + { + lua_getglobal(plugin->state_, functionName.toStdString().c_str()); + lua_pcall(plugin->state_, 0, 0, 0); + } +} + +constexpr int C_FALSE = 0; +constexpr int C_TRUE = 1; + +extern "C" { + +int luaC2SystemMsg(lua_State *L) +{ + if (lua_gettop(L) != 2) + { + luaL_error(L, "need exactly 2 arguments"); // NOLINT + lua_pushboolean(L, C_FALSE); + return 1; + } + const char *channel = luaL_optstring(L, 1, NULL); + const char *text = luaL_optstring(L, 2, NULL); + lua_pop(L, 2); + const auto chn = getApp()->twitch->getChannelOrEmpty(channel); + if (chn->isEmpty()) + { + lua_pushboolean(L, C_FALSE); + return 1; + } + chn->addMessage(makeSystemMessage(text)); + lua_pushboolean(L, C_TRUE); + return 0; +} + +// NOLINTNEXTLINE +static const luaL_Reg C2LIB[] = { + {"system_msg", luaC2SystemMsg}, + {nullptr, nullptr}, +}; +} + +void PluginController::loadChatterinoLib(lua_State *L) +{ + lua_pushglobaltable(L); + luaL_setfuncs(L, C2LIB, 0); } }; // namespace chatterino diff --git a/src/controllers/plugins/PluginController.hpp b/src/controllers/plugins/PluginController.hpp index b2db728a2..3014c9f2b 100644 --- a/src/controllers/plugins/PluginController.hpp +++ b/src/controllers/plugins/PluginController.hpp @@ -3,19 +3,59 @@ #include "common/Singleton.hpp" #include "singletons/Paths.hpp" -#include #include +#include +#include + +#include +#include +#include +#include + +class lua_State; namespace chatterino { +//class Registration +//{ +//public: +// enum Type { +// COMMAND, +// }; +// +// Type type; +// QString name; +// const char *receiverFunctionName; +//}; + +class Plugin +{ +public: + QString name; + Plugin(QString name, lua_State *state) + : name(std::move(name)) + , state_(state) + { + } + +private: + lua_State *state_; + + friend class PluginController; +}; + class PluginController : public Singleton { public: void initialize(Settings &settings, Paths &paths) override; void save() override{}; + void callEvery(const QString &functionName); private: void load(QFileInfo index, QDir pluginDir); + void loadChatterinoLib(lua_State *l); + + std::map> plugins; }; }; // namespace chatterino