From 555a2bf929e6a76609fc06f97de47a731d511f95 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 25 May 2000 16:40:25 +0000 Subject: Print nicks who quit IRC in netsplit message. See netsplit section in docs/manual.txt for more information. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@241 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- docs/manual.txt | 9 +- src/fe-common/irc/fe-netsplit.c | 165 ++++++++++++++++++++++++++++++++++++- src/fe-common/irc/module-formats.c | 3 +- src/fe-common/irc/module-formats.h | 1 + src/irc/core/netsplit.c | 7 +- src/irc/core/netsplit.h | 3 + 6 files changed, 182 insertions(+), 6 deletions(-) diff --git a/docs/manual.txt b/docs/manual.txt index 90cacac4..f51d3cf7 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -487,9 +487,12 @@ he/she/it is just some user that already had ops before the net split. - /SET hide_netsplit_quits - If ON, when detected net splits, display - only "Net split host1 host" message and hide all the quit - messages + /SET hide_netsplit_quits - If ON, hide all netsplit quit messages + and display only "Netsplit host1 host2: nicks". + + /SET netsplit_max_nicks - If non-zero, limit the number of nicks + printed in netsplit message and add "(+ more, use /NETSPLIT + to show all of them)" text. 5.9 Lag checking diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 43a4f1e0..83db043f 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -22,13 +22,163 @@ #include "module-formats.h" #include "signals.h" #include "commands.h" +#include "settings.h" #include "levels.h" #include "netsplit.h" +#define SPLIT_WAIT_TIME 2 /* how many seconds to wait for the QUIT split messages to stop */ + +static int split_tag; +static int netsplit_max_nicks; + +static int get_last_split(IRC_SERVER_REC *server) +{ + GSList *tmp; + time_t last; + + last = 0; + for (tmp = server->split_servers; tmp != NULL; tmp = tmp->next) { + NETSPLIT_SERVER_REC *rec = tmp->data; + + if (rec->last > last) last = rec->last; + } + + return last; +} + +typedef struct { + char *name; + int nick_count; + GString *nicks; +} TEMP_SPLIT_CHAN_REC; + +typedef struct { + NETSPLIT_SERVER_REC *server; + GSList *channels; +} TEMP_SPLIT_REC; + +static TEMP_SPLIT_CHAN_REC *find_split_chan(TEMP_SPLIT_REC *rec, const char *name) +{ + GSList *tmp; + + for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) { + TEMP_SPLIT_CHAN_REC *chanrec = tmp->data; + + if (g_strcasecmp(chanrec->name, name) == 0) + return chanrec; + } + + return NULL; +} + +static void get_server_splits(void *key, NETSPLIT_REC *split, TEMP_SPLIT_REC *rec) +{ + TEMP_SPLIT_CHAN_REC *chanrec; + GSList *tmp; + + if (split->printed || split->server != rec->server) + return; + + split->printed = TRUE; + for (tmp = split->channels; tmp != NULL; tmp = tmp->next) { + NETSPLIT_CHAN_REC *splitchan = tmp->data; + + chanrec = find_split_chan(rec, splitchan->name); + if (chanrec == NULL) { + chanrec = g_new0(TEMP_SPLIT_CHAN_REC, 1); + chanrec->name = splitchan->name; + chanrec->nicks = g_string_new(NULL); + } + + chanrec->nick_count++; + if (netsplit_max_nicks <= 0 || + chanrec->nick_count < netsplit_max_nicks) + g_string_sprintfa(chanrec->nicks, "%s ", split->nick); + } +} + +static void print_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec) +{ + GSList *tmp; + + for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) { + TEMP_SPLIT_CHAN_REC *chan = tmp->data; + + g_string_truncate(chan->nicks, chan->nicks->len-1); + + if (netsplit_max_nicks > 0 && chan->nick_count > netsplit_max_nicks) { + printformat(server, chan->name, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETSPLIT_MORE, + rec->server->server, rec->server->destserver, chan->nicks->str, + chan->nick_count - netsplit_max_nicks); + } else { + printformat(server, chan->name, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETSPLIT, + rec->server->server, rec->server->destserver, chan->nicks->str); + } + } +} + +static void temp_split_chan_free(TEMP_SPLIT_CHAN_REC *rec) +{ + g_string_free(rec->nicks, TRUE); + g_free(rec); +} + +static int check_server_splits(IRC_SERVER_REC *server) +{ + TEMP_SPLIT_REC rec; + GSList *tmp; + time_t last; + + last = get_last_split(server); + if (last+SPLIT_WAIT_TIME >= time(NULL)) + return FALSE; + + for (tmp = server->split_servers; tmp != NULL; tmp = tmp->next) { + NETSPLIT_SERVER_REC *sserver = tmp->data; + + rec.server = sserver; + rec.channels = NULL; + + g_hash_table_foreach(server->splits, (GHFunc) get_server_splits, &rec); + print_splits(server, &rec); + + g_slist_foreach(rec.channels, (GFunc) temp_split_chan_free, NULL); + g_slist_free(rec.channels); + } + + return TRUE; +} + +static int sig_check_splits(void) +{ + GSList *tmp; + int stop; + + stop = TRUE; + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + if (rec->split_servers != NULL) { + if (check_server_splits(rec)) + stop = FALSE; + } + } + + if (stop) { + g_source_remove(split_tag); + split_tag = -1; + } + return 1; +} + static void sig_netsplit_servers(IRC_SERVER_REC *server, NETSPLIT_SERVER_REC *rec) { - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETSPLIT, rec->server, rec->destserver, server->tag); + if (!settings_get_bool("hide_netsplit_quits")) + return; + + if (split_tag != -1) + split_tag = g_timeout_add(1000, (GSourceFunc) sig_check_splits, NULL); } static void split_print(const char *nick, NETSPLIT_REC *rec) @@ -56,14 +206,27 @@ static void cmd_netsplit(const char *data, IRC_SERVER_REC *server) printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_FOOTER); } +static void read_settings(void) +{ + netsplit_max_nicks = settings_get_int("netsplit_max_nicks"); +} + void fe_netsplit_init(void) { + settings_add_int("misc", "netsplit_max_nicks", 10); + split_tag = -1; + + read_settings(); signal_add("netsplit new server", (SIGNAL_FUNC) sig_netsplit_servers); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); command_bind("netsplit", NULL, (SIGNAL_FUNC) cmd_netsplit); } void fe_netsplit_deinit(void) { + if (split_tag != -1) g_source_remove(split_tag); + signal_remove("netsplit new server", (SIGNAL_FUNC) sig_netsplit_servers); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_unbind("netsplit", (SIGNAL_FUNC) cmd_netsplit); } diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index 0d3f1529..f09f50a4 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -41,7 +41,8 @@ FORMAT_REC fecommon_irc_formats[] = { { "setupserver_header", "Server Port IRC Net Settings", 0 }, { "setupserver_line", "%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } }, { "setupserver_footer", "", 0 }, - { "netsplit", "%RNetsplit%n detected between servers %_$0%_ and %_$1%_%:Use /NETSPLIT to see who left", 2, { 0, 0 } }, + { "netsplit", "%RNetsplit%n %_$0%_ %_$1%_ quits: $2", 3, { 0, 0, 0 } }, + { "netsplit_more", "%RNetsplit%n %_$0%_ %_$1%_ quits: $2 (+$3 more, use /NETSPLIT to show all of them)", 4, { 0, 0, 0, 1 } }, { "no_netsplits", "There are no net splits", 0 }, { "netsplits_header", "Nick Channel Server Splitted server", 0 }, { "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index b811a2de..56521f47 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -20,6 +20,7 @@ enum { IRCTXT_SETUPSERVER_LINE, IRCTXT_SETUPSERVER_FOOTER, IRCTXT_NETSPLIT, + IRCTXT_NETSPLIT_MORE, IRCTXT_NO_NETSPLITS, IRCTXT_NETSPLITS_HEADER, IRCTXT_NETSPLITS_LINE, diff --git a/src/irc/core/netsplit.c b/src/irc/core/netsplit.c index e6bb199c..34c478cf 100644 --- a/src/irc/core/netsplit.c +++ b/src/irc/core/netsplit.c @@ -49,14 +49,19 @@ static NETSPLIT_SERVER_REC *netsplit_server_create(IRC_SERVER_REC *server, const NETSPLIT_SERVER_REC *rec; rec = netsplit_server_find(server, servername, destserver); - if (rec != NULL) return rec; + if (rec != NULL) { + rec->last = time(NULL); + return rec; + } rec = g_new0(NETSPLIT_SERVER_REC, 1); + rec->last = time(NULL); rec->server = g_strdup(servername); rec->destserver = g_strdup(destserver); server->split_servers = g_slist_append(server->split_servers, rec); signal_emit("netsplit new server", 2, server, rec); + return rec; } diff --git a/src/irc/core/netsplit.h b/src/irc/core/netsplit.h index c95b5c6f..6ea9cf3f 100644 --- a/src/irc/core/netsplit.h +++ b/src/irc/core/netsplit.h @@ -7,6 +7,8 @@ typedef struct { char *server; char *destserver; int count; + + time_t last; /* last time we received a QUIT msg here */ } NETSPLIT_SERVER_REC; typedef struct { @@ -16,6 +18,7 @@ typedef struct { char *address; GSList *channels; + int printed:1; time_t destroy; } NETSPLIT_REC; -- cgit v1.2.3