summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h3
-rw-r--r--include/modules.h4
-rw-r--r--src/inspircd.cpp79
-rw-r--r--src/modules.cpp1
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