From ac42061c650e31cd396efaadb0605554c6c16df6 Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 3 Feb 2023 18:57:22 +0200 Subject: [PATCH] add away-notify cap also fix away rpl messages --- common.h | 1 + irc.c | 36 +++++++++++++++++++++++------------- ircfmt.c | 13 +++++++++++-- ircfmt.h | 1 + 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/common.h b/common.h index c6c6109..8c8887a 100644 --- a/common.h +++ b/common.h @@ -22,6 +22,7 @@ struct tls; #define CAP_302 1 #define CAP_MULTIPREFIX 2 #define CAP_EXTENDEDJOIN 4 +#define CAP_AWAYNOTIFY 8 struct client_data { SOCKET FD; struct tls *cctx; diff --git a/irc.c b/irc.c index 71fce10..6c35f60 100644 --- a/irc.c +++ b/irc.c @@ -27,14 +27,6 @@ void chanlog() { fflush(fchanlog); } } -void sendbuf_chan(struct channel *chan) { - struct trie_find *f = NULL; - if (trie_findfirst(&f, &chan->members) == 1) - do { - struct client_data *cl = f->n->value; - sendbuf(cl); - } while (trie_findnext(&f) == 1); -} void sendbuf_chan_caps(struct channel *chan, unsigned positive, unsigned negative) { struct trie_find *f = NULL; if (trie_findfirst(&f, &chan->members) == 1) @@ -44,7 +36,10 @@ void sendbuf_chan_caps(struct channel *chan, unsigned positive, unsigned negativ sendbuf(cl); } while (trie_findnext(&f) == 1); } -void sendbuf_list_sans_self(struct client_data *client, struct trie_node **ls, int cookie) { +void sendbuf_chan(struct channel *chan) { + sendbuf_chan_caps(chan, 0, 0); +} +void sendbuf_list_sans_self_caps(struct client_data *client, struct trie_node **ls, int cookie, int positive, int negative) { struct trie_find *f = NULL; if (trie_findfirst(&f, ls) == 1) do { @@ -56,10 +51,14 @@ void sendbuf_list_sans_self(struct client_data *client, struct trie_node **ls, i else continue; } - sendbuf(cl); + if (!(~cl->caps & positive) && !(cl->caps & negative)) + sendbuf(cl); } } while (trie_findnext(&f) == 1); } +void sendbuf_list_sans_self(struct client_data *client, struct trie_node **ls, int cookie) { + sendbuf_list_sans_self_caps(client, ls, cookie, 0, 0); +} int get_cookie() { static int cookie = 0; if (++cookie == 0) { @@ -74,15 +73,18 @@ int get_cookie() { } return cookie; } -void sendbuf_visible(struct client_data *client) { +void sendbuf_visible_caps(struct client_data *client, int positive, int negative) { int cookie = get_cookie(); struct trie_find *f = NULL; if (trie_findfirst(&f, &client->channels) == 1) do { struct channel *chan = f->n->value; - sendbuf_list_sans_self(client, &chan->members, cookie); + sendbuf_list_sans_self_caps(client, &chan->members, cookie, positive, negative); } while (trie_findnext(&f) == 1); } +void sendbuf_visible(struct client_data *client) { + sendbuf_visible_caps(client, 0, 0); +} const char *format_umodes(struct client_data *cl) { static char umodes[6] = ""; char *p = umodes; @@ -194,6 +196,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a { "cap-notify", 0 }, { "multi-prefix", CAP_MULTIPREFIX }, { "extended-join", CAP_EXTENDEDJOIN }, + { "away-notify", CAP_AWAYNOTIFY }, { 0, 0 } }; @@ -203,7 +206,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a if (strcmp(args[0], "LS") == 0) { if (args[1] && atoi(args[1]) >= 302) client->caps |= CAP_302; - copy_strf(&databuf, ":%s CAP * LS :multi-prefix extended-join\r\n", hostname); + copy_strf(&databuf, ":%s CAP * LS :multi-prefix extended-join away-notify\r\n", hostname); sendbuf(client); if (!is_registered(client)) { client->regstate = REG_CAPLS; @@ -1008,6 +1011,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a client->away = NULL; rpl_unaway(client), sendbuf(client); } + msg_away(client); + sendbuf_visible_caps(client, CAP_AWAYNOTIFY, 0); } else { unknown: err_unknowncommand(client, command), sendbuf(client); @@ -1243,6 +1248,11 @@ void channel_join(struct client_data *client, const char *channel, const char *c sendbuf_chan_caps(chan, 0, CAP_EXTENDEDJOIN); msg_join_extended(client, chan); sendbuf_chan_caps(chan, CAP_EXTENDEDJOIN, 0); + // send AWAY + if (client->away) { + msg_away(client); + sendbuf_list_sans_self_caps(client, &chan->members, 0, CAP_AWAYNOTIFY, 0); + } // TODO: send channel modes to the joining client // apply +w modes if (match_list(client, &chan->listwo)) { diff --git a/ircfmt.c b/ircfmt.c index 8100876..6e9ab73 100644 --- a/ircfmt.c +++ b/ircfmt.c @@ -16,6 +16,15 @@ const char *format_prefixes(struct client_data *client, struct client_data *cl, return ""; } +void msg_away(struct client_data *src) +{ + if (src->away) + copy_strf(&databuf, ":%s!%s@%s AWAY :%s\r\n", + src->nick, src->username, src->hostname, src->away); + else + copy_strf(&databuf, ":%s!%s@%s AWAY\r\n", + src->nick, src->username, src->hostname); +} void msg_nick(struct client_data *src, const char *newnick) { copy_strf(&databuf, ":%s!%s@%s NICK %s\r\n", @@ -234,11 +243,11 @@ void rpl_userhost(struct client_data *client, struct client_data **cls, int coun } void rpl_unaway(struct client_data *client) // 305 { - copy_strf(&databuf, ":%s 305 %s :You have been marked as being away\r\n", hostname, client->nick); + copy_strf(&databuf, ":%s 305 %s :You are no longer marked as being away\r\n", hostname, client->nick); } void rpl_nowaway(struct client_data *client) // 306 { - copy_strf(&databuf, ":%s 306 %s :You are no longer marked as being away\r\n", hostname, client->nick); + copy_strf(&databuf, ":%s 306 %s :You have been marked as being away\r\n", hostname, client->nick); } void rpl_whoreply(struct client_data *client, struct client_data *cl, struct channel *chan) // 352 { diff --git a/ircfmt.h b/ircfmt.h index 8df2ed3..cc83cd0 100644 --- a/ircfmt.h +++ b/ircfmt.h @@ -1,6 +1,7 @@ #ifndef IRCFMT_H_ #define IRCFMT_H_ #include "irc.h" +void msg_away(struct client_data *src); void msg_nick(struct client_data *src, const char *newnick); void msg_ping(const char *token); void msg_pong(const char *token); -- 2.56.0