]> jfr.im git - irc/quakenet/newserv.git/blobdiff - nickwatch/nickwatch.c
Introduce a last activation property for nickwatches
[irc/quakenet/newserv.git] / nickwatch / nickwatch.c
index c3bfa110b96efab6fe4d1cc1326e35f000b5334f..e8a834ab68734519ba46ef367888a5f949afc2c8 100644 (file)
@@ -6,11 +6,14 @@
 #include "../newsearch/newsearch.h"
 #include "../newsearch/parser.h"
 
+#define NW_FORMAT_TIME "%d/%m/%y %H:%M GMT"
+
 typedef struct nickwatch {
   int id;
 
   char createdby[64];
   int hits;
+  time_t lastactive;
   char term[512];
   parsertree *tree;
 
@@ -33,12 +36,13 @@ static nickwatch *nw_currentwatch;
 static array nw_pendingnicks;
 
 static void nw_printnick(searchCtx *ctx, nick *sender, nick *np) {
-  char hostbuf[HOSTLEN+NICKLEN+USERLEN+4];
+  char hostbuf[HOSTLEN+NICKLEN+USERLEN+4], modebuf[34];
   char events[512];
   nickwatchevent *nwe = np->exts[nickwatchext];
   int len;
 
   nw_currentwatch->hits++;
+  nw_currentwatch->lastactive = time(NULL);
 
   events[0] = '\0';
   len = 0;
@@ -50,8 +54,10 @@ static void nw_printnick(searchCtx *ctx, nick *sender, nick *np) {
     len += snprintf(events + len, sizeof(events) - len, "%s", nwe->description);
   }
 
+  strncpy(modebuf, printflags(np->umodes, umodeflags), sizeof(modebuf));
+
   controlwall(NO_OPER, NL_HITS, "nickwatch(#%d, %s): %s [%s] (%s) (%s)", nw_currentwatch->id, events, visiblehostmask(np,hostbuf),
-               IPtostr(np->ipaddress), printflags(np->umodes, umodeflags), np->realname->name->content);
+               IPtostr(np->ipaddress), modebuf, np->realname->name->content);
 }
 
 static void nwe_enqueue(nick *np, const char *format, ...) {
@@ -85,21 +91,41 @@ static void nwe_clear(nick *np) {
 
 static void nw_sched_processevents(void *arg) {
   nickwatch *nw;
-  int i;
+  int i, slot;
+  unsigned int marker;
   nick *np;
+  array nicks;
 
-  for (nw = nickwatches; nw; nw = nw->next) {
-    nw_currentwatch = nw;
-    ast_nicksearch(nw->tree->root, &nw_dummyreply, mynick, &nw_dummywall, &nw_printnick, NULL, NULL, 10, &nw_pendingnicks);
-  }
+  array_init(&nicks, sizeof(nick *));
+  marker = nextnickmarker();
 
   for (i = 0; i < nw_pendingnicks.cursi; i++) {
     np = ((nick **)nw_pendingnicks.content)[i];
-    nwe_clear(np);
+
+    if (!np)
+      continue;
+
+    if (np->marker != marker) {
+      np->marker = marker;
+      slot = array_getfreeslot(&nicks);
+      ((nick **)nicks.content)[slot] = np;
+    }
   }
 
   array_free(&nw_pendingnicks);
   array_init(&nw_pendingnicks, sizeof(nick *));
+
+  for (nw = nickwatches; nw; nw = nw->next) {
+    nw_currentwatch = nw;
+    ast_nicksearch(nw->tree->root, &nw_dummyreply, mynick, &nw_dummywall, &nw_printnick, NULL, NULL, 10, &nicks);
+  }
+
+  for (i = 0; i < nicks.cursi; i++) {
+    np = ((nick **)nicks.content)[i];
+    nwe_clear(np);
+  }
+
+  array_free(&nicks);
 }
 
 static void nw_hook_newnick(int hooknum, void *arg) {
@@ -107,17 +133,20 @@ static void nw_hook_newnick(int hooknum, void *arg) {
   nwe_enqueue(np, "new user");
 }
 
+static void nw_hook_account(int hooknum, void *arg) {
+  nick *np = arg;
+  nwe_enqueue(np, "logged in with account %s", np->authname);
+}
+
 static void nw_hook_lostnick(int hooknum, void *arg) {
   nick *np = arg;
   int i;
 
   nwe_clear(np);
 
-  for (i = 0; i < nw_pendingnicks.cursi;)
+  for (i = 0; i < nw_pendingnicks.cursi; i++)
     if (((nick **)nw_pendingnicks.content)[i] == np)
-      array_delslot(&nw_pendingnicks, i);
-    else
-      i++;
+      ((nick **)nw_pendingnicks.content)[i] = NULL;
 }
 
 static void nw_hook_rename(int hooknum, void *arg) {
@@ -168,6 +197,7 @@ static int nw_cmd_nickwatch(void *source, int cargc, char **cargv) {
   nw->id = nextnickwatch++;
   snprintf(nw->createdby, sizeof(nw->createdby), "#%s", sender->authname);
   nw->hits = 0;
+  nw->lastactive = 0;
   strncpy(nw->term, cargv[0], sizeof(nw->term));
   nw->tree = parse_string(reg_nicksearch, cargv[0]);
   nw->next = nickwatches;
@@ -209,33 +239,23 @@ static int nw_cmd_nickunwatch(void *source, int cargc, char **cargv) {
 static int nw_cmd_nickwatches(void *source, int cargc, char **cargv) {
   nick *sender = source;
   nickwatch *nw;
+  char timebuf[20];
 
-  controlreply(sender, "ID    Created By      Hits    Term");
+  controlreply(sender, "ID    Created By      Hits    Last active        Term");
 
-  for (nw = nickwatches; nw; nw = nw->next)
-    controlreply(sender, "%-5d %-15s %-7d %s", nw->id, nw->createdby, nw->hits, nw->term);
+  for (nw = nickwatches; nw; nw = nw->next) {
+    if (nw->lastactive == 0)
+      strncpy(timebuf, "(never)", sizeof(timebuf));
+    else
+      strftime(timebuf, sizeof(timebuf), NW_FORMAT_TIME, gmtime(&nw->lastactive));
+    controlreply(sender, "%-5d %-15s %-7d %-18s %s", nw->id, nw->createdby, nw->hits, timebuf, nw->term);
+  }
 
   controlreply(sender, "--- End of nickwatches.");
 
   return CMD_OK;
 }
 
-static int nw_cmd_nickburst(void *source, int cargc, char **cargv) {
-  nick *sender = source;
-  int i;
-  char *pargv[1];
-
-  pargv[0] = "(and (match (nick) \"*gunnar*\"))";
-
-  for (i = 0; i < 100; i++)
-    nw_cmd_nickwatch(source, 1, pargv);
-
-  for (i = 0; i < 50000; i++)
-    nwe_enqueue(sender, "new user");
-
-  return CMD_OK;
-}
-
 void _init(void) {
   nickwatchext = registernickext("nickwatch");
 
@@ -244,9 +264,9 @@ void _init(void) {
   registercontrolhelpcmd("nickwatch", NO_OPER, 1, &nw_cmd_nickwatch, "Usage: nickwatch <nicksearch term>\nAdds a nickwatch entry.");
   registercontrolhelpcmd("nickunwatch", NO_OPER, 1, &nw_cmd_nickunwatch, "Usage: nickunwatch <#id>\nRemoves a nickwatch entry.");
   registercontrolhelpcmd("nickwatches", NO_OPER, 0, &nw_cmd_nickwatches, "Usage: nickwatches\nLists nickwatches.");
-  registercontrolhelpcmd("nickburst", NO_OPER, 0, &nw_cmd_nickburst, "Usage: nickwatches\nSimulates a burst.");
 
   registerhook(HOOK_NICK_NEWNICK, &nw_hook_newnick);
+  registerhook(HOOK_NICK_ACCOUNT, &nw_hook_account);
   registerhook(HOOK_NICK_LOSTNICK, &nw_hook_lostnick);
   registerhook(HOOK_NICK_RENAME, &nw_hook_rename);
   registerhook(HOOK_NICK_MODECHANGE, &nw_hook_umodechange);
@@ -263,9 +283,9 @@ void _fini(void) {
   deregistercontrolcmd("nickwatch", &nw_cmd_nickwatch);
   deregistercontrolcmd("nickunwatch", &nw_cmd_nickunwatch);
   deregistercontrolcmd("nickwatches", &nw_cmd_nickwatches);
-  deregistercontrolcmd("nickburst", &nw_cmd_nickburst);
 
   deregisterhook(HOOK_NICK_NEWNICK, &nw_hook_newnick);
+  deregisterhook(HOOK_NICK_ACCOUNT, &nw_hook_account);
   deregisterhook(HOOK_NICK_LOSTNICK, &nw_hook_lostnick);
   deregisterhook(HOOK_NICK_RENAME, &nw_hook_rename);
   deregisterhook(HOOK_NICK_MODECHANGE, &nw_hook_umodechange);