diff options
-rw-r--r-- | include/inspircd.h | 3 | ||||
-rw-r--r-- | include/modules.h | 4 | ||||
-rw-r--r-- | src/inspircd.cpp | 79 | ||||
-rw-r--r-- | src/modules.cpp | 1 |
4 files changed, 87 insertions, 0 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index e41482341..2f1b8bc1a 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -104,6 +104,7 @@ class InspIRCd void erase_factory(int j); void erase_module(int j); void BuildISupport(); + void MoveTo(std::string modulename,int slot); public: time_t startup_time; @@ -118,6 +119,8 @@ class InspIRCd char* ModuleError(); bool LoadModule(const char* filename); bool UnloadModule(const char* filename); + void MoveToLast(std::string modulename); + void MoveToFirst(std::string modulename); InspIRCd(int argc, char** argv); int Run(); diff --git a/include/modules.h b/include/modules.h index 1530592d3..5f9dfa29a 100644 --- a/include/modules.h +++ b/include/modules.h @@ -274,6 +274,8 @@ class ExtMode : public classbase }; +enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST }; + enum Implementation { I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, I_OnServerRaw, I_OnExtendedMode, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois, I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserPreNick, I_OnUserMessage, I_OnUserNotice, I_OnMode, @@ -315,6 +317,8 @@ class Module : public classbase virtual void Implements(char* Implements); + virtual Priority Prioritize(); + /** Called when a user connects. * The details of the connecting user are available to you in the parameter userrec *user * @param user The user who is connecting diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 2df5b8688..16b450ec9 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -276,6 +276,62 @@ void InspIRCd::erase_module(int j) } +void InspIRCd::MoveTo(std::string modulename,int slot) +{ + unsigned int v2 = 256; + log(DEBUG,"Moving %s to slot %d",modulename.c_str(),slot); + for (unsigned int v = 0; v < Config->module_names.size(); v++) + { + if (module_names[v] == modulename) + { + // found an instance, swap it with the item at MODCOUNT + v2 = v; + break; + } + } + if (v == slot) + { + log(DEBUG,"Item %s already in slot %d!",modulename.c_str(),slot); + } + else if (v2 < 256) + { + // Swap the module names over + Config->module_names[v2] = Config->module_names[slot]; + Config->module_names[slot] = modulename; + // now swap the module factories + ircd_module* temp = factory[v2]; + factory[v2] = factory[slot]; + factory[slot] = temp; + // now swap the module objects + Module* temp_module = modules[v2]; + modules[v2] = modules[slot]; + modules[slot] = temp_module; + // now swap the implement lists (we dont + // need to swap the global or recount it) + for (int n = 0; n < 255; n++) + { + char x = Config->implement_lists[v2][n]; + Config->implement_lists[v2][n] = Config->implement_lists[slot][n]; + Config->implement_lists[slot][n] = x; + } + log(DEBUG,"Moved %s to slot successfully",modulename.c_str()); + } + else + { + log(DEBUG,"Move of %s to slot failed!",modulename.c_str()); + } +} + +void InspIRCd::MoveToFirst(std::string modulename) +{ + MoveTo(modulename,0); +} + +void InspIRCd::MoveToLast(std::string modulename) +{ + MoveTo(modulename,MODCOUNT); +} + void InspIRCd::BuildISupport() { // the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it... @@ -424,6 +480,29 @@ bool InspIRCd::LoadModule(const char* filename) #endif MODCOUNT++; FOREACH_MOD(I_OnLoadModule,OnLoadModule(modules[MODCOUNT],filename_str)); + // now work out which modules, if any, want to move to the back of the queue, + // and if they do, move them there. + std::vector<std::string> put_to_back; + std::vector<std::string> put_to_front; + for (unsigned int j = 0; j < Config->module_names.size(); j++) + { + if (modules[j]->Prioritize() == PRIORITY_LAST) + { + put_to_back.push_back(Config->module_names[j]); + } + else if (modules[j]->Prioritize() == PRIORITY_FIRST) + { + put_to_front.push_back(Config->module_names[j]); + } + } + for (unsigned int j = 0; j < put_to_back.size(); j++) + { + MoveToLast(put_to_back[j]); + } + for (unsigned int j = 0; j < put_to_front.size(); j++) + { + MoveToFirst(put_to_front[j]); + } BuildISupport(); return true; } diff --git a/src/modules.cpp b/src/modules.cpp index aff7ddc81..b8b17aa93 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -298,6 +298,7 @@ void Module::OnDelQLine(userrec* source, std::string nickmask) { }; void Module::OnDelELine(userrec* source, std::string hostmask) { }; void Module::OnCleanup(int target_type, void* item) { }; void Module::Implements(char* Implements) { for (int j = 0; j < 255; j++) Implements[j] = 0; }; +Priority Prioritize() { return PRIORITY_DONTCARE; } /* server is a wrapper class that provides methods to all of the C-style * exports in the core |