diff --git a/src/core/nicklist.c b/src/core/nicklist.c index bf845c0d..528f2286 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -101,6 +101,14 @@ void nicklist_set_host(CHANNEL_REC *channel, NICK_REC *nick, const char *host) signal_emit("nicklist host changed", 2, channel, nick); } +void nicklist_set_account(CHANNEL_REC *channel, NICK_REC *nick, const char *account) +{ + g_free(nick->account); + nick->account = g_strdup(account); + + signal_emit("nicklist account changed", 2, channel, nick); +} + static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick) { signal_emit("nicklist remove", 2, channel, nick); diff --git a/src/core/nicklist.h b/src/core/nicklist.h index 62afa5ff..7999be0a 100644 --- a/src/core/nicklist.h +++ b/src/core/nicklist.h @@ -18,6 +18,7 @@ struct _NICK_REC { void nicklist_insert(CHANNEL_REC *channel, NICK_REC *nick); /* Set host address for nick */ void nicklist_set_host(CHANNEL_REC *channel, NICK_REC *nick, const char *host); +void nicklist_set_account(CHANNEL_REC *channel, NICK_REC *nick, const char *account); /* Remove nick from list */ void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick); /* Change nick */ diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 17a81e56..3d8651f9 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -465,6 +465,29 @@ static void sig_message_host_changed(SERVER_REC *server, const char *nick, ); } +static void sig_message_account_changed(SERVER_REC *server, const char *nick, + const char *address, const char *account) +{ + gboolean logged_in; + int txt; + + if (!settings_get_bool("show_account_notify")) + return; + + logged_in = g_strcmp0("*", account) != 0; + txt = logged_in ? TXT_LOGGED_IN : TXT_LOGGED_OUT; + + spread_server_message_to_windows( + server, + settings_get_bool("show_quit_once"), + TRUE, + MSGLEVEL_MODES, + txt, txt, + nick, address, account, + "account" + ); +} + static void sig_message_quit(SERVER_REC *server, const char *nick, const char *address, const char *reason) { @@ -764,6 +787,7 @@ void fe_messages_init(void) settings_add_bool("lookandfeel", "show_quit_once", FALSE); settings_add_bool("lookandfeel", "show_own_nickchange_once", FALSE); settings_add_bool("lookandfeel", "away_notify_public", FALSE); + settings_add_bool("lookandfeel", "show_account_notify", FALSE); signal_add_last("message public", (SIGNAL_FUNC) sig_message_public); signal_add_last("message private", (SIGNAL_FUNC) sig_message_private); @@ -771,6 +795,7 @@ void fe_messages_init(void) signal_add_last("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_add_last("message join", (SIGNAL_FUNC) sig_message_join); signal_add_last("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); + signal_add_last("message account_changed", (SIGNAL_FUNC) sig_message_account_changed); signal_add_last("message part", (SIGNAL_FUNC) sig_message_part); signal_add_last("message quit", (SIGNAL_FUNC) sig_message_quit); signal_add_last("message kick", (SIGNAL_FUNC) sig_message_kick); @@ -799,6 +824,7 @@ void fe_messages_deinit(void) signal_remove("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); signal_remove("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); + signal_remove("message account_changed", (SIGNAL_FUNC) sig_message_account_changed); signal_remove("message part", (SIGNAL_FUNC) sig_message_part); signal_remove("message quit", (SIGNAL_FUNC) sig_message_quit); signal_remove("message kick", (SIGNAL_FUNC) sig_message_kick); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 094246a1..a5e99619 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -96,6 +96,8 @@ FORMAT_REC fecommon_core_formats[] = { { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} has changed host", 4, { 0, 0, 0, 0 } }, + { "logged_out", "{channick $0} {chanhost $1} has logged out of their account", 4, { 0, 0, 0, 0 } }, + { "logged_in", "{channick_hilight $0} {chanhost_hilight $1} has logged in to account {hilight $2}", 4, { 0, 0, 0, 0 } }, { "part", "{channick $0} {chanhost $1} has left {channel $2} {reason $3}", 4, { 0, 0, 0, 0 } }, { "kick", "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}", 5, { 0, 0, 0, 0, 0 } }, { "quit", "{channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index dc51e638..b1cf1578 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -72,6 +72,8 @@ enum { TXT_JOIN, TXT_HOST_CHANGED, + TXT_LOGGED_OUT, + TXT_LOGGED_IN, TXT_PART, TXT_KICK, TXT_QUIT, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index a8aea027..b6b3e75a 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -126,7 +126,6 @@ static void event_join(IRC_SERVER_REC *server, const char *data, g_free(params); } - static void event_chghost(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -143,6 +142,20 @@ static void event_chghost(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_account(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *account; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &account); + + signal_emit("message account_changed", 4, server, nick, addr, account); + + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -479,6 +492,7 @@ void fe_events_init(void) signal_add("event notice", (SIGNAL_FUNC) event_notice); signal_add("event join", (SIGNAL_FUNC) event_join); signal_add("event chghost", (SIGNAL_FUNC) event_chghost); + signal_add("event account", (SIGNAL_FUNC) event_account); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event quit", (SIGNAL_FUNC) event_quit); signal_add("event kick", (SIGNAL_FUNC) event_kick); @@ -510,6 +524,7 @@ void fe_events_deinit(void) signal_remove("event notice", (SIGNAL_FUNC) event_notice); signal_remove("event join", (SIGNAL_FUNC) event_join); signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); + signal_remove("event account", (SIGNAL_FUNC) event_account); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event quit", (SIGNAL_FUNC) event_quit); signal_remove("event kick", (SIGNAL_FUNC) event_kick); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 799b4441..a066113f 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -239,6 +239,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); irc_cap_toggle(server, CAP_CHGHOST, TRUE); + irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index b709edab..1a6f9595 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -22,6 +22,7 @@ #define CAP_INVITE_NOTIFY "invite-notify" #define CAP_AWAY_NOTIFY "away-notify" #define CAP_CHGHOST "chghost" +#define CAP_ACCOUNT_NOTIFY "account-notify" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 271ecddc..52b0e86a 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -68,8 +68,7 @@ static void event_join(IRC_SERVER_REC *server, const char *data, /* add user to nicklist */ nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, TRUE, NULL); if (*account != '\0' && g_strcmp0(nickrec->account, account) != 0) { - g_free(nickrec->account); - nickrec->account = g_strdup(account); + nicklist_set_account(CHANNEL(chanrec), nickrec, account); } nicklist_set_host(CHANNEL(chanrec), nickrec, address); @@ -130,6 +129,25 @@ static void event_chghost(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_account(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *address) +{ + char *params, *account; + GSList *nicks, *tmp; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &account); + nicks = nicklist_get_same(SERVER(server), nick); + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + nicklist_set_account(CHANNEL(tmp->data), rec, account); + } + g_slist_free(nicks); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -316,6 +334,7 @@ void massjoin_init(void) read_settings(); signal_add_first("event join", (SIGNAL_FUNC) event_join); signal_add("event chghost", (SIGNAL_FUNC) event_chghost); + signal_add("event account", (SIGNAL_FUNC) event_account); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event kick", (SIGNAL_FUNC) event_kick); signal_add("event quit", (SIGNAL_FUNC) event_quit); @@ -328,6 +347,7 @@ void massjoin_deinit(void) signal_remove("event join", (SIGNAL_FUNC) event_join); signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); + signal_remove("event account", (SIGNAL_FUNC) event_account); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event kick", (SIGNAL_FUNC) event_kick); signal_remove("event quit", (SIGNAL_FUNC) event_quit);