diff --git a/src/fe-common/core/fe-ignore-messages.c b/src/fe-common/core/fe-ignore-messages.c index 6bcfb6da..4f625dec 100644 --- a/src/fe-common/core/fe-ignore-messages.c +++ b/src/fe-common/core/fe-ignore-messages.c @@ -46,6 +46,13 @@ static void sig_message_join(SERVER_REC *server, const char *channel, signal_stop(); } +static void sig_message_host_changed(SERVER_REC *server, const char *nick, + const char *address, const char *old_address) +{ + if (ignore_check(server, nick, address, NULL, NULL, MSGLEVEL_JOINS)) + signal_stop(); +} + static void sig_message_part(SERVER_REC *server, const char *channel, const char *nick, const char *address, const char *reason) @@ -120,6 +127,7 @@ void fe_ignore_messages_init(void) signal_add_first("message public", (SIGNAL_FUNC) sig_message_public); signal_add_first("message private", (SIGNAL_FUNC) sig_message_private); signal_add_first("message join", (SIGNAL_FUNC) sig_message_join); + signal_add_first("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); signal_add_first("message part", (SIGNAL_FUNC) sig_message_part); signal_add_first("message quit", (SIGNAL_FUNC) sig_message_quit); signal_add_first("message kick", (SIGNAL_FUNC) sig_message_kick); @@ -135,6 +143,7 @@ void fe_ignore_messages_deinit(void) signal_remove("message public", (SIGNAL_FUNC) sig_message_public); signal_remove("message private", (SIGNAL_FUNC) sig_message_private); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); + signal_remove("message host_changed", (SIGNAL_FUNC) sig_message_host_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/fe-messages.c b/src/fe-common/core/fe-messages.c index 9545af73..17a81e56 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -451,6 +451,20 @@ static void spread_server_message_to_windows(SERVER_REC *server, gboolean once, g_string_free(chans, TRUE); } +static void sig_message_host_changed(SERVER_REC *server, const char *nick, + const char *address, const char *old_address) +{ + spread_server_message_to_windows( + server, + settings_get_bool("show_quit_once"), + TRUE, + MSGLEVEL_JOINS, + TXT_HOST_CHANGED, TXT_HOST_CHANGED, + nick, address, old_address, + NULL + ); +} + static void sig_message_quit(SERVER_REC *server, const char *nick, const char *address, const char *reason) { @@ -756,6 +770,7 @@ void fe_messages_init(void) signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); 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 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); @@ -783,6 +798,7 @@ void fe_messages_deinit(void) signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public); 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 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 83eae589..094246a1 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -95,6 +95,7 @@ FORMAT_REC fecommon_core_formats[] = { { NULL, "Channels", 0 }, { "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 } }, { "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 74a4dfd9..dc51e638 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -71,6 +71,7 @@ enum { TXT_FILL_3, TXT_JOIN, + TXT_HOST_CHANGED, 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 4608b949..a8aea027 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -126,6 +126,23 @@ 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) +{ + char *params, *user, *host, *new_addr; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &user, &host); + new_addr = g_strconcat(user, "@", host, NULL); + + signal_emit("message host_changed", 4, server, nick, new_addr, addr); + + g_free(new_addr); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -461,6 +478,7 @@ void fe_events_init(void) signal_add("ctcp action", (SIGNAL_FUNC) ctcp_action); 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 part", (SIGNAL_FUNC) event_part); signal_add("event quit", (SIGNAL_FUNC) event_quit); signal_add("event kick", (SIGNAL_FUNC) event_kick); @@ -491,6 +509,7 @@ void fe_events_deinit(void) signal_remove("ctcp action", (SIGNAL_FUNC) ctcp_action); 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 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 16095ed3..799b4441 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -238,6 +238,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SETNAME, TRUE); irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); + irc_cap_toggle(server, CAP_CHGHOST, 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 3fccfe9e..b709edab 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -21,6 +21,7 @@ #define CAP_SETNAME "draft/setname" #define CAP_INVITE_NOTIFY "invite-notify" #define CAP_AWAY_NOTIFY "away-notify" +#define CAP_CHGHOST "chghost" /* 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 4a3f085d..271ecddc 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -106,6 +106,30 @@ static void event_join(IRC_SERVER_REC *server, const char *data, chanrec->massjoins++; } +static void event_chghost(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *old_address) +{ + char *params, *user, *host, *address; + GSList *nicks, *tmp; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &user, &host); + + /* check that the nick isn't already in nicklist. seems to happen + sometimes (server desyncs or something?) */ + nicks = nicklist_get_same(SERVER(server), nick); + address = nicks != NULL ? g_strconcat(user, "@", host, NULL) : NULL; + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + nicklist_set_host(CHANNEL(tmp->data), rec, address); + } + g_free(address); + g_slist_free(nicks); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -291,6 +315,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 part", (SIGNAL_FUNC) event_part); signal_add("event kick", (SIGNAL_FUNC) event_kick); signal_add("event quit", (SIGNAL_FUNC) event_quit); @@ -302,6 +327,7 @@ void massjoin_deinit(void) g_source_remove(massjoin_tag); signal_remove("event join", (SIGNAL_FUNC) event_join); + signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event kick", (SIGNAL_FUNC) event_kick); signal_remove("event quit", (SIGNAL_FUNC) event_quit);