summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h17
-rw-r--r--src/modules.cpp70
-rw-r--r--src/modules/m_auditorium.cpp21
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 &parameter)
+ 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 &parameter)
{
- /* 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'))