ModResult Module::OnPreTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPreTopicChange); return MOD_RES_PASSTHRU; }
void Module::OnEvent(Event&) { DetachEvent(I_OnEvent); }
ModResult Module::OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype) { DetachEvent(I_OnPassCompare); return MOD_RES_PASSTHRU; }
-void Module::OnGlobalOper(User*) { DetachEvent(I_OnGlobalOper); }
void Module::OnPostConnect(User*) { DetachEvent(I_OnPostConnect); }
void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&, MessageType) { DetachEvent(I_OnUserMessage); }
void Module::OnUserInvite(User*, User*, Channel*, time_t) { DetachEvent(I_OnUserInvite); }
}
dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name)
- : name(Name), value(NULL), creator(Creator)
+ : name(Name), hook(NULL), value(NULL), creator(Creator)
{
if (!dynrefs)
dynrefs = new insp::intrusive_list<dynamic_reference_base>;
void dynamic_reference_base::resolve()
{
- std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules->DataProviders.find(name);
- if (i != ServerInstance->Modules->DataProviders.end())
- value = static_cast<DataProvider*>(i->second);
+ // Because find() may return any element with a matching key in case count(key) > 1 use lower_bound()
+ // to ensure a dynref with the same name as another one resolves to the same object
+ std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name);
+ if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name))
+ {
+ ServiceProvider* newvalue = i->second;
+ if (value != newvalue)
+ {
+ value = newvalue;
+ if (hook)
+ hook->OnCapture();
+ }
+ }
else
value = NULL;
}