summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/Anope.cmake17
-rw-r--r--include/modules.h72
-rw-r--r--include/modules/chanserv.h141
-rw-r--r--modules/CMakeLists.txt10
-rw-r--r--modules/commands/cs_access.cpp19
-rw-r--r--modules/commands/cs_flags.cpp17
-rw-r--r--modules/commands/cs_xop.cpp17
-rw-r--r--modules/pseudoclients/chanserv/chanaccess.cpp127
-rw-r--r--modules/pseudoclients/chanserv/chanaccess.h30
-rw-r--r--modules/pseudoclients/chanserv/chanaccesstype.h21
-rw-r--r--modules/pseudoclients/chanserv/channel.h2
-rw-r--r--modules/pseudoclients/chanserv/chanserv.cpp52
-rw-r--r--src/modulemanager.cpp54
13 files changed, 337 insertions, 242 deletions
diff --git a/cmake/Anope.cmake b/cmake/Anope.cmake
index a8624d775..48a57d213 100644
--- a/cmake/Anope.cmake
+++ b/cmake/Anope.cmake
@@ -89,3 +89,20 @@ macro(add_to_cpack_ignored_files ITEM)
set(ENV{CPACK_IGNORED_FILES} "${REAL_ITEM}")
endif(DEFINED ENV{CPACK_IGNORED_FILES})
endmacro(add_to_cpack_ignored_files)
+
+macro(calculate_dependencies SRC)
+ file(STRINGS ${SRC} REQUIRED_LIBRARIES REGEX "/\\*[ \t]*Dependencies:[ \t]*.*[ \t]*\\*/")
+ # Iterate through those lines
+ foreach(REQUIRED_LIBRARY ${REQUIRED_LIBRARIES})
+ string(REGEX REPLACE "/\\*[ \t]*Dependencies:[ \t]*([^ \t]*)[ \t]*\\*/" "\\1" REQUIRED_LIBRARY ${REQUIRED_LIBRARY})
+ # Replace all commas with semicolons
+ string(REGEX REPLACE "," ";" REQUIRED_LIBRARY ${REQUIRED_LIBRARY})
+ # Iterate through the libraries given
+ foreach(LIBRARY ${REQUIRED_LIBRARY})
+ get_filename_component(TARGNAME ${SRC} NAME_WE)
+ target_link_libraries(${TARGNAME} ${LIBRARY})
+ add_dependencies(${TARGNAME} ${LIBRARY})
+ endforeach(LIBRARY)
+ endforeach(REQUIRED_LIBRARY)
+endmacro(calculate_dependencies)
+
diff --git a/include/modules.h b/include/modules.h
index 5daaed613..87051704b 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -19,37 +19,62 @@
#include "logger.h"
#include "extensible.h"
+class ModuleDef;
+
+struct AnopeModule
+{
+ ModuleDef* (*init)();
+ void (*fini)(ModuleDef *);
+};
+
+class ModuleDef
+{
+ std::vector<Anope::string> dependencies;
+
+ public:
+ virtual ~ModuleDef() = default;
+ virtual Module *Create(const Anope::string &modname, const Anope::string &creator) anope_abstract;
+ virtual void Destroy(Module *) anope_abstract;
+ virtual void BuildModuleInfo() anope_abstract;
+
+ void Depends(const Anope::string &modname);
+ const std::vector<Anope::string> &GetDependencies();
+};
+
+template<class ModuleClass> void ModuleInfo(ModuleDef *moddef) { }
+
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
- * It defines the class factory and external AnopeInit and AnopeFini functions.
*/
-#ifdef _WIN32
-# define MODULE_INIT(x) \
- extern "C" DllExport Module *AnopeInit(const Anope::string &, const Anope::string &); \
- extern "C" Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \
+#define MODULE_INIT(ModuleClass) \
+ class ModuleClass ## ModuleDef : public ModuleDef \
{ \
- return new x(modname, creator); \
- } \
- BOOLEAN WINAPI DllMain(HINSTANCE, DWORD, LPVOID) \
+ Module *Create(const Anope::string &modname, const Anope::string &creator) override \
+ { \
+ return new ModuleClass(modname, creator); \
+ } \
+ void Destroy(Module *module) override \
+ { \
+ delete module; \
+ } \
+ void BuildModuleInfo() override \
+ { \
+ ModuleInfo<ModuleClass>(this); \
+ } \
+ }; \
+ static ModuleDef *CreateModuleDef() \
{ \
- return TRUE; \
+ return new ModuleClass ## ModuleDef(); \
} \
- extern "C" DllExport void AnopeFini(x *); \
- extern "C" void AnopeFini(x *m) \
- { \
- delete m; \
- }
-#else
-# define MODULE_INIT(x) \
- extern "C" DllExport Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \
+ static void DeleteModuleDef(ModuleDef *def) \
{ \
- return new x(modname, creator); \
+ delete def; \
} \
- extern "C" DllExport void AnopeFini(x *m) \
+ extern "C" DllExport struct AnopeModule AnopeMod = \
{ \
- delete m; \
- }
-#endif
+ CreateModuleDef, \
+ DeleteModuleDef \
+ };
enum ModuleReturn
{
@@ -145,6 +170,9 @@ class CoreExport Module : public Extensible
*/
void *handle;
+ ModuleDef *def = nullptr;
+ AnopeModule *module = nullptr;
+
/** Time this module was created
*/
time_t created;
diff --git a/include/modules/chanserv.h b/include/modules/chanserv.h
index a6f741c1b..f0c396d39 100644
--- a/include/modules/chanserv.h
+++ b/include/modules/chanserv.h
@@ -141,11 +141,6 @@ namespace ChanServ
virtual Privilege *FindPrivilege(const Anope::string &name) anope_abstract;
virtual std::vector<Privilege> &GetPrivileges() anope_abstract;
virtual void ClearPrivileges() anope_abstract;
-
- //XXX
- typedef std::multimap<ChanAccess *, ChanAccess *> Set;
- typedef std::pair<Set, Set> Path;
- virtual bool Matches(ChanAccess *, const User *u, NickServ::Account *acc, Path &p) anope_abstract;
};
static ServiceReference<ChanServService> service("ChanServService", "ChanServ");
@@ -377,36 +372,33 @@ namespace ChanServ
ChanAccess(Serialize::TypeBase *type) : Serialize::Object(type) { }
ChanAccess(Serialize::TypeBase *type, Serialize::ID id) : Serialize::Object(type, id) { }
- inline Channel *GetChannel();
- inline void SetChannel(Channel *ci);
+ virtual Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(Channel *ci) anope_abstract;
- inline Anope::string GetCreator();
- inline void SetCreator(const Anope::string &c);
+ virtual Anope::string GetCreator() anope_abstract;
+ virtual void SetCreator(const Anope::string &c) anope_abstract;
- inline time_t GetLastSeen();
- inline void SetLastSeen(const time_t &t);
+ virtual time_t GetLastSeen() anope_abstract;
+ virtual void SetLastSeen(const time_t &t) anope_abstract;
- inline time_t GetCreated();
- inline void SetCreated(const time_t &t);
+ virtual time_t GetCreated() anope_abstract;
+ virtual void SetCreated(const time_t &t) anope_abstract;
- inline Anope::string GetMask();
- inline void SetMask(const Anope::string &);
+ virtual Anope::string GetMask() anope_abstract;
+ virtual void SetMask(const Anope::string &) anope_abstract;
- inline Serialize::Object *GetObj();
- inline void SetObj(Serialize::Object *);
+ virtual Serialize::Object *GetObj() anope_abstract;
+ virtual void SetObj(Serialize::Object *) anope_abstract;
- inline Anope::string Mask();
- inline NickServ::Account *GetAccount();
+ virtual Anope::string Mask() anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
/** Check if this access entry matches the given user or account
* @param u The user
- * @param nc The account
+ * @param acc The account
* @param p The path to the access object which matches will be put here
*/
- virtual bool Matches(const User *u, NickServ::Account *acc, Path &p)
- {
- return service->Matches(this, u, acc, p);
- }
+ virtual bool Matches(const User *u, NickServ::Account *acc, Path &p) anope_abstract;
/** Check if this access entry has the given privilege.
* @param name The privilege name
@@ -425,7 +417,7 @@ namespace ChanServ
virtual void AccessUnserialize(const Anope::string &data) anope_abstract;
/* Comparison operators to other Access entries */
- virtual bool operator>(ChanAccess &other)
+ bool operator>(ChanAccess &other)
{
const std::vector<Privilege> &privs = service->GetPrivileges();
for (unsigned i = privs.size(); i > 0; --i)
@@ -442,7 +434,7 @@ namespace ChanServ
return false;
}
- virtual bool operator<(ChanAccess &other)
+ bool operator<(ChanAccess &other)
{
const std::vector<Privilege> &privs = service->GetPrivileges();
for (unsigned i = privs.size(); i > 0; --i)
@@ -470,103 +462,6 @@ namespace ChanServ
}
};
- class ChanAccessType : public Serialize::AbstractType
- {
- public:
- Serialize::ObjectField<ChanServ::ChanAccess, ChanServ::Channel *> ci;
- Serialize::Field<ChanServ::ChanAccess, Anope::string> mask;
- Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj;
- Serialize::Field<ChanServ::ChanAccess, Anope::string> creator;
- Serialize::Field<ChanServ::ChanAccess, time_t> last_seen;
- Serialize::Field<ChanServ::ChanAccess, time_t> created;
-
- ChanAccessType(Module *me, const Anope::string &name) : Serialize::AbstractType(me, name)
- , ci(this, "ci", true)
- , mask(this, "mask")
- , obj(this, "obj", true)
- , creator(this, "creator")
- , last_seen(this, "last_seen")
- , created(this, "created")
- {
- }
- };
-
- ChanServ::Channel *ChanAccess::GetChannel()
- {
- return Get(&ChanAccessType::ci);
- }
-
- void ChanAccess::SetChannel(ChanServ::Channel *ci)
- {
- Object::Set(&ChanAccessType::ci, ci);
- }
-
- Anope::string ChanAccess::GetCreator()
- {
- return Get(&ChanAccessType::creator);
- }
-
- void ChanAccess::SetCreator(const Anope::string &c)
- {
- Object::Set(&ChanAccessType::creator, c);
- }
-
- time_t ChanAccess::GetLastSeen()
- {
- return Get(&ChanAccessType::last_seen);
- }
-
- void ChanAccess::SetLastSeen(const time_t &t)
- {
- Object::Set(&ChanAccessType::last_seen, t);
- }
-
- time_t ChanAccess::GetCreated()
- {
- return Get(&ChanAccessType::created);
- }
-
- void ChanAccess::SetCreated(const time_t &t)
- {
- Object::Set(&ChanAccessType::created, t);
- }
-
- Anope::string ChanAccess::GetMask()
- {
- return Get(&ChanAccessType::mask);
- }
-
- void ChanAccess::SetMask(const Anope::string &n)
- {
- Object::Set(&ChanAccessType::mask, n);
- }
-
- Serialize::Object *ChanAccess::GetObj()
- {
- return Get(&ChanAccessType::obj);
- }
-
- void ChanAccess::SetObj(Serialize::Object *o)
- {
- Object::Set(&ChanAccessType::obj, o);
- }
-
- Anope::string ChanAccess::Mask()
- {
- if (NickServ::Account *acc = GetAccount())
- return acc->GetDisplay();
-
- return GetMask();
- }
-
- NickServ::Account *ChanAccess::GetAccount()
- {
- if (!GetObj() || GetObj()->GetSerializableType() != NickServ::account)
- return nullptr;
-
- return anope_dynamic_static_cast<NickServ::Account *>(GetObj());
- }
-
static Serialize::TypeReference<ChanAccess> chanaccess("ChanAccess");
/* A group of access entries. This is used commonly, for example with ChanServ::Channel::AccessFor,
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index 9078f2654..522ceb674 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -18,7 +18,7 @@ macro(build_modules SRC)
file(RELATIVE_PATH FNAME ${SRC} ${MODULE_SRC})
# Convert the real source file extension to have a .so extension
- string(REGEX REPLACE "\\.cpp$" ".so" SO ${FNAME})
+ string(REGEX REPLACE "\\.cpp$" "" SO ${FNAME})
# Reset linker flags
set(TEMP_LDFLAGS)
@@ -40,7 +40,7 @@ macro(build_modules SRC)
else(WIN32)
set(WIN32_NO_LIBS)
endif(WIN32)
- set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
+ set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX ".so" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
add_dependencies(${SO} ${PROGRAM_NAME})
if(GETTEXT_FOUND)
add_dependencies(${SO} module_language)
@@ -55,6 +55,7 @@ macro(build_modules SRC)
target_link_libraries(${SO} ${PROGRAM_NAME})
endif(APPLE)
endif(WIN32)
+ calculate_dependencies(${MODULE_SRC})
# Set the module to be installed to the module directory under the data directory
install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
endif(CPP)
@@ -68,7 +69,7 @@ macro(build_subdir)
list(SORT MODULES_SUBDIR_SRCS)
GET_FILENAME_COMPONENT(FOLDER_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
- set(SO "${FOLDER_NAME}.so")
+ set(SO "${FOLDER_NAME}")
# Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though)
set_source_files_properties(${MODULES_SUBDIR_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
@@ -81,6 +82,7 @@ macro(build_subdir)
set(TEMP_DEPENDENCIES)
# Calculate the library dependencies for the given source file
calculate_libraries(${SRC} SKIP_LIBRARIES MODULE TEMP_LDFLAGS TEMP_DEPENDENCIES)
+ calculate_dependencies(${SRC})
# Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append
if(TEMP_DEPENDENCIES)
@@ -107,7 +109,7 @@ macro(build_subdir)
# Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand
add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS})
- set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
+ set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX ".so" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON)
add_dependencies(${SO} ${PROGRAM_NAME})
if(GETTEXT_FOUND)
add_dependencies(${SO} module_language)
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 6f1f0f1f0..982d5763f 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -9,15 +9,19 @@
* Based on the original code of Services by Andy Church.
*/
+/* Dependencies: chanserv */
+
#include "module.h"
#include "modules/chanserv.h"
#include "modules/cs_access.h"
+#include "../pseudoclients/chanserv/chanaccess.h"
+#include "../pseudoclients/chanserv/chanaccesstype.h"
-class AccessChanAccess : public ChanServ::ChanAccess
+class AccessChanAccess : public ChanAccessImpl
{
public:
- AccessChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
- AccessChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+ AccessChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { }
+ AccessChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { }
int GetLevel();
void SetLevel(const int &);
@@ -43,6 +47,7 @@ class AccessChanAccess : public ChanServ::ChanAccess
}
}
+#if 0
bool operator>(ChanServ::ChanAccess &other) override
{
if (this->GetSerializableType() != other.GetSerializableType())
@@ -58,9 +63,10 @@ class AccessChanAccess : public ChanServ::ChanAccess
else
return this->GetLevel() < anope_dynamic_static_cast<AccessChanAccess *>(&other)->GetLevel();
}
+#endif
};
-class AccessChanAccessType : public Serialize::Type<AccessChanAccess, ChanServ::ChanAccessType>
+class AccessChanAccessType : public Serialize::Type<AccessChanAccess, ChanAccessType>
{
public:
Serialize::Field<AccessChanAccess, int> level;
@@ -920,4 +926,9 @@ class CSAccess : public Module
}
};
+template<> void ModuleInfo<CSAccess>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
MODULE_INIT(CSAccess)
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
index c8ef11796..88cc501ac 100644
--- a/modules/commands/cs_flags.cpp
+++ b/modules/commands/cs_flags.cpp
@@ -9,16 +9,20 @@
* Based on the original code of Services by Andy Church.
*/
+/* Dependencies: chanserv */
+
#include "module.h"
#include "modules/cs_access.h"
+#include "../pseudoclients/chanserv/chanaccess.h"
+#include "../pseudoclients/chanserv/chanaccesstype.h"
static std::map<Anope::string, char> defaultFlags;
-class FlagsChanAccess : public ChanServ::ChanAccess
+class FlagsChanAccess : public ChanAccessImpl
{
public:
- FlagsChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
- FlagsChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+ FlagsChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { }
+ FlagsChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { }
Anope::string GetFlags();
void SetFlags(const Anope::string &);
@@ -57,7 +61,7 @@ class FlagsChanAccess : public ChanServ::ChanAccess
}
};
-class FlagsChanAccessType : public Serialize::Type<FlagsChanAccess, ChanServ::ChanAccessType>
+class FlagsChanAccessType : public Serialize::Type<FlagsChanAccess, ChanAccessType>
{
public:
Serialize::Field<FlagsChanAccess, Anope::string> flags;
@@ -518,4 +522,9 @@ class CSFlags : public Module
}
};
+template<> void ModuleInfo<CSFlags>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
MODULE_INIT(CSFlags)
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
index 0de467f4f..891ac77e7 100644
--- a/modules/commands/cs_xop.cpp
+++ b/modules/commands/cs_xop.cpp
@@ -9,8 +9,12 @@
* Based on the original code of Services by Andy Church.
*/
+/* Dependencies: chanserv */
+
#include "module.h"
#include "modules/cs_access.h"
+#include "../pseudoclients/chanserv/chanaccess.h"
+#include "../pseudoclients/chanserv/chanaccesstype.h"
namespace
{
@@ -18,11 +22,11 @@ namespace
std::map<Anope::string, std::vector<Anope::string> > permissions;
}
-class XOPChanAccess : public ChanServ::ChanAccess
+class XOPChanAccess : public ChanAccessImpl
{
public:
- XOPChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
- XOPChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+ XOPChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { }
+ XOPChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { }
Anope::string GetType();
void SetType(const Anope::string &);
@@ -81,7 +85,7 @@ class XOPChanAccess : public ChanServ::ChanAccess
};
-class XOPChanAccessType : public Serialize::Type<XOPChanAccess, ChanServ::ChanAccessType>
+class XOPChanAccessType : public Serialize::Type<XOPChanAccess, ChanAccessType>
{
public:
Serialize::Field<XOPChanAccess, Anope::string> type;
@@ -648,4 +652,9 @@ class CSXOP : public Module
}
};
+template<> void ModuleInfo<CSXOP>(ModuleDef *def)
+{
+ def->Depends("chanserv");
+}
+
MODULE_INIT(CSXOP)
diff --git a/modules/pseudoclients/chanserv/chanaccess.cpp b/modules/pseudoclients/chanserv/chanaccess.cpp
new file mode 100644
index 000000000..1601260c2
--- /dev/null
+++ b/modules/pseudoclients/chanserv/chanaccess.cpp
@@ -0,0 +1,127 @@
+#include "module.h"
+#include "chanaccess.h"
+#include "chanaccesstype.h"
+
+ChanServ::Channel *ChanAccessImpl::GetChannel()
+{
+ return Get(&ChanAccessType::ci);
+}
+
+void ChanAccessImpl::SetChannel(ChanServ::Channel *ci)
+{
+ Object::Set(&ChanAccessType::ci, ci);
+}
+
+Anope::string ChanAccessImpl::GetCreator()
+{
+ return Get(&ChanAccessType::creator);
+}
+
+void ChanAccessImpl::SetCreator(const Anope::string &c)
+{
+ Object::Set(&ChanAccessType::creator, c);
+}
+
+time_t ChanAccessImpl::GetLastSeen()
+{
+ return Get(&ChanAccessType::last_seen);
+}
+
+void ChanAccessImpl::SetLastSeen(const time_t &t)
+{
+ Object::Set(&ChanAccessType::last_seen, t);
+}
+
+time_t ChanAccessImpl::GetCreated()
+{
+ return Get(&ChanAccessType::created);
+}
+
+void ChanAccessImpl::SetCreated(const time_t &t)
+{
+ Object::Set(&ChanAccessType::created, t);
+}
+
+Anope::string ChanAccessImpl::GetMask()
+{
+ return Get(&ChanAccessType::mask);
+}
+
+void ChanAccessImpl::SetMask(const Anope::string &n)
+{
+ Object::Set(&ChanAccessType::mask, n);
+}
+
+Serialize::Object *ChanAccessImpl::GetObj()
+{
+ return Get(&ChanAccessType::obj);
+}
+
+void ChanAccessImpl::SetObj(Serialize::Object *o)
+{
+ Object::Set(&ChanAccessType::obj, o);
+}
+
+Anope::string ChanAccessImpl::Mask()
+{
+ if (NickServ::Account *acc = GetAccount())
+ return acc->GetDisplay();
+
+ return GetMask();
+}
+
+NickServ::Account *ChanAccessImpl::GetAccount()
+{
+ if (!GetObj() || GetObj()->GetSerializableType() != NickServ::account)
+ return nullptr;
+
+ return anope_dynamic_static_cast<NickServ::Account *>(GetObj());
+}
+
+bool ChanAccessImpl::Matches(const User *u, NickServ::Account *acc, Path &p)
+{
+ if (this->GetAccount())
+ return this->GetAccount() == acc;
+
+ if (u)
+ {
+ bool is_mask = this->Mask().find_first_of("!@?*") != Anope::string::npos;
+ if (is_mask && Anope::Match(u->nick, this->Mask()))
+ return true;
+ else if (Anope::Match(u->GetDisplayedMask(), this->Mask()))
+ return true;
+ }
+
+ if (acc)
+ for (NickServ::Nick *na : acc->GetRefs<NickServ::Nick *>(NickServ::nick))
+ if (Anope::Match(na->GetNick(), this->Mask()))
+ return true;
+
+ if (IRCD->IsChannelValid(this->Mask()))
+ {
+ ChanServ::Channel *tci = ChanServ::Find(this->Mask());
+ if (tci)
+ {
+ for (unsigned i = 0; i < tci->GetAccessCount(); ++i)
+ {
+ ChanServ::ChanAccess *a = tci->GetAccess(i);
+ std::pair<ChanServ::ChanAccess *, ChanServ::ChanAccess *> pair = std::make_pair(this, a);
+
+ std::pair<Set::iterator, Set::iterator> range = p.first.equal_range(this);
+ for (; range.first != range.second; ++range.first)
+ if (range.first->first == pair.first && range.first->second == pair.second)
+ goto cont;
+
+ p.first.insert(pair);
+ if (a->Matches(u, acc, p))
+ p.second.insert(pair);
+
+ cont:;
+ }
+
+ return p.second.count(this) > 0;
+ }
+ }
+
+ return false;
+}
diff --git a/modules/pseudoclients/chanserv/chanaccess.h b/modules/pseudoclients/chanserv/chanaccess.h
new file mode 100644
index 000000000..bb65f79c5
--- /dev/null
+++ b/modules/pseudoclients/chanserv/chanaccess.h
@@ -0,0 +1,30 @@
+
+class ChanAccessImpl : public ChanServ::ChanAccess
+{
+ public:
+ ChanAccessImpl(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
+ ChanAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *ci) override;
+
+ Anope::string GetCreator() override;
+ void SetCreator(const Anope::string &c) override;
+
+ time_t GetLastSeen() override;
+ void SetLastSeen(const time_t &t) override;
+
+ time_t GetCreated() override;
+ void SetCreated(const time_t &t) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+
+ Serialize::Object *GetObj() override;
+ void SetObj(Serialize::Object *) override;
+
+ Anope::string Mask() override;
+ NickServ::Account *GetAccount() override;
+
+ bool Matches(const User *u, NickServ::Account *acc, Path &p) override;
+};
diff --git a/modules/pseudoclients/chanserv/chanaccesstype.h b/modules/pseudoclients/chanserv/chanaccesstype.h
new file mode 100644
index 000000000..ca8dc1b79
--- /dev/null
+++ b/modules/pseudoclients/chanserv/chanaccesstype.h
@@ -0,0 +1,21 @@
+
+class ChanAccessType : public Serialize::AbstractType
+{
+ public:
+ Serialize::ObjectField<ChanServ::ChanAccess, ChanServ::Channel *> ci;
+ Serialize::Field<ChanServ::ChanAccess, Anope::string> mask;
+ Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj;
+ Serialize::Field<ChanServ::ChanAccess, Anope::string> creator;
+ Serialize::Field<ChanServ::ChanAccess, time_t> last_seen;
+ Serialize::Field<ChanServ::ChanAccess, time_t> created;
+
+ ChanAccessType(Module *me, const Anope::string &name) : Serialize::AbstractType(me, name)
+ , ci(this, "ci", true)
+ , mask(this, "mask")
+ , obj(this, "obj", true)
+ , creator(this, "creator")
+ , last_seen(this, "last_seen")
+ , created(this, "created")
+ {
+ }
+};
diff --git a/modules/pseudoclients/chanserv/channel.h b/modules/pseudoclients/chanserv/channel.h
index 995972ece..18a4be5d6 100644
--- a/modules/pseudoclients/chanserv/channel.h
+++ b/modules/pseudoclients/chanserv/channel.h
@@ -3,11 +3,9 @@
class ChannelImpl : public ChanServ::Channel
{
public:
- //using ChanServ::Channel::Channel;
ChannelImpl(Serialize::TypeBase *type) : ChanServ::Channel(type) { }
ChannelImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::Channel(type, id) { }
ChannelImpl(Serialize::TypeBase *type, const Anope::string &chname);
- /*ChannelImpl(const ChanServ::Channel &ci);*/
~ChannelImpl();
void Delete() override;
diff --git a/modules/pseudoclients/chanserv/chanserv.cpp b/modules/pseudoclients/chanserv/chanserv.cpp
index 5dd83188f..420051252 100644
--- a/modules/pseudoclients/chanserv/chanserv.cpp
+++ b/modules/pseudoclients/chanserv/chanserv.cpp
@@ -19,6 +19,8 @@
#include "channeltype.h"
#include "leveltype.h"
#include "modetype.h"
+#include "chanaccesstype.h"
+#include "chanaccess.h"
class ChanServCore : public Module
, public ChanServ::ChanServService
@@ -52,7 +54,7 @@ class ChanServCore : public Module
std::vector<ChanServ::Privilege> Privileges;
ChanServ::registered_channel_map registered_channels;
ChannelType channel_type;
- ChanServ::ChanAccessType chanaccess_type;
+ ChanAccessType chanaccess_type;
LevelType level_type;
CSModeType mode_type;
@@ -189,54 +191,6 @@ class ChanServCore : public Module
Privileges.clear();
}
- bool Matches(ChanServ::ChanAccess *access, const User *u, NickServ::Account *acc, ChanServ::ChanAccess::Path &p) override
- {
- if (access->GetAccount())
- return access->GetAccount() == acc;
-
- if (u)
- {
- bool is_mask = access->Mask().find_first_of("!@?*") != Anope::string::npos;
- if (is_mask && Anope::Match(u->nick, access->Mask()))
- return true;
- else if (Anope::Match(u->GetDisplayedMask(), access->Mask()))
- return true;
- }
-
- if (acc)
- for (NickServ::Nick *na : acc->GetRefs<NickServ::Nick *>(NickServ::nick))
- if (Anope::Match(na->GetNick(), access->Mask()))
- return true;
-
- if (IRCD->IsChannelValid(access->Mask()))
- {
- ChanServ::Channel *tci = Find(access->Mask());
- if (tci)
- {
- for (unsigned i = 0; i < tci->GetAccessCount(); ++i)
- {
- ChanServ::ChanAccess *a = tci->GetAccess(i);
- std::pair<ChanServ::ChanAccess *, ChanServ::ChanAccess *> pair = std::make_pair(access, a);
-
- std::pair<Set::iterator, Set::iterator> range = p.first.equal_range(access);
- for (; range.first != range.second; ++range.first)
- if (range.first->first == pair.first && range.first->second == pair.second)
- goto cont;
-
- p.first.insert(pair);
- if (a->Matches(u, acc, p))
- p.second.insert(pair);
-
- cont:;
- }
-
- return p.second.count(access) > 0;
- }
- }
-
- return false;
- }
-
void OnReload(Configuration::Conf *conf) override
{
const Anope::string &channick = conf->GetModule(this)->Get<Anope::string>("client");
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index b36d8180b..9e70ab088 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -23,6 +23,16 @@
std::list<Module *> ModuleManager::Modules;
+void ModuleDef::Depends(const Anope::string &modname)
+{
+ dependencies.push_back(modname);
+}
+
+const std::vector<Anope::string> &ModuleDef::GetDependencies()
+{
+ return dependencies;
+}
+
#ifdef _WIN32
void ModuleManager::CleanupRuntimeDirectory()
{
@@ -111,22 +121,6 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out
}
#endif
-/* This code was found online at http://www.linuxjournal.com/article/3687#comment-26593
- *
- * This function will take a pointer from either dlsym or GetProcAddress and cast it in
- * a way that won't cause C++ warnings/errors to come up.
- */
-template <class TYPE> static TYPE function_cast(void *symbol)
-{
- union
- {
- void *symbol;
- TYPE function;
- } cast;
- cast.symbol = symbol;
- return cast.function;
-}
-
ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
{
if (modname.empty())
@@ -166,16 +160,18 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
}
dlerror();
- Module *(*func)(const Anope::string &, const Anope::string &) = function_cast<Module *(*)(const Anope::string &, const Anope::string &)>(dlsym(handle, "AnopeInit"));
+ AnopeModule *module = static_cast<AnopeModule *>(dlsym(handle, "AnopeMod"));
err = dlerror();
- if (!func)
+ if (!module || !module->init || !module->fini)
{
- Log() << "No init function found, not an Anope module";
+ Log() << "No module symbols function found, not an Anope module";
if (err && *err)
Log(LOG_DEBUG) << err;
dlclose(handle);
return MOD_ERR_NOLOAD;
}
+
+ ModuleDef *def = module->init();
/* Create module. */
Anope::string nick;
@@ -187,7 +183,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
ModuleReturn moderr = MOD_ERR_OK;
try
{
- m = func(modname, nick);
+ m = def->Create(modname, nick);
}
catch (const ModuleException &ex)
{
@@ -204,6 +200,8 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
m->filename = pbuf;
m->handle = handle;
+ m->def = def;
+ m->module = module;
ModuleVersion v = m->GetVersion();
if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor()))
@@ -334,17 +332,13 @@ ModuleReturn ModuleManager::DeleteModule(Module *m)
Log(LOG_DEBUG) << "Unloading module " << m->name;
- dlerror();
- void (*destroy_func)(Module *m) = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini"));
- const char *err = dlerror();
- if (!destroy_func || (err && *err))
- {
- Log() << "No destroy function found for " << m->name << ", chancing delete...";
- delete m; /* we just have to chance they haven't overwrote the delete operator then... */
- }
- else
- destroy_func(m); /* Let the module delete it self, just in case */
+ ModuleDef *def = m->def;
+ AnopeModule *module = m->module;
+ def->Destroy(m);
+ module->fini(def);
+
+ dlerror();
if (dlclose(handle))
Log() << dlerror();