class callerid_data
{
public:
+ typedef insp::flat_set<User*> UserSet;
+ typedef std::vector<callerid_data*> CallerIdDataSet;
+
time_t lastnotify;
/** Users I accept messages from
*/
- std::set<User*> accepting;
+ UserSet accepting;
/** Users who list me as accepted
*/
- std::list<callerid_data *> wholistsme;
+ CallerIdDataSet wholistsme;
callerid_data() : lastnotify(0) { }
{
std::ostringstream oss;
oss << lastnotify;
- for (std::set<User*>::const_iterator i = accepting.begin(); i != accepting.end(); ++i)
+ for (UserSet::const_iterator i = accepting.begin(); i != accepting.end(); ++i)
{
User* u = *i;
// Encode UIDs.
struct CallerIDExtInfo : public ExtensionItem
{
CallerIDExtInfo(Module* parent)
- : ExtensionItem("callerid_data", parent)
+ : ExtensionItem("callerid_data", ExtensionItem::EXT_USER, parent)
{
}
callerid_data* dat = static_cast<callerid_data*>(item);
// We need to walk the list of users on our accept list, and remove ourselves from their wholistsme.
- for (std::set<User *>::iterator it = dat->accepting.begin(); it != dat->accepting.end(); it++)
+ for (callerid_data::UserSet::iterator it = dat->accepting.begin(); it != dat->accepting.end(); ++it)
{
callerid_data *targ = this->get(*it, false);
continue; // shouldn't happen, but oh well.
}
- std::list<callerid_data*>::iterator it2 = std::find(targ->wholistsme.begin(), targ->wholistsme.end(), dat);
- if (it2 != targ->wholistsme.end())
- targ->wholistsme.erase(it2);
- else
+ if (!stdalgo::vector::swaperase(targ->wholistsme, dat))
ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (2)");
}
delete dat;
*/
typedef std::pair<User*, bool> ACCEPTAction;
- static ACCEPTAction GetTargetAndAction(std::string& tok)
+ static ACCEPTAction GetTargetAndAction(std::string& tok, User* cmdfrom = NULL)
{
bool remove = (tok[0] == '-');
if ((remove) || (tok[0] == '+'))
tok.erase(tok.begin());
- User* target = ServerInstance->FindNick(tok);
+ User* target;
+ if (!cmdfrom || !IS_LOCAL(cmdfrom))
+ target = ServerInstance->FindNick(tok);
+ else
+ target = ServerInstance->FindNickOnly(tok);
+
if ((!target) || (target->registered != REG_ALL) || (target->quitting) || (IS_SERVER(target)))
target = NULL;
extInfo(Creator)
{
allow_empty_last_param = false;
- syntax = "{[+|-]<nicks>}|*}";
+ syntax = "*|(+|-)<nick>[,(+|-)<nick> ...]";
TRANSLATE1(TR_CUSTOM);
}
}
std::string tok = parameters[0];
- ACCEPTAction action = GetTargetAndAction(tok);
+ ACCEPTAction action = GetTargetAndAction(tok, user);
if (!action.first)
{
user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", tok.c_str());
// Find the target
std::string targetstring = parameters[0];
- ACCEPTAction action = GetTargetAndAction(targetstring);
+ ACCEPTAction action = GetTargetAndAction(targetstring, user);
if (!action.first)
// Target is a "*" or source is local and the target is a list of nicks
return ROUTE_LOCALONLY;
callerid_data* dat = extInfo.get(user, false);
if (dat)
{
- for (std::set<User*>::iterator i = dat->accepting.begin(); i != dat->accepting.end(); ++i)
+ for (callerid_data::UserSet::iterator i = dat->accepting.begin(); i != dat->accepting.end(); ++i)
user->WriteNumeric(RPL_ACCEPTLIST, (*i)->nick);
}
user->WriteNumeric(RPL_ENDOFACCEPT, ":End of ACCEPT list");
user->WriteNumeric(ERR_ACCEPTNOT, "%s :is not on your accept list", whotoremove->nick.c_str());
return false;
}
- std::set<User*>::iterator i = dat->accepting.find(whotoremove);
- if (i == dat->accepting.end())
+ if (!dat->accepting.erase(whotoremove))
{
user->WriteNumeric(ERR_ACCEPTNOT, "%s :is not on your accept list", whotoremove->nick.c_str());
return false;
}
- dat->accepting.erase(i);
-
// Look up their list to remove me.
callerid_data *dat2 = extInfo.get(whotoremove, false);
if (!dat2)
return false;
}
- std::list<callerid_data*>::iterator it = std::find(dat2->wholistsme.begin(), dat2->wholistsme.end(), dat);
- if (it != dat2->wholistsme.end())
- // Found me!
- dat2->wholistsme.erase(it);
- else
+ if (!stdalgo::vector::swaperase(dat2->wholistsme, dat))
ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (4)");
return;
// Iterate over the list of people who accept me, and remove all entries
- for (std::list<callerid_data *>::iterator it = userdata->wholistsme.begin(); it != userdata->wholistsme.end(); it++)
+ for (callerid_data::CallerIdDataSet::iterator it = userdata->wholistsme.begin(); it != userdata->wholistsme.end(); ++it)
{
callerid_data *dat = *(it);
// Find me on their callerid list
- std::set<User *>::iterator it2 = dat->accepting.find(who);
-
- if (it2 != dat->accepting.end())
- dat->accepting.erase(it2);
- else
+ if (!dat->accepting.erase(who))
ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (5)");
}
tokens["CALLERID"] = "g";
}
- ModResult PreText(User* user, User* dest, std::string& text)
+ ModResult OnUserPreMessage(User* user, void* voiddest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE
{
+ if (!IS_LOCAL(user) || target_type != TYPE_USER)
+ return MOD_RES_PASSTHRU;
+
+ User* dest = static_cast<User*>(voiddest);
if (!dest->IsModeSet(myumode) || (user == dest))
return MOD_RES_PASSTHRU;
return MOD_RES_PASSTHRU;
callerid_data* dat = cmd.extInfo.get(dest, true);
- std::set<User*>::iterator i = dat->accepting.find(user);
-
- if (i == dat->accepting.end())
+ if (!dat->accepting.count(user))
{
time_t now = ServerInstance->Time();
/* +g and *not* accepted */
return MOD_RES_PASSTHRU;
}
- ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE
- {
- if (IS_LOCAL(user) && target_type == TYPE_USER)
- return PreText(user, (User*)dest, text);
-
- return MOD_RES_PASSTHRU;
- }
-
void OnUserPostNick(User* user, const std::string& oldnick) CXX11_OVERRIDE
{
if (!tracknick)
tracknick = tag->getBool("tracknick");
notify_cooldown = tag->getInt("cooldown", 60);
}
+
+ void Prioritize() CXX11_OVERRIDE
+ {
+ // Want to be after modules like silence or services_account
+ ServerInstance->Modules->SetPriority(this, I_OnUserPreMessage, PRIORITY_LAST);
+ }
};
MODULE_INIT(ModuleCallerID)