#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;
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;
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, ...) {
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) {
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) {
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;
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");
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);
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);