+ SimpleExtItem<watchlist> ext;
+ CmdResult remove_watch(User* user, const char* nick)
+ {
+ // removing an item from the list
+ if (!ServerInstance->IsNick(nick, ServerInstance->Config->Limits.NickMax))
+ {
+ user->WriteNumeric(942, "%s %s :Invalid nickname", user->nick.c_str(), nick);
+ return CMD_FAILURE;
+ }
+
+ watchlist* wl = ext.get(user);
+ if (wl)
+ {
+ /* Yup, is on my list */
+ watchlist::iterator n = wl->find(nick);
+
+ if (!wl)
+ return CMD_FAILURE;
+
+ if (n != wl->end())
+ {
+ if (!n->second.empty())
+ user->WriteNumeric(602, "%s %s %s :stopped watching", user->nick.c_str(), n->first.c_str(), n->second.c_str());
+ else
+ user->WriteNumeric(602, "%s %s * * 0 :stopped watching", user->nick.c_str(), nick);
+
+ wl->erase(n);
+ }
+
+ if (wl->empty())
+ {
+ ext.unset(user);
+ }
+
+ watchentries::iterator x = whos_watching_me->find(nick);
+ if (x != whos_watching_me->end())
+ {
+ /* People are watching this user, am i one of them? */
+ std::deque<User*>::iterator n2 = std::find(x->second.begin(), x->second.end(), user);
+ if (n2 != x->second.end())
+ /* I'm no longer watching you... */
+ x->second.erase(n2);
+
+ if (x->second.empty())
+ /* nobody else is, either. */
+ whos_watching_me->erase(nick);
+ }
+ }
+
+ return CMD_SUCCESS;
+ }
+
+ CmdResult add_watch(User* user, const char* nick)
+ {
+ if (!ServerInstance->IsNick(nick, ServerInstance->Config->Limits.NickMax))
+ {
+ user->WriteNumeric(942, "%s %s :Invalid nickname",user->nick.c_str(),nick);
+ return CMD_FAILURE;
+ }
+
+ watchlist* wl = ext.get(user);
+ if (!wl)
+ {
+ wl = new watchlist();
+ ext.set(user, wl);
+ }
+
+ if (wl->size() == MAX_WATCH)
+ {
+ user->WriteNumeric(512, "%s %s :Too many WATCH entries", user->nick.c_str(), nick);
+ return CMD_FAILURE;
+ }
+
+ watchlist::iterator n = wl->find(nick);
+ if (n == wl->end())
+ {
+ /* Don't already have the user on my watch list, proceed */
+ watchentries::iterator x = whos_watching_me->find(nick);
+ if (x != whos_watching_me->end())
+ {
+ /* People are watching this user, add myself */
+ x->second.push_back(user);
+ }
+ else
+ {
+ std::deque<User*> newlist;
+ newlist.push_back(user);
+ (*(whos_watching_me))[nick] = newlist;
+ }
+
+ User* target = ServerInstance->FindNick(nick);
+ if (target)
+ {
+ (*wl)[nick] = std::string(target->ident).append(" ").append(target->dhost).append(" ").append(ConvToStr(target->age));
+ user->WriteNumeric(604, "%s %s %s :is online",user->nick.c_str(), nick, (*wl)[nick].c_str());
+ if (IS_AWAY(target))
+ {
+ user->WriteNumeric(609, "%s %s %s %s %lu :is away", user->nick.c_str(), target->nick.c_str(), target->ident.c_str(), target->dhost.c_str(), (unsigned long) target->awaytime);
+ }
+ }
+ else
+ {
+ (*wl)[nick].clear();
+ user->WriteNumeric(605, "%s %s * * 0 :is offline",user->nick.c_str(), nick);
+ }
+ }
+
+ return CMD_SUCCESS;
+ }
+
+ CommandWatch(Module* parent, unsigned int &maxwatch) : Command(parent,"WATCH", 0), MAX_WATCH(maxwatch), ext("watchlist", parent)