diff --git a/Changes b/Changes index b92892b38..b61194571 100644 --- a/Changes +++ b/Changes @@ -1392,3 +1392,6 @@ see #0003084. - Fixed a couple of add_Command/del_Command lines in m_chgname and m_helpop trying to add the same token twice. Didn't cause any trouble, normally, though... +- Committed watch away notification, I did this more than a month ago but can't be bothered + to document it right now, just want to get it off my cvs queue ;P. + Syntax is 'WATCH A +TestUser' to have someone with away notification on your watchlist. diff --git a/include/h.h b/include/h.h index 02ca8aed8..05801bfae 100644 --- a/include/h.h +++ b/include/h.h @@ -391,7 +391,7 @@ extern int add_to_client_hash_table(char *, aClient *); extern int del_from_client_hash_table(char *, aClient *); extern int add_to_channel_hash_table(char *, aChannel *); extern int del_from_channel_hash_table(char *, aChannel *); -extern int add_to_watch_hash_table(char *, aClient *); +extern int add_to_watch_hash_table(char *, aClient *, int); extern int del_from_watch_hash_table(char *, aClient *); extern int hash_check_watch(aClient *, int); extern int hash_del_watch_list(aClient *); diff --git a/include/numeric.h b/include/numeric.h index f058740d0..9498ba8c6 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -336,6 +336,8 @@ * These are also in the range 600-799. */ +#define RPL_GONEAWAY 598 +#define RPL_NOTAWAY 599 #define RPL_LOGON 600 #define RPL_LOGOFF 601 #define RPL_WATCHOFF 602 @@ -344,6 +346,8 @@ #define RPL_NOWOFF 605 #define RPL_WATCHLIST 606 #define RPL_ENDOFWATCHLIST 607 +#define RPL_CLEARWATCH 608 +#define RPL_NOWISAWAY 609 #define RPL_DCCSTATUS 617 #define RPL_DCCLIST 618 diff --git a/include/struct.h b/include/struct.h index aeb5b4697..f9b8e3d20 100644 --- a/include/struct.h +++ b/include/struct.h @@ -774,6 +774,7 @@ struct User { #ifdef JOINTHROTTLE aJFlood *jflood; #endif + TS lastaway; }; struct Server { diff --git a/src/api-isupport.c b/src/api-isupport.c index a51602797..eb9668f61 100644 --- a/src/api-isupport.c +++ b/src/api-isupport.c @@ -132,6 +132,7 @@ void isupport_init(void) IsupportAdd(NULL, "CHANTYPES", "#"); IsupportAdd(NULL, "MODES", my_itoa(MAXMODEPARAMS)); IsupportAdd(NULL, "SILENCE", my_itoa(SILENCE_LIMIT)); + IsupportAdd(NULL, "WATCHOPTS", "A"); IsupportAdd(NULL, "WATCH", my_itoa(MAXWATCH)); IsupportAdd(NULL, "WALLCHOPS", NULL); IsupportAdd(NULL, "MAXTARGETS", my_itoa(MAXTARGETS)); diff --git a/src/hash.c b/src/hash.c index a54d07072..119c12ddd 100644 --- a/src/hash.c +++ b/src/hash.c @@ -480,7 +480,7 @@ void clear_watch_hash_table(void) /* * add_to_watch_hash_table */ -int add_to_watch_hash_table(char *nick, aClient *cptr) +int add_to_watch_hash_table(char *nick, aClient *cptr, int awaynotify) { unsigned int hashv; aWatch *anptr; @@ -516,11 +516,13 @@ int add_to_watch_hash_table(char *nick, aClient *cptr) lp = anptr->watch; anptr->watch = make_link(); anptr->watch->value.cptr = cptr; + anptr->watch->flags = awaynotify; anptr->watch->next = lp; lp = make_link(); lp->next = cptr->watch; lp->value.wptr = anptr; + lp->flags = awaynotify; cptr->watch = lp; cptr->watches++; } @@ -536,6 +538,10 @@ int hash_check_watch(aClient *cptr, int reply) unsigned int hashv; aWatch *anptr; Link *lp; + int awaynotify = 0; + + if ((reply == RPL_GONEAWAY) || (reply == RPL_NOTAWAY)) + awaynotify = 1; /* Get us the right bucket */ @@ -554,22 +560,48 @@ int hash_check_watch(aClient *cptr, int reply) /* Send notifies out to everybody on the list in header */ for (lp = anptr->watch; lp; lp = lp->next) { - if (IsWebTV(lp->value.cptr)) - sendto_one(lp->value.cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) " - " %s IRC", - me.name, lp->value.cptr->name, cptr->name, - (IsPerson(cptr) ? cptr->user->username : ""), - (IsPerson(cptr) ? - (IsHidden(cptr) ? cptr->user->virthost : cptr-> - user->realhost) : ""), reply == RPL_LOGON ? - "is now on" : "has left"); - else - sendto_one(lp->value.cptr, rpl_str(reply), me.name, - lp->value.cptr->name, cptr->name, - (IsPerson(cptr) ? cptr->user->username : ""), - (IsPerson(cptr) ? - (IsHidden(cptr) ? cptr->user->virthost : cptr-> - user->realhost) : ""), anptr->lasttime, cptr->info); + if (!awaynotify) + { + /* Most common: LOGON or LOGOFF */ + if (IsWebTV(lp->value.cptr)) + sendto_one(lp->value.cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) " + " %s IRC", + me.name, lp->value.cptr->name, cptr->name, + (IsPerson(cptr) ? cptr->user->username : ""), + (IsPerson(cptr) ? + (IsHidden(cptr) ? cptr->user->virthost : cptr-> + user->realhost) : ""), reply == RPL_LOGON ? + "is now on" : "has left"); + else + sendto_one(lp->value.cptr, rpl_str(reply), me.name, + lp->value.cptr->name, cptr->name, + (IsPerson(cptr) ? cptr->user->username : ""), + (IsPerson(cptr) ? + (IsHidden(cptr) ? cptr->user->virthost : cptr-> + user->realhost) : ""), anptr->lasttime, cptr->info); + } else + { + /* AWAY or UNAWAY */ + if (!lp->flags) + continue; /* skip away/unaway notification for users not interested in them */ + + if (IsWebTV(lp->value.cptr)) + sendto_one(lp->value.cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) " + " %s IRC", + me.name, lp->value.cptr->name, cptr->name, + (IsPerson(cptr) ? cptr->user->username : ""), + (IsPerson(cptr) ? + (IsHidden(cptr) ? cptr->user->virthost : cptr-> + user->realhost) : ""), reply == RPL_GONEAWAY ? + "is now away" : "is no longer away"); + else + sendto_one(lp->value.cptr, rpl_str(reply), me.name, + lp->value.cptr->name, cptr->name, + (IsPerson(cptr) ? cptr->user->username : ""), + (IsPerson(cptr) ? + (IsHidden(cptr) ? cptr->user->virthost : cptr-> + user->realhost) : ""), cptr->user->lastaway, cptr->info); + } } return 0; diff --git a/src/modules/m_away.c b/src/modules/m_away.c index d859d7a10..c29cb2e40 100644 --- a/src/modules/m_away.c +++ b/src/modules/m_away.c @@ -115,6 +115,7 @@ int n; sptr->user->away = NULL; /* Only send this if they were actually away -- codemastr */ sendto_serv_butone_token(cptr, parv[0], MSG_AWAY, TOK_AWAY, ""); + hash_check_watch(cptr, RPL_NOTAWAY); } /* hope this works XX */ if (MyConnect(sptr)) @@ -151,17 +152,19 @@ int n; if (strcmp(away, parv[1]) == 0) return 0; - sendto_serv_butone_token(cptr, parv[0], MSG_AWAY, TOK_AWAY, ":%s", - awy2); + sptr->user->lastaway = TStime(); + + sendto_serv_butone_token(cptr, parv[0], MSG_AWAY, TOK_AWAY, ":%s", awy2); - if (away) - away = (char *)MyRealloc(away, strlen(awy2) + 1); - else - away = (char *)MyMalloc(strlen(awy2) + 1); + if (away) + MyFree(away); + + away = sptr->user->away = strdup(awy2); - sptr->user->away = away; - (void)strcpy(away, awy2); if (MyConnect(sptr)) sendto_one(sptr, rpl_str(RPL_NOWAWAY), me.name, parv[0]); + + hash_check_watch(cptr, RPL_GONEAWAY); + return 0; } diff --git a/src/modules/m_watch.c b/src/modules/m_watch.c index 07c2f76fb..65c2c3381 100644 --- a/src/modules/m_watch.c +++ b/src/modules/m_watch.c @@ -81,13 +81,28 @@ DLLFUNC int MOD_UNLOAD(m_watch)(int module_unload) * RPL_WATCHOFF - Succesfully removed from WATCH-list. * ERR_TOOMANYWATCH - Take a guess :> Too many WATCH entries. */ -static void show_watch(aClient *cptr, char *name, int rpl1, int rpl2) +static void show_watch(aClient *cptr, char *name, int rpl1, int rpl2, int awaynotify) { aClient *acptr; if ((acptr = find_person(name, NULL))) { + if (awaynotify && acptr->user->away) + { + if (IsWebTV(cptr)) + sendto_one(cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) is on IRC, but away", + me.name, cptr->name, acptr->name, acptr->user->username, + IsHidden(acptr) ? acptr->user->virthost : acptr->user-> + realhost); + else + sendto_one(cptr, rpl_str(RPL_NOWISAWAY), me.name, cptr->name, + acptr->name, acptr->user->username, + IsHidden(acptr) ? acptr->user->virthost : acptr->user-> + realhost, acptr->user->lastaway); + return; + } + if (IsWebTV(cptr)) sendto_one(cptr, ":IRC!IRC@%s PRIVMSG %s :%s (%s@%s) is on IRC", me.name, cptr->name, acptr->name, acptr->user->username, @@ -120,7 +135,7 @@ DLLFUNC CMD_FUNC(m_watch) aClient *acptr; char *s, **pav = parv, *user; char *p = NULL, *def = "l"; - + int awaynotify = 0; if (parc < 2) @@ -137,6 +152,9 @@ DLLFUNC CMD_FUNC(m_watch) { if ((user = (char *)index(s, '!'))) *user++ = '\0'; /* Not used */ + + if (!strcmp(s, "A")) + awaynotify = 1; /* * Prefix of "+", they want to add a name to their WATCH @@ -157,10 +175,10 @@ DLLFUNC CMD_FUNC(m_watch) continue; } - add_to_watch_hash_table(s + 1, sptr); + add_to_watch_hash_table(s + 1, sptr, awaynotify); } - show_watch(sptr, s + 1, RPL_NOWON, RPL_NOWOFF); + show_watch(sptr, s + 1, RPL_NOWON, RPL_NOWOFF, awaynotify); continue; } @@ -173,7 +191,7 @@ DLLFUNC CMD_FUNC(m_watch) if (!*(s+1)) continue; del_from_watch_hash_table(s + 1, sptr); - show_watch(sptr, s + 1, RPL_WATCHOFF, RPL_WATCHOFF); + show_watch(sptr, s + 1, RPL_WATCHOFF, RPL_WATCHOFF, 0); continue; } diff --git a/src/s_err.c b/src/s_err.c index e0211ff63..b62b8c610 100644 --- a/src/s_err.c +++ b/src/s_err.c @@ -654,8 +654,8 @@ static char *replies[] = { /* 595 */ NULL, /* 596 */ NULL, /* 597 */ NULL, -/* 598 */ NULL, -/* 599 */ NULL, +/* 598 RPL_GONEAWAY */ ":%s 598 %s %s %s %s %d :is now away", +/* 599 RPL_NOTAWAY */ ":%s 599 %s %s %s %s %d :is no longer away", /* 600 RPL_LOGON */ ":%s 600 %s %s %s %s %d :logged online", /* 601 RPL_LOGOFF */ ":%s 601 %s %s %s %s %d :logged offline", /* 602 RPL_WATCHOFF */ ":%s 602 %s %s %s %s %d :stopped watching", @@ -664,8 +664,8 @@ static char *replies[] = { /* 605 RPL_NOWOFF */ ":%s 605 %s %s %s %s %ld :is offline", /* 606 RPL_WATCHLIST */ ":%s 606 %s :%s", /* 607 RPL_ENDOFWATCHLIST */ ":%s 607 %s :End of WATCH %c", -/* 608 */ NULL, -/* 609 */ NULL, +/* 608 RPL_CLEARWATCH */ ":%s 607 %s :Your WATCH list is now empty", +/* 609 RPL_NOWISAWAY */ ":%s 604 %s %s %s %s %ld :is away", /* 610 RPL_MAPMORE */ ":%s 610 %s :%s%-*s --> *more*", /* 611 */ NULL, /* ultimate */ /* 612 */ NULL, /* ultimate */