]> PatchyGit - patchyircd.git/commitdiff
add chghost, setname, account-notify
authorEgor <egor@patchysicp.xyz>
Fri, 27 Oct 2023 20:59:10 +0000 (23:59 +0300)
committerEgor <egor@patchysicp.xyz>
Fri, 27 Oct 2023 20:59:10 +0000 (23:59 +0300)
src/admin.c
src/common.h
src/irc.c
src/irc.h
src/ircfmt.c
src/ircfmt.h

index 431d699..b249422 100644 (file)
@@ -253,6 +253,15 @@ static int fn_channel_part(lua_State *L)
        channel_part(cl, chan, reason, kicker);
        return 0;
 }
+static int fn_client_chghost(lua_State *L)
+{
+       struct client_data *cl = *(struct client_data **)luaL_checkudata(L, 1, "client");
+       const char *newusername = luaL_checkstring(L, 2);
+       const char *newhostname = luaL_checkstring(L, 3);
+       client_chghost(cl, newusername, newhostname);
+       return 0;
+}
+
 void admin_init(void)
 {
        lua_State *L = luaL_newstate();
@@ -309,6 +318,8 @@ void admin_init(void)
        lua_setglobal(L, "channel_join");
        lua_pushcfunction(L, fn_channel_part);
        lua_setglobal(L, "channel_part");
+       lua_pushcfunction(L, fn_client_chghost);
+       lua_setglobal(L, "client_chghost");
 }
 void admin_fini(void)
 {
index 3f1dafe..1c59cba 100644 (file)
@@ -29,6 +29,9 @@ struct tls;
 #define CAP_AWAYNOTIFY 8
 #define CAP_INVITENOTIFY 16
 #define CAP_EXTENDEDMONITOR 32
+#define CAP_CHGHOST 64
+#define CAP_SETNAME 128
+#define CAP_ACCOUNTNOTIFY 256
 struct client_data {
        SOCKET FD;
        struct tls *cctx;
index 508457f..83ee3fc 100644 (file)
--- a/src/irc.c
+++ b/src/irc.c
@@ -201,6 +201,9 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        { "away-notify", CAP_AWAYNOTIFY },
                        { "invite-notify", CAP_INVITENOTIFY },
                        { "extended-monitor", CAP_EXTENDEDMONITOR },
+                       { "chghost", CAP_CHGHOST },
+                       { "setname", CAP_SETNAME },
+                       { "account-notify", CAP_ACCOUNTNOTIFY },
                        { 0, 0 }
                };
 
@@ -1137,6 +1140,16 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                default:
                        return err_needmoreparams(client, command), sendbuf(client), 0; /* FIXME: wrong error */
                }
