commit fc9a7b8e501ffacf92de6bd4397f45242f2bdbd7
parent 1f6d02a39ebad76585e9ddb1e1383275c548c6d3
Author: hhvn <dev@hhvn.uk>
Date: Mon, 20 Dec 2021 17:01:05 +0000
s/commands.c s/handle.c s/ui.c s/config.c s/struct.h: /nick
Diffstat:
5 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/src/commands.c b/src/commands.c
@@ -38,6 +38,7 @@ static void command_join(struct Server *server, char *str);
static void command_part(struct Server *server, char *str);
static void command_kick(struct Server *server, char *str);
static void command_mode(struct Server *server, char *str);
+static void command_nick(struct Server *server, char *str);
static void command_whois(struct Server *server, char *str);
static void command_whowas(struct Server *server, char *str);
static void command_ping(struct Server *server, char *str);
@@ -102,6 +103,9 @@ struct Command commands[] = {
{"mode", command_mode, 1, {
"usage: /mode <channel> modes...",
"Set/unset channel modes", NULL}},
+ {"nick", command_nick, 1, {
+ "usage: /nick <nick>",
+ "Get a new nick", NULL}},
{"whois", command_whois, 1, {
"usage: /whois [server] [nick]",
"Request information on a nick or oneself", NULL}},
@@ -421,6 +425,17 @@ command_mode(struct Server *server, char *str) {
}
static void
+command_nick(struct Server *server, char *str) {
+ if (!str || strchr(str, ' ')) {
+ ui_error("/nick takes 1 argument", NULL);
+ return;
+ }
+
+ ircprintf(server, "NICK %s\r\n", str);
+ handle_expect(server, Expect_nicknameinuse, str);
+}
+
+static void
command_whois(struct Server *server, char *str) {
char *tserver, *nick;
diff --git a/src/config.c b/src/config.c
@@ -400,6 +400,11 @@ struct Config config[] = {
.strhandle = config_redraws,
.description = {
"Format of notices", NULL}},
+ {"format.nick", 1, Val_string,
+ .str = "%{nick:${nick}}${nick}%{o}%{=}is now known as %{nick:${1}}${1}",
+ .strhandle = config_redraws,
+ .description = {
+ "Format of NICK messages", NULL}},
{"format.join", 1, Val_string,
.str = "%{b}%{c:44}+%{o}%{=}%{nick:${nick}}${nick}%{o} (${ident}@${host})",
.strhandle = config_redraws,
@@ -948,12 +953,12 @@ struct Config config[] = {
.description = {
"Format of ERR_NONICKNAMEGIVEN (431) numeric", NULL}},
{"format.err.erroneusnickname", 1, Val_string,
- .str = "${2-}",
+ .str = "Erroneous nickname: ${2}",
.strhandle = config_redraws,
.description = {
"Format of ERR_ERRONEUSNICKNAME (432) numeric", NULL}},
{"format.err.nicknameinuse", 1, Val_string,
- .str = "${2-}",
+ .str = "Nickname already in use: ${2}",
.strhandle = config_redraws,
.description = {
"Format of ERR_NICKNAMEINUSE (433) numeric", NULL}},
diff --git a/src/handle.c b/src/handle.c
@@ -425,11 +425,16 @@ handle_ERR_NICKNAMEINUSE(char *msg, char **params, struct Server *server, time_t
char nick[64]; /* should be limited to 9 chars, but newer servers *shrug*/
hist_add(server->history, NULL, msg, params, Activity_status, timestamp, HIST_DFL);
- snprintf(nick, sizeof(nick), "%s_", server->self->nick);
- nick_free(server->self);
- server->self = nick_create(nick, ' ', server);
- server->self->self = 1;
- ircprintf(server, "NICK %s\r\n", nick);
+
+ if (handle_expect_get(server, Expect_nicknameinuse) == NULL) {
+ snprintf(nick, sizeof(nick), "%s_", server->self->nick);
+ nick_free(server->self);
+ server->self = nick_create(nick, ' ', server);
+ server->self->self = 1;
+ ircprintf(server, "NICK %s\r\n", nick);
+ } else {
+ handle_expect(server, Expect_nicknameinuse, NULL);
+ }
}
static void
@@ -438,6 +443,7 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) {
struct Channel *chan;
char prefix[128];
char *newnick;
+ char priv;
if (**params != ':' || !*(params+1) || !*(params+2))
return;
@@ -453,14 +459,17 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) {
nick_free(server->self);
server->self = nick_create(newnick, ' ', server);
server->self->self = 1;
+ handle_expect(server, Expect_nicknameinuse, NULL);
}
for (chan = server->channels; chan; chan = chan->next) {
if ((chnick = nick_get(&chan->nicks, nick->nick)) != NULL) {
snprintf(prefix, sizeof(prefix), ":%s!%s@%s",
newnick, chnick->ident, chnick->host);
+ priv = chnick->priv;
nick_remove(&chan->nicks, nick->nick);
- nick_add(&chan->nicks, prefix, chnick->priv, server);
+ nick_add(&chan->nicks, prefix, priv, server);
+ hist_add(chan->history, nick, msg, params, Activity_status, timestamp, HIST_SHOW);
if (selected.channel == chan)
windows[Win_nicklist].refresh = 1;
}
diff --git a/src/struct.h b/src/struct.h
@@ -115,6 +115,7 @@ enum Expect {
Expect_topic,
Expect_topicwhotime,
Expect_channelmodeis,
+ Expect_nicknameinuse,
Expect_last,
};
diff --git a/src/ui.c b/src/ui.c
@@ -96,6 +96,7 @@ struct {
{"PART", "format.part"},
{"KICK", "format.kick"},
{"QUIT", "format.quit"},
+ {"NICK", "format.nick"},
/* START: misc/rpl-ui-gen.awk */
{"200", "format.rpl.tracelink"},
{"201", "format.rpl.traceconnecting"},