mirror of
https://github.com/irssi/irssi.git
synced 2024-11-03 04:27:19 -05:00
Support for multiple identical nicknames.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1241 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
c2a1971cc3
commit
6a469c46bb
@ -389,6 +389,26 @@ void nicklist_update_flags_unique(SERVER_REC *server, void *id,
|
|||||||
nicklist_get_same_unique(server, id));
|
nicklist_get_same_unique(server, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Specify which nick in channel is ours */
|
||||||
|
void nicklist_set_own(CHANNEL_REC *channel, NICK_REC *nick)
|
||||||
|
{
|
||||||
|
NICK_REC *first, *next;
|
||||||
|
|
||||||
|
channel->ownnick = nick;
|
||||||
|
|
||||||
|
/* move our nick in the list to first, makes some things easier
|
||||||
|
(like handling multiple identical nicks in fe-messages.c) */
|
||||||
|
first = g_hash_table_lookup(channel->nicks, nick->nick);
|
||||||
|
if (first->next == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
next = nick->next;
|
||||||
|
nick->next = first;
|
||||||
|
first->next = next;
|
||||||
|
|
||||||
|
g_hash_table_insert(channel->nicks, nick->nick, nick);
|
||||||
|
}
|
||||||
|
|
||||||
static void sig_channel_created(CHANNEL_REC *channel)
|
static void sig_channel_created(CHANNEL_REC *channel)
|
||||||
{
|
{
|
||||||
g_return_if_fail(IS_CHANNEL(channel));
|
g_return_if_fail(IS_CHANNEL(channel));
|
||||||
|
@ -44,6 +44,9 @@ void nicklist_update_flags(SERVER_REC *server, const char *nick,
|
|||||||
void nicklist_update_flags_unique(SERVER_REC *server, void *id,
|
void nicklist_update_flags_unique(SERVER_REC *server, void *id,
|
||||||
int gone, int ircop);
|
int gone, int ircop);
|
||||||
|
|
||||||
|
/* Specify which nick in channel is ours */
|
||||||
|
void nicklist_set_own(CHANNEL_REC *channel, NICK_REC *nick);
|
||||||
|
|
||||||
/* Nick record comparision for sort functions */
|
/* Nick record comparision for sort functions */
|
||||||
int nicklist_compare(NICK_REC *p1, NICK_REC *p2);
|
int nicklist_compare(NICK_REC *p1, NICK_REC *p2);
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
#define ishighalnum(c) ((unsigned char) (c) >= 128 || isalnum(c))
|
#define ishighalnum(c) ((unsigned char) (c) >= 128 || isalnum(c))
|
||||||
|
|
||||||
|
static GHashTable *printnicks;
|
||||||
|
|
||||||
/* convert _underlined_ and *bold* words (and phrases) to use real
|
/* convert _underlined_ and *bold* words (and phrases) to use real
|
||||||
underlining or bolding */
|
underlining or bolding */
|
||||||
char *expand_emphasis(WI_ITEM_REC *item, const char *text)
|
char *expand_emphasis(WI_ITEM_REC *item, const char *text)
|
||||||
@ -127,18 +129,33 @@ char *channel_get_nickmode(CHANNEL_REC *channel, const char *nick)
|
|||||||
(nickrec->op ? "@" : (nickrec->voice ? "+" : emptystr));
|
(nickrec->op ? "@" : (nickrec->voice ? "+" : emptystr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *channel_get_nickmode_rec(NICK_REC *nickrec)
|
||||||
|
{
|
||||||
|
char *emptystr;
|
||||||
|
|
||||||
|
if (!settings_get_bool("show_nickmode"))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
emptystr = settings_get_bool("show_nickmode_empty") ? " " : "";
|
||||||
|
|
||||||
|
return nickrec == NULL ? emptystr :
|
||||||
|
(nickrec->op ? "@" : (nickrec->voice ? "+" : emptystr));
|
||||||
|
}
|
||||||
|
|
||||||
static void sig_message_public(SERVER_REC *server, const char *msg,
|
static void sig_message_public(SERVER_REC *server, const char *msg,
|
||||||
const char *nick, const char *address,
|
const char *nick, const char *address,
|
||||||
const char *target)
|
const char *target, NICK_REC *nickrec)
|
||||||
{
|
{
|
||||||
CHANNEL_REC *chanrec;
|
CHANNEL_REC *chanrec;
|
||||||
const char *nickmode;
|
const char *nickmode, *printnick;
|
||||||
int for_me, print_channel, level;
|
int for_me, print_channel, level;
|
||||||
char *color, *freemsg = NULL;
|
char *color, *freemsg = NULL;
|
||||||
|
|
||||||
/* NOTE: this may return NULL if some channel is just closed with
|
/* NOTE: this may return NULL if some channel is just closed with
|
||||||
/WINDOW CLOSE and server still sends the few last messages */
|
/WINDOW CLOSE and server still sends the few last messages */
|
||||||
chanrec = channel_find(server, target);
|
chanrec = channel_find(server, target);
|
||||||
|
if (nickrec == NULL && chanrec != NULL)
|
||||||
|
nickrec = nicklist_find(chanrec, nick);
|
||||||
|
|
||||||
for_me = nick_match_msg(chanrec, msg, server->nick);
|
for_me = nick_match_msg(chanrec, msg, server->nick);
|
||||||
color = for_me ? NULL :
|
color = for_me ? NULL :
|
||||||
@ -156,18 +173,25 @@ static void sig_message_public(SERVER_REC *server, const char *msg,
|
|||||||
if (settings_get_bool("emphasis"))
|
if (settings_get_bool("emphasis"))
|
||||||
msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg);
|
msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg);
|
||||||
|
|
||||||
nickmode = channel_get_nickmode(chanrec, nick);
|
/* get nick mode & nick what to print the msg with
|
||||||
|
(in case there's multiple identical nicks) */
|
||||||
|
nickmode = channel_get_nickmode_rec(nickrec);
|
||||||
|
printnick = nickrec == NULL ? nick :
|
||||||
|
g_hash_table_lookup(printnicks, nickrec);
|
||||||
|
if (printnick == NULL)
|
||||||
|
printnick = nick;
|
||||||
|
|
||||||
if (!print_channel) {
|
if (!print_channel) {
|
||||||
/* message to active channel in window */
|
/* message to active channel in window */
|
||||||
if (color != NULL) {
|
if (color != NULL) {
|
||||||
/* highlighted nick */
|
/* highlighted nick */
|
||||||
printformat(server, target, level,
|
printformat(server, target, level,
|
||||||
TXT_PUBMSG_HILIGHT,
|
TXT_PUBMSG_HILIGHT,
|
||||||
color, nick, msg, nickmode);
|
color, printnick, msg, nickmode);
|
||||||
} else {
|
} else {
|
||||||
printformat(server, target, level,
|
printformat(server, target, level,
|
||||||
for_me ? TXT_PUBMSG_ME : TXT_PUBMSG,
|
for_me ? TXT_PUBMSG_ME : TXT_PUBMSG,
|
||||||
nick, msg, nickmode);
|
printnick, msg, nickmode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* message to not existing/active channel */
|
/* message to not existing/active channel */
|
||||||
@ -175,12 +199,12 @@ static void sig_message_public(SERVER_REC *server, const char *msg,
|
|||||||
/* highlighted nick */
|
/* highlighted nick */
|
||||||
printformat(server, target, level,
|
printformat(server, target, level,
|
||||||
TXT_PUBMSG_HILIGHT_CHANNEL,
|
TXT_PUBMSG_HILIGHT_CHANNEL,
|
||||||
color, nick, target, msg, nickmode);
|
color, printnick, target, msg, nickmode);
|
||||||
} else {
|
} else {
|
||||||
printformat(server, target, level,
|
printformat(server, target, level,
|
||||||
for_me ? TXT_PUBMSG_ME_CHANNEL :
|
for_me ? TXT_PUBMSG_ME_CHANNEL :
|
||||||
TXT_PUBMSG_CHANNEL,
|
TXT_PUBMSG_CHANNEL,
|
||||||
nick, target, msg, nickmode);
|
printnick, target, msg, nickmode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,8 +498,110 @@ static void sig_message_topic(SERVER_REC *server, const char *channel,
|
|||||||
nick, channel, topic);
|
nick, channel, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int printnick_exists(NICK_REC *first, NICK_REC *ignore,
|
||||||
|
const char *nick)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
while (first != NULL) {
|
||||||
|
if (first != ignore) {
|
||||||
|
str = g_hash_table_lookup(printnicks, first->nick);
|
||||||
|
if (str != NULL && strcmp(str, nick) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
first = first->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_nicklist_new(CHANNEL_REC *channel, NICK_REC *nick)
|
||||||
|
{
|
||||||
|
NICK_REC *firstnick;
|
||||||
|
GString *newnick;
|
||||||
|
char *nickhost, *p;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (nick->host == NULL || nick == channel->ownnick)
|
||||||
|
return;
|
||||||
|
|
||||||
|
firstnick = g_hash_table_lookup(channel->nicks, nick->nick);
|
||||||
|
if (firstnick->next == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* identical nick already exists, have to change it somehow.. */
|
||||||
|
p = strchr(nick->host, '@');
|
||||||
|
if (p == NULL) p = nick->host; else p++;
|
||||||
|
|
||||||
|
nickhost = g_strdup_printf("%s@%s", nick->nick, p);
|
||||||
|
p = strchr(nickhost+strlen(nick->nick), '.');
|
||||||
|
if (p != NULL) *p = '\0';
|
||||||
|
|
||||||
|
if (!printnick_exists(firstnick, nick, nickhost)) {
|
||||||
|
/* use nick@host */
|
||||||
|
g_hash_table_insert(printnicks, nick, nickhost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newnick = g_string_new(NULL);
|
||||||
|
n = 2;
|
||||||
|
do {
|
||||||
|
g_string_sprintf(newnick, "%s%d", nickhost, n);
|
||||||
|
n++;
|
||||||
|
} while (printnick_exists(firstnick, nick, newnick->str));
|
||||||
|
|
||||||
|
g_hash_table_insert(printnicks, nick, newnick->str);
|
||||||
|
g_string_free(newnick, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick)
|
||||||
|
{
|
||||||
|
g_hash_table_remove(printnicks, nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_nicklist_changed(CHANNEL_REC *channel, NICK_REC *nick)
|
||||||
|
{
|
||||||
|
sig_nicklist_remove(channel, nick);
|
||||||
|
sig_nicklist_new(channel, nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_channel_joined(CHANNEL_REC *channel)
|
||||||
|
{
|
||||||
|
NICK_REC *nick;
|
||||||
|
char *nickname;
|
||||||
|
|
||||||
|
/* channel->ownnick is set at this point - check if our own nick
|
||||||
|
has been changed, if it was set it back to the original nick and
|
||||||
|
change the previous original to something else */
|
||||||
|
|
||||||
|
nickname = g_hash_table_lookup(printnicks, channel->ownnick);
|
||||||
|
if (nickname == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free(nickname);
|
||||||
|
g_hash_table_remove(printnicks, channel->ownnick);
|
||||||
|
|
||||||
|
/* our own nick is guaranteed to be the first in list */
|
||||||
|
nick = channel->ownnick->next;
|
||||||
|
while (nick != NULL) {
|
||||||
|
if (g_hash_table_lookup(printnicks, nick) == NULL) {
|
||||||
|
sig_nicklist_new(channel, nick);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nick = nick->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void g_hash_free_value(void *key, void *value)
|
||||||
|
{
|
||||||
|
g_free(value);
|
||||||
|
}
|
||||||
|
|
||||||
void fe_messages_init(void)
|
void fe_messages_init(void)
|
||||||
{
|
{
|
||||||
|
printnicks = g_hash_table_new((GHashFunc) g_direct_hash,
|
||||||
|
(GCompareFunc) g_direct_equal);
|
||||||
|
|
||||||
settings_add_bool("lookandfeel", "emphasis", TRUE);
|
settings_add_bool("lookandfeel", "emphasis", TRUE);
|
||||||
settings_add_bool("lookandfeel", "emphasis_replace", FALSE);
|
settings_add_bool("lookandfeel", "emphasis_replace", FALSE);
|
||||||
settings_add_bool("lookandfeel", "emphasis_multiword", FALSE);
|
settings_add_bool("lookandfeel", "emphasis_multiword", FALSE);
|
||||||
@ -496,10 +622,19 @@ void fe_messages_init(void)
|
|||||||
signal_add("message own_nick", (SIGNAL_FUNC) sig_message_own_nick);
|
signal_add("message own_nick", (SIGNAL_FUNC) sig_message_own_nick);
|
||||||
signal_add("message invite", (SIGNAL_FUNC) sig_message_invite);
|
signal_add("message invite", (SIGNAL_FUNC) sig_message_invite);
|
||||||
signal_add("message topic", (SIGNAL_FUNC) sig_message_topic);
|
signal_add("message topic", (SIGNAL_FUNC) sig_message_topic);
|
||||||
|
|
||||||
|
signal_add("nicklist new", (SIGNAL_FUNC) sig_nicklist_new);
|
||||||
|
signal_add("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove);
|
||||||
|
signal_add("nicklist changed", (SIGNAL_FUNC) sig_nicklist_changed);
|
||||||
|
signal_add("nicklist host changed", (SIGNAL_FUNC) sig_nicklist_new);
|
||||||
|
signal_add("channel joined", (SIGNAL_FUNC) sig_channel_joined);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_messages_deinit(void)
|
void fe_messages_deinit(void)
|
||||||
{
|
{
|
||||||
|
g_hash_table_foreach(printnicks, (GHFunc) g_hash_free_value, NULL);
|
||||||
|
g_hash_table_destroy(printnicks);
|
||||||
|
|
||||||
signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
|
signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
|
||||||
signal_remove("message private", (SIGNAL_FUNC) sig_message_private);
|
signal_remove("message private", (SIGNAL_FUNC) sig_message_private);
|
||||||
signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public);
|
signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public);
|
||||||
@ -512,4 +647,10 @@ void fe_messages_deinit(void)
|
|||||||
signal_remove("message own_nick", (SIGNAL_FUNC) sig_message_own_nick);
|
signal_remove("message own_nick", (SIGNAL_FUNC) sig_message_own_nick);
|
||||||
signal_remove("message invite", (SIGNAL_FUNC) sig_message_invite);
|
signal_remove("message invite", (SIGNAL_FUNC) sig_message_invite);
|
||||||
signal_remove("message topic", (SIGNAL_FUNC) sig_message_topic);
|
signal_remove("message topic", (SIGNAL_FUNC) sig_message_topic);
|
||||||
|
|
||||||
|
signal_remove("nicklist new", (SIGNAL_FUNC) sig_nicklist_new);
|
||||||
|
signal_remove("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove);
|
||||||
|
signal_remove("nicklist changed", (SIGNAL_FUNC) sig_nicklist_changed);
|
||||||
|
signal_remove("nicklist host changed", (SIGNAL_FUNC) sig_nicklist_new);
|
||||||
|
signal_remove("channel joined", (SIGNAL_FUNC) sig_channel_joined);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,8 @@ static void event_end_of_names(SERVER_REC *server, const char *data)
|
|||||||
|
|
||||||
chanrec = channel_find(server, channel);
|
chanrec = channel_find(server, channel);
|
||||||
if (chanrec != NULL && !chanrec->names_got) {
|
if (chanrec != NULL && !chanrec->names_got) {
|
||||||
chanrec->ownnick = nicklist_find(chanrec, server->nick);
|
nicklist_set_own(chanrec,
|
||||||
|
nicklist_find(chanrec, server->nick));
|
||||||
chanrec->chanop = chanrec->ownnick->op;
|
chanrec->chanop = chanrec->ownnick->op;
|
||||||
chanrec->names_got = TRUE;
|
chanrec->names_got = TRUE;
|
||||||
signal_emit("channel joined", 1, chanrec);
|
signal_emit("channel joined", 1, chanrec);
|
||||||
|
Loading…
Reference in New Issue
Block a user