Mercurial > irccd
changeset 1009:637a98de3910
misc: add more examples
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 17 Feb 2021 19:45:00 +0100 |
parents | 201ddc487807 |
children | d1ec9b99b580 |
files | CMakeLists.txt examples/CMakeLists.txt examples/sample-plugin.c examples/sample-plugin.js man/CMakeLists.txt man/irccd-api.3 plugins/ask/ask.js plugins/auth/auth.js plugins/hangman/hangman.js plugins/history/history.js plugins/joke/joke.js plugins/logger/logger.js plugins/plugin/plugin.js plugins/roulette/roulette.js plugins/tictactoe/tictactoe.js |
diffstat | 15 files changed, 405 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Wed Feb 17 19:33:00 2021 +0100 +++ b/CMakeLists.txt Wed Feb 17 19:45:00 2021 +0100 @@ -59,6 +59,7 @@ add_subdirectory(lib) add_subdirectory(irccd) add_subdirectory(irccdctl) +add_subdirectory(examples) add_subdirectory(plugins) add_subdirectory(man)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/CMakeLists.txt Wed Feb 17 19:45:00 2021 +0100 @@ -0,0 +1,26 @@ +# +# CMakeLists.txt -- CMake build for irccd +# +# Copyright (c) 2013-2021 David Demelier <markand@malikania.fr> +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +project(examples) + +install( + FILES + ${examples_SOURCE_DIR}/sample-plugin.c + ${examples_SOURCE_DIR}/sample-plugin.js + DESTINATION ${CMAKE_INSTALL_DATADIR}/irccd +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/sample-plugin.c Wed Feb 17 19:45:00 2021 +0100 @@ -0,0 +1,174 @@ +/* + * This is a sample plugin in native C API. + * + * Note: we recommend that C plugins should be used as last resort because any + * error will crash the whole daemon. It is also less convenient to share and + * update. + * + * You can use CMake to build and install it to appropriate place using the + * following code: + * + * find_package(irccd REQUIRED) + * irccd_define_c_plugin( + * MAME myplugin + * SOURCES muplugin.c + * ) + * + * You can also compile by hand using the pkg-config irccd file. + * + * cc myplugin.c -o myplugin.so $(pkg-config --libs --cflags irccd) + * + * All symbols exported from the file must start with the plugin file basename + * without its extension and with every non allowed character translated to + * `_'. For example if the plugin is name `example-stuff' symbol must start + * with `example_stuff_'. In this example we consider `example_`. + */ + +/* + * Include convention is using irccd/ prefix. + * + * The compat.h header contains additional BSD/POSIX extensions that may be + * missing on your system. It is optional unless you explicitly use them. + */ + +#include <string.h> + +#include <irccd/compat.h> +#include <irccd/event.h> +#include <irccd/server.h> + +/* + * This is the plugin identifier, every variable are optional. + */ +const char *example_description = "Example of C plugin" +const char *example_version = "0.1.0"; +const char *example_license = "ISC"; +const char *example_author = "Name and optional email"; + +/* + * get_options | get_templates | get_paths + * ---------------------------------------------------------------------- + * + * The following optional functions indicate to the daemon which keys are + * supported as options, templates and paths respectively. + * + * Note: even if get_paths is not present or return NULL, irccd allows `cache', + * `data' and `config' as standard keys. + * + * All three functions should return an array of strings which should be + * terminated with a NULL value. They should not be dynamically allocated + * because irccd does not assume they are. + */ + +const char ** +example_get_options(void) +{ + /* Indicate to irccd we support options `level' and `language' */ + static const char *keys[] = { + "level", + "language", + NULL + }; + + return keys; +} + +const char ** +example_get_templates(void) +{ + /* Indicate to irccd we support templates `start' and `finish' */ + static const char *keys[] = { + "start", + "finish", + NULL + }; + + return keys; +} + +/* + * get_option | get_template | get_path + * ---------------------------------------------------------------------- + * + * Those optional functions are analogous to their respective plural form + * except they take a key as parameter. + * + * The plugin can receive an unknown key from the user, NULL can be returned if + * they are not supported. + * + * The returned string isn't free'd by irccd so don't allocate any value + * without storing it somewhere if really needed. + */ + +const char * +example_get_option(const char *key) +{ + if (strcmp(key, "level") == 0) + return "hard"; + else if (strcmp(key, "language") == 0) + return "french"; + + return NULL; +} + +const char * +example_get_template(const char *key) +{ + if (strcmp(key, "start") == 0) + return "#{nickname}, the game has started"; + else if (strcmp(key, "finish") == 0) + return "#{nickname}, the game has finished"; + + return NULL; +} + +/* + * set_option | set_template | set_path + * ---------------------------------------------------------------------- + * + * Finally the three functions are used to set a new value as options, + * templates and paths respectively. Like their `get_*' counterpart, the plugin + * may receive a unknown key from the user in that case it should be simply + * ignored. + * + * Tip: the easiest to manage those is to use global fixed size strings. + */ + +void +example_set_option(const char *key, const char *value) +{ + /* Assuming my_option_* variable exist. */ + if (strcmp(key, "level") == 0) + strlcpy(my_option_level, value, sizeof (my_option_level)); + else if (strcmp(key, "language") == 0) + strlcpy(my_option_language, value, sizeof (my_option_language)); +} + +void +example_set_template(const char *key) +{ + /* Assuming my_template_* variable exist. */ + if (strcmp(key, "level") == 0) + strlcpy(my_template_level, value, sizeof (my_template_level)); + else if (strcmp(key, "language") == 0) + strlcpy(my_template_language, value, sizeof (my_template_language)); +} + +/* + * event + * ---------------------------------------------------------------------- + * + * This function is called when an event has been received. The parameter ev + * contains a union with every possible supported event, the plugin must not + * modify it. + * + * Use the ev->type enumeration to read the appropriate union member. + */ + +void +example_event(const struct irc_event *ev) +{ + /* Simply echo back in case of message. */ + if (ev->type == IRC_EVENT_MESSAGE) + irc_server_message(ev->server, ev->message.channel, ev->message.message); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/sample-plugin.js Wed Feb 17 19:45:00 2021 +0100 @@ -0,0 +1,153 @@ +/* + * This is a sample plugin in Javascript API. + */ + +/* + * This is the plugin identifier, every variable are optional. + */ +info = { + author: "David Demelier <markand@malikania.fr>", + license: "ISC", + summary: "Crazy module for asking a medium", + version: "@IRCCD_VERSION@" +}; + +/* + * Called when the user invoke the plugin using its identifier and the server + * prefix. + * + * Example: !example foo bar baz + */ +function onCommand(server, origin, channel, message) +{ +} + +/* + * Called when a server successfully connect and identifies to a IRC server. + */ +function onConnect(server) +{ +} + +/* + * Called when a server disconnection is detected. + */ +function onDisconnect(server) +{ +} + +/* + * Called when someone invites the bot on a channel. + */ +function onInvite(server, origin, channel) +{ +} + +/* + * Called when someones join a channel (the bot included). + */ +function onJoin(server, origin, channel) +{ +} + +/* + * Called when a someone was kicked from a channel. + */ +function onKick(server, origin, channel, reason) +{ +} + +/* + * Called when a plugin is being loaded. Never happens from IRC. + */ +function onLoad() +{ +} + +/* + * Called when a special CTCP ACTION (/me) is received. + */ +function onMe(server, origin, channel, message) +{ +} + +/* + * Called when a message has been received. + */ +function onMessage(server, origin, channel, message) +{ +} + +/* + * Called when a user/channel mode change. The channel can be the bot nickname. + * The args is a list of string containing mode arguments. + */ +function onMode(server, origin, channel, args) +{ +} + +/* + * Called when a list of names have been received. + * + * Note: in contrast to the IRC names listing, the names are not prefixed with + * their optional channel mode (e.g. @+ etc). + * + * Tip: using this event is no longer necessary starting from irccd 4, the bot + * keeps track of users of every channel it is present and can be accessed + * through the method Irccd.Server.prototype.info. + */ +function onNames(server, channel, names) +{ +} + +/* + * Called when a nickname change. + */ +function onNick(server, origin, nickname) +{ +} + +/* + * Called when a notice is received. The channel can be the bot nickname as + * well. + */ +function onNotice(server, origin, channel, notice) +{ +} + +/* + * Called when someone leaves a channel. + */ +function onPart(server, origin, channel, reason) +{ +} + +/* + * Called when the user request a plugin reload. Never happens from IRC. + */ +function onReload() +{ +} + +/* + * Called when a topic change. + */ +function onTopic(server, origin, channel, topic) +{ +} + +/* + * Called when the plugin is about to be removed. Never happens from IRC. + */ +function onUnload() +{ +} + +/* + * Called when a whois information has been received. This function is usually + * never called unless the plugin explicitly calls Irccd.Server.prototype.whois + * beforehand. + */ +function onWhois(server, info) +{ +}
--- a/man/CMakeLists.txt Wed Feb 17 19:33:00 2021 +0100 +++ b/man/CMakeLists.txt Wed Feb 17 19:45:00 2021 +0100 @@ -18,6 +18,15 @@ project(man) +function(man file section) + get_filename_component(basename ${file} NAME) + configure_file(${file} ${man_BINARY_DIR}/${basename}) + install( + FILES ${man_BINARY_DIR}/${basename} + DESTINATION ${CMAKE_INSTALL_MANDIR}/${section} + ) +endfunction() + set( MAN1 ${man_SOURCE_DIR}/irccd.1 @@ -26,21 +35,27 @@ set( MAN3 - ${man_SOURCE_DIR}/irccd-api-chrono.3 - ${man_SOURCE_DIR}/irccd-api-directory.3 - ${man_SOURCE_DIR}/irccd-api-file.3 - ${man_SOURCE_DIR}/irccd-api-hook.3 - ${man_SOURCE_DIR}/irccd-api-logger.3 - ${man_SOURCE_DIR}/irccd-api-plugin.3 - ${man_SOURCE_DIR}/irccd-api-rule.3 - ${man_SOURCE_DIR}/irccd-api-server.3 - ${man_SOURCE_DIR}/irccd-api-system.3 - ${man_SOURCE_DIR}/irccd-api-timer.3 - ${man_SOURCE_DIR}/irccd-api-unicode.3 - ${man_SOURCE_DIR}/irccd-api-util.3 - ${man_SOURCE_DIR}/irccd-api.3 ) +if (IRCCD_WITH_JS) + list( + APPEND MAN3 + ${man_SOURCE_DIR}/irccd-api-chrono.3 + ${man_SOURCE_DIR}/irccd-api-directory.3 + ${man_SOURCE_DIR}/irccd-api-file.3 + ${man_SOURCE_DIR}/irccd-api-hook.3 + ${man_SOURCE_DIR}/irccd-api-logger.3 + ${man_SOURCE_DIR}/irccd-api-plugin.3 + ${man_SOURCE_DIR}/irccd-api-rule.3 + ${man_SOURCE_DIR}/irccd-api-server.3 + ${man_SOURCE_DIR}/irccd-api-system.3 + ${man_SOURCE_DIR}/irccd-api-timer.3 + ${man_SOURCE_DIR}/irccd-api-unicode.3 + ${man_SOURCE_DIR}/irccd-api-util.3 + ${man_SOURCE_DIR}/irccd-api.3 + ) +endif () + set( MAN5 ${man_SOURCE_DIR}/irccd.conf.5 @@ -53,17 +68,17 @@ ) foreach (m ${MAN1}) - install(FILES ${m} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + man(${m} man1) endforeach () foreach (m ${MAN3}) - install(FILES ${m} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) + man(${m} man3) endforeach () foreach (m ${MAN5}) - install(FILES ${m} DESTINATION ${CMAKE_INSTALL_MANDIR}/man5) + man(${m} man5) endforeach () foreach (m ${MAN7}) - install(FILES ${m} DESTINATION ${CMAKE_INSTALL_MANDIR}/man7) + man(${m} man7) endforeach ()
--- a/man/irccd-api.3 Wed Feb 17 19:33:00 2021 +0100 +++ b/man/irccd-api.3 Wed Feb 17 19:45:00 2021 +0100 @@ -65,6 +65,25 @@ .Em optional in square brackets means it may not exist on your platform. A quick check in Javascript will let you test its presence. +.Pp +An example of plugin can be found at +.Pa @CMAKE_INSTALL_FULL_DATADIR@/irccd/sample-plugin.js +.\" INFO +.Sh INFO +The global +.Vt info +object in the plugin can contain the following strings which identifies the +plugin information: +.Bl -tag +.It Vt license +Plugin license. +.It Vt version +Arbitraty version. +.It Vt author +Author. +.It Vt summary +A short description about the plugin. +.El .\" EVENTS .Sh EVENTS The following is a list of events that Javascript plugins support. All functions
--- a/plugins/ask/ask.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/ask/ask.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "ask", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "Crazy module for asking a medium",
--- a/plugins/auth/auth.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/auth/auth.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "auth", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "Generic plugin to authenticate to services",
--- a/plugins/hangman/hangman.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/hangman/hangman.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "hangman", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "A hangman game for IRC",
--- a/plugins/history/history.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/history/history.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "history", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "track nickname's history",
--- a/plugins/joke/joke.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/joke/joke.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "joke", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "display some jokes",
--- a/plugins/logger/logger.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/logger/logger.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "logger", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "A plugin to log everything",
--- a/plugins/plugin/plugin.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/plugin/plugin.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "plugin", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "A plugin to inspect plugins",
--- a/plugins/roulette/roulette.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/roulette/roulette.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "roulette", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "A russian roulette for IRC",
--- a/plugins/tictactoe/tictactoe.js Wed Feb 17 19:33:00 2021 +0100 +++ b/plugins/tictactoe/tictactoe.js Wed Feb 17 19:45:00 2021 +0100 @@ -18,7 +18,6 @@ // Plugin information. info = { - name: "tictactoe", author: "David Demelier <markand@malikania.fr>", license: "ISC", summary: "A tictactoe game for IRC",