]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules.cpp
Change storage of UserManager::all_opers to be a vector
[user/henk/code/inspircd.git] / src / modules.cpp
index 92f619743d11f0b640c57539f8eb0765b49b9a8a..a4b5ae4bc37653dbfdd04a869187adc08550c817 100644 (file)
@@ -114,7 +114,7 @@ ModResult   Module::OnCheckReady(LocalUser*) { DetachEvent(I_OnCheckReady); return
 ModResult      Module::OnUserRegister(LocalUser*) { DetachEvent(I_OnUserRegister); return MOD_RES_PASSTHRU; }
 ModResult      Module::OnUserPreKick(User*, Membership*, const std::string&) { DetachEvent(I_OnUserPreKick); return MOD_RES_PASSTHRU; }
 void           Module::OnUserKick(User*, Membership*, const std::string&, CUList&) { DetachEvent(I_OnUserKick); }
-ModResult      Module::OnRawMode(User*, Channel*, const char, const std::string &, bool, int) { DetachEvent(I_OnRawMode); return MOD_RES_PASSTHRU; }
+ModResult      Module::OnRawMode(User*, Channel*, ModeHandler*, const std::string&, bool) { DetachEvent(I_OnRawMode); return MOD_RES_PASSTHRU; }
 ModResult      Module::OnCheckInvite(User*, Channel*) { DetachEvent(I_OnCheckInvite); return MOD_RES_PASSTHRU; }
 ModResult      Module::OnCheckKey(User*, Channel*, const std::string&) { DetachEvent(I_OnCheckKey); return MOD_RES_PASSTHRU; }
 ModResult      Module::OnCheckLimit(User*, Channel*) { DetachEvent(I_OnCheckLimit); return MOD_RES_PASSTHRU; }
@@ -132,7 +132,6 @@ 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); }
 void           Module::OnPostTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPostTopicChange); }
-void           Module::OnGetServerDescription(const std::string&, std::string&) { DetachEvent(I_OnGetServerDescription); }
 void           Module::OnSyncUser(User*, ProtocolInterface::Server&) { DetachEvent(I_OnSyncUser); }
 void           Module::OnSyncChannel(Channel*, ProtocolInterface::Server&) { DetachEvent(I_OnSyncChannel); }
 void           Module::OnSyncNetwork(ProtocolInterface::Server&) { DetachEvent(I_OnSyncNetwork); }
@@ -148,18 +147,20 @@ ModResult Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelet
 void           Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); }
 ModResult      Module::OnSetAway(User*, const std::string &) { DetachEvent(I_OnSetAway); return MOD_RES_PASSTHRU; }
 ModResult      Module::OnWhoisLine(User*, User*, int&, std::string&) { DetachEvent(I_OnWhoisLine); return MOD_RES_PASSTHRU; }
-void           Module::OnBuildNeighborList(User*, UserChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
+void           Module::OnBuildNeighborList(User*, IncludeChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
 void           Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); }
 ModResult      Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; }
 void           Module::OnText(User*, void*, int, const std::string&, char, CUList&) { DetachEvent(I_OnText); }
-void           Module::OnRunTestSuite() { DetachEvent(I_OnRunTestSuite); }
 void           Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { DetachEvent(I_OnNamesListItem); }
 ModResult      Module::OnNumeric(User*, unsigned int, const std::string&) { DetachEvent(I_OnNumeric); return MOD_RES_PASSTHRU; }
-void           Module::OnHookIO(StreamSocket*, ListenSocket*) { DetachEvent(I_OnHookIO); }
 ModResult   Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { DetachEvent(I_OnAcceptConnection); return MOD_RES_PASSTHRU; }
-void           Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, std::string&) { DetachEvent(I_OnSendWhoLine); }
+void           Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, Membership*, std::string&) { DetachEvent(I_OnSendWhoLine); }
 void           Module::OnSetUserIP(LocalUser*) { DetachEvent(I_OnSetUserIP); }
 
+#ifdef INSPIRCD_ENABLE_TESTSUITE
+void           Module::OnRunTestSuite() { }
+#endif
+
 ServiceProvider::ServiceProvider(Module* Creator, const std::string& Name, ServiceType Type)
        : creator(Creator), name(Name), service(Type)
 {
@@ -389,29 +390,46 @@ void ModuleManager::DoSafeUnload(Module* mod)
        std::vector<reference<ExtensionItem> > items;
        ServerInstance->Extensions.BeginUnregister(modfind->second, items);
        /* Give the module a chance to tidy out all its metadata */
-       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+       const chan_hash& chans = ServerInstance->GetChans();
+       for (chan_hash::const_iterator c = chans.begin(); c != chans.end(); )
        {
-               mod->OnCleanup(TYPE_CHANNEL,c->second);
-               c->second->doUnhookExtensions(items);
-               const UserMembList* users = c->second->GetUsers();
+               Channel* chan = c->second;
+               ++c;
+               mod->OnCleanup(TYPE_CHANNEL, chan);
+               chan->doUnhookExtensions(items);
+               const UserMembList* users = chan->GetUsers();
                for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
                        mi->second->doUnhookExtensions(items);
        }
-       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
+
+       const user_hash& users = ServerInstance->Users->GetUsers();
+       for (user_hash::const_iterator u = users.begin(); u != users.end(); )
        {
-               mod->OnCleanup(TYPE_USER,u->second);
-               u->second->doUnhookExtensions(items);
+               User* user = u->second;
+               // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container
+               ++u;
+               mod->OnCleanup(TYPE_USER, user);
+               user->doUnhookExtensions(items);
        }
-       for(char m='A'; m <= 'z'; m++)
+
+       const ModeParser::ModeHandlerMap& usermodes = ServerInstance->Modes->GetModes(MODETYPE_USER);
+       for (ModeParser::ModeHandlerMap::const_iterator i = usermodes.begin(); i != usermodes.end(); )
        {
-               ModeHandler* mh;
-               mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
-               if (mh && mh->creator == mod)
+               ModeHandler* mh = i->second;
+               ++i;
+               if (mh->creator == mod)
                        this->DelService(*mh);
-               mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL);
-               if (mh && mh->creator == mod)
+       }
+
+       const ModeParser::ModeHandlerMap& chanmodes = ServerInstance->Modes->GetModes(MODETYPE_CHANNEL);
+       for (ModeParser::ModeHandlerMap::const_iterator i = chanmodes.begin(); i != chanmodes.end(); )
+       {
+               ModeHandler* mh = i->second;
+               ++i;
+               if (mh->creator == mod)
                        this->DelService(*mh);
        }
+
        for(std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
        {
                std::multimap<std::string, ServiceProvider*>::iterator curr = i++;
@@ -550,6 +568,8 @@ void ModuleManager::LoadAll()
                }
        }
 
+       this->NewServices = NULL;
+
        if (!PrioritizeHooks())
                ServerInstance->Exit(EXIT_STATUS_MODULE);
 }
@@ -579,8 +599,7 @@ void ModuleManager::AddService(ServiceProvider& item)
                case SERVICE_MODE:
                {
                        ModeHandler* mh = static_cast<ModeHandler*>(&item);
-                       if (!ServerInstance->Modes->AddMode(mh))
-                               throw ModuleException("Mode "+std::string(item.name)+" already exists.");
+                       ServerInstance->Modes->AddMode(mh);
                        DataProviders.insert(std::make_pair((mh->GetModeType() == MODETYPE_CHANNEL ? "mode/" : "umode/") + item.name, &item));
                        dynamic_reference_base::reset_all();
                        return;