diff options
-rw-r--r-- | include/modules.h | 17 | ||||
-rw-r--r-- | src/modules.cpp | 70 | ||||
-rw-r--r-- | src/modules/m_auditorium.cpp | 21 |
3 files changed, 94 insertions, 14 deletions
diff --git a/include/modules.h b/include/modules.h index b9dcd0b8d..27fec9010 100644 --- a/include/modules.h +++ b/include/modules.h @@ -416,6 +416,10 @@ class CoreExport Module : public Extensible */ virtual ~Module(); + virtual void Prioritize() + { + } + /** Returns the version number of a Module. * The method should return a Version object with its version information assigned via * Version::Version @@ -1522,10 +1526,19 @@ typedef std::vector<Module*> ModuleList; */ typedef std::vector<ircd_module*> ModuleHandleList; -typedef std::list<Module*> IntModuleList; +typedef std::vector<Module*> IntModuleList; typedef std::vector<IntModuleList> EventHandlerList; typedef IntModuleList::iterator EventHandlerIter; +enum PriorityState +{ + PRIO_DONTCARE, + PRIO_FIRST, + PRIO_LAST, + PRIO_AFTER, + PRIO_BEFORE +}; + /** ModuleManager takes care of all things module-related * in the core. */ @@ -1574,6 +1587,8 @@ class CoreExport ModuleManager : public classbase ~ModuleManager(); + bool SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules = NULL, size_t sz = 1); + /** Attach an event to a module * @param i Event type to attach * @param mod Module to attach event to diff --git a/src/modules.cpp b/src/modules.cpp index f0d52d331..ae6767765 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -192,7 +192,7 @@ void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { } ModuleManager::ModuleManager(InspIRCd* Ins) : ModCount(0), Instance(Ins) { for (int n = I_BEGIN + 1; n != I_END; ++n) - EventHandlers.push_back(std::list<Module*>()); + EventHandlers.push_back(std::vector<Module*>()); } ModuleManager::~ModuleManager() @@ -231,6 +231,70 @@ void ModuleManager::DetachAll(Module* mod) Detach((Implementation)n, mod); } +bool ModuleManager::SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules, size_t sz) +{ + size_t swap_pos; + size_t source; + bool swap = true; + + for (size_t x = 0; x != EventHandlers[i].size(); ++x) + { + if (EventHandlers[i][x] == mod) + { + source = x; + break; + } + } + + switch (s) + { + case PRIO_DONTCARE: + swap = false; + break; + case PRIO_FIRST: + swap_pos = 0; + break; + case PRIO_LAST: + if (EventHandlers[i].empty()) + swap_pos = 0; + else + swap_pos = EventHandlers[i].size() - 1; + break; + case PRIO_AFTER: + { + /* Find the latest possible position */ + swap_pos = 0; + for (size_t x = 0; x != EventHandlers[i].size(); ++x) + { + for (size_t n = 0; n < sz; ++n) + { + if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x >= swap_pos)) + swap_pos = x; + } + } + } + break; + case PRIO_BEFORE: + { + swap_pos = EventHandlers[i].size() - 1; + for (size_t x = 0; x != EventHandlers[i].size(); ++x) + { + for (size_t n = 0; n < sz; ++n) + { + if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x <= swap_pos)) + swap_pos = x; + } + } + } + break; + } + + if (swap) + std::swap(EventHandlers[i][swap_pos], EventHandlers[i][source]); + + return true; +} + const char* ModuleManager::LastError() { return MODERR; @@ -359,6 +423,10 @@ bool ModuleManager::Load(const char* filename) this->ModCount++; FOREACH_MOD_I(Instance,I_OnLoadModule,OnLoadModule(modules[this->ModCount],filename_str)); + + for (int n = 0; n != this->ModCount+1; ++n) + modules[n]->Prioritize(); + Instance->BuildISupport(); return true; } diff --git a/src/modules/m_auditorium.cpp b/src/modules/m_auditorium.cpp index a686d7444..173b13311 100644 --- a/src/modules/m_auditorium.cpp +++ b/src/modules/m_auditorium.cpp @@ -55,8 +55,11 @@ class ModuleAuditorium : public Module { aum = new AuditoriumMode(ServerInstance); if (!ServerInstance->AddMode(aum)) - throw ModuleException("Could not add new modes!"); + throw ModuleException("Could not add new modes!") OnRehash(NULL, ""); + + Implements eventlist[] = { I_OnUserJoin, I_OnUserPart, I_OnUserKick, I_OnUserQuit, I_OnUserList, I_OnRehash }; + Me->Modules->Attach(eventlist, this, sizeof(eventlist)); } virtual ~ModuleAuditorium() @@ -65,16 +68,15 @@ class ModuleAuditorium : public Module DELETE(aum); } - virtual void OnRehash(User* user, const std::string ¶meter) + void Prioritize() { - ConfigReader conf(ServerInstance); - ShowOps = conf.ReadFlag("auditorium", "showops", 0); + ServerInstance->Modules->SetPriority(this, I_OnUserList, PRIO_BEFORE, &(ServerInstance->Modules->Find("m_namesx.so"))); } - Priority Prioritize() + virtual void OnRehash(User* user, const std::string ¶meter) { - /* To ensure that we get priority over namesx for names list generation on +u channels */ - return (Priority)ServerInstance->Modules->PriorityBefore("m_namesx.so"); + ConfigReader conf(ServerInstance); + ShowOps = conf.ReadFlag("auditorium", "showops", 0); } virtual Version GetVersion() @@ -82,11 +84,6 @@ class ModuleAuditorium : public Module return Version(1, 1, 0, 0, VF_COMMON | VF_VENDOR, API_VERSION); } - void Implements(char* List) - { - List[I_OnUserJoin] = List[I_OnUserPart] = List[I_OnUserKick] = List[I_OnUserQuit] = List[I_OnUserList] = List[I_OnRehash] = 1; - } - virtual int OnUserList(User* user, Channel* Ptr, CUList* &nameslist) { if (Ptr->IsModeSet('u')) |