--- /dev/null
+#include <stdinc.h>
+#include <modules.h>
+#include <msgbuf.h>
+
+static const char identify_msg_desc[] = "Provides the solanum.chat/identify-msg client capability";
+
+static void identmsg_outbound(void *);
+unsigned int CLICAP_IDENTIFY_MSG = 0;
+
+mapi_cap_list_av2 identmsg_cap_list[] = {
+ { MAPI_CAP_CLIENT, "solanum.chat/identify-msg", NULL, &CLICAP_IDENTIFY_MSG },
+ { 0, NULL, NULL, NULL }
+};
+
+static mapi_hfn_list_av1 identmsg_hfnlist[] = {
+ { "outbound_msgbuf", identmsg_outbound },
+ { NULL, NULL }
+};
+
+static void identmsg_outbound(void *data_)
+{
+ hook_data *data = data_;
+ struct MsgBuf *msgbuf = data->arg1;
+
+ if (IsIdentified(data->client))
+ msgbuf_append_tag(msgbuf, "solanum.chat/identified", NULL, CLICAP_IDENTIFY_MSG);
+}
+
+DECLARE_MODULE_AV2(identify_msg, NULL, NULL, NULL, NULL, identmsg_hfnlist, identmsg_cap_list, NULL, identify_msg_desc);
#define FLAGS_EXEMPTSPAMBOT 0x02000000
#define FLAGS_EXEMPTSHIDE 0x04000000
#define FLAGS_EXEMPTJUPE 0x08000000
+#define FLAGS_IDENTIFIED 0x10000000 /* owns their current nick */
/* flags for local clients, this needs stuff moved from above to here at some point */
#define IsTGExcessive(x) ((x)->flags & FLAGS_TGEXCESSIVE)
#define SetTGExcessive(x) ((x)->flags |= FLAGS_TGEXCESSIVE)
#define ClearTGExcessive(x) ((x)->flags &= ~FLAGS_TGEXCESSIVE)
+#define IsIdentified(x) ((x)->flags & FLAGS_IDENTIFIED)
+#define SetIdentified(x) ((x)->flags |= FLAGS_IDENTIFIED)
+#define ClearIdentified(x) ((x)->flags &= ~FLAGS_IDENTIFIED)
/* local flags */
--- /dev/null
+#include <stdinc.h>
+#include <modules.h>
+#include <messages.h>
+#include <send.h>
+
+static const char identified_desc[] = "Provides the IDENTIFIED server-to-server command";
+
+static void m_identified(struct MsgBuf *, struct Client *, struct Client *, int, const char *[]);
+
+static struct Message identified_msgtab = {
+ "IDENTIFIED", 0, 0, 0, 0,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {m_identified, 3}, mg_ignore}
+};
+
+static mapi_clist_av1 identified_clist[] = {
+ &identified_msgtab,
+ NULL
+};
+
+static void identified_nick_change(void *);
+static void identified_burst_client(void *);
+
+static mapi_hfn_list_av1 identified_hfnlist[] = {
+ { "local_nick_change", identified_nick_change, HOOK_MONITOR },
+ { "remote_nick_change", identified_nick_change, HOOK_MONITOR },
+ { "burst_client", identified_burst_client },
+ { NULL, NULL }
+};
+
+static void m_identified(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p = find_person(parv[1]);
+ const char *nick = parv[2];
+
+ if (target_p == NULL)
+ return;
+
+ if (irccmp(target_p->name, nick))
+ return;
+
+ if (parc > 3 && irccmp(parv[3], "OFF") == 0)
+ ClearIdentified(target_p);
+ else
+ SetIdentified(target_p);
+}
+
+static void identified_nick_change(void *data_)
+{
+ hook_cdata *data = data_;
+ const char *oldnick = data->arg1, *newnick = data->arg2;
+
+ if (irccmp(oldnick, newnick) != 0)
+ ClearIdentified(data->client);
+}
+
+static void identified_burst_client(void *data_)
+{
+ hook_data_client *data = data_;
+
+ if (IsIdentified(data->target))
+ sendto_one(data->client, ":%s ENCAP * IDENTIFIED %s :%s", me.id, use_id(data->target), data->target->name);
+}
+
+DECLARE_MODULE_AV2(identified, NULL, NULL, identified_clist, NULL, identified_hfnlist, NULL, NULL, identified_desc);