--- /dev/null
+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.
#define CLICAP_IDENTIFY_MSG 0x0004
#define CLICAP_ACCOUNT_NOTIFY 0x0008
#define CLICAP_EXTENDED_JOIN 0x0010
+#define CLICAP_AWAY_NOTIFY 0x0020
/*
* flags macros.
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));
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;
}
_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))
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()
*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);