diff --git a/extensions/Makefile.am b/extensions/Makefile.am index b09e1824..634d4469 100644 --- a/extensions/Makefile.am +++ b/extensions/Makefile.am @@ -45,6 +45,7 @@ extension_LTLIBRARIES = \ sno_globaloper.la \ umode_noctcp.la \ m_adminwall.la \ + m_botmode.la \ m_echotags.la \ m_extendchans.la \ m_findforwards.la \ diff --git a/extensions/m_botmode.c b/extensions/m_botmode.c new file mode 100644 index 00000000..069f5916 --- /dev/null +++ b/extensions/m_botmode.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 David Schultz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "stdinc.h" +#include "capability.h" +#include "client.h" +#include "hook.h" +#include "ircd.h" +#include "send.h" +#include "logger.h" +#include "modules.h" +#include "msgbuf.h" +#include "numeric.h" +#include "supported.h" +#include "s_conf.h" +#include "s_serv.h" +#include "s_user.h" +#include "s_newconf.h" + +static char botmode_desc[] = "Provides support for the IRCv3 draft/bot spec"; + +static void h_bm_outbound_msgbuf(void *); +static void h_bm_whois(void *); + +static unsigned CLICAP_BOT; + +mapi_cap_list_av2 botmode_caps[] = { + { MAPI_CAP_CLIENT, "draft/bot", NULL, &CLICAP_BOT }, + { 0, NULL, NULL, NULL}, +}; + +mapi_hfn_list_av1 botmode_hfnlist[] = { + { "outbound_msgbuf", h_bm_outbound_msgbuf, HOOK_NORMAL }, + { "doing_whois_global", h_bm_whois, HOOK_MONITOR }, + { "doing_whois", h_bm_whois, HOOK_MONITOR }, + { NULL, NULL, 0 } +}; + +static void +h_bm_outbound_msgbuf(void *data_) +{ + hook_data *data = data_; + struct MsgBuf *msgbuf = data->arg1; + + if (data->client->umodes & user_modes['B']) + { + msgbuf_append_tag(msgbuf, "draft/bot", NULL, CLICAP_BOT); + } +} + +static void +h_bm_whois(void *data_) +{ + hook_data_client *data = data_; + if (data->target->umodes & user_modes['B']) + { + sendto_one_numeric(data->client, RPL_WHOISBOT, + form_str(RPL_WHOISBOT), data->target->name, ServerInfo.network_name); + } +} + +static int +_modinit(void) +{ + user_modes['B'] = find_umode_slot(); + construct_umodebuf(); + if (!user_modes['B']) + { + ierror("m_botmode: unable to allocate usermode slot for +B, unloading extension"); + return -1; + } + add_isupport("BOT", isupport_umode, "B"); + return 0; +} + +static void +_moddeinit(void) +{ + user_modes['B'] = 0; + construct_umodebuf(); + delete_isupport("BOT"); +} + +DECLARE_MODULE_AV2(botmode, _modinit, _moddeinit, NULL, NULL, botmode_hfnlist, botmode_caps, NULL, botmode_desc); diff --git a/include/messages.h b/include/messages.h index a50d9a6d..6112098a 100644 --- a/include/messages.h +++ b/include/messages.h @@ -107,6 +107,7 @@ #define NUMERIC_STR_331 ":%s 331 %s %s :No topic is set." #define NUMERIC_STR_332 ":%s 332 %s %s :%s" #define NUMERIC_STR_333 ":%s 333 %s %s %s %lld" +#define NUMERIC_STR_335 "%s :is a bot on %s" #define NUMERIC_STR_338 "%s %s :actually using host" #define NUMERIC_STR_341 ":%s 341 %s %s %s" #define NUMERIC_STR_346 ":%s 346 %s %s %s %s %lu" diff --git a/include/numeric.h b/include/numeric.h index 9132b7d1..06c59d71 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -160,6 +160,7 @@ #define RPL_NOTOPIC 331 #define RPL_TOPIC 332 #define RPL_TOPICWHOTIME 333 +#define RPL_WHOISBOT 335 #define RPL_WHOISACTUALLY 338 #define RPL_INVITING 341