summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS4
-rw-r--r--src/plugins/irc/irc-bar-item.c11
-rw-r--r--src/plugins/irc/irc-channel.c31
-rw-r--r--src/plugins/irc/irc-command.c2
-rw-r--r--src/plugins/irc/irc-info.c2
-rw-r--r--src/plugins/irc/irc-mode.c230
-rw-r--r--src/plugins/irc/irc-mode.h6
-rw-r--r--src/plugins/irc/irc-nick.c456
-rw-r--r--src/plugins/irc/irc-nick.h67
-rw-r--r--src/plugins/irc/irc-protocol.c100
-rw-r--r--src/plugins/irc/irc-server.c206
-rw-r--r--src/plugins/irc/irc-server.h15
-rw-r--r--src/plugins/irc/irc-upgrade.c109
14 files changed, 648 insertions, 595 deletions
diff --git a/ChangeLog b/ChangeLog
index 618276efb..fe9bf5bb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
-v0.3.4-dev, 2010-10-26
+v0.3.4-dev, 2010-10-28
Version 0.3.4 (under dev!)
@@ -26,6 +26,8 @@ Version 0.3.4 (under dev!)
* api: add priority for hooks (task #10550)
* api: add new functions: hashtable_get_string, hook_info_hashtable,
info_get_hashtable, hook_hsignal, hook_hsignal_send
+* irc: improve nick prefixes, all modes (even unknown) are used with PREFIX
+ value from message 005
* irc: add command redirection (task #6703)
* irc: add new options irc.color.nick_prefix and irc.color.nick_suffix
* irc: add new option irc.look.item_away_message
diff --git a/NEWS b/NEWS
index fbefe88f1..360247be9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,7 @@
WeeChat News
============
Sébastien Helleu <flashcode@flashtux.org>
-v0.3.4-dev, 2010-10-12
+v0.3.4-dev, 2010-10-28
Version 0.3.4 (under dev!)
@@ -9,6 +9,8 @@ Version 0.3.4 (under dev!)
Important release notes:
+* if you are using `/upgrade` from a previous release, some nick prefixes can
+ be wrong, so it is recommended to do `/allchan names`.
* some IRC options have been renamed, before upgrading to this version, note
value for old options, and set them again with new name:
** options moved from 'network' section to servers (with global value, and server
diff --git a/src/plugins/irc/irc-bar-item.c b/src/plugins/irc/irc-bar-item.c
index 1deec1b6f..a2c4047e0 100644
--- a/src/plugins/irc/irc-bar-item.c
+++ b/src/plugins/irc/irc-bar-item.c
@@ -422,7 +422,7 @@ irc_bar_item_input_prompt (void *data, struct t_gui_bar_item *item,
struct t_irc_server *server;
struct t_irc_channel *channel;
struct t_irc_nick *ptr_nick;
- char *buf, prefix[2], str_prefix[64];
+ char *buf, str_prefix[64];
int length, prefix_color;
/* make C compiler happy */
@@ -449,15 +449,12 @@ irc_bar_item_input_prompt (void *data, struct t_gui_bar_item *item,
ptr_nick = irc_nick_search (channel, server->nick);
if (ptr_nick)
{
- prefix[0] = '\0';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, ptr_nick,
- &prefix[0], &prefix_color, NULL, NULL);
- if (prefix[0] != ' ')
+ if (ptr_nick->prefix[0] != ' ')
{
+ prefix_color = irc_nick_get_prefix_color (server, ptr_nick);
snprintf (str_prefix, sizeof (str_prefix), "%s%s",
weechat_color (weechat_config_string (weechat_config_get (irc_nick_get_prefix_color_name (prefix_color)))),
- prefix);
+ ptr_nick->prefix);
}
}
}
diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c
index 6ffed14e0..ac9ad55db 100644
--- a/src/plugins/irc/irc-channel.c
+++ b/src/plugins/irc/irc-channel.c
@@ -150,8 +150,9 @@ irc_channel_new (struct t_irc_server *server, int channel_type,
{
struct t_irc_channel *new_channel;
struct t_gui_buffer *new_buffer;
- int buffer_created, current_buffer_number, buffer_position;
- char *buffer_name, str_number[32];;
+ int i, buffer_created, current_buffer_number, buffer_position;
+ char *buffer_name, str_number[32], str_group[32];
+ const char *prefix_modes;
/* alloc memory for new channel */
if ((new_channel = malloc (sizeof (*new_channel))) == NULL)
@@ -234,21 +235,15 @@ irc_channel_new (struct t_irc_server *server, int channel_type,
if (channel_type == IRC_CHANNEL_TYPE_CHANNEL)
{
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_CHANOWNER,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_CHANADMIN,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_CHANADMIN2,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_OP,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_HALFOP,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_VOICE,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_CHANUSER,
- "weechat.color.nicklist_group", 1);
- weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_NORMAL,
+ prefix_modes = irc_server_get_prefix_modes (server);
+ for (i = 0; prefix_modes[i]; i++)
+ {
+ snprintf (str_group, sizeof (str_group),
+ "%03d|%c", i, prefix_modes[i]);
+ weechat_nicklist_add_group (new_buffer, NULL, str_group,
+ "weechat.color.nicklist_group", 1);
+ }
+ weechat_nicklist_add_group (new_buffer, NULL, IRC_NICK_GROUP_OTHER,
"weechat.color.nicklist_group", 1);
}
@@ -367,7 +362,7 @@ irc_channel_remove_away (struct t_irc_server *server,
{
for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick)
{
- irc_nick_set (server, channel, ptr_nick, 0, IRC_NICK_AWAY);
+ irc_nick_set_away (server, channel, ptr_nick, 0);
}
}
}
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index 9ff26ef7c..e2fe5baa1 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -4212,7 +4212,7 @@ irc_command_wallchops (void *data, struct t_gui_buffer *buffer, int argc,
for (ptr_nick = ptr_channel->nicks; ptr_nick;
ptr_nick = ptr_nick->next_nick)
{
- if (IRC_NICK_IS_OP(ptr_nick)
+ if (irc_nick_is_op (ptr_server, ptr_nick)
&& (strcmp (ptr_nick->name, ptr_server->nick) != 0))
{
irc_server_sendf (ptr_server,
diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c
index 9efe59419..5d9562f34 100644
--- a/src/plugins/irc/irc-info.c
+++ b/src/plugins/irc/irc-info.c
@@ -434,7 +434,6 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name,
{
/* build list with only one nick */
if (!irc_nick_add_to_infolist (ptr_infolist,
- ptr_server,
pointer))
{
weechat_infolist_free (ptr_infolist);
@@ -449,7 +448,6 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name,
ptr_nick = ptr_nick->next_nick)
{
if (!irc_nick_add_to_infolist (ptr_infolist,
- ptr_server,
ptr_nick))
{
weechat_infolist_free (ptr_infolist);
diff --git a/src/plugins/irc/irc-mode.c b/src/plugins/irc/irc-mode.c
index 24664e9d0..ee02e2c3a 100644
--- a/src/plugins/irc/irc-mode.c
+++ b/src/plugins/irc/irc-mode.c
@@ -33,25 +33,6 @@
/*
- * irc_mode_channel_set_nick: set a mode for a nick on a channel
- */
-
-void
-irc_mode_channel_set_nick (struct t_irc_server *server,
- struct t_irc_channel *channel, const char *nick,
- char set_flag, int flag)
-{
- struct t_irc_nick *ptr_nick;
-
- if (nick)
- {
- ptr_nick = irc_nick_search (channel, nick);
- if (ptr_nick)
- irc_nick_set (server, channel, ptr_nick, (set_flag == '+'), flag);
- }
-}
-
-/*
* irc_mode_channel_set: set channel modes
* return: 1 if channel modes are updated
* 0 if channel modes are NOT updated
@@ -63,7 +44,8 @@ irc_mode_channel_set (struct t_irc_server *server,
struct t_irc_channel *channel, const char *modes)
{
char *pos_args, *str_modes, set_flag, **argv, *pos, *ptr_arg;
- int mode, modes_count, channel_modes_updated, argc, current_arg;
+ int modes_count, channel_modes_updated, argc, current_arg;
+ struct t_irc_nick *ptr_nick;
if (!server || !channel || !modes)
return 0;
@@ -121,33 +103,11 @@ irc_mode_channel_set (struct t_irc_server *server,
case '-':
set_flag = '-';
break;
- case 'a': /* channel admin (unrealircd specific flag) */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "a", '~');
- if (mode >= 0)
- {
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
- }
- current_arg++;
- break;
case 'b': /* ban (ignored) */
ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
argv[current_arg] : NULL;
current_arg++;
break;
- case 'h': /* half-op */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "h", '%');
- if (mode >= 0)
- {
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
- }
- current_arg++;
- break;
case 'k': /* channel key */
if (channel->key)
{
@@ -177,54 +137,25 @@ irc_mode_channel_set (struct t_irc_server *server,
channel_modes_updated = 1;
current_arg++;
break;
- case 'o': /* op */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "o", '@');
- if (mode >= 0)
- {
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
- }
- current_arg++;
- break;
- case 'q': /* channel owner (unrealircd specific flag) */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "q", '~');
- if (mode >= 0)
- {
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
- }
- current_arg++;
- break;
- case 'u': /* channel user */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "u", '-');
- if (mode >= 0)
- {
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
- }
- current_arg++;
- break;
- case 'v': /* voice */
- ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
- argv[current_arg] : NULL;
- mode = irc_mode_get_nick_attr (server, "v", '+');
- if (mode >= 0)
+ default:
+ if (irc_server_get_prefix_mode_index (server, pos[0]) >= 0)
{
- irc_mode_channel_set_nick (server, channel, ptr_arg,
- set_flag, mode);
+ ptr_arg = ((current_arg >= 0) && (current_arg < argc)) ?
+ argv[current_arg] : NULL;
+ if (ptr_arg)
+ {
+ ptr_nick = irc_nick_search (channel, ptr_arg);
+ if (ptr_nick)
+ {
+ irc_nick_set_mode (server, channel, ptr_nick,
+ (set_flag == '+'), pos[0]);
+ }
+ }
}
+ else
+ channel_modes_updated = 1;
current_arg++;
break;
- default:
- current_arg++;
- channel_modes_updated = 1;
- break;
}
pos++;
}
@@ -326,130 +257,3 @@ irc_mode_user_set (struct t_irc_server *server, const char *modes)
modes++;
}
}
-
-/*
- * irc_mode_prefix_to_nick_attr: get nick attribute for prefix
- * return -1 if prefix is unknown
- */
-
-int
-irc_mode_prefix_to_nick_attr (char prefix)
-{
- switch (prefix)
- {
- case '@': /* op */
- return IRC_NICK_OP;
- case '~': /* channel owner */
- return IRC_NICK_CHANOWNER;
- case '*': /* channel owner */
- return IRC_NICK_CHANOWNER;
- case '&': /* channel admin */
- return IRC_NICK_CHANADMIN;
- case '!': /* channel admin (2) */
- return IRC_NICK_CHANADMIN2;
- case '%': /* half-op */
- return IRC_NICK_HALFOP;
- case '+': /* voice */
- return IRC_NICK_VOICE;
- case '-': /* channel user */
- return IRC_NICK_CHANUSER;
- }
-
- return -1;
-}
-
-/*
- * irc_mode_get_nick_attr: return nick attribute for mode, if allowed by server
- * return -1 if not allowed
- * for example :
- * IRC: 005 (...) PREFIX=(ohv)@%+
- * => allowed modes: ohv
- */
-
-int
-irc_mode_get_nick_attr (struct t_irc_server *server, char *mode,
- char prefix)
-{
- char str[2], *pos, *ptr_prefixes, *pos_mode;
- int index;
-
- /* if server did not send any prefix info, then use default prefixes */
- if (!server->prefix)
- {
- str[0] = prefix;
- str[1] = '\0';
- pos = strpbrk (str, IRC_MODE_NICK_DEFAULT_PREFIXES_LIST);
- if (!pos)
- return -1;
- return irc_mode_prefix_to_nick_attr (pos[0]);
- }
-
- /* find start of prefixes, after "(...)" */
- ptr_prefixes = strchr (server->prefix, ')');
- if (ptr_prefixes)
- ptr_prefixes++;
-
- /* we check if mode is in list and return prefix found */
- if (mode && ptr_prefixes)
- {
- pos_mode = strchr (server->prefix + 1, mode[0]);
- if (pos_mode && (pos_mode < ptr_prefixes))
- {
- index = pos_mode - server->prefix - 1;
- if (pos_mode && (index < (int)strlen (ptr_prefixes)))
- {
- return irc_mode_prefix_to_nick_attr (ptr_prefixes[index]);
- }
- }
- }
-
- if (!ptr_prefixes)
- ptr_prefixes = server->prefix;
-
- pos = strchr (ptr_prefixes, prefix);
- if (!pos)
- return -1;
-
- return irc_mode_prefix_to_nick_attr (pos[0]);
-}
-
-/*
- * irc_mode_get_prefix: return prefix for mode
- * for example if prefixes are:
- * IRC: 005 (...) PREFIX=(ohv)@%+
- * 'o' will return '@'
- * 'h' will return '%'
- * 'v' will return '+'
- */
-
-char
-irc_mode_get_prefix (struct t_irc_server *server, char mode,
- char default_prefix)
-{
- char *ptr_prefixes, *pos_mode;
- int index;
-
- if (!server->prefix)
- return default_prefix;
-
- /* find start of prefixes, after "(...)" */
- ptr_prefixes = strchr (server->prefix, ')');
- if (ptr_prefixes)
- ptr_prefixes++;
-
- if (!ptr_prefixes || !ptr_prefixes[0])
- return default_prefix;
-
- /* search prefix for mode */
- pos_mode = strchr (server->prefix + 1, mode);
- if (pos_mode && (pos_mode < ptr_prefixes))
- {
- index = pos_mode - server->prefix - 1;
- if (pos_mode && (index < (int)strlen (ptr_prefixes)))
- {
- return ptr_prefixes[index];
- }
- }
-
- return default_prefix;
-}
diff --git a/src/plugins/irc/irc-mode.h b/src/plugins/irc/irc-mode.h
index 358ba5b77..1bd7b3aef 100644
--- a/src/plugins/irc/irc-mode.h
+++ b/src/plugins/irc/irc-mode.h
@@ -20,8 +20,6 @@
#ifndef __WEECHAT_IRC_MODE_H
#define __WEECHAT_IRC_MODE_H 1
-#define IRC_MODE_NICK_DEFAULT_PREFIXES_LIST "@%+~*&!-"
-
struct t_irc_server;
struct t_irc_channel;
@@ -29,9 +27,5 @@ extern int irc_mode_channel_set (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *modes);
extern void irc_mode_user_set (struct t_irc_server *server, const char *modes);
-extern int irc_mode_get_nick_attr (struct t_irc_server *server, char *mode,
- char prefix);
-extern char irc_mode_get_prefix (struct t_irc_server *server, char mode,
- char default_prefix);
#endif /* __WEECHAT_IRC_MODE_H */
diff --git a/src/plugins/irc/irc-nick.c b/src/plugins/irc/irc-nick.c
index b88b986ef..ae6ee1faf 100644
--- a/src/plugins/irc/irc-nick.c
+++ b/src/plugins/irc/irc-nick.c
@@ -197,97 +197,213 @@ irc_nick_find_color_name (const char *nickname)
}
/*
- * irc_nick_get_gui_infos: get GUI infos for a nick (sort_index, prefix,
- * prefix color)
+ * irc_nick_set_current_prefix: set current prefix, using higher prefix set in
+ * prefixes
*/
void
-irc_nick_get_gui_infos (struct t_irc_server *server,
- struct t_irc_nick *nick,
- char *prefix, int *prefix_color,
- struct t_gui_buffer *buffer,
- struct t_gui_nick_group **group)
+irc_nick_set_current_prefix (struct t_irc_nick *nick)
{
- if (nick->flags & IRC_NICK_CHANOWNER)
- {
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'q', '~');
- if (prefix_color)
- *prefix_color = 1;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_CHANOWNER);
- }
- else if (nick->flags & IRC_NICK_CHANADMIN)
- {
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'a', '&');
- if (prefix_color)
- *prefix_color = 1;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_CHANADMIN);
- }
- else if (nick->flags & IRC_NICK_CHANADMIN2)
+ char *ptr_prefixes;
+
+ nick->prefix[0] = ' ';
+ for (ptr_prefixes = nick->prefixes; ptr_prefixes[0]; ptr_prefixes++)
{
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'a', '!');
- if (prefix_color)
- *prefix_color = 1;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_CHANADMIN2);
+ if (ptr_prefixes[0] != ' ')
+ {
+ nick->prefix[0] = ptr_prefixes[0];
+ break;
+ }
}
- else if (nick->flags & IRC_NICK_OP)
+}
+
+/*
+ * irc_nick_set_prefix: set or unset a prefix in prefixes
+ * if set == 1, prefix is set (prefix is used)
+ * 0, prefix is unset (space is used)
+ */
+
+void
+irc_nick_set_prefix (struct t_irc_server *server, struct t_irc_nick *nick,
+ int set, char prefix)
+{
+ int index;
+
+ index = irc_server_get_prefix_char_index (server, prefix);
+ if (index >= 0)
{
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'o', '@');
- if (prefix_color)
- *prefix_color = 1;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_OP);
+ nick->prefixes[index] = (set) ? prefix : ' ';
+ irc_nick_set_current_prefix (nick);
}
- else if (nick->flags & IRC_NICK_HALFOP)
+}
+
+/*
+ * irc_nick_set_prefixes: set prefixes for nick
+ */
+
+void
+irc_nick_set_prefixes (struct t_irc_server *server, struct t_irc_nick *nick,
+ const char *prefixes)
+{
+ const char *ptr_prefixes;
+
+ /* reset all prefixes in nick */
+ memset (nick->prefixes, ' ', strlen (nick->prefixes));
+
+ /* add prefixes in nick */
+ if (prefixes)
{
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'h', '%');
- if (prefix_color)
- *prefix_color = 2;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_HALFOP);
+ for (ptr_prefixes = prefixes; ptr_prefixes[0]; ptr_prefixes++)
+ {
+ irc_nick_set_prefix (server, nick, 1, ptr_prefixes[0]);
+ }
}
- else if (nick->flags & IRC_NICK_VOICE)
+
+ /* set current prefix */
+ irc_nick_set_current_prefix (nick);
+}
+
+/*
+ * irc_nick_is_op: return 1 is nick is "op" (or better than "op", for example
+ * channel admin or channel owner)
+ */
+
+int
+irc_nick_is_op (struct t_irc_server *server, struct t_irc_nick *nick)
+{
+ int index;
+
+ if (nick->prefix[0] == ' ')
+ return 0;
+
+ index = irc_server_get_prefix_char_index (server, nick->prefix[0]);
+ if (index < 0)
+ return 0;
+
+ return (index <= irc_server_get_prefix_mode_index (server, 'o')) ? 1 : 0;
+}
+
+/*
+ * irc_nick_has_prefix_mode: return 1 if nick prefixes contains prefix
+ * for a mode given
+ * for example if mode is 'o', we'll search for '@'
+ * in nick prefixes
+ */
+
+int
+irc_nick_has_prefix_mode (struct t_irc_server *server, struct t_irc_nick *nick,
+ char prefix_mode)
+{
+ char prefix_char;
+
+ prefix_char = irc_server_get_prefix_char_for_mode (server, prefix_mode);
+ if (prefix_char == ' ')
+ return 0;
+
+ return (strchr (nick->prefixes, prefix_char)) ? 1 : 0;
+}
+
+/*
+ * irc_nick_get_nicklist_group: get nicklist group for a nick
+ */
+
+struct t_gui_nick_group *
+irc_nick_get_nicklist_group (struct t_irc_server *server,
+ struct t_gui_buffer *buffer,
+ struct t_irc_nick *nick)
+{
+ int index;
+ char str_group[32];
+ const char *prefix_modes;
+ struct t_gui_nick_group *ptr_group;
+
+ if (!server || !buffer || !nick)
+ return NULL;
+
+ ptr_group = NULL;
+ index = irc_server_get_prefix_char_index (server, nick->prefix[0]);
+ if (index < 0)
{
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'v', '+');
- if (prefix_color)
- *prefix_color = 3;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_VOICE);
+ ptr_group = weechat_nicklist_search_group (buffer, NULL,
+ IRC_NICK_GROUP_OTHER);
}
- else if (nick->flags & IRC_NICK_CHANUSER)
+ else
{
- if (prefix)
- prefix[0] = irc_mode_get_prefix (server, 'u', '-');
- if (prefix_color)
- *prefix_color = 4;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_CHANUSER);
+ prefix_modes = irc_server_get_prefix_modes (server);
+ snprintf (str_group, sizeof (str_group),
+ "%03d|%c", index, prefix_modes[index]);
+ ptr_group = weechat_nicklist_search_group (buffer, NULL, str_group);
}
- else
+
+ return ptr_group;
+}
+
+/*
+ * irc_nick_get_prefix_color: get prefix color index for a nick
+ */
+
+int
+irc_nick_get_prefix_color (struct t_irc_server *server,
+ struct t_irc_nick *nick)
+{
+ int index, prefix_color;
+
+ prefix_color = 0;
+ index = irc_server_get_prefix_char_index (server, nick->prefix[0]);
+ if (index >= 0)
{
- if (prefix)
- prefix[0] = ' ';
- if (prefix_color)
- *prefix_color = 0;
- if (buffer && group)
- *group = weechat_nicklist_search_group (buffer, NULL,
- IRC_NICK_GROUP_NORMAL);
+ if (index <= irc_server_get_prefix_mode_index (server, 'o'))
+ prefix_color = 1; /* color for op (or better than op) */
+ else if (index == irc_server_get_prefix_mode_index (server, 'h'))
+ prefix_color = 2; /* color for halh-op */
+ else if (index == irc_server_get_prefix_mode_index (server, 'v'))
+ prefix_color = 3; /* color for voice */
+ else if (index == irc_server_get_prefix_mode_index (server, 'u'))
+ prefix_color = 4; /* color for chan user */
}
+
+ return prefix_color;
+}
+
+/*
+ * irc_nick_nicklist_add: add nick to buffer nicklist
+ */
+
+void
+irc_nick_nicklist_add (struct t_irc_server *server,
+ struct t_irc_channel *channel,
+ struct t_irc_nick *nick)
+{
+ int prefix_color;
+ struct t_gui_nick_group *ptr_group;
+
+ ptr_group = irc_nick_get_nicklist_group (server, channel->buffer, nick);
+ prefix_color = irc_nick_get_prefix_color (server, nick);
+ weechat_nicklist_add_nick (channel->buffer, ptr_group,
+ nick->name,
+ (nick->away) ?
+ "weechat.color.nicklist_away" : "bar_fg",
+ nick->prefix,
+ irc_nick_get_prefix_color_name (prefix_color),
+ 1);
+}
+
+/*
+ * irc_nick_nicklist_remove: remove nick from buffer nicklist
+ */
+
+void
+irc_nick_nicklist_remove (struct t_irc_server *server,
+ struct t_irc_channel *channel,
+ struct t_irc_nick *nick)
+{
+ struct t_gui_nick_group *ptr_group;
+
+ ptr_group = irc_nick_get_nicklist_group (server, channel->buffer, nick);
+ weechat_nicklist_remove_nick (channel->buffer,
+ weechat_nicklist_search_nick (channel->buffer,
+ ptr_group,
+ nick->name));
}
/*
@@ -318,49 +434,24 @@ irc_nick_get_prefix_color_name (int prefix_color)
struct t_irc_nick *
irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
- const char *nickname, int is_chanowner, int is_chanadmin,
- int is_chanadmin2, int is_op, int is_halfop, int has_voice,
- int is_chanuser, int is_away)
+ const char *nickname, const char *prefixes, int away)
{
struct t_irc_nick *new_nick, *ptr_nick;
- char prefix[2];
- int prefix_color;
- struct t_gui_nick_group *ptr_group;
+ int length;
/* nick already exists on this channel? */
ptr_nick = irc_nick_search (channel, nickname);
if (ptr_nick)
{
/* remove old nick from nicklist */
- irc_nick_get_gui_infos (server, ptr_nick, prefix,
- &prefix_color, channel->buffer, &ptr_group);
- weechat_nicklist_remove_nick (channel->buffer,
- weechat_nicklist_search_nick (channel->buffer,
- ptr_group,
- ptr_nick->name));
+ irc_nick_nicklist_remove (server, channel, ptr_nick);
/* update nick */
- IRC_NICK_SET_FLAG(ptr_nick, is_chanowner, IRC_NICK_CHANOWNER);
- IRC_NICK_SET_FLAG(ptr_nick, is_chanadmin, IRC_NICK_CHANADMIN);
- IRC_NICK_SET_FLAG(ptr_nick, is_chanadmin2, IRC_NICK_CHANADMIN2);
- IRC_NICK_SET_FLAG(ptr_nick, is_op, IRC_NICK_OP);
- IRC_NICK_SET_FLAG(ptr_nick, is_halfop, IRC_NICK_HALFOP);
- IRC_NICK_SET_FLAG(ptr_nick, has_voice, IRC_NICK_VOICE);
- IRC_NICK_SET_FLAG(ptr_nick, is_chanuser, IRC_NICK_CHANUSER);
- IRC_NICK_SET_FLAG(ptr_nick, is_away, IRC_NICK_AWAY);
+ irc_nick_set_prefixes (server, ptr_nick, prefixes);
+ ptr_nick->away = away;
/* add new nick in nicklist */
- prefix[0] = ' ';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, ptr_nick, prefix,
- &prefix_color, channel->buffer, &ptr_group);
- weechat_nicklist_add_nick (channel->buffer, ptr_group,
- ptr_nick->name,
- (is_away) ?
- "weechat.color.nicklist_away" : "bar_fg",
- prefix,
- irc_nick_get_prefix_color_name (prefix_color),
- 1);
+ irc_nick_nicklist_add (server, channel, ptr_nick);
return ptr_nick;
}
@@ -372,15 +463,17 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
/* initialize new nick */
new_nick->name = strdup (nickname);
new_nick->host = NULL;
- new_nick->flags = 0;
- IRC_NICK_SET_FLAG(new_nick, is_chanowner, IRC_NICK_CHANOWNER);
- IRC_NICK_SET_FLAG(new_nick, is_chanadmin, IRC_NICK_CHANADMIN);
- IRC_NICK_SET_FLAG(new_nick, is_chanadmin2, IRC_NICK_CHANADMIN2);
- IRC_NICK_SET_FLAG(new_nick, is_op, IRC_NICK_OP);
- IRC_NICK_SET_FLAG(new_nick, is_halfop, IRC_NICK_HALFOP);
- IRC_NICK_SET_FLAG(new_nick, has_voice, IRC_NICK_VOICE);
- IRC_NICK_SET_FLAG(new_nick, is_chanuser, IRC_NICK_CHANUSER);
- IRC_NICK_SET_FLAG(new_nick, is_away, IRC_NICK_AWAY);
+ length = strlen (irc_server_get_prefix_chars (server));
+ new_nick->prefixes = malloc (length + 1);
+ if (new_nick->prefixes)
+ {
+ memset (new_nick->prefixes, ' ', length);
+ new_nick->prefixes[length] = '\0';
+ }
+ new_nick->prefix[0] = ' ';
+ new_nick->prefix[1] = '\0';
+ irc_nick_set_prefixes (server, new_nick, prefixes);
+ new_nick->away = away;
if (weechat_strcasecmp (new_nick->name, server->nick) == 0)
new_nick->color = IRC_COLOR_CHAT_NICK_SELF;
else
@@ -400,17 +493,7 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
channel->nick_completion_reset = 1;
/* add nick to buffer nicklist */
- prefix[0] = ' ';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, new_nick, prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_add_nick (channel->buffer, ptr_group,
- new_nick->name,
- (is_away) ?
- "weechat.color.nicklist_away" : "bar_fg",
- prefix,
- irc_nick_get_prefix_color_name (prefix_color),
- 1);
+ irc_nick_nicklist_add (server, channel, new_nick);
/* all is ok, return address of new nick */
return new_nick;
@@ -424,17 +507,10 @@ void
irc_nick_change (struct t_irc_server *server, struct t_irc_channel *channel,
struct t_irc_nick *nick, const char *new_nick)
{
- int nick_is_me, prefix_color;
- struct t_gui_nick_group *ptr_group;
- char prefix[2];
+ int nick_is_me;
/* remove nick from nicklist */
- irc_nick_get_gui_infos (server, nick, prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_remove_nick (channel->buffer,
- weechat_nicklist_search_nick (channel->buffer,
- ptr_group,
- nick->name));
+ irc_nick_nicklist_remove (server, channel, nick);
/* update nicks speaking */
nick_is_me = (strcmp (nick->name, server->nick) == 0) ? 1 : 0;
@@ -451,54 +527,33 @@ irc_nick_change (struct t_irc_server *server, struct t_irc_channel *channel,
nick->color = irc_nick_find_color (nick->name);
/* add nick in nicklist */
- prefix[0] = ' ';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, nick, prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_add_nick (channel->buffer, ptr_group,
- nick->name,
- (nick->flags & IRC_NICK_AWAY) ?
- "weechat.color.nicklist_away" : "bar_fg",
- prefix,
- irc_nick_get_prefix_color_name (prefix_color),
- 1);
+ irc_nick_nicklist_add (server, channel, nick);
}
/*
- * irc_nick_set: set a flag for a nick
+ * irc_nick_set_mode: set a mode for a nick
*/
void
-irc_nick_set (struct t_irc_server *server, struct t_irc_channel *channel,
- struct t_irc_nick *nick, int set, int flag)
+irc_nick_set_mode (struct t_irc_server *server, struct t_irc_channel *channel,
+ struct t_irc_nick *nick, int set, char mode)
{
- char prefix[2];
- int prefix_color;
- struct t_gui_nick_group *ptr_group;
+ int index;
+ const char *prefix_chars;
+
+ index = irc_server_get_prefix_mode_index (server, mode);
+ if (index < 0)
+ return;
/* remove nick from nicklist */
- irc_nick_get_gui_infos (server, nick, prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_remove_nick (channel->buffer,
- weechat_nicklist_search_nick (channel->buffer,
- ptr_group,
- nick->name));
+ irc_nick_nicklist_remove (server, channel, nick);
/* set flag */
- IRC_NICK_SET_FLAG(nick, set, flag);
+ prefix_chars = irc_server_get_prefix_chars (server);
+ irc_nick_set_prefix (server, nick, set, prefix_chars[index]);
/* add nick in nicklist */
- prefix[0] = ' ';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, nick, prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_add_nick (channel->buffer, ptr_group,
- nick->name,
- (nick->flags & IRC_NICK_AWAY) ?
- "weechat.color.nicklist_away" : "bar_fg",
- prefix,
- irc_nick_get_prefix_color_name (prefix_color),
- 1);
+ irc_nick_nicklist_add (server, channel, nick);
if (strcmp (nick->name, server->nick) == 0)
weechat_bar_item_update ("input_prompt");
@@ -513,20 +568,12 @@ irc_nick_free (struct t_irc_server *server, struct t_irc_channel *channel,
struct t_irc_nick *nick)
{
struct t_irc_nick *new_nicks;
- char prefix;
- int prefix_color;
- struct t_gui_nick_group *ptr_group;
if (!channel || !nick)
return;
/* remove nick from nicklist */
- irc_nick_get_gui_infos (server, nick, &prefix, &prefix_color,
- channel->buffer, &ptr_group);
- weechat_nicklist_remove_nick (channel->buffer,
- weechat_nicklist_search_nick (channel->buffer,
- ptr_group,
- nick->name));
+ irc_nick_nicklist_remove (server, channel, nick);
/* remove nick */
if (channel->last_nick == nick)
@@ -549,6 +596,8 @@ irc_nick_free (struct t_irc_server *server, struct t_irc_channel *channel,
free (nick->name);
if (nick->host)
free (nick->host);
+ if (nick->prefixes)
+ free (nick->prefixes);
free (nick);
@@ -604,8 +653,9 @@ irc_nick_search (struct t_irc_channel *channel, const char *nickname)
*/
void
-irc_nick_count (struct t_irc_channel *channel, int *total, int *count_op,
- int *count_halfop, int *count_voice, int *count_normal)
+irc_nick_count (struct t_irc_server *server, struct t_irc_channel *channel,
+ int *total, int *count_op, int *count_halfop, int *count_voice,
+ int *count_normal)
{
struct t_irc_nick *ptr_nick;
@@ -618,15 +668,15 @@ irc_nick_count (struct t_irc_channel *channel, int *total, int *count_op,
ptr_nick = ptr_nick->next_nick)
{
(*total)++;
- if (IRC_NICK_IS_OP(ptr_nick))
+ if (irc_nick_is_op (server, ptr_nick))
(*count_op)++;
else
{
- if (ptr_nick->flags & IRC_NICK_HALFOP)
+ if (irc_nick_has_prefix_mode (server, ptr_nick, 'h'))
(*count_halfop)++;
else
{
- if (ptr_nick->flags & IRC_NICK_VOICE)
+ if (irc_nick_has_prefix_mode (server, ptr_nick, 'v'))
(*count_voice)++;
else
(*count_normal)++;
@@ -643,14 +693,16 @@ void
irc_nick_set_away (struct t_irc_server *server, struct t_irc_channel *channel,
struct t_irc_nick *nick, int is_away)
{
- if ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK) > 0)
- && ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS) == 0)
- || (channel->nicks_count <= IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS))))
+ if (!is_away
+ || ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK) > 0)
+ && ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS) == 0)
+ || (channel->nicks_count <= IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS)))))
{
- if (((is_away) && (!(nick->flags & IRC_NICK_AWAY))) ||
- ((!is_away) && (nick->flags & IRC_NICK_AWAY)))
+ if ((is_away && !nick->away) || (!is_away && nick->away))
{
- irc_nick_set (server, channel, nick, is_away, IRC_NICK_AWAY);
+ irc_nick_nicklist_remove (server, channel, nick);
+ nick->away = is_away;
+ irc_nick_nicklist_add (server, channel, nick);
}
}
}
@@ -669,14 +721,13 @@ irc_nick_as_prefix (struct t_irc_server *server, struct t_irc_nick *nick,
const char *str_prefix_color;
int prefix_color;
- prefix[0] = '\0';
+ prefix[0] = (nick) ? nick->prefix[0] : '\0';
prefix[1] = '\0';
if (weechat_config_boolean (weechat_config_get ("weechat.look.nickmode")))
{
if (nick)
{
- irc_nick_get_gui_infos (server, nick, &prefix[0], &prefix_color,
- NULL, NULL);
+ prefix_color = irc_nick_get_prefix_color (server, nick);
if ((prefix[0] == ' ')
&& !weechat_config_boolean (weechat_config_get ("weechat.look.nickmode_empty")))
prefix[0] = '\0';
@@ -741,11 +792,9 @@ irc_nick_color_for_pv (struct t_irc_channel *channel, const char *nickname)
int
irc_nick_add_to_infolist (struct t_infolist *infolist,
- struct t_irc_server *server,
struct t_irc_nick *nick)
{
struct t_infolist_item *ptr_item;
- char prefix[2];
if (!infolist || !nick)
return 0;
@@ -758,14 +807,13 @@ irc_nick_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "host", nick->host))
return 0;
- if (!weechat_infolist_new_var_integer (ptr_item, "flags", nick->flags))
+ if (!weechat_infolist_new_var_string (ptr_item, "prefixes", nick->prefixes))
return 0;
- if (!weechat_infolist_new_var_string (ptr_item, "color", nick->color))
+ if (!weechat_infolist_new_var_string (ptr_item, "prefix", nick->prefix))
return 0;
- prefix[0] = ' ';
- prefix[1] = '\0';
- irc_nick_get_gui_infos (server, nick, prefix, NULL, NULL, NULL);
- if (!weechat_infolist_new_var_string (ptr_item, "prefix", prefix))
+ if (!weechat_infolist_new_var_integer (ptr_item, "away", nick->away))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "color", nick->color))
return 0;
return 1;
@@ -780,8 +828,10 @@ irc_nick_print_log (struct t_irc_nick *nick)
{
weechat_log_printf ("");
weechat_log_printf (" => nick %s (addr:0x%lx):", nick->name, nick);
- weechat_log_printf (" host . . . . . : %s", nick->host);
- weechat_log_printf (" flags. . . . . : %d", nick->flags);
+ weechat_log_printf (" host . . . . . : '%s'", nick->host);
+ weechat_log_printf (" prefixes . . . : '%s'", nick->prefixes);
+ weechat_log_printf (" prefix . . . . : '%s'", nick->prefix);
+ weechat_log_printf (" away . . . . . : %d", nick->away);
weechat_log_printf (" color. . . . . : '%s'", nick->color);
weechat_log_printf (" prev_nick. . . : 0x%lx", nick->prev_nick);
weechat_log_printf (" next_nick. . . : 0x%lx", nick->next_nick);
diff --git a/src/plugins/irc/irc-nick.h b/src/plugins/irc/irc-nick.h
index 9dffce6ea..d1d787652 100644
--- a/src/plugins/irc/irc-nick.h
+++ b/src/plugins/irc/irc-nick.h
@@ -23,34 +23,7 @@
#define IRC_NICK_VALID_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHI" \
"JKLMNOPQRSTUVWXYZ0123456789-[]\\`_^{|}"
-#define IRC_NICK_CHANOWNER 1
-#define IRC_NICK_CHANADMIN 2
-#define IRC_NICK_CHANADMIN2 4
-#define IRC_NICK_OP 8
-#define IRC_NICK_HALFOP 16
-#define IRC_NICK_VOICE 32
-#define IRC_NICK_AWAY 64
-#define IRC_NICK_CHANUSER 128
-#define IRC_NICK_SET_FLAG(nick, set, flag) \
- if (set) \
- nick->flags |= flag; \
- else \
- nick->flags &= 0xFFFF - flag;
-
-#define IRC_NICK_IS_OP(__nick) \
- ((__nick->flags & IRC_NICK_CHANOWNER) || \
- (__nick->flags & IRC_NICK_CHANADMIN) || \
- (__nick->flags & IRC_NICK_CHANADMIN2) || \
- (__nick->flags & IRC_NICK_OP))
-
-#define IRC_NICK_GROUP_CHANOWNER "01|chanowner"
-#define IRC_NICK_GROUP_CHANADMIN "02|chanadmin"
-#define IRC_NICK_GROUP_CHANADMIN2 "03|chanadmin2"
-#define IRC_NICK_GROUP_OP "04|op"
-#define IRC_NICK_GROUP_HALFOP "05|halfop"
-#define IRC_NICK_GROUP_VOICE "06|voice"
-#define IRC_NICK_GROUP_CHANUSER "07|chanuser"
-#define IRC_NICK_GROUP_NORMAL "08|normal"
+#define IRC_NICK_GROUP_OTHER "999|..."
struct t_irc_server;
struct t_irc_channel;
@@ -59,8 +32,10 @@ struct t_irc_nick
{
char *name; /* nickname */
char *host; /* full hostname */
- int flags; /* chanowner/chanadmin (unrealircd), */
- /* op, halfop, voice, away */
+ char *prefixes; /* string with prefixes enabled for nick */
+ char prefix[2]; /* current prefix (higher prefix set in */
+ /* prefixes) */
+ int away; /* 1 if nick is away */
const char *color; /* color for nickname in chat window */
struct t_irc_nick *prev_nick; /* link to previous nick on channel */
struct t_irc_nick *next_nick; /* link to next nick on channel */
@@ -71,29 +46,25 @@ extern int irc_nick_valid (struct t_irc_channel *channel,
extern int irc_nick_is_nick (const char *string);
extern const char *irc_nick_find_color (const char *nickname);
extern const char *irc_nick_find_color_name (const char *nickname);
-extern void irc_nick_get_gui_infos (struct t_irc_server *server,
- struct t_irc_nick *nick,
- char *prefix, int *prefix_color,
- struct t_gui_buffer *buffer,
- struct t_gui_nick_group **group);
+extern int irc_nick_is_op (struct t_irc_server *server,
+ struct t_irc_nick *nick);
+extern int irc_nick_has_prefix_mode (struct t_irc_server *server,
+ struct t_irc_nick *nick,
+ char prefix_mode);
+extern int irc_nick_get_prefix_color (struct t_irc_server *server,
+ struct t_irc_nick *nick);
extern const char *irc_nick_get_prefix_color_name (int prefix_color);
extern struct t_irc_nick *irc_nick_new (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *nickname,
- int is_chanowner,
- int is_chanadmin,
- int is_chanadmin2,
- int is_op,
- int is_halfop,
- int has_voice,
- int is_chanuser,
- int is_away);
+ const char *prefixes,
+ int away);
extern void irc_nick_change (struct t_irc_server *server,
struct t_irc_channel *channel,
struct t_irc_nick *nick, const char *new_nick);
-extern void irc_nick_set (struct t_irc_server *server,
- struct t_irc_channel *channel,
- struct t_irc_nick *nick, int set, int flag);
+extern void irc_nick_set_mode (struct t_irc_server *server,
+ struct t_irc_channel *channel,
+ struct t_irc_nick *nick, int set, char mode);
extern void irc_nick_free (struct t_irc_server *server,
struct t_irc_channel *channel,
struct t_irc_nick *nick);
@@ -101,7 +72,8 @@ extern void irc_nick_free_all (struct t_irc_server *server,
struct t_irc_channel *channel);
extern struct t_irc_nick *irc_nick_search (struct t_irc_channel *channel,
const char *nickname);
-extern void irc_nick_count (struct t_irc_channel *channel, int *total,
+extern void irc_nick_count (struct t_irc_server *server,
+ struct t_irc_channel *channel, int *total,
int *count_op, int *count_halfop, int *count_voice,
int *count_normal);
extern void irc_nick_set_away (struct t_irc_server *server,
@@ -114,7 +86,6 @@ extern char *irc_nick_as_prefix (struct t_irc_server *server,
extern const char * irc_nick_color_for_pv (struct t_irc_channel *channel,
const char *nickname);
extern int irc_nick_add_to_infolist (struct t_infolist *infolist,
- struct t_irc_server *server,
struct t_irc_nick *nick);
extern void irc_nick_print_log (struct t_irc_nick *nick);
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 118b9e6ab..17f709afe 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -604,7 +604,7 @@ IRC_PROTOCOL_CALLBACK(join)
}
/* add nick in channel */
- ptr_nick = irc_nick_new (server, ptr_channel, nick, 0, 0, 0, 0, 0, 0, 0, 0);
+ ptr_nick = irc_nick_new (server, ptr_channel, nick, NULL, 0);
if (ptr_nick)
ptr_nick->host = strdup (address);
@@ -2007,9 +2007,7 @@ IRC_PROTOCOL_CALLBACK(005)
pos2 = strchr (pos, ' ');
if (pos2)
pos2[0] = '\0';
- if (server->prefix)
- free (server->prefix);
- server->prefix = strdup (pos);
+ irc_server_set_prefix_modes_chars (server, pos);
if (pos2)
pos2[0] = ' ';
}
@@ -3497,11 +3495,9 @@ IRC_PROTOCOL_CALLBACK(352)
IRC_PROTOCOL_CALLBACK(353)
{
- char *pos_channel, *pos_nick, *pos_host, *nickname;
- const char *color;
- int args, i, prefix_found;
- int is_chanowner, is_chanadmin, is_chanadmin2, is_op, is_halfop;
- int has_voice, is_chanuser, is_away;
+ char *pos_channel, *pos_nick, *pos_nick_orig, *pos_host, *nickname;
+ char *prefixes;
+ int args, i, away;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
@@ -3527,84 +3523,36 @@ IRC_PROTOCOL_CALLBACK(353)
ptr_channel = irc_channel_search (server, pos_channel);
- for (i = args; i < argc; i++)
+ if (ptr_channel && ptr_channel->nicks)
{
- pos_nick = (argv[i][0] == ':') ? argv[i] + 1 : argv[i];
-
- is_chanowner = 0;
- is_chanadmin = 0;
- is_chanadmin2 = 0;
- is_op = 0;
- is_halfop = 0;
- has_voice = 0;
- is_chanuser = 0;
- is_away = 0;
- prefix_found = 1;
-
- while (prefix_found)
+ for (i = args; i < argc; i++)
{
- prefix_found = 0;
+ pos_nick = (argv[i][0] == ':') ? argv[i] + 1 : argv[i];
+ pos_nick_orig = pos_nick;
- if (irc_mode_get_nick_attr (server, NULL, pos_nick[0]) >= 0)
+ /* skip prefix(es) */
+ while (pos_nick[0]
+ && (irc_server_get_prefix_char_index (server, pos_nick[0]) >= 0))
{
- prefix_found = 1;
- switch (pos_nick[0])
- {
- case '@': /* op */
- is_op = 1;
- color = IRC_COLOR_NICK_PREFIX_OP;
- break;
- case '~': /* channel owner */
- is_chanowner = 1;
- color = IRC_COLOR_NICK_PREFIX_OP;
- break;
- case '*': /* channel owner */
- is_chanowner = 1;
- color = IRC_COLOR_NICK_PREFIX_OP;
- break;
- case '&': /* channel admin */
- is_chanadmin = 1;
- color = IRC_COLOR_NICK_PREFIX_OP;
- break;
- case '!': /* channel admin (2) */
- is_chanadmin2 = 1;
- color = IRC_COLOR_NICK_PREFIX_OP;
- break;
- case '%': /* half-op */
- is_halfop = 1;
- color = IRC_COLOR_NICK_PREFIX_HALFOP;
- break;
- case '+': /* voice */
- has_voice = 1;
- color = IRC_COLOR_NICK_PREFIX_VOICE;
- break;
- case '-': /* channel user */
- is_chanuser = 1;
- color = IRC_COLOR_NICK_PREFIX_USER;
- break;
- default:
- color = IRC_COLOR_CHAT;
- break;
- }
- }
- if (prefix_found)
pos_nick++;
- }
- if (ptr_channel && ptr_channel->nicks)
- {
+ }
+
+ /* extract nick from host */
pos_host = strchr (pos_nick, '!');
if (pos_host)
nickname = weechat_strndup (pos_nick, pos_host - pos_nick);
else
nickname = strdup (pos_nick);
+
+ /* add or update nick on channel */
if (nickname)
{
ptr_nick = irc_nick_search (ptr_channel, nickname);
- is_away = (ptr_nick && (ptr_nick->flags & IRC_NICK_AWAY)) ? 1 : 0;
- if (!irc_nick_new (server, ptr_channel, nickname,
- is_chanowner, is_chanadmin, is_chanadmin2,
- is_op, is_halfop, has_voice, is_chanuser,
- is_away))
+ away = (ptr_nick && ptr_nick->away) ? 1 : 0;
+ prefixes = (pos_nick > pos_nick_orig) ?
+ weechat_strndup (pos_nick_orig, pos_nick - pos_nick_orig) : NULL;
+ if (!irc_nick_new (server, ptr_channel, nickname, prefixes,
+ away))
{
weechat_printf (server->buffer,
_("%s%s: cannot create nick \"%s\" "
@@ -3613,6 +3561,8 @@ IRC_PROTOCOL_CALLBACK(353)
IRC_PLUGIN_NAME, nickname, ptr_channel->name);
}
free (nickname);
+ if (prefixes)
+ free (prefixes);
}
}
}
@@ -3724,7 +3674,7 @@ IRC_PROTOCOL_CALLBACK(366)
}
/* display number of nicks, ops, halfops & voices on the channel */
- irc_nick_count (ptr_channel, &num_nicks, &num_op, &num_halfop,
+ irc_nick_count (server, ptr_channel, &num_nicks, &num_op, &num_halfop,
&num_voice, &num_normal);
weechat_printf_tags (ptr_channel->buffer,
irc_protocol_tags (command, "irc_numeric", NULL),
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 74f274d1b..b1c04983a 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -88,6 +88,9 @@ char *irc_server_option_default[IRC_SERVER_NUM_OPTIONS] =
"WeeChat %v", "WeeChat %v",
};
+char *irc_server_prefix_modes_default = "qaohvu";
+char *irc_server_prefix_chars_default = "~&@%+-";
+
const char *irc_server_send_default_tags = NULL; /* default tags when */
/* sending a message */
@@ -385,6 +388,182 @@ irc_server_get_isupport_value (struct t_irc_server *server, const char *feature)
}
/*
+ * irc_server_set_prefix_modes_chars: set "prefix_modes" and "prefix_chars" in
+ * server using value of PREFIX in IRC
+ * message 005
+ * for example, if prefix is "(aohv)&@%+",
+ * prefix_modes = "aohv"
+ * prefix_chars = "&@%+"
+ */
+
+void
+irc_server_set_prefix_modes_chars (struct t_irc_server *server,
+ const char *prefix)
+{
+ char *pos;
+ int i, length_modes, length_chars;
+
+ if (!server || !prefix)
+ return;
+
+ /* free previous values */
+ if (server->prefix_modes)
+ {
+ free (server->prefix_modes);
+ server->prefix_modes = NULL;
+ }
+ if (server->prefix_chars)
+ {
+ free (server->prefix_chars);
+ server->prefix_chars = NULL;
+ }
+
+ /* assign new values */
+ pos = strchr (prefix, ')');
+ if (pos)
+ {
+ server->prefix_modes = weechat_strndup (prefix + 1,
+ pos - prefix - 1);
+ if (server->prefix_modes)
+ {
+ pos++;
+ length_modes = strlen (server->prefix_modes);
+ length_chars = strlen (pos);
+ server->prefix_chars = malloc (length_modes + 1);
+ if (server->prefix_chars)
+ {
+ for (i = 0; i < length_modes; i++)
+ {
+ server->prefix_chars[i] = (i < length_chars) ? pos[i] : ' ';
+ }
+ server->prefix_chars[length_modes] = '\0';
+ }
+ else
+ {
+ free (server->prefix_modes);
+ server->prefix_modes = NULL;
+ }
+ }
+ }
+}
+
+/*
+ * irc_server_get_prefix_modes: get prefix_modes for server (return default
+ * modes if prefix_modes is not set)
+ */
+
+const char *
+irc_server_get_prefix_modes (struct t_irc_server *server)
+{
+ return (server && server->prefix_modes) ?
+ server->prefix_modes : irc_server_prefix_modes_default;
+}
+
+/*
+ * irc_server_get_prefix_chars: get prefix_chars for server (return default
+ * chars if prefix_chars is not set)
+ */
+
+const char *
+irc_server_get_prefix_chars (struct t_irc_server *server)
+{
+ return (server && server->prefix_chars) ?
+ server->prefix_chars : irc_server_prefix_chars_default;
+}
+
+/*
+ * irc_server_get_prefix_mode_index: get index of mode in prefix_modes
+ * return -1 if mode does not exist in server
+ */
+
+int
+irc_server_get_prefix_mode_index (struct t_irc_server *server, char mode)
+{
+ const char *prefix_modes;
+ char *pos;
+
+ if (server)
+ {
+ prefix_modes = irc_server_get_prefix_modes (server);
+ pos = strchr (prefix_modes, mode);
+ if (pos)
+ return pos - prefix_modes;
+ }
+
+ return -1;
+}
+
+/*
+ * irc_server_get_prefix_char_index: get index of prefix_char in prefix_chars
+ * return -1 if prefix_char does not exist in
+ * server
+ */
+
+int
+irc_server_get_prefix_char_index (struct t_irc_server *server,
+ char prefix_char)
+{
+ const char *prefix_chars;
+ char *pos;
+
+ if (server)
+ {
+ prefix_chars = irc_server_get_prefix_chars (server);
+ pos = strchr (prefix_chars, prefix_char);
+ if (pos)
+ return pos - prefix_chars;
+ }
+
+ return -1;
+}
+
+/*
+ * irc_server_get_prefix_mode_for_char: get mode for prefix char
+ * return ' ' (space) if prefix char is
+ * not found
+ */
+
+char
+irc_server_get_prefix_mode_for_char (struct t_irc_server *server,
+ char prefix_char)
+{
+ const char *prefix_modes;
+ int index;
+
+ if (server)
+ {
+ prefix_modes = irc_server_get_prefix_modes (server);
+ index = irc_server_get_prefix_char_index (server, prefix_char);
+ if (index >= 0)
+ return prefix_modes[index];
+ }
+
+ return ' ';
+}
+
+/*
+ * irc_server_get_prefix_mode_for_char: get prefix char for mode
+ * return ' ' (space) if mode is not found
+ */
+
+char
+irc_server_get_prefix_char_for_mode (struct t_irc_server *server, char mode)
+{
+ const char *prefix_chars;
+ int index;
+
+ if (server)
+ {
+ prefix_chars = irc_server_get_prefix_chars (server);
+ index = irc_server_get_prefix_mode_index (server, mode);
+ if (index >= 0)
+ return prefix_chars[index];
+ }
+
+ return ' ';
+}
+
+/*
* irc_server_alloc: allocate a new server and add it to the servers queue
*/
@@ -445,7 +624,8 @@ irc_server_alloc (const char *name)
new_server->nick = NULL;
new_server->nick_modes = NULL;
new_server->isupport = NULL;
- new_server->prefix = NULL;
+ new_server->prefix_modes = NULL;
+ new_server->prefix_chars = NULL;
new_server->reconnect_delay = 0;
new_server->reconnect_start = 0;
new_server->command_time = 0;
@@ -894,8 +1074,10 @@ irc_server_free_data (struct t_irc_server *server)
free (server->nick_modes);
if (server->isupport)
free (server->isupport);
- if (server->prefix)
- free (server->prefix);
+ if (server->prefix_modes)
+ free (server->prefix_modes);
+ if (server->prefix_chars)
+ free (server->prefix_chars);
if (server->away_message)
free (server->away_message);
if (server->cmd_list_regexp)
@@ -3350,10 +3532,15 @@ irc_server_disconnect (struct t_irc_server *server, int switch_address,
free (server->isupport);
server->isupport = NULL;
}
- if (server->prefix)
+ if (server->prefix_modes)
{
- free (server->prefix);
- server->prefix = NULL;
+ free (server->prefix_modes);
+ server->prefix_modes = NULL;
+ }
+ if (server->prefix_chars)
+ {
+ free (server->prefix_chars);
+ server->prefix_chars = NULL;
}
server->is_away = 0;
server->away_time = 0;
@@ -3972,7 +4159,9 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "isupport", server->isupport))
return 0;
- if (!weechat_infolist_new_var_string (ptr_item, "prefix", server->prefix))
+ if (!weechat_infolist_new_var_string (ptr_item, "prefix_modes", server->prefix_modes))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "prefix_chars", server->prefix_chars))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "reconnect_delay", server->reconnect_delay))
return 0;
@@ -4266,7 +4455,8 @@ irc_server_print_log ()
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);
- weechat_log_printf (" prefix . . . . . . . : '%s'", ptr_server->prefix);
+ weechat_log_printf (" prefix_modes . . . . : '%s'", ptr_server->prefix_modes);
+ weechat_log_printf (" prefix_chars . . . . : '%s'", ptr_server->prefix_chars);
weechat_log_printf (" reconnect_delay. . . : %d", ptr_server->reconnect_delay);
weechat_log_printf (" reconnect_start. . . : %ld", ptr_server->reconnect_start);
weechat_log_printf (" command_time . . . . : %ld", ptr_server->command_time);
diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h
index 251afb337..b8e728d3c 100644
--- a/src/plugins/irc/irc-server.h
+++ b/src/plugins/irc/irc-server.h
@@ -150,7 +150,8 @@ struct t_irc_server
char *nick; /* current nickname */
char *nick_modes; /* nick modes */
char *isupport; /* copy of message 005 (ISUPPORT) */
- char *prefix; /* nick prefix allowed (from msg 005) */
+ char *prefix_modes; /* prefix modes from msg 005 (eg "aohv") */
+ char *prefix_chars; /* prefix chars from msg 005 (eg "&@%+") */
int reconnect_delay; /* current reconnect delay (growing) */
time_t reconnect_start; /* this time + delay = reconnect time */
time_t command_time; /* this time + command_delay = time to */
@@ -209,6 +210,18 @@ 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_isupport_value (struct t_irc_server *server,
const char *feature);
+extern void irc_server_set_prefix_modes_chars (struct t_irc_server *server,
+ const char *prefix);
+extern const char *irc_server_get_prefix_modes (struct t_irc_server *server);
+extern const char *irc_server_get_prefix_chars (struct t_irc_server *server);
+extern int irc_server_get_prefix_mode_index (struct t_irc_server *server,
+ char mode);
+extern int irc_server_get_prefix_char_index (struct t_irc_server *server,
+ char prefix_char);
+extern char irc_server_get_prefix_mode_for_char (struct t_irc_server *server,
+ char prefix_char);
+extern char irc_server_get_prefix_char_for_mode (struct t_irc_server *server,
+ char mode);
extern struct t_irc_server *irc_server_alloc (const char *name);
extern int irc_server_alloc_with_url (const char *irc_url);
extern void irc_server_apply_command_line_options (struct t_irc_server *server,
diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c
index 1e5d48c29..d4c5d0522 100644
--- a/src/plugins/irc/irc-upgrade.c
+++ b/src/plugins/irc/irc-upgrade.c
@@ -21,6 +21,7 @@
* irc-upgrade.c: save/restore IRC plugin data when upgrading WeeChat
*/
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -103,7 +104,7 @@ irc_upgrade_save_all_data (struct t_upgrade_file *upgrade_file)
infolist = weechat_infolist_new ();
if (!infolist)
return 0;
- if (!irc_nick_add_to_infolist (infolist, ptr_server, ptr_nick))
+ if (!irc_nick_add_to_infolist (infolist, ptr_nick))
{
weechat_infolist_free (infolist);
return 0;
@@ -324,9 +325,30 @@ irc_upgrade_read_cb (void *data,
str = weechat_infolist_string (infolist, "isupport");
if (str)
irc_upgrade_current_server->isupport = strdup (str);
+ /*
+ * "prefix" is not any more in this infolist (since
+ * WeeChat 0.3.4), but we read it to keep compatibility
+ * with old WeeChat versions, on /upgrade)
+ */
str = weechat_infolist_string (infolist, "prefix");
if (str)
- irc_upgrade_current_server->prefix = strdup (str);
+ irc_server_set_prefix_modes_chars (irc_upgrade_current_server, str);
+ /* "prefix_modes" is new in WeeChat 0.3.4 */
+ str = weechat_infolist_string (infolist, "prefix_modes");
+ if (str)
+ {
+ if (irc_upgrade_current_server->prefix_modes)
+ free (irc_upgrade_current_server->prefix_modes);
+ irc_upgrade_current_server->prefix_modes = strdup (str);
+ }
+ /* "prefix_chars" is new in WeeChat 0.3.4 */
+ str = weechat_infolist_string (infolist, "prefix_chars");
+ if (str)
+ {
+ if (irc_upgrade_current_server->prefix_chars)
+ free (irc_upgrade_current_server->prefix_chars);
+ irc_upgrade_current_server->prefix_chars = strdup (str);
+ }
irc_upgrade_current_server->reconnect_delay = weechat_infolist_integer (infolist, "reconnect_delay");
irc_upgrade_current_server->reconnect_start = weechat_infolist_time (infolist, "reconnect_start");
irc_upgrade_current_server->command_time = weechat_infolist_time (infolist, "command_time");
@@ -412,23 +434,88 @@ irc_upgrade_read_cb (void *data,
case IRC_UPGRADE_TYPE_NICK:
if (irc_upgrade_current_server && irc_upgrade_current_channel)
{
- flags = weechat_infolist_integer (infolist, "flags");
ptr_nick = irc_nick_new (irc_upgrade_current_server,
irc_upgrade_current_channel,
weechat_infolist_string (infolist, "name"),
- flags & IRC_NICK_CHANOWNER,
- flags & IRC_NICK_CHANADMIN,
- flags & IRC_NICK_CHANADMIN2,
- flags & IRC_NICK_OP,
- flags & IRC_NICK_HALFOP,
- flags & IRC_NICK_VOICE,
- flags & IRC_NICK_CHANUSER,
- flags & IRC_NICK_AWAY);
+ weechat_infolist_string (infolist, "prefixes"),
+ weechat_infolist_integer (infolist, "away"));
if (ptr_nick)
{
str = weechat_infolist_string (infolist, "host");
if (str)
ptr_nick->host = strdup (str);
+
+ /*
+ * "flags" is not any more in this infolist (since
+ * WeeChat 0.3.4), but we read it to keep compatibility
+ * with old WeeChat versions, on /upgrade)
+ * We try to restore prefixes with old flags, but
+ * this is approximation, it's not sure we will
+ * restore good prefixes here (a /names on channel
+ * will fix problem if prefixes are wrong).
+ * Flags were defined in irc-nick.h:
+ * #define IRC_NICK_CHANOWNER 1
+ * #define IRC_NICK_CHANADMIN 2
+ * #define IRC_NICK_CHANADMIN2 4
+ * #define IRC_NICK_OP 8
+ * #define IRC_NICK_HALFOP 16
+ * #define IRC_NICK_VOICE 32
+ * #define IRC_NICK_AWAY 64
+ * #define IRC_NICK_CHANUSER 128
+ */
+ flags = weechat_infolist_integer (infolist, "flags");
+ if (flags > 0)
+ {
+ /* channel owner */
+ if (flags & 1)
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'q');
+ }
+ /* channel admin */
+ if ((flags & 2) || (flags & 4))
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'a');
+ }
+ /* op */
+ if (flags & 8)
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'o');
+ }
+ /* half-op */
+ if (flags & 16)
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'h');
+ }
+ /* voice */
+ if (flags & 32)
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'v');
+ }
+ /* away */
+ if (flags & 64)
+ {
+ irc_nick_set_away (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1);
+ }
+ /* channel user */
+ if (flags & 128)
+ {
+ irc_nick_set_mode (irc_upgrade_current_server,
+ irc_upgrade_current_channel,
+ ptr_nick, 1, 'u');
+ }
+ }
}
}
break;