Mercurial > irccd
changeset 954:30643d18a635
irccd: add onCommand support
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 20 Jan 2021 14:08:14 +0100 |
parents | ab43ba409f9d |
children | 9b167c5c4b78 |
files | irccd/main.c lib/irccd/event.h lib/irccd/irccd.c lib/irccd/js-plugin.c lib/irccd/jsapi-server.c lib/irccd/server.c |
diffstat | 6 files changed, 76 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/irccd/main.c Wed Jan 20 12:32:59 2021 +0100 +++ b/irccd/main.c Wed Jan 20 14:08:14 2021 +0100 @@ -38,10 +38,13 @@ .username = "circ", .nickname = "circ", .hostname = "malikania.fr", + .commandchar = "!", .port = 6697, .flags = IRC_SERVER_FLAGS_SSL | IRC_SERVER_FLAGS_JOIN_INVITE }; - struct irc_plugin p = {0}; + struct irc_plugin p = { + .name = "test" + }; irc_log_set_verbose(true); irc_bot_init();
--- a/lib/irccd/event.h Wed Jan 20 12:32:59 2021 +0100 +++ b/lib/irccd/event.h Wed Jan 20 14:08:14 2021 +0100 @@ -28,6 +28,7 @@ enum irc_event_type { IRC_EVENT_UNKNOWN, + IRC_EVENT_COMMAND, IRC_EVENT_CONNECT, IRC_EVENT_DISCONNECT, IRC_EVENT_INVITE,
--- a/lib/irccd/irccd.c Wed Jan 20 12:32:59 2021 +0100 +++ b/lib/irccd/irccd.c Wed Jan 20 14:08:14 2021 +0100 @@ -17,6 +17,7 @@ */ #include <assert.h> +#include <ctype.h> #include <err.h> #include <errno.h> #include <poll.h> @@ -43,7 +44,7 @@ struct defer { void (*exec)(void *); - void (*data); + void *data; }; struct irc irc; @@ -62,6 +63,39 @@ return p1->fd - p2->fd; } +static bool +is_command(const struct irc_plugin *p, const struct irc_event *ev) +{ + const char *cc; + size_t ccsz; + + if (ev->type != IRC_EVENT_MESSAGE) + return false; + + /* Get the command prefix (e.g !)*/ + cc = ev->server->commandchar; + ccsz = strlen(cc); + + return strncmp(ev->msg.args[1], cc, ccsz) == 0 && + strncmp(ev->msg.args[1] + ccsz, p->name, strlen(p->name)) == 0; +} + +static struct irc_event * +to_command(const struct irc_plugin *p, struct irc_event *ev) +{ + char *s; + + ev->type = IRC_EVENT_COMMAND; + ev->msg.args[1] = ev->msg.args[1] + strlen(ev->server->commandchar) + strlen(p->name); + + for (s = ev->msg.args[1]; *s && isspace(*s); ) + ++s; + + ev->msg.args[1] = s; + + return ev; +} + static struct pkg prepare(void) { @@ -103,11 +137,34 @@ irc_peer_send(&irc.peers[i], buf); } -static inline void -invoke(const struct irc_event *ev) +static void +invoke(struct irc_event *ev) { - for (size_t i = 0; i < irc.pluginsz; ++i) - irc_plugin_handle(&irc.plugins[i], ev); + struct irc_plugin *plgcmd = NULL; + + /* + * Invoke for every plugin the event verbatim. Then, the event may match + * a plugin name command in that case we need to modify the event but + * only one plugin can match by its identifier. For example, the + * following plugins are loaded: + * + * - ask + * - hangman + * - logger + * + * If the message is "!ask will I be reach?" then it will invoke + * onMessage for hangman and logger but onCommand for ask. As such call + * hangman and logger first and modify event before ask. + */ + for (size_t i = 0; i < irc.pluginsz; ++i) { + if (is_command(&irc.plugins[i], ev)) + plgcmd = &irc.plugins[i]; + else + irc_plugin_handle(&irc.plugins[i], ev); + } + + if (plgcmd) + irc_plugin_handle(plgcmd, to_command(plgcmd, ev)); } static void @@ -222,7 +279,7 @@ irc_server_disconnect(s); /* Don't forget to notify plugins. */ - invoke(&(const struct irc_event) { + invoke(&(struct irc_event) { .type = IRC_EVENT_DISCONNECT, .server = s });
--- a/lib/irccd/js-plugin.c Wed Jan 20 12:32:59 2021 +0100 +++ b/lib/irccd/js-plugin.c Wed Jan 20 14:08:14 2021 +0100 @@ -278,6 +278,10 @@ (void)ev; switch (ev->type) { + case IRC_EVENT_COMMAND: + call(plg, "onCommand", "Ss ss", ev->server, ev->msg.prefix, + ev->msg.args[0], ev->msg.args[1]); + break; case IRC_EVENT_CONNECT: call(plg, "onConnect", "S", ev->server); break;
--- a/lib/irccd/jsapi-server.c Wed Jan 20 12:32:59 2021 +0100 +++ b/lib/irccd/jsapi-server.c Wed Jan 20 14:08:14 2021 +0100 @@ -585,7 +585,7 @@ irc_server_incref(s); duk_push_object(ctx); - duk_push_string(ctx, s->name); + duk_push_pointer(ctx, s); duk_put_prop_string(ctx, -2, SIGNATURE); duk_get_global_string(ctx, PROTOTYPE); duk_set_prototype(ctx, -2);
--- a/lib/irccd/server.c Wed Jan 20 12:32:59 2021 +0100 +++ b/lib/irccd/server.c Wed Jan 20 14:08:14 2021 +0100 @@ -336,8 +336,10 @@ const struct handler *c = bsearch(ev->msg.cmd, handlers, IRC_UTIL_SIZE(handlers), sizeof (*c), &(compare_handler)); - if (c) + if (c) { + ev->server = s; c->handle(s, ev); + } } static void