mirror of
https://github.com/weechat/weechat.git
synced 2026-06-26 04:46:37 +02:00
irc: generate alternate nicks dynamically when all nicks are already in use (task #12209)
This commit is contained in:
@@ -4082,7 +4082,7 @@ IRC_PROTOCOL_CALLBACK(368)
|
||||
|
||||
IRC_PROTOCOL_CALLBACK(432)
|
||||
{
|
||||
int nick_index;
|
||||
const char *alternate_nick;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
/*
|
||||
@@ -4099,13 +4099,8 @@ IRC_PROTOCOL_CALLBACK(432)
|
||||
ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL,
|
||||
command, NULL, NULL);
|
||||
|
||||
nick_index = irc_server_get_nick_index (server);
|
||||
if (nick_index < 0)
|
||||
nick_index = 0;
|
||||
else
|
||||
nick_index = (nick_index + 1) % server->nicks_count;
|
||||
|
||||
if (nick_index == server->nick_first_tried)
|
||||
alternate_nick = irc_server_get_alternate_nick (server);
|
||||
if (!alternate_nick)
|
||||
{
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s%s: all declared nicknames are "
|
||||
@@ -4119,12 +4114,11 @@ IRC_PROTOCOL_CALLBACK(432)
|
||||
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s%s: nickname \"%s\" is invalid, "
|
||||
"trying nickname #%d (\"%s\")"),
|
||||
"trying nickname \"%s\""),
|
||||
weechat_prefix ("error"),
|
||||
IRC_PLUGIN_NAME, server->nick, nick_index + 1,
|
||||
server->nicks_array[nick_index]);
|
||||
IRC_PLUGIN_NAME, server->nick, alternate_nick);
|
||||
|
||||
irc_server_set_nick (server, server->nicks_array[nick_index]);
|
||||
irc_server_set_nick (server, alternate_nick);
|
||||
|
||||
irc_server_sendf (server, 0, NULL, "NICK %s", server->nick);
|
||||
}
|
||||
@@ -4138,7 +4132,7 @@ IRC_PROTOCOL_CALLBACK(432)
|
||||
|
||||
IRC_PROTOCOL_CALLBACK(433)
|
||||
{
|
||||
int nick_index;
|
||||
const char *alternate_nick;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
/*
|
||||
@@ -4151,13 +4145,8 @@ IRC_PROTOCOL_CALLBACK(433)
|
||||
ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL,
|
||||
command, NULL, NULL);
|
||||
|
||||
nick_index = irc_server_get_nick_index (server);
|
||||
if (nick_index < 0)
|
||||
nick_index = 0;
|
||||
else
|
||||
nick_index = (nick_index + 1) % server->nicks_count;
|
||||
|
||||
if (nick_index == server->nick_first_tried)
|
||||
alternate_nick = irc_server_get_alternate_nick (server);
|
||||
if (!alternate_nick)
|
||||
{
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s%s: all declared nicknames are "
|
||||
@@ -4171,11 +4160,10 @@ IRC_PROTOCOL_CALLBACK(433)
|
||||
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s: nickname \"%s\" is already in use, "
|
||||
"trying nickname #%d (\"%s\")"),
|
||||
IRC_PLUGIN_NAME, server->nick, nick_index + 1,
|
||||
server->nicks_array[nick_index]);
|
||||
"trying nickname \"%s\""),
|
||||
IRC_PLUGIN_NAME, server->nick, alternate_nick);
|
||||
|
||||
irc_server_set_nick (server, server->nicks_array[nick_index]);
|
||||
irc_server_set_nick (server, alternate_nick);
|
||||
|
||||
irc_server_sendf (server, 0, NULL, "NICK %s", server->nick);
|
||||
}
|
||||
@@ -4196,7 +4184,7 @@ IRC_PROTOCOL_CALLBACK(433)
|
||||
|
||||
IRC_PROTOCOL_CALLBACK(437)
|
||||
{
|
||||
int nick_index;
|
||||
const char *alternate_nick;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
/*
|
||||
@@ -4216,13 +4204,8 @@ IRC_PROTOCOL_CALLBACK(437)
|
||||
ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL,
|
||||
command, NULL, NULL);
|
||||
|
||||
nick_index = irc_server_get_nick_index (server);
|
||||
if (nick_index < 0)
|
||||
nick_index = 0;
|
||||
else
|
||||
nick_index = (nick_index + 1) % server->nicks_count;
|
||||
|
||||
if (nick_index == server->nick_first_tried)
|
||||
alternate_nick = irc_server_get_alternate_nick (server);
|
||||
if (!alternate_nick)
|
||||
{
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s%s: all declared nicknames are "
|
||||
@@ -4236,12 +4219,11 @@ IRC_PROTOCOL_CALLBACK(437)
|
||||
|
||||
weechat_printf (ptr_buffer,
|
||||
_("%s%s: nickname \"%s\" is unavailable, "
|
||||
"trying nickname #%d (\"%s\")"),
|
||||
"trying nickname \"%s\""),
|
||||
weechat_prefix ("error"),
|
||||
IRC_PLUGIN_NAME, server->nick, nick_index + 1,
|
||||
server->nicks_array[nick_index]);
|
||||
IRC_PLUGIN_NAME, server->nick, alternate_nick);
|
||||
|
||||
irc_server_set_nick (server, server->nicks_array[nick_index]);
|
||||
irc_server_set_nick (server, alternate_nick);
|
||||
|
||||
irc_server_sendf (server, 0, NULL, "NICK %s", server->nick);
|
||||
}
|
||||
|
||||
@@ -485,6 +485,100 @@ irc_server_get_nick_index (struct t_irc_server *server)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* irc_server_get_alternate_nick: get an alternate nick when the nick is
|
||||
* already used on server
|
||||
* We first try all declared nicks, then we
|
||||
* build nicks by adding "_", until length of 9.
|
||||
* If all nicks are still used, build 99
|
||||
* alternate nicks by using number at the end.
|
||||
* Example: nicks = "abcde,fghi,jkl"
|
||||
* Nicks tried: abcde
|
||||
* fghi
|
||||
* jkl
|
||||
* abcde_
|
||||
* abcde__
|
||||
* abcde___
|
||||
* abcde____
|
||||
* abcde___1
|
||||
* abcde___2
|
||||
* ...
|
||||
* abcde__99
|
||||
* Return NULL if no more alternate nick is
|
||||
* available
|
||||
*/
|
||||
|
||||
const char *
|
||||
irc_server_get_alternate_nick (struct t_irc_server *server)
|
||||
{
|
||||
static char nick[64];
|
||||
char str_number[64];
|
||||
int nick_index, length_nick, length_number;
|
||||
|
||||
nick[0] = '\0';
|
||||
|
||||
/* we are still trying nicks from option "nicks" */
|
||||
if (server->nick_alternate_number < 0)
|
||||
{
|
||||
nick_index = irc_server_get_nick_index (server);
|
||||
if (nick_index < 0)
|
||||
nick_index = 0;
|
||||
else
|
||||
{
|
||||
nick_index = (nick_index + 1) % server->nicks_count;
|
||||
/* stop loop if first nick tried was not in the list of nicks */
|
||||
if ((nick_index == 0) && (server->nick_first_tried < 0))
|
||||
server->nick_first_tried = 0;
|
||||
}
|
||||
|
||||
if (nick_index != server->nick_first_tried)
|
||||
{
|
||||
snprintf (nick, sizeof (nick),
|
||||
"%s", server->nicks_array[nick_index]);
|
||||
return nick;
|
||||
}
|
||||
|
||||
/*
|
||||
* we have tried all nicks in list, then use main nick
|
||||
* and we will add "_" and then number if needed
|
||||
*/
|
||||
server->nick_alternate_number = 0;
|
||||
snprintf (nick, sizeof (nick), "%s", server->nicks_array[0]);
|
||||
}
|
||||
else
|
||||
snprintf (nick, sizeof (nick), "%s", server->nick);
|
||||
|
||||
/* if length is < 9, just add a "_" */
|
||||
if (strlen (nick) < 9)
|
||||
{
|
||||
strcat (nick, "_");
|
||||
return nick;
|
||||
}
|
||||
|
||||
server->nick_alternate_number++;
|
||||
|
||||
/* number is max 99 */
|
||||
if (server->nick_alternate_number > 99)
|
||||
return NULL;
|
||||
|
||||
/* be sure the nick has 9 chars max */
|
||||
nick[9] = '\0';
|
||||
|
||||
/* generate number */
|
||||
snprintf (str_number, sizeof (str_number),
|
||||
"%d", server->nick_alternate_number);
|
||||
|
||||
/* copy number in nick */
|
||||
length_nick = strlen (nick);
|
||||
length_number = strlen (str_number);
|
||||
if (length_number > length_nick)
|
||||
return NULL;
|
||||
memcpy (nick + length_nick - length_number, str_number, length_number);
|
||||
|
||||
/* return alternate nick */
|
||||
return nick;
|
||||
}
|
||||
|
||||
/*
|
||||
* irc_server_get_isupport_value: return value of an item in "isupport" (copy
|
||||
* of IRC message 005)
|
||||
@@ -782,6 +876,7 @@ irc_server_alloc (const char *name)
|
||||
new_server->nicks_count = 0;
|
||||
new_server->nicks_array = NULL;
|
||||
new_server->nick_first_tried = 0;
|
||||
new_server->nick_alternate_number = -1;
|
||||
new_server->nick = NULL;
|
||||
new_server->nick_modes = NULL;
|
||||
new_server->isupport = NULL;
|
||||
@@ -2811,6 +2906,8 @@ irc_server_login (struct t_irc_server *server)
|
||||
else
|
||||
server->nick_first_tried = irc_server_get_nick_index (server);
|
||||
|
||||
server->nick_alternate_number = -1;
|
||||
|
||||
if (irc_server_sasl_enabled (server) || (capabilities && capabilities[0]))
|
||||
{
|
||||
irc_server_sendf (server, 0, NULL, "CAP LS");
|
||||
@@ -4290,6 +4387,7 @@ irc_server_hdata_server_cb (void *data, const char *hdata_name)
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nicks_count, INTEGER, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nicks_array, STRING, "nicks_count", NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nick_first_tried, INTEGER, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nick_alternate_number, INTEGER, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nick, STRING, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, nick_modes, STRING, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, isupport, STRING, NULL, NULL);
|
||||
@@ -4800,6 +4898,7 @@ irc_server_print_log ()
|
||||
weechat_log_printf (" nicks_count. . . . . : %d", ptr_server->nicks_count);
|
||||
weechat_log_printf (" nicks_array. . . . . : 0x%lx", ptr_server->nicks_array);
|
||||
weechat_log_printf (" nick_first_tried . . : %d", ptr_server->nick_first_tried);
|
||||
weechat_log_printf (" nick_alternate_number: %d", ptr_server->nick_alternate_number);
|
||||
weechat_log_printf (" nick . . . . . . . . : '%s'", ptr_server->nick);
|
||||
weechat_log_printf (" nick_modes . . . . . : '%s'", ptr_server->nick_modes);
|
||||
weechat_log_printf (" isupport . . . . . . : '%s'", ptr_server->isupport);
|
||||
|
||||
@@ -161,6 +161,8 @@ struct t_irc_server
|
||||
char **nicks_array; /* nicknames (after split) */
|
||||
int nick_first_tried; /* first nick tried in list of nicks */
|
||||
/* when (re-)connecting to server */
|
||||
int nick_alternate_number; /* number used to build alternate nicks */
|
||||
/* (nick____1, nick____2, ...) */
|
||||
char *nick; /* current nickname */
|
||||
char *nick_modes; /* nick modes */
|
||||
char *isupport; /* copy of message 005 (ISUPPORT) */
|
||||
@@ -237,7 +239,7 @@ extern void irc_server_set_addresses (struct t_irc_server *server,
|
||||
const char *addresses);
|
||||
extern void irc_server_set_nicks (struct t_irc_server *server, const char *nicks);
|
||||
extern void irc_server_set_nick (struct t_irc_server *server, const char *nick);
|
||||
extern int irc_server_get_nick_index (struct t_irc_server *server);
|
||||
extern const char *irc_server_get_alternate_nick (struct t_irc_server *server);
|
||||
extern const char *irc_server_get_isupport_value (struct t_irc_server *server,
|
||||
const char *feature);
|
||||
extern void irc_server_set_prefix_modes_chars (struct t_irc_server *server,
|
||||
|
||||
Reference in New Issue
Block a user