]> PatchyGit - patchyircd.git/commitdiff
add away-notify cap
authorEgor <egor@patchysicp.xyz>
Fri, 3 Feb 2023 16:57:22 +0000 (18:57 +0200)
committerEgor <egor@patchysicp.xyz>
Fri, 3 Feb 2023 17:24:21 +0000 (19:24 +0200)
also fix away rpl messages

common.h
irc.c
ircfmt.c
ircfmt.h

index c6c6109..8c8887a 100644 (file)
--- 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 (file)
--- 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)) {
index 8100876..6e9ab73 100644 (file)
--- 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
 {
index 8df2ed3..cc83cd0 100644 (file)
--- 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);