Add away-notify client capability.
This commit is contained in:
parent
e5520caf0a
commit
c5bbc60375
6 changed files with 64 additions and 0 deletions
43
doc/away-notify.txt
Normal file
43
doc/away-notify.txt
Normal file
|
@ -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.
|
|
@ -444,6 +444,7 @@ struct ListClient
|
||||||
#define CLICAP_SASL 0x0002
|
#define CLICAP_SASL 0x0002
|
||||||
#define CLICAP_ACCOUNT_NOTIFY 0x0004
|
#define CLICAP_ACCOUNT_NOTIFY 0x0004
|
||||||
#define CLICAP_EXTENDED_JOIN 0x0008
|
#define CLICAP_EXTENDED_JOIN 0x0008
|
||||||
|
#define CLICAP_AWAY_NOTIFY 0x0010
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flags macros.
|
* flags macros.
|
||||||
|
|
|
@ -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,
|
sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
|
||||||
":%s AWAY", use_id(source_p));
|
":%s AWAY", use_id(source_p));
|
||||||
free_away(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))
|
if(MyConnect(source_p))
|
||||||
sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
|
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))
|
if(MyConnect(source_p))
|
||||||
sendto_one_numeric(source_p, RPL_NOWAWAY, form_str(RPL_NOWAWAY));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ static struct clicap
|
||||||
_CLICAP("sasl", CLICAP_SASL, 0, 0),
|
_CLICAP("sasl", CLICAP_SASL, 0, 0),
|
||||||
_CLICAP("account-notify", CLICAP_ACCOUNT_NOTIFY, 0, 0),
|
_CLICAP("account-notify", CLICAP_ACCOUNT_NOTIFY, 0, 0),
|
||||||
_CLICAP("extended-join", CLICAP_EXTENDED_JOIN, 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))
|
#define CLICAP_LIST_LEN (sizeof(clicap_list) / sizeof(struct clicap))
|
||||||
|
|
|
@ -136,6 +136,12 @@ send_channel_join(struct Channel *chptr, struct Client *client_p)
|
||||||
client_p->name, client_p->username, client_p->host, chptr->chname,
|
client_p->name, client_p->username, client_p->host, chptr->chname,
|
||||||
EmptyString(client_p->user->suser) ? "*" : client_p->user->suser,
|
EmptyString(client_p->user->suser) ? "*" : client_p->user->suser,
|
||||||
client_p->info);
|
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()
|
/* find_channel_membership()
|
||||||
|
|
|
@ -1468,6 +1468,12 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
||||||
*modeval = '\0';
|
*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)
|
if(MyClient(target_p) && changed_case)
|
||||||
sendto_one(target_p, ":%s!%s@%s NICK %s",
|
sendto_one(target_p, ":%s!%s@%s NICK %s",
|
||||||
target_p->name, target_p->username, target_p->host, nick);
|
target_p->name, target_p->username, target_p->host, nick);
|
||||||
|
|
Loading…
Reference in a new issue