]> jfr.im git - irc/freenode/ircd-seven.git/commitdiff
Add away-notify client capability.
authorKeith Buck <redacted>
Tue, 14 Feb 2012 14:15:44 +0000 (14:15 +0000)
committerEd Kellett <redacted>
Wed, 29 Nov 2017 13:58:21 +0000 (13:58 +0000)
doc/away-notify.txt [new file with mode: 0644]
include/client.h
modules/m_away.c
modules/m_cap.c
src/channel.c
src/s_user.c

diff --git a/doc/away-notify.txt b/doc/away-notify.txt
new file mode 100644 (file)
index 0000000..f427d0d
--- /dev/null
@@ -0,0 +1,43 @@
+away-notify client capability specification
+----------------------------------------------
+
+Copyright (c) 2012 Keith Buck <mr_flea@esper.net>.
+
+Unlimited redistribution and modification of this document is allowed
+provided that the above copyright notice and this permission notice
+remains in tact.
+
+The away-notify client capability allows a client to specify that it
+would like to be notified when users are marked/unmarked as away. This
+capability is referred to as 'away-notify' at capability negotiation
+time.
+
+This capability is designed to replace polling of WHO as a more
+efficient method of tracking the away state of users in a channel. The
+away-notify capability both conserves bandwidth as WHO requests are
+not continually sent and allows the client to be notified immediately
+upon a user setting or removing their away state (as opposed to when
+WHO is next polled).
+
+When this capability is enabled, clients will be sent an AWAY message
+when a user sharing a channel with them sets or removes their away
+state, as well as when a user joins and has an away message set.
+(Note that AWAY will not be sent for joining users with no away
+message set.)
+
+The format of the AWAY message is as follows:
+
+   :nick!user@host AWAY [:message]
+
+If the message is present, the user (specified by the nick!user@host
+mask) is going away.  If the message is not present, the user is
+removing their away message/state.
+
+To fully track the away state of users, clients should:
+
+1) Enable the away-notify capability at negotiation time.
+
+2) Execute WHO when joining a channel to capture the current away
+   state of all users in that channel.
+
+3) Update state appropriately upon receiving an AWAY message.
index 183f7ccb2e82929857fba16fef1ea32338866160..c50174cc520560484e5e5ddf71028a84dd6ea569 100644 (file)
@@ -467,6 +467,7 @@ struct ListClient
 #define CLICAP_IDENTIFY_MSG    0x0004
 #define CLICAP_ACCOUNT_NOTIFY  0x0008
 #define CLICAP_EXTENDED_JOIN   0x0010
+#define CLICAP_AWAY_NOTIFY     0x0020
 
 /*
  * flags macros.
index 1cdd5ed7fbe669dc5166c1fb5eedfeb460fb83e2..9fba635d318d43443f65f911bdeddaa2840b49ff 100644 (file)
@@ -84,6 +84,9 @@ m_away(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
                                      ":%s AWAY", use_id(source_p));
                        free_away(source_p);
+
+                       sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, ":%s!%s@%s AWAY",
+                                                           source_p->name, source_p->username, source_p->host);
                }
                if(MyConnect(source_p))
                        sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
@@ -102,5 +105,9 @@ m_away(struct Client *client_p, struct Client *source_p, int parc, const char *p
        if(MyConnect(source_p))
                sendto_one_numeric(source_p, RPL_NOWAWAY, form_str(RPL_NOWAWAY));
 
+       sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, ":%s!%s@%s AWAY :%s",
+                                           source_p->name, source_p->username, source_p->host,
+                                           source_p->user->away);
+
        return 0;
 }
index 1d2f8c7e327547e0ebb08b7634af9f377798ac67..8c8673d68a459f51a25a14c5fc64a42606b678b9 100644 (file)
@@ -73,6 +73,7 @@ static struct clicap
        _CLICAP("sasl", CLICAP_SASL, 0, 0),
        _CLICAP("account-notify", CLICAP_ACCOUNT_NOTIFY, 0, 0),
        _CLICAP("extended-join", CLICAP_EXTENDED_JOIN, 0, 0),
+       _CLICAP("away-notify", CLICAP_AWAY_NOTIFY, 0, 0),
 };
 
 #define CLICAP_LIST_LEN (sizeof(clicap_list) / sizeof(struct clicap))
index 1ea607d975433cf5d91a42181bb968c6fd9e75a7..91cef9bd40d12af21a6c101d7e850866b5751540 100644 (file)
@@ -145,6 +145,12 @@ send_channel_join(struct Channel *chptr, struct Client *client_p)
                                             client_p->name, client_p->username, client_p->host, chptr->chname,
                                             EmptyString(client_p->user->suser) ? "*" : client_p->user->suser,
                                             client_p->info);
+
+       /* Send away message to away-notify enabled clients. */
+       if (client_p->user->away)
+               sendto_channel_local_with_capability_butone(client_p, ALL_MEMBERS, CLICAP_AWAY_NOTIFY, NOCAPS, chptr,
+                                                           ":%s!%s@%s AWAY :%s", client_p->name, client_p->username,
+                                                           client_p->host, client_p->user->away);
 }
 
 /* find_channel_membership()
index e007effbbd244beb8dad8cf833770e3049f5fcc7..2ef53bcfa36c21acc4e7e14caeadb5584f2fdb1e 100644 (file)
@@ -1553,6 +1553,12 @@ change_nick_user_host(struct Client *target_p,   const char *nick, const char *use
                        *modeval = '\0';
                }
 
+               /* Resend away message to away-notify enabled clients. */
+               if (target_p->user->away)
+                       sendto_common_channels_local_butone(target_p, CLICAP_AWAY_NOTIFY, ":%s!%s@%s AWAY :%s",
+                                                           target_p->name, target_p->username, target_p->host,
+                                                           target_p->user->away);
+
                if(MyClient(target_p) && changed_case)
                        sendto_one(target_p, ":%s!%s@%s NICK %s",
                                        target_p->name, target_p->username, target_p->host, nick);