From 61906329ccbe96c25c75533f819dea269492f5a7 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 16 Jun 2019 23:16:18 +0100 Subject: Implement two new auto replay modes: - replaymode = "noclients": All messages since the bouncer last had no clients connected - replaymode = "lastchange": All messages since the last client connect or disconnect --- functions.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'functions.c') diff --git a/functions.c b/functions.c index 3aa474f..edb77e7 100644 --- a/functions.c +++ b/functions.c @@ -550,6 +550,10 @@ int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].fd == fd) { debugprint(DEBUG_FULL, "found and clearing fd %d from clients[%d]\n", fd, i); + // If the client was registered, record the time of the last client disconnect + if (clients[i].registered) { + ircdstate->clientchangetime = time(NULL); + } clients[i].fd = 0; clients[i].authed = 0; clients[i].registered = 0; @@ -569,6 +573,10 @@ int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate close(fd); // Now clients array is cleared, inform all other clients (source "0" since we trust this message) sendtoallclients(clients, alertmsg, 0, settings); + // If there are now no clients connected, record the time + if (numclients(clients) == 0) { + ircdstate->clientsnonetime = time(NULL); + } return 1; } } @@ -858,7 +866,7 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings return 1; } - // If replaymode = "lastspoke" then send whatever replayseconds is set to + // If replaymode = "lastspoke" then send whatever happened since the user's current nick last spoke if (!strncmp(settings->replaymode, "lastspoke", strlen("lastspoke"))) { debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastspoke\".\n", settings->replayseconds); int secondsago = lastspokesecondsago(ircdstate->ircnick, settings->basedir); @@ -874,6 +882,24 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings return 1; } + // If replaymode = "noclients" and there is currently only one client connected, then send whatever happened since there were last no clients connected + if (!strncmp(settings->replaymode, "noclients", strlen("noclients")) && numclients(clients) == 1) { + debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"noclients\", sending '%d' seconds of replay.\n", time(NULL) - ircdstate->clientsnonetime); + if (!doreplay(sourcefd, time(NULL) - ircdstate->clientsnonetime, clients, settings, ircdstate, channels)) { + debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n"); + return 0; + } + } + + // If replaymode = "lastchange" then send whatever happened since the last client registration or disconnection + if (!strncmp(settings->replaymode, "lastchange", strlen("lastchange"))) { + debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastchange\", sending '%d' seconds of replay.\n", time(NULL) - ircdstate->clientchangetime); + if (!doreplay(sourcefd, time(NULL) - ircdstate->clientchangetime, clients, settings, ircdstate, channels)) { + debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n"); + return 0; + } + } + // We shouldn't get here return 0; } @@ -1046,9 +1072,10 @@ int rehash(struct settings *settings, char *failuremsg) { strcpy(failuremsg, "error getting 'replaymode' from configuration file"); return 0; } else { - if (strcmp(settings->replaymode, "none") && strcmp(settings->replaymode, "time") && strcmp(settings->replaymode, "lastspoke")) { + if (strcmp(settings->replaymode, "none") && strcmp(settings->replaymode, "time") && strcmp(settings->replaymode, "lastspoke") && + strcmp(settings->replaymode, "noclients") && strcmp(settings->replaymode, "lastchange")) { strcpy(settings->replaymode, oldreplaymode); - strcpy(failuremsg, "replaymode in configuration file must be one of \"none\", \"time\", or \"lastspoke\""); + strcpy(failuremsg, "replaymode in configuration file must be one of \"none\", \"time\", \"lastspoke\", \"noclients\", or \"lastchange\""); return 0; } } -- cgit v1.2.3