+       } else if(strcmp(command, "SETNAME") == 0) {
+               if (!is_registered(client))
+                       return err_notregistered(client), sendbuf(client), 0;
+               if (argc == 0)
+                       return err_needmoreparams(client, command), sendbuf(client), 0;
+               free(client->realname);
+               client->realname = mystrdup(args[0]);
+               msg_setname(client);
+               int cookie = sendbuf_visible_caps(client, CAP_SETNAME, 0);
+               sendbuf_monitor(client->key, cookie, CAP_SETNAME|CAP_EXTENDEDMONITOR, 0);
 #ifdef HAS_LUA
        } else if(strcmp(command, "LUA") == 0) {
                if (argc < 1)
@@ -1301,9 +1314,43 @@ void setNick(struct client_data *client, char* nickname) {
        if (map_set(&client_map, client->key, client, 0) == -1)
                abort();
        rpl_mononline(0, client), sendbuf_monitor(client->key, 0, 0, 0);
-
        return;
 }
+void client_chghost(struct client_data *client, const char *newusername, const char *newhostname)
+{
+       if (!strcmp(client->username, newusername) && !strcmp(client->hostname, newhostname))
+               return;
+       msg_quit(client, "Changing hostname", "");
+       sendbuf_visible_caps(client, 0, CAP_CHGHOST);
+       msg_chghost(client, newusername, newhostname);
+       int cookie = sendbuf_visible_caps(client, CAP_CHGHOST, 0);
+       sendbuf_monitor(client->key, cookie, CAP_CHGHOST|CAP_EXTENDEDMONITOR, 0);
+       int changedacc = client->username[0] != '~' || newusername[0] != '~';
+       free(client->username);
+       client->username = mystrdup(newusername);
+       free(client->hostname);
+       client->hostname = mystrdup(newhostname);
+       struct channel *chan;
+       map_foreach(&client->channels, 0, &chan) {
+               msg_join(client, chan);
+               sendbuf_list_sans_self_caps(client, &chan->members, 0, 0, CAP_EXTENDEDJOIN|CAP_CHGHOST);
+               msg_join(client, chan);
+               sendbuf_list_sans_self_caps(client, &chan->members, 0, CAP_EXTENDEDJOIN, CAP_CHGHOST);
+               if (map_get(&chan->v, client->key)) {
+                       copy_strf(&databuf, ":cia!cia@cia.gov MODE %s +v %s\r\n", chan->name, client->nick);
+                       sendbuf_list_sans_self_caps(client, &chan->members, 0, 0, CAP_CHGHOST);
+               }
+               if (map_get(&chan->o, client->key)) {
+                       copy_strf(&databuf, ":cia!cia@cia.gov MODE %s +o %s\r\n", chan->name, client->nick);
+                       sendbuf_list_sans_self_caps(client, &chan->members, 0, 0, CAP_CHGHOST);
+               }
+       }
+       if (changedacc) {
+               msg_account(client);
+               int cookie = sendbuf_visible_caps(client, CAP_ACCOUNTNOTIFY, 0);
+               sendbuf_monitor(client->key, cookie, CAP_ACCOUNTNOTIFY|CAP_EXTENDEDMONITOR, 0);
+       }
+}
 void channel_sendtopic(struct client_data *client, struct channel *chan, int joining)
 {
        if (chan->topic) {
index 93b2cf8..0a1f9e4 100644 (file)
--- a/src/irc.h
+++ b/src/irc.h
@@ -13,6 +13,7 @@ void newUser(struct client_data *client);
 void sendLUSERS(struct client_data *client);
 void sendMOTD(struct client_data *client);
 void setNick(struct client_data *client, char* nickname);
+void client_chghost(struct client_data *client, const char *newusername, const char *newhostname);
 struct client_data *findClient(const char *nickname);
 struct channel *findChannel(const char *channel);
 void channel_sendtopic(struct client_data *client, struct channel *chan, int joining);
index 79de2e5..5a1457d 100644 (file)
@@ -115,6 +115,21 @@ void msg_wallops(struct client_data *src, const char *msg)
        copy_strf(&databuf, ":%s!%s@%s WALLOPS :%s\r\n",
                        src->nick, src->username, src->hostname, msg);
 }
+void msg_chghost(struct client_data *src, const char *newusername, const char *newhostname)
+{
+       copy_strf(&databuf, ":%s!%s@%s CHGHOST %s %s\r\n",
+                       src->nick, src->username, src->hostname, newusername, newhostname);
+}
+void msg_setname(struct client_data *src)
+{
+       copy_strf(&databuf, ":%s!%s@%s SETNAME :%s\r\n",
+                       src->nick, src->username, src->hostname, src->realname);
+}
+void msg_account(struct client_data *src)
+{
+       copy_strf(&databuf, ":%s!%s@%s ACCOUNT %s\r\n",
+                       src->nick, src->username, src->hostname, src->username[0] != '~' ? src->username : "*");
+}
 void rpl_welcome(struct client_data *client) // 001
 {
        copy_strf(&databuf, ":%s 001 %s :Welcome to the Patchy Network, %s\r\n", hostname, client->nick, client->nick);
index b39a76b..2b0f285 100644 (file)
@@ -18,6 +18,9 @@ void msg_notice(struct client_data *src, const char *dst, const char *msg);
 void msg_notice_server(const char *src, const char *dst, const char *msg);
 void msg_kill(struct client_data *src, struct client_data *dst, const char *reason);
 void msg_wallops(struct client_data *src, const char *msg);
+void msg_chghost(struct client_data *src, const char *newusername, const char *newhostname);
+void msg_setname(struct client_data *src);
+void msg_account(struct client_data *src);
 void rpl_welcome(struct client_data *client); // 001
 void rpl_yourhost(struct client_data *client); // 002
 void rpl_created(struct client_data *client); // 003