diff options
Diffstat (limited to 'modules')
189 files changed, 2680 insertions, 4478 deletions
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1402a7c68..928466e41 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,213 +1,164 @@ -add_subdirectory("third/language") - -# Get a list of ALL files and directories within the current directory -file(GLOB MODULES_FOLDERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*") -remove_item_from_list(MODULES_FOLDERS "CMakeFiles") - # If using Windows, add the MODULE_COMPILE define if(WIN32) add_definitions(-DMODULE_COMPILE) endif(WIN32) -# Iterate through the directories -foreach(MODULE_FOLDER ${MODULES_FOLDERS}) - if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FOLDER}") - # Get a list of all .cpp files in this directory - file(GLOB MODULES_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${MODULE_FOLDER}/*.cpp") - sort_list(MODULES_SRCS) - - # 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_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}") - - # Create an empty list to store extra include directories - set(EXTRA_INCLUDES) - - # Get the length of the folder name - string(LENGTH ${MODULE_FOLDER} FOLDER_LEN) - # Add one (the /) - math(EXPR FOLDER_LEN "${FOLDER_LEN} + 1") - - # Iterate through all the source files - foreach(SRC ${MODULES_SRCS}) - # Get the length of the new source file - string(LENGTH ${SRC} SRC_LEN) - # Set FILE_LEN to the length of the source file minus folder length - math(EXPR FILE_LEN "${SRC_LEN} - ${FOLDER_LEN}") - # Get the real name of the source file now - string(SUBSTRING ${SRC} ${FOLDER_LEN} ${FILE_LEN} SRC_REALNAME) - # Convert the real source file extension to have a .so extension - string(REGEX REPLACE "\\.cpp$" ".so" SO ${SRC_REALNAME}) - # Reset skip_depends - set(SKIP_DEPENDS) +function(build_modules SRC) + if(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt") + add_subdirectory("${SRC}") + else(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt") + file(GLOB MODULES_SRCS "${SRC}/*") + foreach(MODULE_SRC ${MODULES_SRCS}) + if(IS_DIRECTORY "${MODULE_SRC}") + build_modules("${MODULE_SRC}") + else(IS_DIRECTORY "${MODULE_SRC}") + string(REGEX MATCH "\\.cpp$" CPP ${MODULE_SRC}) + if(CPP) + 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}) + # Temporary variable for the current source's include directories + set(TEMP_INCLUDES) + # Calculate the header file dependencies for the given source file + calculate_depends(${MODULE_SRC} TEMP_INCLUDES) + # If there were some extra include directories, add them to the list + if(TEMP_INCLUDES) + append_to_list(EXTRA_INCLUDES ${TEMP_INCLUDES}) + endif(TEMP_INCLUDES) + + # Reset linker flags + set(TEMP_LDFLAGS) + # Reset extra dependencies + set(TEMP_DEPENDENCIES) + # Calculate the library dependencies for the given source file + calculate_libraries(${MODULE_SRC} TEMP_LDFLAGS TEMP_DEPENDENCIES) + # Reset has_function + set(HAS_FUNCTION) + # Check the function dependencies for the given source file + check_functions(${MODULE_SRC} HAS_FUNCTION) + # Only continue if this module has all of the required functions + if(HAS_FUNCTION) + # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators + if(MSVC) + set(WIN32_MEMORY win32_memory) + else(MSVC) + set(WIN32_MEMORY) + endif(MSVC) + # Generate the module and set its linker flags, also set it to depend on the main Anope executable to be built beforehand + add_library(${SO} MODULE ${MODULE_SRC}) + # Windows requires this because it's weird + if(WIN32) + set(WIN32_NO_LIBS "/nodefaultlib:\"libcmt.lib\"") + 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) + add_dependencies(${SO} ${PROGRAM_NAME}) + if(GETTEXT_FOUND) + add_dependencies(${SO} module_language) + endif(GETTEXT_FOUND) + target_link_libraries(${SO} ${TEMP_DEPENDENCIES}) + # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set its version + if(WIN32) + target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY}) + set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") + else(WIN32) + if(APPLE) + target_link_libraries(${SO} ${PROGRAM_NAME}) + endif(APPLE) + endif(WIN32) + # Set the module to be installed to the module directory under the data directory + install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules) + endif(HAS_FUNCTION) + endif(CPP) + endif(IS_DIRECTORY "${MODULE_SRC}") + endforeach(MODULE_SRC ${MODULES_SRCS}) + endif(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt") +endfunction(build_modules) + +function(build_subdir) + file(GLOB_RECURSE MODULES_SUBDIR_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") + sort_list(MODULES_SUBDIR_SRCS) + + GET_FILENAME_COMPONENT(FOLDER_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + set(SO "${FOLDER_NAME}.so") + + # 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}") + + set(HAS_FUNCTION TRUE) + + # Iterate through the source files in the subdirectory + foreach(SRC ${MODULES_SUBDIR_SRCS}) + if(HAS_FUNCTION) # Temporary variable for the current source's include directories set(TEMP_INCLUDES) # Calculate the header file dependencies for the given source file - calculate_depends(${SRC} SKIP_DEPENDS FALSE TEMP_INCLUDES) + calculate_depends(${SRC} TEMP_INCLUDES) # If there were some extra include directories, add them to the list if(TEMP_INCLUDES) - append_to_list(EXTRA_INCLUDES ${TEMP_INCLUDES}) + include_directories(${TEMP_INCLUDES}) endif(TEMP_INCLUDES) + # Reset linker flags set(TEMP_LDFLAGS) # Reset extra dependencies set(TEMP_DEPENDENCIES) - # Reset skip_libraries - set(SKIP_LIBRARIES) # Calculate the library dependencies for the given source file - calculate_libraries(${SRC} SKIP_LIBRARIES FALSE TEMP_LDFLAGS TEMP_DEPENDENCIES) - if(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES) - # Reset has_function - set(HAS_FUNCTION) - # Check the function dependencies for the given source file - check_functions(${SRC} HAS_FUNCTION) - # Only continue if this module has all of the required functions - if(HAS_FUNCTION) - # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators - if(MSVC) - set(WIN32_MEMORY win32_memory) - else(MSVC) - set(WIN32_MEMORY) - endif(MSVC) - # 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 ${SRC}) - # Windows requires this because it's weird - if(WIN32) - set(WIN32_NO_LIBS "/nodefaultlib:\"libcmt.lib\"") - 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) - add_dependencies(${SO} ${PROGRAM_NAME}) - if(GETTEXT_FOUND) - add_dependencies(${SO} module_language) - endif(GETTEXT_FOUND) - # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version - if(WIN32) - target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES}) - set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") - else(WIN32) - target_link_libraries(${SO} ${TEMP_DEPENDENCIES}) - endif(WIN32) - # Set the module to be installed to the module directory under the data directory - install(TARGETS ${SO} - DESTINATION ${LIB_DIR}/modules - ) - endif(HAS_FUNCTION) - else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES) - message(" ${SRC} can not be built due to missing dependencies.") - endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES) - endforeach(SRC) - - # Get a list of ALL files and directories within this modules directory - file(GLOB SUBMODULE_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${MODULE_FOLDER}/*") - remove_item_from_list(SUBMODULE_DIRS "CMakeFiles") - remove_item_from_list(SUBMODULE_DIRS "third/language") - - foreach(SUBDIR ${SUBMODULE_DIRS}) - if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}") - file(GLOB_RECURSE MODULES_SUBDIR_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${SUBDIR}/*.cpp") - sort_list(MODULES_SUBDIR_SRCS) - - # 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}") - - # Get the length of this subdir - string(LENGTH ${SUBDIR} SUBDIR_LEN) - # Calculate the length of the folder - math(EXPR FILE_LEN "${SUBDIR_LEN} - ${FOLDER_LEN}") - # Extract this subfolders name to use to generate the .so file - string(SUBSTRING ${SUBDIR} ${FOLDER_LEN} ${FILE_LEN} SUBDIR_REALNAME) - # Add .so to the end of the directory name, this will be the module's name - set(SO "${SUBDIR_REALNAME}.so") - - # Temporary linker flags for this subdirectory - set(SUBDIR_LDFLAGS "${LDFLAGS}") - # Temporary extra dependencies for this subdirectory - set(SUBDIR_EXTRA_DEPENDS) - # Reset skip_depends - set(SKIP_DEPENDS) - # Reset skip_libraries - set(SKIP_LIBRARIES) - # Reset has_function - set(HAS_FUNCTION TRUE) - - # Iterate through the source files in the subdirectory - foreach(SRC ${MODULES_SUBDIR_SRCS}) - if(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION) - # Temporary variable for the current source's include directories - set(TEMP_INCLUDES) - # Calculate the header file dependencies for the given source file - calculate_depends(${SRC} SKIP_DEPENDS FALSE TEMP_INCLUDES) - # If there were some extra include directories, add them to the list - if(TEMP_INCLUDES) - append_to_list(EXTRA_INCLUDES ${TEMP_INCLUDES}) - endif(TEMP_INCLUDES) - # Reset linker flags - set(TEMP_LDFLAGS) - # Reset extra dependencies - set(TEMP_DEPENDENCIES) - # Calculate the library dependencies for the given source file - calculate_libraries(${SRC} SKIP_LIBRARIES FALSE TEMP_LDFLAGS TEMP_DEPENDENCIES) - # Check the function dependencies for the given source file - check_functions(${SRC} HAS_FUNCTION) - - # Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append - if(TEMP_DEPENDENCIES) - append_to_list(SUBDIR_EXTRA_DEPENDS ${TEMP_DEPDENCIES}) - endif(TEMP_DEPENDENCIES) - endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION) - endforeach(SRC) - - # Continue if library and function requirements are met - if(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION) - # Remove duplicates from the linker flags - if(SUBDIR_LDFLAGS) - remove_list_duplicates(SUBDIR_LDFLAGS) - endif(SUBDIR_LDFLAGS) - # Remove duplicates from the extra dependencies - if(SUBDIR_EXTRA_DEPENDS) - remove_list_duplicates(SUBDIR_EXTRA_DEPENDS) - endif(SUBDIR_EXTRA_DEPENDS) - - # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators - if(MSVC) - set(WIN32_MEMORY win32_memory) - else(MSVC) - set(WIN32_MEMORY) - endif(MSVC) - - # 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) - add_dependencies(${SO} ${PROGRAM_NAME}) - target_link_libraries(${SO} ${PROGRAM_NAME}) - if(GETTEXT_FOUND) - add_dependencies(${SO} module_language) - endif(GETTEXT_FOUND) - # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version - if(WIN32) - target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS}) - set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") - endif(WIN32) - # Set the module to be installed to the module directory under the data directory - install(TARGETS ${SO} - DESTINATION ${LIB_DIR}/modules - ) - else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION) - message(" ${SUBDIR} can not be built due to missing dependencies.") - endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION) - - # Run the directories CMakeLists.txt if there is one - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/CMakeLists.txt") - add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}") - endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/CMakeLists.txt") - endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}") - endforeach(SUBDIR) - endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FOLDER}") -endforeach(MODULE_FOLDER) - -# If there were extra include directories, remove the duplicates and add the directories to the include path -if(EXTRA_INCLUDES) - remove_list_duplicates(EXTRA_INCLUDES) - include_directories(${EXTRA_INCLUDES}) -endif(EXTRA_INCLUDES) + calculate_libraries(${SRC} SKIP_LIBRARIES MODULE TEMP_LDFLAGS TEMP_DEPENDENCIES) + # Check the function dependencies for the given source file + check_functions(${SRC} HAS_FUNCTION) + + # Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append + if(TEMP_DEPENDENCIES) + append_to_list(SUBDIR_EXTRA_DEPENDS ${TEMP_DEPDENCIES}) + endif(TEMP_DEPENDENCIES) + endif(HAS_FUNCTION) + endforeach(SRC ${MODULES_SUBDIR_SRCS}) + + # Continue if library and function requirements are met + if(HAS_FUNCTION) + # Remove duplicates from the linker flags + if(SUBDIR_LDFLAGS) + remove_list_duplicates(SUBDIR_LDFLAGS) + endif(SUBDIR_LDFLAGS) + + # Remove duplicates from the extra dependencies + if(SUBDIR_EXTRA_DEPENDS) + remove_list_duplicates(SUBDIR_EXTRA_DEPENDS) + endif(SUBDIR_EXTRA_DEPENDS) + + # For Visual Studio only, include win32_memory static library, required to override Visual Studio's overrides of the new/delete operators + if(MSVC) + set(WIN32_MEMORY win32_memory) + else(MSVC) + set(WIN32_MEMORY) + endif(MSVC) + + # 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) + add_dependencies(${SO} ${PROGRAM_NAME}) + if(GETTEXT_FOUND) + add_dependencies(${SO} module_language) + endif(GETTEXT_FOUND) + target_link_libraries(${SO} ${SUBDIR_EXTRA_DEPENDS}) + # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version + if(WIN32) + target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY}) + set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") + else(WIN32) + if(APPLE) + target_link_libraries(${SO} ${PROGRAM_NAME}) + endif(APPLE) + endif(WIN32) + + # Set the module to be installed to the module directory under the data directory + install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules) + + endif(HAS_FUNCTION) +endfunction(build_subdir) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +build_modules(${CMAKE_CURRENT_SOURCE_DIR}) + diff --git a/modules/extra/bs_autoassign.cpp b/modules/bs_autoassign.cpp index 8bdab26d7..ae60f5b5a 100644 --- a/modules/extra/bs_autoassign.cpp +++ b/modules/bs_autoassign.cpp @@ -5,47 +5,34 @@ * * Please read COPYING and README for further details. * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. */ #include "module.h" class BSAutoAssign : public Module { - Anope::string bot; - public: - BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnChanRegistered, I_OnReload }; + Implementation i[] = { I_OnChanRegistered }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } void OnChanRegistered(ChannelInfo *ci) anope_override { - if (this->bot.empty()) + const Anope::string &bot = Config->GetModule(this)->Get<const Anope::string>("bot"); + if (bot.empty()) return; - BotInfo *bi = BotInfo::Find(this->bot); + BotInfo *bi = BotInfo::Find(bot); if (bi == NULL) { - Log(this) << "bs_autoassign is configured to assign bot " << this->bot << ", but it does not exist?"; + Log(this) << "bs_autoassign is configured to assign bot " << bot << ", but it does not exist?"; return; } bi->Assign(NULL, ci); } - - void OnReload() anope_override - { - ConfigReader config; - this->bot = config.ReadValue("bs_autoassign", "bot", "", 0); - } }; MODULE_INIT(BSAutoAssign) diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp index 93cb5f907..bbac6e689 100644 --- a/modules/commands/bs_assign.cpp +++ b/modules/commands/bs_assign.cpp @@ -153,11 +153,40 @@ class BSAssign : public Module CommandBSUnassign commandbsunassign; public: - BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsassign(this), commandbsunassign(this) { - this->SetAuthor("Anope"); + Implementation i[] = { I_OnInvite }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + + void OnInvite(User *source, Channel *c, User *targ) anope_override + { + BotInfo *bi; + if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = dynamic_cast<BotInfo *>(targ))) + return; + + AccessGroup access = c->ci->AccessFor(source); + if (c->ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration"))) + { + targ->SendMessage(bi, ACCESS_DENIED); + return; + } + + if (bi->oper_only && !source->HasPriv("botserv/administration")) + { + targ->SendMessage(bi, ACCESS_DENIED); + return; + } + + if (c->ci->bi == bi) + { + targ->SendMessage(bi, _("Bot \002%s\002 is already assigned to channel \002%s\002."), c->ci->bi->nick.c_str(), c->name.c_str()); + return; + } + bi->Assign(source, c->ci); + targ->SendMessage(bi, _("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), c->name.c_str()); } }; diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp index 147b23b95..31dee8f8e 100644 --- a/modules/commands/bs_badwords.cpp +++ b/modules/commands/bs_badwords.cpp @@ -9,11 +9,8 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" - class BadwordsDelCallback : public NumberList { CommandSource &source; @@ -146,17 +143,20 @@ class CommandBSBadwords : public Command realword = word.substr(0, pos); } - if (ci->GetBadWordCount() >= Config->BSBadWordsMax) + unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax"); + if (ci->GetBadWordCount() >= badwordsmax) { - source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax); + source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax); return; } + bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive"); + for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) { const BadWord *bw = ci->GetBadWord(i); - if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word)))) + if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && realword.equals_ci(bw->word))) { source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str()); return; @@ -168,8 +168,6 @@ class CommandBSBadwords : public Command ci->AddBadWord(realword, bwtype); source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str()); - - return; } void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word) @@ -219,6 +217,7 @@ class CommandBSBadwords : public Command source.Reply(_("Bad words list is now empty.")); return; } + public: CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) { @@ -289,7 +288,7 @@ class CommandBSBadwords : public Command "will be done if a user says a word that ends with\n" "\037word\037. If you don't specify anything, a kick will\n" "be issued every time \037word\037 is said by a user.\n" - " \n"), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + " \n"), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); source.Reply(_("The \002DEL\002 command removes the given word from the\n" "bad words list. If a list of entry numbers is given, those\n" "entries are deleted. (See the example for LIST below.)\n" @@ -313,11 +312,9 @@ class BSBadwords : public Module CommandBSBadwords commandbsbadwords; public: - BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsbadwords(this) { - this->SetAuthor("Anope"); - } }; diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index dd6da27d6..16fd9f2f2 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -29,21 +29,23 @@ class CommandBSBot : public Command return; } - if (nick.length() > Config->NickLen) + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get<unsigned>("nicklen")) { - source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen")); return; } - if (user.length() > Config->UserLen) + if (user.length() > networkinfo->Get<unsigned>("userlen")) { - source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen")); return; } - if (host.length() > Config->HostLen) + if (host.length() > networkinfo->Get<unsigned>("hostlen")) { - source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen")); return; } @@ -112,21 +114,23 @@ class CommandBSBot : public Command return; } - if (nick.length() > Config->NickLen) + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get<unsigned>("nicklen")) { - source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen")); return; } - if (!user.empty() && user.length() > Config->UserLen) + if (user.length() > networkinfo->Get<unsigned>("userlen")) { - source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen")); return; } - if (!host.empty() && host.length() > Config->HostLen) + if (host.length() > networkinfo->Get<unsigned>("hostlen")) { - source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen")); return; } @@ -204,7 +208,15 @@ class CommandBSBot : public Command if (!user.empty()) { IRCD->SendClientIntroduction(bi); - bi->RejoinAll(); + unsigned minusers = Config->GetBlock("botserv")->Get<unsigned>("minusers"); + const std::set<ChannelInfo *> &channels = bi->GetChannels(); + for (std::set<ChannelInfo *>::const_iterator it = channels.begin(), it_end = channels.end(); it != it_end; ++it) + { + const ChannelInfo *ci = *it; + + if (ci->c && ci->c->users.size() >= minusers) + bi->Join(ci->c); + } } source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); @@ -355,10 +367,9 @@ class BSBot : public Module CommandBSBot commandbsbot; public: - BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsbot(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp index cacfce903..e682bd47d 100644 --- a/modules/commands/bs_botlist.cpp +++ b/modules/commands/bs_botlist.cpp @@ -19,7 +19,6 @@ class CommandBSBotList : public Command CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0) { this->SetDesc(_("Lists available bots")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -75,10 +74,9 @@ class BSBotList : public Module CommandBSBotList commandbsbotlist; public: - BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsbotlist(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp index d78ca6851..32e9392d7 100644 --- a/modules/commands/bs_control.cpp +++ b/modules/commands/bs_control.cpp @@ -138,10 +138,9 @@ class BSControl : public Module CommandBSAct commandbsact; public: - BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbssay(this), commandbsact(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp index b1e05bb17..6c017dc55 100644 --- a/modules/commands/bs_info.cpp +++ b/modules/commands/bs_info.cpp @@ -238,10 +238,9 @@ class BSInfo : public Module CommandBSInfo commandbsinfo; public: - BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsinfo(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp index 3f7cc16c2..5c1bdc6a8 100644 --- a/modules/commands/bs_kick.cpp +++ b/modules/commands/bs_kick.cpp @@ -13,6 +13,8 @@ #include "module.h" +static Module *me; + class CommandBSKick : public Command { public: @@ -54,7 +56,7 @@ class CommandBSKick : public Command "on a specific option.\n" " \n" "Note: access to this command is controlled by the\n" - "level SET."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -199,7 +201,7 @@ class CommandBSKickBadwords : public CommandBSKickBase "more information.\n" "ttb is the number of times a user can be kicked\n" "before it get banned. Don't give ttb to disable\n" - "the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -406,8 +408,8 @@ class CommandBSKickFlood : public CommandBSKickBase catch (const ConvertException &) { } if (ci->floodsecs < 1) ci->floodsecs = 10; - if (ci->floodsecs > Config->BSKeepData) - ci->floodsecs = Config->BSKeepData; + if (ci->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata")) + ci->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata"); ci->ExtendMetadata("BS_KICK_FLOOD"); if (ci->ttb[TTB_FLOOD]) @@ -639,13 +641,14 @@ struct BanData : ExtensibleItem void purge() { + time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata"); for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;) { const Anope::string &user = it->first; Data &bd = it->second; ++it; - if (Anope::CurTime - bd.last_use > Config->BSKeepData) + if (Anope::CurTime - bd.last_use > keepdata) data_map.erase(user); } } @@ -789,7 +792,7 @@ class BSKick : public Module } public: - BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbskick(this), commandbskickamsg(this), commandbskickbadwords(this), commandbskickbolds(this), commandbskickcaps(this), commandbskickcolors(this), commandbskickflood(this), commandbskickitalics(this), commandbskickrepeat(this), @@ -797,9 +800,10 @@ class BSKick : public Module purger(this) { - this->SetAuthor("Anope"); + me = this; - ModuleManager::Attach(I_OnPrivmsg, this); + Implementation i[] = { I_OnPrivmsg }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } ~BSKick() @@ -808,7 +812,7 @@ class BSKick : public Module { Channel *c = cit->second; for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) - (*it)->Shrink("bs_main_userdata"); + it->second->Shrink("bs_main_userdata"); c->Shrink("bs_main_bandata"); } } @@ -921,30 +925,31 @@ class BSKick : public Module /* Normalize the buffer */ Anope::string nbuf = Anope::NormalizeBuffer(realbuf); + bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive"); for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) { const BadWord *bw = ci->GetBadWord(i); - if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) + if (bw->type == BW_ANY && ((casesensitive && nbuf.find(bw->word) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) mustkick = true; else if (bw->type == BW_SINGLE) { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))) + if ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf))) mustkick = true; - else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))) + else if (nbuf.find(' ') == len && ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf)))) mustkick = true; else { - if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) + if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) mustkick = true; else { Anope::string wordbuf = " " + bw->word + " "; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -953,13 +958,13 @@ class BSKick : public Module { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word))) + if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = " " + bw->word; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -967,13 +972,13 @@ class BSKick : public Module { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) + if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = bw->word + " "; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -981,7 +986,7 @@ class BSKick : public Module if (mustkick) { check_ban(ci, u, TTB_BADWORDS); - if (Config->BSGentleBWReason) + if (Config->GetModule(me)->Get<bool>("gentlebadwordreason")) bot_kick(ci, u, _("Watch your language!")); else bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str()); @@ -1033,7 +1038,7 @@ class BSKick : public Module { for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();) { - Channel *chan = (*it)->chan; + Channel *chan = it->second->chan; ++it; if (chan->ci && chan->ci->HasExt("BS_KICK_AMSGS") && !chan->ci->AccessFor(u).HasPriv("NOKICK")) diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp index 784ea7f8b..95500ac94 100644 --- a/modules/commands/bs_set.cpp +++ b/modules/commands/bs_set.cpp @@ -48,7 +48,7 @@ class CommandBSSet : public Command } } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n" - "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -105,6 +105,10 @@ class CommandBSSetBanExpire : public Command } ci->banexpire = Anope::DoTime(arg); + + bool override = !access.HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change banexpire to " << ci->banexpire; + if (!ci->banexpire) source.Reply(_("Bot bans will no longer automatically expire.")); else @@ -305,15 +309,13 @@ class CommandBSSetFantasy : public Command source.Reply(_(" \n" "Enables or disables \002fantasy\002 mode on a channel.\n" "When it is enabled, users will be able to use\n" - "%s commands on a channel when prefixed\n" + "fantasy commands on a channel when prefixed\n" "with one of the following fantasy characters: \002%s\002\n" " \n" "Note that users wanting to use fantaisist\n" - "commands MUST have enough level for both\n" - "the FANTASIA and another level depending\n" - "of the command if required (for example, to use\n" - "!op, user must have enough access for the OPDEOP\n" - "level)."), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); + "commands MUST have enough access for both\n" + "the FANTASIA and the command they are executing."), + Config->GetModule("botserv")->Get<const Anope::string>("fantasycharacter", "!").c_str()); return true; } }; @@ -404,8 +406,7 @@ class CommandBSSetNoBot : public Command if (value.equals_ci("ON")) { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to enable nobot"; + Log(LOG_ADMIN, source, this, ci) << "to enable nobot"; ci->ExtendMetadata("BS_NOBOT"); if (ci->bi) @@ -414,8 +415,7 @@ class CommandBSSetNoBot : public Command } else if (value.equals_ci("OFF")) { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to disable nobot"; + Log(LOG_ADMIN, source, this, ci) << "to disable nobot"; ci->Shrink("BS_NOBOT"); source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str()); @@ -491,12 +491,10 @@ class BSSet : public Module CommandBSSetPrivate commandbssetprivate; public: - BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsset(this), commandbssetbanexpire(this), commandbssetdontkickops(this), commandbssetdontkickvoices(this), commandbssetfantasy(this), commandbssetgreet(this), commandbssetnobot(this), commandbssetprivate(this) { - this->SetAuthor("Anope"); - ModuleManager::Attach(I_OnBotBan, this); } diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 239c344ab..88dd751c3 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -158,9 +158,10 @@ class CommandCSAccess : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); return; } @@ -326,7 +327,7 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) - if (access->Matches((*cit)->user, (*cit)->user->Account())) + if (access->Matches(cit->second->user, cit->second->user->Account())) timebuf = "Now"; if (timebuf.empty()) { @@ -360,7 +361,7 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) - if (access->Matches((*cit)->user, (*cit)->user->Account())) + if (access->Matches(cit->second->user, cit->second->user->Account())) timebuf = "Now"; if (timebuf.empty()) { @@ -552,24 +553,10 @@ class CommandCSAccess : public Command " \n" "The \002ACCESS CLEAR\002 command clears all entries of the\n" "access list.")); - source.Reply(_("\002User access levels\002\n" - " \n" - "By default, the following access levels are defined:\n" - " \n" - " \002Founder\002 Full access to %s functions; automatic\n" - " opping upon entering channel. Note\n" - " that only one person may have founder\n" - " status (it cannot be given using the\n" - " \002ACCESS\002 command).\n" - " \002 10\002 Access to AKICK command; automatic opping.\n" - " \002 5\002 Automatic opping.\n" - " \002 3\002 Automatic voicing.\n" - " \002 0\002 No special privileges; can be opped by other\n" - " ops (unless \002secure-ops\002 is set).\n" - " \n" - "These levels may be changed, or new ones added, using the\n" + source.Reply(" "); + source.Reply(_("\002User access levels\002 can be seen by using the\n" "\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n" - "information."), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + "information."), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -604,7 +591,7 @@ class CommandCSLevels : public Command { Privilege *p = PrivilegeManager::FindPrivilege(what); if (p == NULL) - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); else { ci->SetLevel(p->name, level); @@ -642,7 +629,7 @@ class CommandCSLevels : public Command } } - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return; } @@ -797,39 +784,30 @@ class CSAccess : public Module CommandCSLevels commandcslevels; public: - CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), accessprovider(this), commandcsaccess(this), commandcslevels(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); Implementation i[] = { I_OnReload, I_OnCreateChan, I_OnGroupCheckPriv }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - try - { - this->OnReload(); - } - catch (const ConfigException &ex) - { - throw ModuleException(ex.GetReason()); - } } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { defaultLevels.clear(); - ConfigReader config; - for (int i = 0; i < config.Enumerate("privilege"); ++i) + for (int i = 0; i < conf->CountBlock("privilege"); ++i) { - const Anope::string &pname = config.ReadValue("privilege", "name", "", i); + Configuration::Block *priv = conf->GetBlock("privilege", i); + + const Anope::string &pname = priv->Get<const Anope::string>("name"); Privilege *p = PrivilegeManager::FindPrivilege(pname); if (p == NULL) continue; - const Anope::string &value = config.ReadValue("privilege", "level", "", i); + const Anope::string &value = priv->Get<const Anope::string>("level"); if (value.empty()) continue; else if (value.equals_ci("founder")) @@ -837,7 +815,7 @@ class CSAccess : public Module else if (value.equals_ci("disabled")) defaultLevels[p->name] = ACCESS_INVALID; else - defaultLevels[p->name] = config.ReadInteger("privilege", "level", i, false); + defaultLevels[p->name] = priv->Get<int16_t>("level"); } } diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp index a3133b8e9..51665d309 100644 --- a/modules/commands/cs_akick.cpp +++ b/modules/commands/cs_akick.cpp @@ -23,8 +23,9 @@ class CommandCSAKick : public Command NickCore *nc = NULL; const AutoKick *akick; - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); if (IRCD->IsExtbanValid(mask)) ; /* If this is an extban don't try to complete the mask */ @@ -148,9 +149,9 @@ class CommandCSAKick : public Command } } - if (ci->GetAkickCount() >= Config->CSAutokickMax) + if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax")) { - source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->CSAutokickMax); + source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax")); return; } @@ -390,9 +391,10 @@ class CommandCSAKick : public Command return; } - for (User::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) { - ChanUserContainer *uc = *it++; + ChanUserContainer *uc = it->second; + ++it; if (ci->CheckKick(uc->user)) ++count; @@ -509,11 +511,9 @@ class CSAKick : public Module CommandCSAKick commandcsakick; public: - CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsakick(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnCheckKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -544,7 +544,11 @@ class CSAKick : public Module autokick->last_used = Anope::CurTime; if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos) mask = autokick->mask; - reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason; + reason = autokick->reason; + if (reason.empty()) + reason = Config->GetModule(this)->Get<const Anope::string>("autokickreason"); + if (reason.empty()) + reason = "User has been banned from the channel"; return EVENT_STOP; } } diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp index e46bfcecb..c3fffecd9 100644 --- a/modules/commands/cs_ban.cpp +++ b/modules/commands/cs_ban.cpp @@ -91,8 +91,9 @@ class CommandCSBan : public Command reason += " " + params[3]; } - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); User *u = source.GetUser(); User *u2 = User::Find(target, true); @@ -142,7 +143,7 @@ class CommandCSBan : public Command c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); } } - else if (u_access.HasPriv("FOUNDER")) + else { Log(LOG_COMMAND, source, this, ci) << "for " << target; @@ -156,10 +157,12 @@ class CommandCSBan : public Command } } + bool founder = u_access.HasPriv("FOUNDER"); int matched = 0, kicked = 0; for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) { - ChanUserContainer *uc = *it++; + ChanUserContainer *uc = it->second; + ++it; if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) { @@ -167,6 +170,8 @@ class CommandCSBan : public Command AccessGroup u2_access = ci->AccessFor(uc->user); + if (matched > 1 && !founder) + continue; if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access) continue; else if (ci->c->MatchesList(uc->user, "EXCEPT")) @@ -187,8 +192,6 @@ class CommandCSBan : public Command else source.Reply(_("No users on %s match %s."), c->name.c_str(), target.c_str()); } - else - source.Reply(NICK_X_NOT_IN_USE, target.c_str()); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -210,9 +213,8 @@ class CSBan : public Module CommandCSBan commandcsban; public: - CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsban(this) + CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsban(this) { - this->SetAuthor("Anope"); me = this; } }; diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp index 9a33a6fab..e4c1ac7f6 100644 --- a/modules/commands/cs_clone.cpp +++ b/modules/commands/cs_clone.cpp @@ -64,31 +64,25 @@ public: target_ci->name = target; (*RegisteredChannelList)[target_ci->name] = target_ci; target_ci->c = Channel::Find(target_ci->name); + + target_ci->bi = NULL; + if (ci->bi) + ci->bi->Assign(u, target_ci); + if (target_ci->c) { target_ci->c->ci = target_ci; target_ci->c->CheckModes(); - ChannelMode *cm; - if (u && u->FindChannel(target_ci->c) != NULL) - { - /* On most ircds you do not receive the admin/owner mode till its registered */ - if ((cm = ModeManager::FindChannelModeByName("OWNER"))) - target_ci->c->SetMode(NULL, cm, u->GetUID()); - else if ((cm = ModeManager::FindChannelModeByName("PROTECT"))) - target_ci->c->RemoveMode(NULL, cm, u->GetUID()); - } + target_ci->c->SetCorrectModes(u, true, true); /* Mark the channel as persistent */ if (target_ci->c->HasMode("PERM")) target_ci->ExtendMetadata("PERSIST"); /* Persist may be in def cflags, set it here */ - else if (target_ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM"))) - target_ci->c->SetMode(NULL, cm); - - if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL) - target_ci->bi->Join(target_ci->c, &ModeManager::DefaultBotModes); + else if (target_ci->HasExt("PERSIST")) + target_ci->c->SetMode(NULL, "PERM"); } if (target_ci->c && !target_ci->c->topic.empty()) @@ -177,9 +171,8 @@ class CSClone : public Module CommandCSClone commandcsclone; public: - CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsclone(this) + CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsclone(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_drop.cpp b/modules/commands/cs_drop.cpp index 884544211..ade021dc1 100644 --- a/modules/commands/cs_drop.cpp +++ b/modules/commands/cs_drop.cpp @@ -87,9 +87,8 @@ class CSDrop : public Module CommandCSDrop commandcsdrop; public: - CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsdrop(this) + CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsdrop(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_enforce.cpp b/modules/commands/cs_enforce.cpp index 4d5ba0242..0579ebb2b 100644 --- a/modules/commands/cs_enforce.cpp +++ b/modules/commands/cs_enforce.cpp @@ -31,7 +31,7 @@ class CommandCSEnforce : public Command for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; ci->c->SetCorrectModes(uc->user, false, false); } @@ -50,7 +50,7 @@ class CommandCSEnforce : public Command std::vector<User *> users; for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (user->IsProtected()) @@ -81,7 +81,7 @@ class CommandCSEnforce : public Command std::vector<User *> users; for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (user->IsProtected()) @@ -113,7 +113,7 @@ class CommandCSEnforce : public Command std::vector<User *> users; for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (user->IsProtected()) @@ -145,7 +145,7 @@ class CommandCSEnforce : public Command std::vector<User *> users; for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (user->IsProtected()) @@ -195,7 +195,7 @@ class CommandCSEnforce : public Command /* The newer users are at the end of the list, so kick users starting from the end */ for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (user->IsProtected()) @@ -282,10 +282,9 @@ class CSEnforce : public Module CommandCSEnforce commandcsenforce; public: - CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsenforce(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index 68c36e7c7..da764d81c 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -39,8 +39,6 @@ struct EntryMsg : Serializable static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); }; -static unsigned MaxEntries = 0; - struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >, ExtensibleItem { EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { } @@ -140,7 +138,7 @@ class CommandEntryMessage : public Command ci->Extend("cs_entrymsg", messages); } - if (MaxEntries && (*messages)->size() >= MaxEntries) + if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries")) source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str()); else { @@ -273,14 +271,11 @@ class CSEntryMessage : public Module CommandEntryMessage commandentrymsg; public: - CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this) + CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnJoinChannel }; + Implementation i[] = { I_OnJoinChannel }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } void OnJoinChannel(User *u, Channel *c) anope_override @@ -294,12 +289,6 @@ class CSEntryMessage : public Module u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str()); } } - - void OnReload() anope_override - { - ConfigReader config; - MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true); - } }; MODULE_INIT(CSEntryMessage) diff --git a/modules/commands/cs_fantasy_stats.cpp b/modules/commands/cs_fantasy_stats.cpp index 580307441..b8c83e73b 100644 --- a/modules/commands/cs_fantasy_stats.cpp +++ b/modules/commands/cs_fantasy_stats.cpp @@ -12,7 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "../extra/sql.h" +#include "modules/sql.h" class MySQLInterface : public SQL::Interface { @@ -68,23 +68,21 @@ class CSStats : public Module MySQLInterface sqlinterface; Anope::string prefix; public: - CSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsstats(this), commandcsgstats(this), sql("", ""), sqlinterface(this) { me = this; - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - prefix = config.ReadValue("chanstats", "prefix", "anope_", 0); - Anope::string engine = config.ReadValue("chanstats", "engine", "", 0); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); + prefix = conf->GetModule(this)->Get<const Anope::string>("prefix"); + if (prefix.empty()) + prefix = "anope_"; + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string>("engine")); } SQL::Result RunQuery(const SQL::Query &query) diff --git a/modules/commands/cs_fantasy_top.cpp b/modules/commands/cs_fantasy_top.cpp index 16d65dd05..7f82ba221 100644 --- a/modules/commands/cs_fantasy_top.cpp +++ b/modules/commands/cs_fantasy_top.cpp @@ -12,7 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "../extra/sql.h" +#include "modules/sql.h" class MySQLInterface : public SQL::Interface { @@ -62,7 +62,6 @@ class CommandCSGTop : public Command CommandCSGTop(Module *creator) : Command (creator, "chanserv/gtop", 0, 1) { this->SetDesc(_("Displays the top 3 users of the network")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms); @@ -74,7 +73,6 @@ class CommandCSGTop10 : public Command CommandCSGTop10(Module *creator) : Command (creator, "chanserv/gtop10", 0, 1) { this->SetDesc(_("Displays the top 10 users of the network")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms); @@ -94,24 +92,22 @@ class CSTop : public Module Anope::string prefix; public: - CSTop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSTop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcstop(this), commandcsgtop(this), commandcstop10(this), commandcsgtop10(this), sql("", ""), sqlinterface(this) { me = this; - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - prefix = config.ReadValue("chanstats", "prefix", "anope_", 0); - Anope::string engine = config.ReadValue("chanstats", "engine", "", 0); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); + prefix = conf->GetModule(this)->Get<const Anope::string>("prefix"); + if (prefix.empty()) + prefix = "anope_"; + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string>("engine")); } SQL::Result RunQuery(const SQL::Query &query) diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index 4681c3d61..18b72ef29 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -13,6 +13,7 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); static std::map<Anope::string, char> defaultFlags; class FlagsChanAccess : public ChanAccess @@ -113,9 +114,10 @@ class CommandCSFlags : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); return; } @@ -387,32 +389,30 @@ class CSFlags : public Module CommandCSFlags commandcsflags; public: - CSFlags(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSFlags(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), accessprovider(this), commandcsflags(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, 1); - - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; defaultFlags.clear(); - for (int i = 0; i < config.Enumerate("privilege"); ++i) + for (int i = 0; i < conf->CountBlock("privilege"); ++i) { - const Anope::string &pname = config.ReadValue("privilege", "name", "", i); + Configuration::Block *priv = conf->GetBlock("privilege", i); + + const Anope::string &pname = priv->Get<const Anope::string>("name"); Privilege *p = PrivilegeManager::FindPrivilege(pname); if (p == NULL) continue; - const Anope::string &value = config.ReadValue("privilege", "flag", "", i); + const Anope::string &value = priv->Get<const Anope::string>("flag"); if (value.empty()) continue; diff --git a/modules/commands/cs_getkey.cpp b/modules/commands/cs_getkey.cpp index 1ac5633ea..ec64b45f8 100644 --- a/modules/commands/cs_getkey.cpp +++ b/modules/commands/cs_getkey.cpp @@ -67,9 +67,8 @@ class CSGetKey : public Module CommandCSGetKey commandcsgetkey; public: - CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsgetkey(this) + CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsgetkey(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp index 9485e81fd..e26dc1970 100644 --- a/modules/commands/cs_info.cpp +++ b/modules/commands/cs_info.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + class CommandCSInfo : public Command { void CheckOptStr(Anope::string &buf, const Anope::string &opt, const char *str, const ChannelInfo *ci, const NickCore *nc) @@ -102,8 +104,9 @@ class CommandCSInfo : public Command if (!ml.empty()) info["Mode lock"] = ml; - if (!ci->HasExt("NO_EXPIRE")) - info["Expires on"] = Anope::strftime(ci->last_used + Config->CSExpire); + time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d"); + if (!ci->HasExt("NO_EXPIRE") && chanserv_expire && !Anope::NoExpire) + info["Expires on"] = Anope::strftime(ci->last_used + chanserv_expire); } if (ci->HasExt("SUSPENDED")) { @@ -142,10 +145,9 @@ class CSInfo : public Module CommandCSInfo commandcsinfo; public: - CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsinfo(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_invite.cpp b/modules/commands/cs_invite.cpp index bb59d538e..4b204bfc4 100644 --- a/modules/commands/cs_invite.cpp +++ b/modules/commands/cs_invite.cpp @@ -104,9 +104,8 @@ class CSInvite : public Module CommandCSInvite commandcsinvite; public: - CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsinvite(this) + CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsinvite(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp index 03beaf0a8..f1a632af3 100644 --- a/modules/commands/cs_kick.cpp +++ b/modules/commands/cs_kick.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + class CommandCSKick : public Command { public: @@ -45,8 +47,9 @@ class CommandCSKick : public Command return; } - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); AccessGroup u_access = source.AccessFor(ci); @@ -79,7 +82,8 @@ class CommandCSKick : public Command int matched = 0, kicked = 0; for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) { - ChanUserContainer *uc = *it++; + ChanUserContainer *uc = it->second; + ++it; if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) { @@ -125,9 +129,8 @@ class CSKick : public Module CommandCSKick commandcskick; public: - CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcskick(this) + CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcskick(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp index 29c8a827b..13492c007 100644 --- a/modules/commands/cs_list.cpp +++ b/modules/commands/cs_list.cpp @@ -68,6 +68,7 @@ class CommandCSList : public Command } Anope::string spattern = "#" + pattern; + unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str()); @@ -91,7 +92,7 @@ class CommandCSList : public Command if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true)) { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= Config->CSListMax) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax) { bool isnoexpire = false; if (is_servadmin && (ci->HasExt("NO_EXPIRE"))) @@ -115,7 +116,7 @@ class CommandCSList : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans); + source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans); return; } @@ -150,11 +151,11 @@ class CommandCSList : public Command " \002LIST #51-100\002\n" " Lists all registered channels within the given range (51-100).")); - if (!Config->RegexEngine.empty()) + if (!Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const Anope::string>("regexengine").c_str()); } return true; @@ -166,10 +167,8 @@ class CSList : public Module CommandCSList commandcslist; public: - CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcslist(this) + CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcslist(this) { - this->SetAuthor("Anope"); - } }; diff --git a/modules/commands/cs_log.cpp b/modules/commands/cs_log.cpp index 41d8229f6..b3ad62859 100644 --- a/modules/commands/cs_log.cpp +++ b/modules/commands/cs_log.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" class CommandCSLog : public Command { @@ -31,7 +30,7 @@ public: ChannelInfo *ci = ChannelInfo::Find(channel); if (ci == NULL) source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str()); - else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/set")) + else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration")) source.Reply(ACCESS_DENIED); else if (params.size() == 1) { @@ -185,10 +184,9 @@ class CSLog : public Module CommandCSLog commandcslog; public: - CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), MSService("MemoServService", "MemoServ"), commandcslog(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnLog }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 823b60f8e..38390251b 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -20,25 +20,7 @@ class CommandCSMode : public Command if (!ci || !cm || cm->type != MODE_STATUS) return false; - const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" }, - accesses_self[] = { "VOICEME", "HALFOPME", "OPDEOPME", "PROTECTME", "OWNERME", "" }; - const Anope::string modes[] = { "VOICE", "HALFOP", "OP", "PROTECT", "OWNER" }; - ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - AccessGroup access = source.AccessFor(ci); - short u_level = -1; - - for (int i = 0; !accesses[i].empty(); ++i) - if (access.HasPriv(self ? accesses_self[i] : accesses[i])) - { - ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]); - if (cm2 == NULL || cm2->type != MODE_STATUS) - continue; - ChannelModeStatus *cms2 = anope_dynamic_static_cast<ChannelModeStatus *>(cm2); - if (cms2->level > u_level) - u_level = cms2->level; - } - - return u_level >= cms->level; + return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : "")); } void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) @@ -170,7 +152,7 @@ class CommandCSMode : public Command } Anope::string mode_param; - if (!cm->type == MODE_REGULAR && !sep.GetToken(mode_param)) + if (cm->type != MODE_REGULAR && !sep.GetToken(mode_param)) source.Reply(_("Missing parameter for mode %c."), cm->mchar); else { @@ -231,12 +213,12 @@ class CommandCSMode : public Command { User *u = source.GetUser(); - bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/set"); + bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/administration"); spacesepstream sep(params.size() > 3 ? params[3] : ""); Anope::string modes = params[2], param; - bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/set"); + bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/administration"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2]; int adding = -1; @@ -253,9 +235,11 @@ class CommandCSMode : public Command case '*': if (adding == -1 || !has_access) break; - for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j) + for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j) { - ChannelMode *cm = ModeManager::ChannelModes[j]; + ChannelMode *cm = ModeManager::GetChannelModes()[j]; + if (!cm) + continue; if (!u || cm->CanSet(u)) { if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM)) @@ -309,9 +293,10 @@ class CommandCSMode : public Command break; } - for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; + ++it; AccessGroup targ_access = ci->AccessFor(uc->user); @@ -406,7 +391,7 @@ class CommandCSMode : public Command new_params.push_back("-*"); this->DoSet(source, ci, new_params); } - else if (param.equals_ci("BANS") || param.equals_ci("EXCEPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS")) + else if (param.equals_ci("BANS") || param.equals_ci("EXEMPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS")) { const Anope::string &mname = param.upper().substr(0, param.length() - 1); ChannelMode *cm = ModeManager::FindChannelModeByName(mname); @@ -446,7 +431,7 @@ class CommandCSMode : public Command source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str()); else if (subcommand.equals_ci("LOCK") && params.size() > 2) { - if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set")) + if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration")) source.Reply(ACCESS_DENIED); else this->DoLock(source, ci, params); @@ -455,7 +440,7 @@ class CommandCSMode : public Command this->DoSet(source, ci, params); else if (subcommand.equals_ci("CLEAR")) { - if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set")) + if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration")) source.Reply(ACCESS_DENIED); else this->DoClear(source, ci, params); @@ -500,10 +485,9 @@ class CSMode : public Module CommandCSMode commandcsmode; public: - CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsmode(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp index a79942fc3..feeb605bc 100644 --- a/modules/commands/cs_register.cpp +++ b/modules/commands/cs_register.cpp @@ -26,6 +26,7 @@ class CommandCSRegister : public Command { const Anope::string &chan = params[0]; const Anope::string &chdesc = params.size() > 1 ? params[1] : ""; + unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); User *u = source.GetUser(); NickCore *nc = source.nc; @@ -48,19 +49,14 @@ class CommandCSRegister : public Command source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); else if (c && !c->HasUserStatus(u, "OP")) source.Reply(_("You must be a channel operator to register the channel.")); - else if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) - source.Reply(nc->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg); + else if (maxregistered && nc->channelcount >= maxregistered && !source.HasPriv("chanserv/no-register-limit")) + source.Reply(nc->channelcount > maxregistered ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, maxregistered); else { ci = new ChannelInfo(chan); ci->SetFounder(nc); ci->desc = chdesc; - for (std::list<std::pair<Anope::string, Anope::string> >::const_iterator it = ModeManager::ModeLockOn.begin(), it_end = ModeManager::ModeLockOn.end(); it != it_end; ++it) - ci->SetMLock(ModeManager::FindChannelModeByName(it->first), true, it->second, source.GetNick()); - for (std::list<Anope::string>::const_iterator it = ModeManager::ModeLockOff.begin(), it_end = ModeManager::ModeLockOff.end(); it != it_end; ++it) - ci->SetMLock(ModeManager::FindChannelModeByName(*it), false, "", source.GetNick()); - if (c && !c->topic.empty()) { ci->last_topic = c->topic; @@ -77,22 +73,14 @@ class CommandCSRegister : public Command if (c) { c->CheckModes(); - - ChannelMode *cm; - if (u && u->FindChannel(c) != NULL) - { - /* On most ircds you do not receive the admin/owner mode till its registered */ - if ((cm = ModeManager::FindChannelModeByName("OWNER"))) - c->SetMode(NULL, cm, u->GetUID()); - else if ((cm = ModeManager::FindChannelModeByName("PROTECT"))) - c->RemoveMode(NULL, cm, u->GetUID()); - } + if (u) + c->SetCorrectModes(u, true, true); /* Mark the channel as persistent */ if (c->HasMode("PERM")) ci->Extend("PERSIST"); /* Persist may be in def cflags, set it here */ - else if (ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM"))) + else if (ci->HasExt("PERSIST")) c->SetMode(NULL, "PERM"); } @@ -121,9 +109,8 @@ class CommandCSRegister : public Command "other channel users.\n" " \n" "NOTICE: In order to register a channel, you must have\n" - "first registered your nickname. If you haven't,\n" - "\002%s%s HELP\002 for information on how to do so."), - source.service->nick.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + "first registered your nickname."), + source.service->nick.c_str(), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -134,10 +121,9 @@ class CSRegister : public Module CommandCSRegister commandcsregister; public: - CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsregister(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp index 10c23dd53..610ad4475 100644 --- a/modules/commands/cs_seen.cpp +++ b/modules/commands/cs_seen.cpp @@ -60,10 +60,10 @@ struct SeenInfo : Serializable s = anope_dynamic_static_cast<SeenInfo *>(obj); else { - /* ignore duplicate entries in the db, created by an old bug */ - s = FindInfo(snick); - if (!s) - s = new SeenInfo(); + SeenInfo* &info = database[snick]; + if (!info) + info = new SeenInfo(); + s = info; } data["nick"] >> s->nick; @@ -82,9 +82,6 @@ struct SeenInfo : Serializable } }; -static time_t purgetime; -static time_t expiretimeout; - static SeenInfo *FindInfo(const Anope::string &nick) { database_map::iterator iter = database.find(nick); @@ -192,9 +189,9 @@ class CommandSeen : public Command { const Anope::string &target = params[0]; - if (target.length() > Config->NickLen) + if (target.length() > Config->GetBlock("networkinfo")->Get<unsigned>("nicklen")) { - source.Reply(_("Nick too long, max length is %u characters."), Config->NickLen); + source.Reply(_("Nick too long, max length is %u characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen")); return; } @@ -300,7 +297,9 @@ class DataBasePurger : public Timer void Tick(time_t) anope_override { - size_t previous_size = database.size(); + size_t previous_size = database.size(), purgetime = Config->GetModule(this->GetOwner())->Get<time_t>("purgetime"); + if (!purgetime) + purgetime = Anope::DoTime("30d"); for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;) { database_map::iterator cur = it; @@ -324,9 +323,8 @@ class CSSeen : public Module CommandOSSeen commandosseen; DataBasePurger purger; public: - CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), seeninfo_type("SeenInfo", SeenInfo::Unserialize), commandseen(this), commandosseen(this), purger(this) + CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), seeninfo_type("SeenInfo", SeenInfo::Unserialize), commandseen(this), commandosseen(this), purger(this) { - this->SetAuthor("Anope"); Implementation eventlist[] = { I_OnReload, I_OnUserConnect, @@ -334,17 +332,15 @@ class CSSeen : public Module I_OnUserQuit, I_OnJoinChannel, I_OnPartChannel, - I_OnUserKicked }; + I_OnPreUserKicked }; ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); - - OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - purgetime = Anope::DoTime(config.ReadValue("cs_seen", "purgetime", "30d", 0)); - expiretimeout = Anope::DoTime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0)); + time_t expiretimeout = conf->GetModule(this)->Get<time_t>("expiretimeout"); + if (!expiretimeout) + expiretimeout = Anope::DoTime("1d"); if (purger.GetSecs() != expiretimeout) purger.SetSecs(expiretimeout); @@ -377,9 +373,9 @@ class CSSeen : public Module UpdateUser(u, PART, u->nick, "", channel, msg); } - void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &msg) anope_override + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) anope_override { - UpdateUser(target, KICK, target->nick, source.GetSource(), c->name, msg); + UpdateUser(cu->user, KICK, cu->user->nick, source.GetSource(), cu->chan->name, msg); } private: @@ -388,12 +384,9 @@ class CSSeen : public Module if (!u->server->IsSynced()) return; - SeenInfo *info = FindInfo(nick); + SeenInfo* &info = database[nick]; if (!info) - { - info = new SeenInfo; - database.insert(std::pair<Anope::string, SeenInfo *>(nick, info)); - } + info = new SeenInfo(); info->nick = nick; info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost(); info->type = Type; diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp index e3d2493ff..0de1a39ad 100644 --- a/modules/commands/cs_set.cpp +++ b/modules/commands/cs_set.cpp @@ -50,51 +50,7 @@ class CommandCSSet : public Command } } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n" - "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); - return true; - } -}; - -class CommandCSSASet : public Command -{ - public: - CommandCSSASet(Module *creator) : Command(creator, "chanserv/saset", 2, 3) - { - this->SetDesc(_("Forcefully set channel options and information")); - this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->OnSyntaxError(source, ""); - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows Services Operators to forcefully change settings\n" - "on channels.\n" - " \n" - "Available options:")); - Anope::string this_name = source.command; - for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) - { - const Anope::string &c_name = it->first; - const CommandInfo &info = it->second; - if (c_name.find_ci(this_name + " ") == 0) - { - ServiceReference<Command> command("Command", info.name); - if (command) - { - source.command = it->first; - command->OnServHelp(source); - } - } - } - source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n" - "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } }; @@ -122,7 +78,7 @@ class CommandCSSetAutoOp : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -130,11 +86,13 @@ class CommandCSSetAutoOp : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable autoop"; ci->Shrink("NOAUTOOP"); source.Reply(_("Services will now automatically give modes to users in \002%s\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable autoop"; ci->ExtendMetadata("NOAUTOOP"); source.Reply(_("Services will no longer automatically give modes to users in \002%s\002."), ci->name.c_str()); } @@ -148,8 +106,8 @@ class CommandCSSetAutoOp : public Command source.Reply(" "); source.Reply(_("Enables or disables %s's autoop feature for a\n" "channel. When disabled, users who join the channel will\n" - "not automatically gain any status from %s."), Config->ChanServ.c_str(), - Config->ChanServ.c_str(), this->name.c_str()); + "not automatically gain any status from %s."), ChanServ->nick.c_str(), + ChanServ->nick.c_str(), this->name.c_str()); return true; } }; @@ -177,7 +135,7 @@ class CommandCSSetBanType : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -188,6 +146,7 @@ class CommandCSSetBanType : public Command int16_t new_type = convertTo<int16_t>(params[1]); if (new_type < 0 || new_type > 3) throw ConvertException("Invalid range"); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the ban type to " << new_type; ci->bantype = new_type; source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype); } @@ -195,8 +154,6 @@ class CommandCSSetBanType : public Command { source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str()); } - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -239,7 +196,7 @@ class CommandCSSetChanstats : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -249,15 +206,16 @@ class CommandCSSetChanstats : public Command { ci->ExtendMetadata("STATS"); source.Reply(_("Chanstats statistics are now enabled for this channel.")); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable chanstats"; } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable chanstats"; ci->Shrink("STATS"); source.Reply(_("Chanstats statistics are now disabled for this channel.")); } else this->OnSyntaxError(source, ""); - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -292,7 +250,7 @@ class CommandCSSetDescription : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -301,11 +259,13 @@ class CommandCSSetDescription : public Command if (params.size() > 1) { ci->desc = params[1]; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the description to " << ci->desc; source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str()); } else { ci->desc.clear(); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset the description"; source.Reply(_("Description of %s unset."), ci->name.c_str()); } @@ -345,7 +305,7 @@ class CommandCSSetFounder : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"))) + if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -359,13 +319,14 @@ class CommandCSSetFounder : public Command } NickCore *nc = na->nc; - if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) + unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); + if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit")) { source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str()); return; } - Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display; ci->SetFounder(nc); @@ -407,7 +368,7 @@ class CommandCSSetKeepTopic : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -415,18 +376,18 @@ class CommandCSSetKeepTopic : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic"; ci->ExtendMetadata("KEEPTOPIC"); source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic"; ci->Shrink("KEEPTOPIC"); source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str()); } else this->OnSyntaxError(source, "KEEPTOPIC"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -464,7 +425,7 @@ class CommandCSSetPeace : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -472,11 +433,13 @@ class CommandCSSetPeace : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable peace"; ci->ExtendMetadata("PEACE"); source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable peace"; ci->Shrink("PEACE"); source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str()); } @@ -521,7 +484,7 @@ class CommandCSSetPersist : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -538,7 +501,8 @@ class CommandCSSetPersist : public Command /* Channel doesn't exist, create it */ if (!ci->c) { - Channel *c = new Channel(ci->name); + bool created; + Channel *c = Channel::FindOrCreate(ci->name, created); if (ci->bi) ci->bi->Join(c); } @@ -568,6 +532,7 @@ class CommandCSSetPersist : public Command } } + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable persist"; source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) @@ -588,7 +553,7 @@ class CommandCSSetPersist : public Command /* No channel mode, no BotServ, but using ChanServ as the botserv bot * which was assigned when persist was set on */ - if (!cm && Config->BotServ.empty() && ci->bi) + if (!cm && !BotServ && ci->bi) { if (!ChanServ) { @@ -600,6 +565,7 @@ class CommandCSSetPersist : public Command } } + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable persist"; source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str()); } else @@ -658,7 +624,7 @@ class CommandCSSetPrivate : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -666,11 +632,13 @@ class CommandCSSetPrivate : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private"; ci->ExtendMetadata("PRIVATE"); source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private"; ci->Shrink("PRIVATE"); source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str()); } @@ -687,7 +655,7 @@ class CommandCSSetPrivate : public Command source.Reply(_("Enables or disables the \002private\002 option for a channel.\n" "When \002private\002 is set, a \002%s%s LIST\002 will not\n" "include the channel in any lists."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -715,7 +683,7 @@ class CommandCSSetRestricted : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -723,18 +691,18 @@ class CommandCSSetRestricted : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable restricted"; ci->ExtendMetadata("RESTRICTED"); source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable restricted"; ci->Shrink("RESTRICTED"); source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str()); } else this->OnSyntaxError(source, "RESTRICTED"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -771,7 +739,7 @@ class CommandCSSetSecure : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -779,18 +747,18 @@ class CommandCSSetSecure : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure"; ci->ExtendMetadata("SECURE"); source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure"; ci->Shrink("SECURE"); source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str()); } else this->OnSyntaxError(source, "SECURE"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -829,7 +797,7 @@ class CommandCSSetSecureFounder : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"))) + if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -837,18 +805,18 @@ class CommandCSSetSecureFounder : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure founder"; ci->ExtendMetadata("SECUREFOUNDER"); source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure founder"; ci->Shrink("SECUREFOUNDER"); source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str()); } else this->OnSyntaxError(source, "SECUREFOUNDER"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -887,7 +855,7 @@ class CommandCSSetSecureOps : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -895,18 +863,18 @@ class CommandCSSetSecureOps : public Command if (params[1].equals_ci("ON")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure ops"; ci->ExtendMetadata("SECUREOPS"); source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure ops"; ci->Shrink("SECUREOPS"); source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str()); } else this->OnSyntaxError(source, "SECUREOPS"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -943,7 +911,7 @@ class CommandCSSetSignKick : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -954,6 +922,7 @@ class CommandCSSetSignKick : public Command ci->ExtendMetadata("SIGNKICK"); ci->Shrink("SIGNKICK_LEVEL"); source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str()); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick"; } else if (params[1].equals_ci("LEVEL")) { @@ -961,12 +930,14 @@ class CommandCSSetSignKick : public Command ci->Shrink("SIGNKICK"); source.Reply(_("Signed kick option for %s is now \002on\002, but depends of the\n" "level of the user that is using the command."), ci->name.c_str()); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick level"; } else if (params[1].equals_ci("OFF")) { ci->Shrink("SIGNKICK"); ci->Shrink("SIGNKICK_LEVEL"); source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str()); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable sign kick"; } else this->OnSyntaxError(source, "SIGNKICK"); @@ -1011,7 +982,7 @@ class CommandCSSetSuccessor : public Command if (MOD_RESULT == EVENT_STOP) return; - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"))) + if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -1057,18 +1028,20 @@ class CommandCSSetSuccessor : public Command source.Reply(_("Changes the successor of a channel. If the founder's\n" "nickname expires or is dropped while the channel is still\n" "registered, the successor will become the new founder of the\n" - "channel. However, if the successor already has too many\n" + "channel. The new nickname must be a registered one.")); + unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); + if (max_reg) + source.Reply(_("However, if the successor already has too many\n" "channels registered (%d), the channel will be dropped\n" - "instead, just as if no successor had been set. The new\n" - "nickname must be a registered one."), Config->CSMaxReg); + "instead, just as if no successor had been set."), max_reg); return true; } }; -class CommandCSSASetNoexpire : public Command +class CommandCSSetNoexpire : public Command { public: - CommandCSSASetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2) + CommandCSSetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2) { this->SetDesc(_("Prevent the channel from expiring")); this->SetSyntax(_("\037channel\037 {ON | OFF}")); @@ -1091,11 +1064,13 @@ class CommandCSSASetNoexpire : public Command if (params[1].equals_ci("ON")) { + Log(LOG_ADMIN, source, this, ci) << "to enable noexpire"; ci->ExtendMetadata("NO_EXPIRE"); source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { + Log(LOG_ADMIN, source, this, ci) << "to disable noexpire"; ci->Shrink("NO_EXPIRE"); source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str()); } @@ -1118,7 +1093,6 @@ class CommandCSSASetNoexpire : public Command class CSSet : public Module { CommandCSSet commandcsset; - CommandCSSASet commandcssaset; CommandCSSetAutoOp commandcssetautoop; CommandCSSetBanType commandcssetbantype; CommandCSSetChanstats commandcssetchanstats; @@ -1135,34 +1109,19 @@ class CSSet : public Module CommandCSSetSecureOps commandcssetsecureops; CommandCSSetSignKick commandcssetsignkick; CommandCSSetSuccessor commandcssetsuccessor; - CommandCSSASetNoexpire commandcssasetnoexpire; + CommandCSSetNoexpire commandcssetnoexpire; public: - CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsset(this), commandcssaset(this), commandcssetautoop(this), commandcssetbantype(this), commandcssetchanstats(this), + CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + commandcsset(this), commandcssetautoop(this), commandcssetbantype(this), commandcssetchanstats(this), CSDefChanstats(false), commandcssetdescription(this), commandcssetfounder(this), commandcssetkeeptopic(this), commandcssetpeace(this), commandcssetpersist(this), commandcssetprivate(this), commandcssetrestricted(this), commandcssetsecure(this), commandcssetsecurefounder(this), commandcssetsecureops(this), commandcssetsignkick(this), - commandcssetsuccessor(this), commandcssasetnoexpire(this) + commandcssetsuccessor(this), commandcssetnoexpire(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCheckKick, I_OnDelChan }; + Implementation i[] = { I_OnCheckKick, I_OnDelChan }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); - } - - void OnReload() anope_override - { - ConfigReader config; - CSDefChanstats = config.ReadFlag("chanstats", "CSDefChanstats", "0", 0); - } - - void OnChanRegistered(ChannelInfo *ci) anope_override - { - if (CSDefChanstats) - ci->ExtendMetadata("STATS"); } EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp index 3b6e761a7..9402f5b78 100644 --- a/modules/commands/cs_set_misc.cpp +++ b/modules/commands/cs_set_misc.cpp @@ -135,30 +135,26 @@ class CSSetMisc : public Module CommandCSSetMisc commandcssetmisc; public: - CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), csmiscdata_type("CSMiscData", CSMiscData::Unserialize), commandcssetmisc(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnChanInfo }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - descriptions.clear(); - for (int i = 0; i < config.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (config.ReadValue("command", "command", "", i) != "chanserv/set/misc") + Configuration::Block *block = conf->GetBlock("command", i); + + if (block->Get<const Anope::string>("command") != "chanserv/set/misc") continue; - Anope::string cname = config.ReadValue("command", "name", "", i); - Anope::string desc = config.ReadValue("command", "misc_description", "", i); + Anope::string cname = block->Get<const Anope::string>("name"); + Anope::string desc = block->Get<const Anope::string>("misc_description"); if (cname.empty() || desc.empty()) continue; diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp index 1d1aa619c..50f7080ac 100644 --- a/modules/commands/cs_status.cpp +++ b/modules/commands/cs_status.cpp @@ -104,9 +104,8 @@ class CSStatus : public Module CommandCSStatus commandcsstatus; public: - CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsstatus(this) + CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsstatus(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp index fdfd2d55a..a26cbacd5 100644 --- a/modules/commands/cs_suspend.cpp +++ b/modules/commands/cs_suspend.cpp @@ -27,8 +27,7 @@ class CommandCSSuspend : public Command const Anope::string &chan = params[0]; Anope::string expiry = params.size() > 1 ? params[1] : ""; Anope::string reason = params.size() > 2 ? params[2] : ""; - time_t expiry_secs = Config->CSSuspendExpire; - + time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire"); if (!expiry.empty() && expiry[0] != '+') { @@ -39,12 +38,6 @@ class CommandCSSuspend : public Command else expiry_secs = Anope::DoTime(expiry); - if (Config->ForceForbidReason && reason.empty()) - { - this->OnSyntaxError(source, ""); - return; - } - if (Anope::ReadOnly) source.Reply(READ_ONLY_MODE); @@ -66,7 +59,7 @@ class CommandCSSuspend : public Command for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (!user->HasMode("OPER") && user->server != Me) users.push_back(user); @@ -164,15 +157,16 @@ class CSSuspend : public Module CommandCSUnSuspend commandcsunsuspend; public: - CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcssuspend(this), commandcsunsuspend(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnPreChanExpire, I_OnCheckKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } + // cs info output? + void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override { if (!ci->HasExt("SUSPENDED")) diff --git a/modules/commands/cs_sync.cpp b/modules/commands/cs_sync.cpp index 1a02c813c..9e6dfb0ec 100644 --- a/modules/commands/cs_sync.cpp +++ b/modules/commands/cs_sync.cpp @@ -35,7 +35,7 @@ class CommandCSSync : public Command Log(LOG_COMMAND, source, this, ci); for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) - ci->c->SetCorrectModes((*it)->user, true, false); + ci->c->SetCorrectModes(it->second->user, true, false); source.Reply(_("All user modes on \002%s\002 have been synced."), ci->name.c_str()); } @@ -55,10 +55,9 @@ class CSSync : public Module { CommandCSSync commandcssync; public: - CSSync(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSSync(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcssync(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp index c98c5c958..64e710017 100644 --- a/modules/commands/cs_topic.cpp +++ b/modules/commands/cs_topic.cpp @@ -122,10 +122,9 @@ class CSTopic : public Module CommandCSTopic commandcstopic; public: - CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcstopic(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp index eaf371a34..8b90ee93d 100644 --- a/modules/commands/cs_unban.cpp +++ b/modules/commands/cs_unban.cpp @@ -107,10 +107,9 @@ class CSUnban : public Module CommandCSUnban commandcsunban; public: - CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsunban(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_updown.cpp b/modules/commands/cs_updown.cpp index 27e1984d1..8a8f3f336 100644 --- a/modules/commands/cs_updown.cpp +++ b/modules/commands/cs_updown.cpp @@ -30,7 +30,7 @@ class CommandCSUp : public Command return; for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it) { - Channel *c = (*it)->chan; + Channel *c = it->second->chan; c->SetCorrectModes(source.GetUser(), true, false); } } @@ -87,13 +87,10 @@ class CommandCSDown : public Command { void RemoveAll(User *u, Channel *c) { - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - { - ChannelMode *cm = ModeManager::ChannelModes[i]; - - if (cm != NULL && cm->type == MODE_STATUS) - c->RemoveMode(NULL, cm, u->nick); - } + ChanUserContainer *cu = c->FindUser(u); + if (cu != NULL) + for (size_t i = 0; i < cu->status.Modes().length(); ++i) + c->RemoveMode(NULL, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), u->GetUID()); } public: @@ -111,7 +108,7 @@ class CommandCSDown : public Command return; for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it) { - Channel *c = (*it)->chan; + Channel *c = it->second->chan; RemoveAll(source.GetUser(), c); } } @@ -169,10 +166,9 @@ class CSUpDown : public Module CommandCSDown commandcsdown; public: - CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsup(this), commandcsdown(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 546175e14..9efde866c 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -9,93 +9,18 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" -enum XOPType +namespace { - XOP_QOP, - XOP_SOP, - XOP_AOP, - XOP_HOP, - XOP_VOP, - XOP_UNKNOWN -}; - -static struct XOPAccess -{ - XOPType type; - Anope::string name; - Anope::string access[10]; -} xopAccess[] = { - { XOP_QOP, "QOP", - { - "SIGNKICK", - "SET", - "MODE", - "AUTOOWNER", - "OWNERME", - "PROTECT", - "INFO", - "ASSIGN", - "" - } - }, - { XOP_SOP, "SOP", - { - "AUTOPROTECT", - "AKICK", - "BADWORDS", - "MEMO", - "ACCESS_CHANGE", - "PROTECTME", - "OPDEOP", - "" - } - }, - { XOP_AOP, "AOP", - { - "TOPIC", - "GETKEY", - "INVITE", - "AUTOOP", - "OPDEOPME", - "HALFOP", - "SAY", - "GREET", - "" - } - }, - { XOP_HOP, "HOP", - { - "AUTOHALFOP", - "HALFOPME", - "VOICE", - "KICK", - "BAN", - "UNBAN", - "" - } - }, - { XOP_VOP, "VOP", - { - "AUTOVOICE", - "VOICEME", - "ACCESS_LIST", - "FANTASIA", - "NOKICK", - "" - } - }, - { XOP_UNKNOWN, "", { } - } -}; + std::vector<Anope::string> order; + std::map<Anope::string, std::vector<Anope::string> > permissions; +} class XOPChanAccess : public ChanAccess { public: - XOPType type; + Anope::string type; XOPChanAccess(AccessProvider *p) : ChanAccess(p) { @@ -103,51 +28,26 @@ class XOPChanAccess : public ChanAccess bool HasPriv(const Anope::string &priv) const anope_override { - for (int i = 0; xopAccess[i].type != XOP_UNKNOWN; ++i) + for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it) { - XOPAccess &x = xopAccess[i]; - - if (this->type > x.type) - continue; - - for (int j = 0; !x.access[j].empty(); ++j) - if (x.access[j] == priv) - return true; + const std::vector<Anope::string> &privs = permissions[*it]; + if (std::find(privs.begin(), privs.end(), priv) != privs.end()) + return true; } - return false; } Anope::string AccessSerialize() const { - for (int i = 0; xopAccess[i].type != XOP_UNKNOWN; ++i) - { - XOPAccess &x = xopAccess[i]; - - if (this->type == x.type) - return x.name; - } - - return ""; + return this->type; } void AccessUnserialize(const Anope::string &data) anope_override { - for (int i = 0; xopAccess[i].type != XOP_UNKNOWN; ++i) - { - XOPAccess &x = xopAccess[i]; - - if (data == x.name) - { - this->type = x.type; - return; - } - } - - this->type = XOP_UNKNOWN; + this->type = data; } - static XOPType DetermineLevel(const ChanAccess *access) + static Anope::string DetermineLevel(const ChanAccess *access) { if (access->provider->name == "access/xop") { @@ -156,26 +56,24 @@ class XOPChanAccess : public ChanAccess } else { - int count[XOP_UNKNOWN]; - for (int i = 0; i < XOP_UNKNOWN; ++i) - count[i] = 0; + std::map<Anope::string, int> count; - for (int i = 0; xopAccess[i].type != XOP_UNKNOWN; ++i) + for (std::map<Anope::string, std::vector<Anope::string> >::const_iterator it = permissions.begin(), it_end = permissions.end(); it != it_end; ++it) { - XOPAccess &x = xopAccess[i]; - - for (int j = 0; !x.access[j].empty(); ++j) - if (access->HasPriv(x.access[j])) - ++count[x.type]; + int &c = count[it->first]; + const std::vector<Anope::string> &perms = it->second; + for (unsigned i = 0; i < perms.size(); ++i) + if (access->HasPriv(perms[i])) + ++c; } - XOPType max = XOP_UNKNOWN; + Anope::string max; int maxn = 0; - for (int i = 0; i < XOP_UNKNOWN; ++i) - if (count[i] > maxn) + for (std::map<Anope::string, int>::iterator it = count.begin(), it_end = count.end(); it != it_end; ++it) + if (it->second > maxn) { - max = static_cast<XOPType>(i); - maxn = count[i]; + maxn = it->second; + max = it->first; } return max; @@ -196,12 +94,11 @@ class XOPAccessProvider : public AccessProvider } }; -class XOPBase : public Command +class CommandCSXOP : public Command { private: - void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms, XOPType level) + void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) { - Anope::string mask = params.size() > 2 ? params[2] : ""; if (mask.empty()) @@ -218,7 +115,7 @@ class XOPBase : public Command XOPChanAccess tmp_access(NULL); tmp_access.ci = ci; - tmp_access.type = level; + tmp_access.type = source.command.upper(); AccessGroup access = source.AccessFor(ci); const ChanAccess *highest = access.Highest(); @@ -264,9 +161,10 @@ class XOPBase : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d %s entries on a channel."), Config->CSAccessMax, source.command.c_str()); + source.Reply(_("Sorry, you can only have %d %s entries on a channel."), access_max, source.command.c_str()); return; } @@ -277,7 +175,7 @@ class XOPBase : public Command acc->ci = ci; acc->mask = mask; acc->creator = source.GetNick(); - acc->type = level; + acc->type = source.command.upper(); acc->last_seen = 0; acc->created = Anope::CurTime; ci->AddAccess(acc); @@ -288,7 +186,7 @@ class XOPBase : public Command source.Reply(_("\002%s\002 added to %s %s list."), acc->mask.c_str(), ci->name.c_str(), source.command.c_str()); } - void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms, XOPType level) + void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) { NickCore *nc = source.nc; Anope::string mask = params.size() > 2 ? params[2] : ""; @@ -313,7 +211,7 @@ class XOPBase : public Command XOPChanAccess tmp_access(NULL); tmp_access.ci = ci; - tmp_access.type = level; + tmp_access.type = source.command.upper(); AccessGroup access = source.AccessFor(ci); const ChanAccess *highest = access.Highest(); @@ -353,9 +251,8 @@ class XOPBase : public Command unsigned deleted; Anope::string nicks; bool override; - XOPType type; public: - XOPDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, bool _override, XOPType _type, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), override(_override), type(_type) + XOPDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, bool _override, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), override(_override) { } @@ -381,7 +278,7 @@ class XOPBase : public Command ChanAccess *caccess = ci->GetAccess(number - 1); - if (this->type != XOPChanAccess::DetermineLevel(caccess)) + if (this->source.command.upper() != XOPChanAccess::DetermineLevel(caccess)) return; ++deleted; @@ -395,7 +292,7 @@ class XOPBase : public Command ci->EraseAccess(number - 1); } } - delcallback(source, ci, this, override, level, mask); + delcallback(source, ci, this, override, mask); delcallback.Process(); } else @@ -404,7 +301,7 @@ class XOPBase : public Command { ChanAccess *a = ci->GetAccess(i); - if (a->mask.equals_ci(mask) && XOPChanAccess::DetermineLevel(a) == level) + if (a->mask.equals_ci(mask) && XOPChanAccess::DetermineLevel(a) == source.command.upper()) { Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->mask; @@ -421,7 +318,7 @@ class XOPBase : public Command } } - void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms, XOPType level) + void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) { const Anope::string &nick = params.size() > 2 ? params[2] : ""; @@ -449,9 +346,9 @@ class XOPBase : public Command { ListFormatter &list; ChannelInfo *ci; - XOPType type; + CommandSource &source; public: - XOPListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, XOPType _type) : NumberList(numlist, false), list(_list), ci(_ci), type(_type) + XOPListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, CommandSource &src) : NumberList(numlist, false), list(_list), ci(_ci), source(src) { } @@ -462,7 +359,7 @@ class XOPBase : public Command const ChanAccess *a = ci->GetAccess(Number - 1); - if (this->type != XOPChanAccess::DetermineLevel(a)) + if (this->source.command.upper() != XOPChanAccess::DetermineLevel(a)) return; ListFormatter::ListEntry entry; @@ -470,7 +367,7 @@ class XOPBase : public Command entry["Mask"] = a->mask; this->list.AddEntry(entry); } - } nl_list(list, ci, nick, level); + } nl_list(list, ci, nick, source); nl_list.Process(); } else @@ -479,7 +376,7 @@ class XOPBase : public Command { const ChanAccess *a = ci->GetAccess(i); - if (XOPChanAccess::DetermineLevel(a) != level) + if (XOPChanAccess::DetermineLevel(a) != source.command.upper()) continue; else if (!nick.empty() && !Anope::Match(a->mask, nick)) continue; @@ -504,9 +401,8 @@ class XOPBase : public Command } } - void DoClear(CommandSource &source, ChannelInfo *ci, XOPType level) + void DoClear(CommandSource &source, ChannelInfo *ci) { - if (Anope::ReadOnly) { source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str()); @@ -531,19 +427,30 @@ class XOPBase : public Command for (unsigned i = ci->GetAccessCount(); i > 0; --i) { const ChanAccess *access = ci->GetAccess(i - 1); - if (XOPChanAccess::DetermineLevel(access) == level) + if (XOPChanAccess::DetermineLevel(access) == source.command.upper()) ci->EraseAccess(i - 1); } FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, source)); source.Reply(_("Channel %s %s list has been cleared."), ci->name.c_str(), source.command.c_str()); + } - return; + public: + CommandCSXOP(Module *modname) : Command(modname, "chanserv/xop", 2, 4) + { + this->SetSyntax("\037channel\037 ADD \037mask\037"); + this->SetSyntax("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"); + this->SetSyntax("\037channel\037 LIST [\037mask\037 | \037list\037]"); + this->SetSyntax("\037channel\037 CLEAR"); + } + + const Anope::string GetDesc(CommandSource &source) const anope_override + { + return Anope::printf(_("Modify the list of %s users"), source.command.upper().c_str()); } - protected: - void DoXop(CommandSource &source, const std::vector<Anope::string> ¶ms, XOPType level) + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { ChannelInfo *ci = ChannelInfo::Find(params[0]); if (ci == NULL) @@ -555,321 +462,124 @@ class XOPBase : public Command const Anope::string &cmd = params[1]; if (cmd.equals_ci("ADD")) - return this->DoAdd(source, ci, params, level); + return this->DoAdd(source, ci, params); else if (cmd.equals_ci("DEL")) - return this->DoDel(source, ci, params, level); + return this->DoDel(source, ci, params); else if (cmd.equals_ci("LIST")) - return this->DoList(source, ci, params, level); + return this->DoList(source, ci, params); else if (cmd.equals_ci("CLEAR")) - return this->DoClear(source, ci, level); + return this->DoClear(source, ci); else this->OnSyntaxError(source, ""); - - return; - } - public: - XOPBase(Module *modname, const Anope::string &command) : Command(modname, command, 2, 4) - { - this->SetSyntax("\037channel\037 ADD \037mask\037"); - this->SetSyntax("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"); - this->SetSyntax("\037channel\037 LIST [\037mask\037 | \037list\037]"); - this->SetSyntax("\037channel\037 CLEAR"); } - virtual ~XOPBase() - { - } - - virtual void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) = 0; - - virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0; -}; - -class CommandCSQOP : public XOPBase -{ - public: - CommandCSQOP(Module *creator) : XOPBase(creator, "chanserv/qop") - { - this->SetDesc(_("Modify the list of QOP users")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - return this->DoXop(source, params, XOP_QOP); - } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Maintains the \002QOP\002 (AutoOwner) \002list\002 for a channel. The QOP\n" - "list gives users the right to be auto-owner on your channel,\n" - "which gives them almost (or potentially, total) access.\n" - " \n" - "The \002QOP ADD\002 command adds the given nickname to the\n" - "QOP list.\n" - " \n" - "The \002QOP DEL\002 command removes the given nick from the\n" - "QOP list. If a list of entry numbers is given, those\n" - "entries are deleted. (See the example for LIST below.)\n" - " \n" - "The \002QOP LIST\002 command displays the QOP list. If\n" - "a wildcard mask is given, only those entries matching the\n" - "mask are displayed. If a list of entry numbers is given,\n" - "only those entries are shown; for example:\n" - " \002QOP #channel LIST 2-5,7-9\002\n" - " Lists QOP entries numbered 2 through 5 and\n" - " 7 through 9.\n" - " \n" - "The \002QOP CLEAR\002 command clears all entries of the\n" - "QOP list.")); - source.Reply(_(" \n" - "The \002QOP\002 commands are limited to founders\n" - "(unless SECUREOPS is off). However, any user on the\n" - "VOP list or above may use the \002QOP LIST\002 command.\n" - " \n")); - source.Reply(_("Alternative methods of modifying channel access lists are\n" - "available. See \002%s%s HELP ACCESS\002 for information\n" - "about the access list, and \002%s%s HELP FLAGS\002 for\n" - "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); - return true; - } -}; - -class CommandCSAOP : public XOPBase -{ - public: - CommandCSAOP(Module *creator) : XOPBase(creator, "chanserv/aop") - { - this->SetDesc(_("Modify the list of AOP users")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - return this->DoXop(source, params, XOP_AOP); - } + const Anope::string &cmd = source.command.upper(); - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Maintains the \002AOP\002 (AutoOP) \002list\002 for a channel. The AOP\n" - "list gives users the right to be auto-opped on your channel,\n" - "to unban or invite themselves if needed, to have their\n" - "greet message showed on join, and so on.\n" - " \n" - "The \002AOP ADD\002 command adds the given nickname to the\n" - "AOP list.\n" - " \n" - "The \002AOP DEL\002 command removes the given nick from the\n" - "AOP list. If a list of entry numbers is given, those\n" - "entries are deleted. (See the example for LIST below.)\n" - " \n" - "The \002AOP LIST\002 command displays the AOP list. If\n" - "a wildcard mask is given, only those entries matching the\n" - "mask are displayed. If a list of entry numbers is given,\n" - "only those entries are shown; for example:\n" - " \002AOP #channel LIST 2-5,7-9\002\n" - " Lists AOP entries numbered 2 through 5 and\n" - " 7 through 9.\n" - " \n" - "The \002AOP CLEAR\002 command clears all entries of the\n" - "AOP list.")); - source.Reply(_(" \n" - "The \002AOP ADD\002 and \002AOP DEL\002 commands are limited to\n" - "SOPs or above, while the \002AOP CLEAR\002 command can only\n" - "be used by the channel founder. However, any user on the\n" - "VOP list or above may use the \002AOP LIST\002 command.\n" - " \n")); - source.Reply(_("Alternative methods of modifying channel access lists are\n" - "available. See \002%s%s HELP ACCESS\002 for information\n" - "about the access list, and \002%s%s HELP FLAGS\002 for\n" - "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); - return true; - } -}; + source.Reply(_("Maintains the \2%s list\2 for a channel. Users who match an access entry\n" + "on the %s list receive the following privileges:\n" + " "), cmd.c_str(), cmd.c_str()); -class CommandCSHOP : public XOPBase -{ - public: - CommandCSHOP(Module *creator) : XOPBase(creator, "chanserv/hop") - { - this->SetDesc(_("Maintains the HOP (HalfOP) list for a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - return this->DoXop(source, params, XOP_HOP); - } + Anope::string buf; + for (unsigned i = 0; i < permissions[cmd].size(); ++i) + { + buf += ", " + permissions[cmd][i]; + if (buf.length() > 75) + { + source.Reply(" %s\n", buf.substr(2).c_str()); + buf.clear(); + } + } + if (!buf.empty()) + { + source.Reply(" %s\n", buf.substr(2).c_str()); + buf.clear(); + } - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Maintains the \002HOP\002 (HalfOP) \002list\002 for a channel. The HOP\n" - "list gives users the right to be auto-halfopped on your\n" - "channel.\n" - " \n" - "The \002HOP ADD\002 command adds the given nickname to the\n" - "HOP list.\n" + source.Reply(_(" \n" + "The \002%s ADD\002 command adds the given nickname to the\n" + "%s list.\n" " \n" - "The \002HOP DEL\002 command removes the given nick from the\n" - "HOP list. If a list of entry numbers is given, those\n" + "The \002%s DEL\002 command removes the given nick from the\n" + "%s list. If a list of entry numbers is given, those\n" "entries are deleted. (See the example for LIST below.)\n" " \n" - "The \002HOP LIST\002 command displays the HOP list. If\n" + "The \002%s LIST\002 command displays the %s list. If\n" "a wildcard mask is given, only those entries matching the\n" "mask are displayed. If a list of entry numbers is given,\n" "only those entries are shown; for example:\n" - " \002HOP #channel LIST 2-5,7-9\002\n" - " Lists HOP entries numbered 2 through 5 and\n" + " \002%s #channel LIST 2-5,7-9\002\n" + " Lists %s entries numbered 2 through 5 and\n" " 7 through 9.\n" " \n" - "The \002HOP CLEAR\002 command clears all entries of the\n" - "HOP list.")); + "The \002%s CLEAR\002 command clears all entries of the\n" + "%s list."), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), + cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str()); source.Reply(_(" \n" - "The \002HOP ADD\002 and \002HOP DEL\002 commands are limited\n" - "to SOPs or above, while \002HOP LIST\002 is available to VOPs\n" - "and above. The \002HOP CLEAR\002 command can only be used by the\n" - "channel founder.\n" - " \n")); + "The \002%s\002 commands are limited to founders\n" + "(unless SECUREOPS is off). However, any user on the\n" + "VOP list or above may use the \002%s LIST\002 command.\n" + " \n"), cmd.c_str(), cmd.c_str()); source.Reply(_("Alternative methods of modifying channel access lists are\n" "available. See \002%s%s HELP ACCESS\002 for information\n" "about the access list, and \002%s%s HELP FLAGS\002 for\n" "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), + Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; -class CommandCSSOP : public XOPBase +class CSXOP : public Module { + XOPAccessProvider accessprovider; + CommandCSXOP commandcsxop; + public: - CommandCSSOP(Module *creator) : XOPBase(creator, "chanserv/sop") + CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + accessprovider(this), commandcsxop(this) { - this->SetDesc(_("Modify the list of SOP users")); - } + this->SetPermanent(true); - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - return this->DoXop(source, params, XOP_SOP); + Implementation i[] = { I_OnReload }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Maintains the \002SOP\002 (SuperOP) \002list\002 for a channel. The SOP\n" - "list gives users all rights given by the AOP list, and adds\n" - "those needed to use the AutoKick and the BadWords lists,\n" - "to send and read channel memos, and so on.\n" - " \n" - "The \002SOP ADD\002 command adds the given nickname to the\n" - "SOP list.\n" - " \n" - "The \002SOP DEL\002 command removes the given nick from the\n" - "SOP list. If a list of entry numbers is given, those\n" - "entries are deleted. (See the example for LIST below.)\n" - " \n" - "The \002SOP LIST\002 command displays the SOP list. If\n" - "a wildcard mask is given, only those entries matching the\n" - "mask are displayed. If a list of entry numbers is given,\n" - "only those entries are shown; for example:\n" - " \002SOP #channel LIST 2-5,7-9\002\n" - " Lists SOP entries numbered 2 through 5 and\n" - " 7 through 9.\n" - " \n" - "The \002SOP CLEAR\002 command clears all entries of the\n" - "SOP list.")); - source.Reply(_(" \n" - "The \002SOP ADD\002, \002SOP DEL\002 and \002SOP CLEAR\002 commands are\n" - "limited to the channel founder. However, any user on the\n" - "VOP list or above may use the \002SOP LIST\002 command.\n" - " \n")); - source.Reply(_("Alternative methods of modifying channel access lists are\n" - "available. See \002%s%s HELP ACCESS\002 for information\n" - "about the access list, and \002%s%s HELP FLAGS\002 for\n" - "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); - return true; - } -}; + order.clear(); + permissions.clear(); -class CommandCSVOP : public XOPBase -{ - public: - CommandCSVOP(Module *creator) : XOPBase(creator, "chanserv/vop") - { - this->SetDesc(_("Maintains the VOP (VOicePeople) list for a channel")); - } + for (int i = 0; i < conf->CountBlock("privilege"); ++i) + { + Configuration::Block *block = conf->GetBlock("privilege", i); + const Anope::string &pname = block->Get<const Anope::string>("name"); - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - return this->DoXop(source, params, XOP_VOP); - } + Privilege *p = PrivilegeManager::FindPrivilege(pname); + if (p == NULL) + continue; - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Maintains the \002VOP\002 (VOicePeople) \002list\002 for a channel.\n" - "The VOP list allows users to be auto-voiced and to voice\n" - "themselves if they aren't.\n" - " \n" - "The \002VOP ADD\002 command adds the given nickname to the\n" - "VOP list.\n" - " \n" - "The \002VOP DEL\002 command removes the given nick from the\n" - "VOP list. If a list of entry numbers is given, those\n" - "entries are deleted. (See the example for LIST below.)\n" - " \n" - "The \002VOP LIST\002 command displays the VOP list. If\n" - "a wildcard mask is given, only those entries matching the\n" - "mask are displayed. If a list of entry numbers is given,\n" - "only those entries are shown; for example:\n" - " \002VOP #channel LIST 2-5,7-9\002\n" - " Lists VOP entries numbered 2 through 5 and\n" - " 7 through 9.\n" - " \n" - "The \002VOP CLEAR\002 command clears all entries of the\n" - "VOP list.")); - source.Reply(_(" \n" - "The \002VOP ADD\002 and \002VOP DEL\002 commands are limited\n" - "to SOPs or above, while \002VOP LIST\002 is available to VOPs\n" - "and above. The \002VOP CLEAR\002 command can only be used by the\n" - "channel founder.\n" - " \n")); - source.Reply(_("Alternative methods of modifying channel access lists are\n" - "available. See \002%s%s HELP ACCESS\002 for information\n" - "about the access list, and \002%s%s HELP FLAGS\002 for\n" - "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); - return true; - } -}; + const Anope::string &xop = block->Get<const Anope::string>("xop"); + if (pname.empty() || xop.empty()) + continue; -class CSXOP : public Module -{ - XOPAccessProvider accessprovider; - CommandCSQOP commandcsqop; - CommandCSSOP commandcssop; - CommandCSAOP commandcsaop; - CommandCSHOP commandcshop; - CommandCSVOP commandcsvop; + permissions[xop].push_back(pname); + } - public: - CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - accessprovider(this), commandcsqop(this), commandcssop(this), commandcsaop(this), commandcshop(this), commandcsvop(this) - { - this->SetAuthor("Anope"); - this->SetPermanent(true); + for (int i = 0; i < conf->CountBlock("command"); ++i) + { + Configuration::Block *block = conf->GetBlock("command", i); + const Anope::string &cname = block->Get<const Anope::string>("name"), + &cserv = block->Get<const Anope::string>("command"); + if (cname.empty() || cserv != "chanserv/xop") + continue; + + order.push_back(cname); + } } }; diff --git a/modules/commands/gl_global.cpp b/modules/commands/gl_global.cpp index 7cc4dbdc8..70dd4d324 100644 --- a/modules/commands/gl_global.cpp +++ b/modules/commands/gl_global.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "global.h" class CommandGLGlobal : public Command { @@ -53,10 +52,9 @@ class GLGlobal : public Module CommandGLGlobal commandglglobal; public: - GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandglglobal(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/help.cpp b/modules/commands/help.cpp index fcac6863c..eaf45ebf4 100644 --- a/modules/commands/help.cpp +++ b/modules/commands/help.cpp @@ -46,6 +46,7 @@ class CommandHelp : public Command Anope::string source_command = source.command; const BotInfo *bi = source.service; const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands; + bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"); if (params.empty() || params[0].equals_ci("ALL")) { @@ -73,8 +74,8 @@ class CommandHelp : public Command ServiceReference<Command> c("Command", info.name); if (!c) continue; - else if (!Config->HidePrivilegedCommands) - ; // Always show with HidePrivilegedCommands disabled + else if (!hide_privileged_commands) + ; // Always show with hide_privileged_commands disabled else if (!c->AllowUnregistered() && !source.GetAccount()) continue; else if (!info.permission.empty() && !source.HasCommand(info.permission)) @@ -146,8 +147,8 @@ class CommandHelp : public Command ServiceReference<Command> c("Command", info.name); if (!c) continue; - else if (!Config->HidePrivilegedCommands) - ; // Always show with HidePrivilegedCommands disabled + else if (!hide_privileged_commands) + ; // Always show with hide_privileged_commands disabled else if (!info.permission.empty() && !source.HasCommand(info.permission)) continue; @@ -196,10 +197,9 @@ class Help : public Module CommandHelp commandhelp; public: - Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhelp(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp index 5df23e721..ad9347ce0 100644 --- a/modules/commands/hs_del.cpp +++ b/modules/commands/hs_del.cpp @@ -92,10 +92,9 @@ class HSDel : public Module CommandHSDelAll commandhsdelall; public: - HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsdel(this), commandhsdelall(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp index ee997f704..13062fc9e 100644 --- a/modules/commands/hs_group.cpp +++ b/modules/commands/hs_group.cpp @@ -32,7 +32,6 @@ class CommandHSGroup : public Command CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0) { this->SetDesc(_("Syncs the vhost for all nicks in a group")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -68,10 +67,9 @@ class HSGroup : public Module CommandHSGroup commandhsgroup; public: - HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsgroup(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp index 96e6866f0..6bf6d49a9 100644 --- a/modules/commands/hs_list.cpp +++ b/modules/commands/hs_list.cpp @@ -55,7 +55,7 @@ class CommandHSList : public Command } } - unsigned display_counter = 0; + unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); ListFormatter list; list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Creator").AddColumn("Created"); @@ -68,7 +68,7 @@ class CommandHSList : public Command if (!key.empty() && key[0] != '#') { - if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < Config->NSListMax) + if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax) { ++display_counter; @@ -90,7 +90,7 @@ class CommandHSList : public Command * List the host if its in the display range, and not more * than NSListMax records have been displayed... **/ - if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax) + if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax) { ++display_counter; ListFormatter::ListEntry entry; @@ -141,9 +141,7 @@ class CommandHSList : public Command "entries beginning with \"Rob\"\n" "If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n" "and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n" - "nick/vhost entries.\n" - "The list uses the value of NSListMax as a hard limit for the\n" - "number of items to display to a operator at any one time.")); + "nick/vhost entries.")); return true; } }; @@ -153,11 +151,9 @@ class HSList : public Module CommandHSList commandhslist; public: - HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhslist(this) { - this->SetAuthor("Anope"); - } }; diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp index 3db3c1adf..13a64c9d9 100644 --- a/modules/commands/hs_off.cpp +++ b/modules/commands/hs_off.cpp @@ -19,7 +19,6 @@ class CommandHSOff : public Command CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0) { this->SetDesc(_("Deactivates your assigned vhost")); - this->SetSyntax(""); this->RequireUser(true); } @@ -56,10 +55,9 @@ class HSOff : public Module CommandHSOff commandhsoff; public: - HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsoff(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp index e19482c9a..fb3ca1396 100644 --- a/modules/commands/hs_on.cpp +++ b/modules/commands/hs_on.cpp @@ -19,7 +19,6 @@ class CommandHSOn : public Command CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0) { this->SetDesc(_("Activates your assigned vhost")); - this->SetSyntax(""); this->RequireUser(true); } @@ -65,10 +64,9 @@ class HSOn : public Module CommandHSOn commandhson; public: - HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhson(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp index df104f721..99c5a4811 100644 --- a/modules/commands/hs_request.cpp +++ b/modules/commands/hs_request.cpp @@ -16,14 +16,10 @@ */ #include "module.h" -#include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); -static bool HSRequestMemoUser = false; -static bool HSRequestMemoOper = false; - -void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost); +static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost); struct HostRequest : ExtensibleItem, Serializable { @@ -114,9 +110,9 @@ class CommandHSRequest : public Command if (!user.empty()) { - if (user.length() > Config->UserLen) + if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) { - source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen); + source.Reply(HOST_SET_IDENTTOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("userlen")); return; } else if (!IRCD->CanSetVIdent) @@ -132,9 +128,9 @@ class CommandHSRequest : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } @@ -144,14 +140,14 @@ class CommandHSRequest : public Command return; } - if (HSRequestMemoOper && Config->MSSendDelay > 0 && u && u->lastmemosend + Config->MSSendDelay > Anope::CurTime) + time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); + if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime) { - source.Reply(_("Please wait %d seconds before requesting a new vHost."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay); u->lastmemosend = Anope::CurTime; return; } - HostRequest *req = new HostRequest; req->nick = source.GetNick(); req->ident = user; @@ -160,10 +156,8 @@ class CommandHSRequest : public Command na->Extend("hs_request", req); source.Reply(_("Your vHost has been requested.")); - req_send_memos(source, user, host); + req_send_memos(owner, source, user, host); Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host; - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -198,8 +192,8 @@ class CommandHSActivate : public Command na->SetVhost(req->ident, req->host, source.GetNick(), req->time); FOREACH_MOD(I_OnSetVhost, OnSetVhost(na)); - if (HSRequestMemoUser && MemoServService) - MemoServService->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true); + if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv) + memoserv->Send(HostServ->nick, na->nick, _("[auto memo] Your requested vHost has been approved."), true); source.Reply(_("vHost for %s has been activated."), na->nick.c_str()); Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host; @@ -214,7 +208,7 @@ class CommandHSActivate : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Activate the requested vHost for the given nick.")); - if (HSRequestMemoUser) + if (Config->GetModule(this->owner)->Get<bool>("memouser")) source.Reply(_("A memo informing the user will also be sent.")); return true; @@ -242,7 +236,7 @@ class CommandHSReject : public Command { na->Shrink("hs_request"); - if (HSRequestMemoUser && MemoServService) + if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv) { Anope::string message; if (!reason.empty()) @@ -250,7 +244,7 @@ class CommandHSReject : public Command else message = _("[auto memo] Your requested vHost has been rejected."); - MemoServService->Send(Config->HostServ, nick, message, true); + memoserv->Send(HostServ->nick, nick, message, true); } source.Reply(_("vHost for %s has been rejected."), nick.c_str()); @@ -267,7 +261,7 @@ class CommandHSReject : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Reject the requested vHost for the given nick.")); - if (HSRequestMemoUser) + if (Config->GetModule(this->owner)->Get<bool>("memouser")) source.Reply(_("A memo informing the user will also be sent.")); return true; @@ -280,7 +274,7 @@ class CommandHSWaiting : public Command { int counter = 1; int from = 0, to = 0; - unsigned display_counter = 0; + unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); ListFormatter list; list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Created"); @@ -292,7 +286,7 @@ class CommandHSWaiting : public Command if (!hr) continue; - if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax) + if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax) { ++display_counter; @@ -321,7 +315,6 @@ class CommandHSWaiting : public Command CommandHSWaiting(Module *creator) : Command(creator, "hostserv/waiting", 0, 0) { this->SetDesc(_("Retrieves the vhost requests")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -348,18 +341,12 @@ class HSRequest : public Module CommandHSWaiting commandhswaiting; public: - HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), request_type("HostRequest", HostRequest::Unserialize), commandhsrequest(this), commandhsactive(this), commandhsreject(this), commandhswaiting(this) { - this->SetAuthor("Anope"); if (!IRCD || !IRCD->CanSetVHost) throw ModuleException("Your IRCd does not support vhosts"); - - Implementation i[] = { I_OnReload }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } ~HSRequest() @@ -370,18 +357,9 @@ class HSRequest : public Module na->Shrink("hs_request"); } } - - void OnReload() anope_override - { - ConfigReader config; - HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0); - HSRequestMemoOper = config.ReadFlag("hs_request", "memooper", "no", 0); - - Log(LOG_DEBUG) << "[hs_request] Set config vars: MemoUser=" << HSRequestMemoUser << " MemoOper=" << HSRequestMemoOper; - } }; -void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) +static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) { Anope::string host; std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end; @@ -391,7 +369,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An else host = vHost; - if (HSRequestMemoOper == 1 && MemoServService) + if (Config->GetModule(me)->Get<bool>("memooper") && memoserv) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -402,7 +380,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str()); - MemoServService->Send(Config->HostServ, na->nick, message, true); + memoserv->Send(HostServ->nick, na->nick, message, true); } } diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp index 11ecbca5a..8e83ae8a8 100644 --- a/modules/commands/hs_set.cpp +++ b/modules/commands/hs_set.cpp @@ -67,9 +67,9 @@ class CommandHSSet : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } @@ -168,9 +168,9 @@ class CommandHSSetAll : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } @@ -211,9 +211,8 @@ class HSSet : public Module CommandHSSetAll commandhssetall; public: - HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandhsset(this), commandhssetall(this) + HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsset(this), commandhssetall(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_cancel.cpp b/modules/commands/ms_cancel.cpp index e03883d91..2ab605f40 100644 --- a/modules/commands/ms_cancel.cpp +++ b/modules/commands/ms_cancel.cpp @@ -12,9 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" - -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); class CommandMSCancel : public Command { @@ -27,10 +24,6 @@ class CommandMSCancel : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) - return; - - const Anope::string &nname = params[0]; bool ischan; @@ -78,13 +71,9 @@ class MSCancel : public Module CommandMSCancel commandmscancel; public: - MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmscancel(this) { - this->SetAuthor("Anope"); - - if (!MemoServService) - throw ModuleException("No MemoServ!"); } }; diff --git a/modules/commands/ms_check.cpp b/modules/commands/ms_check.cpp index 984126ee6..9a24e9973 100644 --- a/modules/commands/ms_check.cpp +++ b/modules/commands/ms_check.cpp @@ -76,10 +76,9 @@ class MSCheck : public Module CommandMSCheck commandmscheck; public: - MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmscheck(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_del.cpp b/modules/commands/ms_del.cpp index 33175d023..18927f8ee 100644 --- a/modules/commands/ms_del.cpp +++ b/modules/commands/ms_del.cpp @@ -153,10 +153,9 @@ class MSDel : public Module CommandMSDel commandmsdel; public: - MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsdel(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_ignore.cpp b/modules/commands/ms_ignore.cpp index 41e139eff..056b20128 100644 --- a/modules/commands/ms_ignore.cpp +++ b/modules/commands/ms_ignore.cpp @@ -13,7 +13,6 @@ #include "module.h" -#include "memoserv.h" static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); @@ -121,10 +120,9 @@ class MSIgnore : public Module CommandMSIgnore commandmsignore; public: - MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsignore(this) { - this->SetAuthor("Anope"); if (!MemoServService) throw ModuleException("No MemoServ!"); diff --git a/modules/commands/ms_info.cpp b/modules/commands/ms_info.cpp index 21ec9ba13..517e6b1ac 100644 --- a/modules/commands/ms_info.cpp +++ b/modules/commands/ms_info.cpp @@ -207,10 +207,9 @@ class MSInfo : public Module CommandMSInfo commandmsinfo; public: - MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsinfo(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_list.cpp b/modules/commands/ms_list.cpp index 3181f9dff..8b7ebeb62 100644 --- a/modules/commands/ms_list.cpp +++ b/modules/commands/ms_list.cpp @@ -156,10 +156,9 @@ class MSList : public Module CommandMSList commandmslist; public: - MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmslist(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp index 14b952922..7e1e89236 100644 --- a/modules/commands/ms_read.cpp +++ b/modules/commands/ms_read.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); @@ -71,10 +70,13 @@ class MemoListCallback : public NumberList static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index) { Memo *m = mi->GetMemo(index); + if (!m) + return; + if (ci) - source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), index + 1); + source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), index + 1); else - source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), index + 1); + source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), index + 1); source.Reply("%s", m->text.c_str()); m->unread = false; @@ -186,10 +188,9 @@ class MSRead : public Module CommandMSRead commandmsread; public: - MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsread(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp index e5c345c75..a9372c328 100644 --- a/modules/commands/ms_rsend.cpp +++ b/modules/commands/ms_rsend.cpp @@ -12,9 +12,11 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} class CommandMSRSend : public Command { @@ -27,10 +29,9 @@ class CommandMSRSend : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) + if (!memoserv) return; - const Anope::string &nick = params[0]; const Anope::string &text = params[1]; const NickAlias *na = NULL; @@ -42,25 +43,20 @@ class CommandMSRSend : public Command return; } - if (Config->MSMemoReceipt == 1 && !source.IsServicesOper()) + if (Config->GetModule(this->owner)->Get<bool>("operonly") && !source.IsServicesOper()) source.Reply(ACCESS_DENIED); - else if (Config->MSMemoReceipt > 2 || Config->MSMemoReceipt == 0) - { - Log(this->owner) << "MSMemoReceipt is misconfigured to " << Config->MSMemoReceipt; - source.Reply(_("Sorry, RSEND has been disabled on this network.")); - } else { - MemoServService::MemoResult result = MemoServService->Send(source.GetNick(), nick, text); + MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text); if (result == MemoServService::MEMO_INVALID_TARGET) source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str()); else if (result == MemoServService::MEMO_TOO_FAST) - source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str()); else if (result == MemoServService::MEMO_TARGET_FULL) source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str()); else { - source.Reply(_("Memo sent to \002%s\002."), name.c_str()); + source.Reply(_("Memo sent to \002%s\002."), nick.c_str()); bool ischan; MemoInfo *mi = MemoInfo::GetMemoInfo(nick, ischan); @@ -71,8 +67,6 @@ class CommandMSRSend : public Command m->receipt = true; } } - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -95,15 +89,11 @@ class MSRSend : public Module CommandMSRSend commandmsrsend; public: - MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsrsend(this) { - this->SetAuthor("Anope"); - - if (!MemoServService) + if (!memoserv) throw ModuleException("No MemoServ!"); - else if (!Config->MSMemoReceipt) - throw ModuleException("Invalid value for memoreceipt"); } }; diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp index f92955dcf..d4d63a383 100644 --- a/modules/commands/ms_send.cpp +++ b/modules/commands/ms_send.cpp @@ -12,9 +12,11 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} class CommandMSSend : public Command { @@ -27,23 +29,21 @@ class CommandMSSend : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) + if (!memoserv) return; const Anope::string &nick = params[0]; const Anope::string &text = params[1]; - MemoServService::MemoResult result = MemoServService->Send(source.GetNick(), nick, text); + MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text); if (result == MemoServService::MEMO_SUCCESS) source.Reply(_("Memo sent to \002%s\002."), nick.c_str()); else if (result == MemoServService::MEMO_INVALID_TARGET) source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str()); else if (result == MemoServService::MEMO_TOO_FAST) - source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str()); else if (result == MemoServService::MEMO_TARGET_FULL) source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str()); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -63,12 +63,11 @@ class MSSend : public Module CommandMSSend commandmssend; public: - MSSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmssend(this) { - this->SetAuthor("Anope"); - if (!MemoServService) + if (!memoserv) throw ModuleException("No MemoServ!"); } }; diff --git a/modules/commands/ms_sendall.cpp b/modules/commands/ms_sendall.cpp index 59d532bf9..b19b96036 100644 --- a/modules/commands/ms_sendall.cpp +++ b/modules/commands/ms_sendall.cpp @@ -12,9 +12,11 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} class CommandMSSendAll : public Command { @@ -27,7 +29,7 @@ class CommandMSSendAll : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) + if (!memoserv) return; const Anope::string &text = params[0]; @@ -43,11 +45,10 @@ class CommandMSSendAll : public Command const NickCore *nc = it->second; if (nc != source.nc) - MemoServService->Send(source.GetNick(), nc->display, text); + memoserv->Send(source.GetNick(), nc->display, text); } source.Reply(_("A massmemo has been sent to all registered users.")); - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -64,12 +65,10 @@ class MSSendAll : public Module CommandMSSendAll commandmssendall; public: - MSSendAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSSendAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmssendall(this) { - this->SetAuthor("Anope"); - - if (!MemoServService) + if (!memoserv) throw ModuleException("No MemoServ!"); } }; diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp index f2fc15c09..d1edaecca 100644 --- a/modules/commands/ms_set.cpp +++ b/modules/commands/ms_set.cpp @@ -25,19 +25,19 @@ class CommandMSSet : public Command { nc->ExtendMetadata("MEMO_SIGNON"); nc->ExtendMetadata("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str()); } else if (param.equals_ci("LOGON")) { nc->ExtendMetadata("MEMO_SIGNON"); nc->Shrink("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str()); } else if (param.equals_ci("NEW")) { nc->Shrink("MEMO_SIGNON"); nc->ExtendMetadata("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when they are sent to you."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str()); } else if (param.equals_ci("MAIL")) { @@ -59,7 +59,7 @@ class CommandMSSet : public Command nc->Shrink("MEMO_SIGNON"); nc->Shrink("MEMO_RECEIVE"); nc->Shrink("MEMO_MAIL"); - source.Reply(_("%s will not send you any notification of memos."), Config->MemoServ.c_str()); + source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str()); } else this->OnSyntaxError(source, ""); @@ -158,6 +158,7 @@ class CommandMSSet : public Command source.Reply(_("You are not permitted to change your memo limit.")); return; } + int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos"); limit = -1; try { @@ -166,12 +167,12 @@ class CommandMSSet : public Command catch (const ConvertException &) { } /* The first character is a digit, but we could still go negative * from overflow... watch out! */ - if (limit < 0 || (Config->MSMaxMemos > 0 && static_cast<unsigned>(limit) > Config->MSMaxMemos)) + if (limit < 0 || (max_memos > 0 && limit > max_memos)) { if (!chan.empty()) - source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), Config->MSMaxMemos); + source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos); else - source.Reply(_("You cannot set your memo limit higher than %d."), Config->MSMaxMemos); + source.Reply(_("You cannot set your memo limit higher than %d."), max_memos); return; } } @@ -239,7 +240,7 @@ class CommandMSSet : public Command " receive\n" " \n" "Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); } else if (subcommand.equals_ci("NOTIFY")) source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n" @@ -260,6 +261,7 @@ class CommandMSSet : public Command "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined.")); else if (subcommand.equals_ci("LIMIT")) { + int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos"); if (source.IsServicesOper()) source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n" " \n" @@ -278,14 +280,14 @@ class CommandMSSet : public Command "\002Admins\002. Other users may only enter a limit for themselves\n" "or a channel on which they have such privileges, may not\n" "remove their limit, may not set a limit above %d, and may\n" - "not set a hard limit."), Config->MSMaxMemos); + "not set a hard limit."), max_memos); else source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n" " \n" "Sets the maximum number of memos you (or the given channel)\n" "are allowed to have. If you set this to 0, no one will be\n" "able to send any memos to you. However, you cannot set\n" - "this any higher than %d."), Config->MSMaxMemos); + "this any higher than %d."), max_memos); } else return false; @@ -299,10 +301,9 @@ class MSSet : public Module CommandMSSet commandmsset; public: - MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsset(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ms_staff.cpp b/modules/commands/ms_staff.cpp index 6a1263fa7..30ec92b16 100644 --- a/modules/commands/ms_staff.cpp +++ b/modules/commands/ms_staff.cpp @@ -12,9 +12,11 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} class CommandMSStaff : public Command { @@ -27,7 +29,7 @@ class CommandMSStaff : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) + if (!memoserv) return; const Anope::string &text = params[0]; @@ -43,10 +45,8 @@ class CommandMSStaff : public Command const NickCore *nc = it->second; if (source.nc != nc && nc->IsServicesOper()) - MemoServService->Send(source.GetNick(), nc->display, text, true); + memoserv->Send(source.GetNick(), nc->display, text, true); } - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -64,12 +64,10 @@ class MSStaff : public Module CommandMSStaff commandmsstaff; public: - MSStaff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSStaff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsstaff(this) { - this->SetAuthor("Anope"); - - if (!MemoServService) + if (!memoserv) throw ModuleException("No MemoServ!"); } }; diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp index bd26dbb2c..7de20b9b7 100644 --- a/modules/commands/ns_access.cpp +++ b/modules/commands/ns_access.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSAccess : public Command { private: @@ -24,9 +26,9 @@ class CommandNSAccess : public Command return; } - if (nc->access.size() >= Config->NSAccessMax) + if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) { - source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->NSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax")); return; } @@ -119,7 +121,7 @@ class CommandNSAccess : public Command source.Reply(ACCESS_DENIED); return; } - else if (Config->NSSecureAdmins && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) { source.Reply(_("You may view but not modify the access list of other Services Operators.")); return; @@ -133,7 +135,7 @@ class CommandNSAccess : public Command if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos)) { source.Reply(BAD_USERHOST_MASK); - source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this->name.c_str()); + source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); } else if (nc->HasExt("SUSPENDED")) source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); @@ -145,8 +147,6 @@ class CommandNSAccess : public Command return this->DoList(source, nc, mask); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -171,7 +171,7 @@ class CommandNSAccess : public Command " Reverses the previous command.\n" " \n" " \002ACCESS LIST\002\n" - " Displays the current access list."), Config->NickServ.c_str(), Config->NickServ.c_str()); + " Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str()); return true; } }; @@ -181,11 +181,17 @@ class NSAccess : public Module CommandNSAccess commandnsaccess; public: - NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsaccess(this) { - this->SetAuthor("Anope"); + Implementation i[] = { I_OnNickRegister }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + void OnNickRegister(User *u, NickAlias *na) anope_override + { + if (u && Config->GetModule(this)->Get<bool>("addaccessonreg")) + na->nc->AddAccess(u->Mask()); } }; diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp index 3f4d9d3ec..ba7e53912 100644 --- a/modules/commands/ns_ajoin.cpp +++ b/modules/commands/ns_ajoin.cpp @@ -133,7 +133,7 @@ class CommandNSAJoin : public Command if ((*channels)->at(i)->channel.equals_ci(chan)) break; - if (*source.nc == nc && (*channels)->size() >= Config->AJoinMax) + if (*source.nc == nc && (*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")) source.Reply(_("Your auto join list is full.")); else if (i != (*channels)->size()) source.Reply(_("%s is already on %s's auto join list."), chan.c_str(), nc->display.c_str()); @@ -237,10 +237,9 @@ class NSAJoin : public Module CommandNSAJoin commandnsajoin; public: - NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize), commandnsajoin(this) { - this->SetAuthor("Anope"); if (!IRCD->CanSVSJoin) throw ModuleException("Your IRCd does not support SVSJOIN"); diff --git a/modules/commands/ns_alist.cpp b/modules/commands/ns_alist.cpp index c8d7eef0f..9c673a7fc 100644 --- a/modules/commands/ns_alist.cpp +++ b/modules/commands/ns_alist.cpp @@ -121,10 +121,9 @@ class NSAList : public Module CommandNSAList commandnsalist; public: - NSAList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSAList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsalist(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp index bbfbdd3e8..71836481a 100644 --- a/modules/commands/ns_cert.cpp +++ b/modules/commands/ns_cert.cpp @@ -13,6 +13,8 @@ #include "module.h" +static unsigned accessmax; + class CommandNSCert : public Command { private: @@ -54,9 +56,9 @@ class CommandNSCert : public Command void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask) { - if (nc->cert.size() >= Config->NSAccessMax) + if (nc->cert.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) { - source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->NSAccessMax); + source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax")); return; } @@ -179,7 +181,7 @@ class CommandNSCert : public Command "If you connect to IRC and provide a client certificate with a\n" "matching fingerprint in the cert list, your nick will be\n" "automatically identified to %s.\n" - " \n"), Config->NickServ.c_str(), Config->NickServ.c_str()); + " \n"), NickServ ? NickServ->nick.c_str() : source.service->nick.c_str()); source.Reply(_("Examples:\n" " \n" " \002CERT ADD <fingerprint>\002\n" @@ -191,7 +193,7 @@ class CommandNSCert : public Command " Reverses the previous command.\n" " \n" " \002CERT LIST\002\n" - " Displays the current certificate list."), Config->NickServ.c_str()); + " Displays the current certificate list.")); return true; } }; @@ -219,10 +221,9 @@ class NSCert : public Module } public: - NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnscert(this) { - this->SetAuthor("Anope"); if (!IRCD || !IRCD->CanCertFP) throw ModuleException("Your IRCd does not support ssl client certificates"); diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp index e52ca5681..023d696f6 100644 --- a/modules/commands/ns_drop.cpp +++ b/modules/commands/ns_drop.cpp @@ -13,95 +13,63 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSDrop : public Command { public: - CommandNSDrop(Module *creator) : Command(creator, "nickserv/drop", 0, 1) + CommandNSDrop(Module *creator) : Command(creator, "nickserv/drop", 1, 1) { + this->SetSyntax(_("\037nickname\037")); this->SetDesc(_("Cancel the registration of a nickname")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - Anope::string nick = !params.empty() ? params[0] : ""; + const Anope::string &nick = params[0]; - if (Anope::ReadOnly) + if (Anope::ReadOnly && !source.HasPriv("nickserv/drop")) { source.Reply(_("Sorry, nickname de-registration is temporarily disabled.")); return; } - NickAlias *na = NickAlias::Find(!nick.empty() ? nick : source.GetNick()); + NickAlias *na = NickAlias::Find(nick); if (!na) { - if (!nick.empty()) - source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else - source.Reply(NICK_NOT_REGISTERED); + source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); return; } bool is_mine = source.GetAccount() == na->nc; - Anope::string my_nick; - if (is_mine && nick.empty()) - my_nick = na->nick; if (!is_mine && !source.HasPriv("nickserv/drop")) source.Reply(ACCESS_DENIED); - else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->nc->IsServicesOper()) source.Reply(_("You may not drop other Services Operators' nicknames.")); else { - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - FOREACH_MOD(I_OnNickDrop, OnNickDrop(source, na)); - Log(!is_mine ? LOG_OVERRIDE : LOG_COMMAND, source, this) << "to drop nickname " << na->nick << " (group: " << na->nc->display << ") (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; + Log(!is_mine ? LOG_ADMIN : LOG_COMMAND, source, this) << "to drop nickname " << na->nick << " (group: " << na->nc->display << ") (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; delete na; - if (!is_mine) - { - source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str()); - } - else - { - if (!nick.empty()) - source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str()); - else - source.Reply(_("Your nickname has been dropped.")); - } + source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str()); } - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { - if (source.HasPriv("nickserv/drop")) - source.Reply(_("Syntax: \002%s [\037nickname\037]\002\n" - " \n" - "Without a parameter, deletes your nickname.\n" - " \n" - "With a parameter, drops the named nick from the database.\n" - "You may drop any nick within your group without any\n" - "special privileges. Dropping any nick is limited to\n" - "\002Services Operators\002."), source.command.c_str()); + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Drops the given nick from the database. Once your nickname\n" + "is dropped you may lose all of your access and channels that\n" + "you may own. Any other user will be able to gain control of\n" + "this nick.")); + if (!source.HasPriv("nickserv/drop")) + source.Reply(_("You may drop any nick within your group.")); else - source.Reply(_("Syntax: \002%s [\037nickname\037 | \037password\037]\002\n" - " \n" - "Deletes your nickname. A nick\n" - "that has been dropped is free for anyone to re-register.\n" - " \n" - "You may drop a nick within your group by passing it\n" - "as the \002nick\002 parameter.\n" - " \n" - "If you have a nickname registration pending but can not confirm\n" - "it for any reason, you can cancel your registration by passing\n" - "your password as the \002password\002 parameter.\n" - " \n" - "In order to use this command, you must first identify\n" - "with your password."), source.command.c_str()); + source.Reply(_("As a Services Operator, you may drop any nick.")); return true; } @@ -112,10 +80,9 @@ class NSDrop : public Module CommandNSDrop commandnsdrop; public: - NSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsdrop(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_getemail.cpp b/modules/commands/ns_getemail.cpp index 7728f3178..386940a0a 100644 --- a/modules/commands/ns_getemail.cpp +++ b/modules/commands/ns_getemail.cpp @@ -69,10 +69,9 @@ class NSGetEMail : public Module { CommandNSGetEMail commandnsgetemail; public: - NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsgetemail(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp index 987e98827..a99181b3f 100644 --- a/modules/commands/ns_getpass.cpp +++ b/modules/commands/ns_getpass.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSGetPass : public Command { public: @@ -30,7 +32,7 @@ class CommandNSGetPass : public Command if (!(na = NickAlias::Find(nick))) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else if (Config->NSSecureAdmins && na->nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper()) source.Reply(_("You may not get the password of other Services Operators.")); else { @@ -62,10 +64,9 @@ class NSGetPass : public Module CommandNSGetPass commandnsgetpass; public: - NSGetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSGetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsgetpass(this) { - this->SetAuthor("Anope"); Anope::string tmp_pass = "plain:tmp"; if (Anope::Decrypt(tmp_pass, tmp_pass) == -1) diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp index b8191046a..97551cfcb 100644 --- a/modules/commands/ns_group.cpp +++ b/modules/commands/ns_group.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class NSGroupRequest : public IdentifyRequest { CommandSource source; @@ -46,7 +48,7 @@ class NSGroupRequest : public IdentifyRequest u->Login(target->nc); IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); @@ -102,7 +104,7 @@ class CommandNSGroup : public Command return; } - if (Config->RestrictOperNicks) + if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks")) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -115,10 +117,12 @@ class CommandNSGroup : public Command } NickAlias *target, *na = NickAlias::Find(u->nick); + const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string>("guestnickprefix"); + time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay"); if (!(target = NickAlias::Find(nick))) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else if (Anope::CurTime < u->lastnickreg + Config->NSRegDelay) - source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime); + else if (Anope::CurTime < u->lastnickreg + reg_delay) + source.Reply(_("Please wait %d seconds before using the GROUP command again."), (reg_delay + u->lastnickreg) - Anope::CurTime); else if (target->nc->HasExt("SUSPENDED")) { Log(LOG_COMMAND, source, this) << "tried to use GROUP for SUSPENDED nick " << target->nick; @@ -127,14 +131,14 @@ class CommandNSGroup : public Command else if (na && *target->nc == *na->nc) source.Reply(_("You are already a member of the group of \002%s\002."), target->nick.c_str()); else if (na && na->nc != u->Account()) - source.Reply(NICK_IDENTIFY_REQUIRED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); - else if (na && Config->NSNoGroupChange) + source.Reply(NICK_IDENTIFY_REQUIRED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); + else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange")) source.Reply(_("Your nick is already registered.")); - else if (Config->NSMaxAliases && (target->nc->aliases->size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper()) - source.Reply(_("There are too many nicks in %s's group.")); - else if (u->nick.length() <= Config->NSGuestNickPrefix.length() + 7 && - u->nick.length() >= Config->NSGuestNickPrefix.length() + 1 && - !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(Config->NSGuestNickPrefix.length()).find_first_not_of("1234567890")) + else if (target->nc->aliases->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxaliases") && !target->nc->IsServicesOper()) + source.Reply(_("There are too many nicks in your group.")); + else if (u->nick.length() <= guestnick.length() + 7 && + u->nick.length() >= guestnick.length() + 1 && + !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890")) { source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); } @@ -289,7 +293,7 @@ class CommandNSGList : public Command } else if (na->nc != source.GetAccount() && !source.IsServicesOper()) { - source.Reply(ACCESS_DENIED, Config->NickServ.c_str()); + source.Reply(ACCESS_DENIED); return; } @@ -300,13 +304,14 @@ class CommandNSGList : public Command ListFormatter list; list.AddColumn("Nick").AddColumn("Expires"); + time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire"); for (unsigned i = 0; i < nc->aliases->size(); ++i) { const NickAlias *na2 = nc->aliases->at(i); ListFormatter::ListEntry entry; entry["Nick"] = na2->nick; - entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !Config->NSExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + Config->NSExpire)); + entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + nickserv_expire)); list.AddEntry(entry); } @@ -348,12 +353,10 @@ class NSGroup : public Module CommandNSGList commandnsglist; public: - NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsgroup(this), commandnsungroup(this), commandnsglist(this) { - this->SetAuthor("Anope"); - - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); } }; diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp index adbe97de5..037072728 100644 --- a/modules/commands/ns_identify.cpp +++ b/modules/commands/ns_identify.cpp @@ -109,10 +109,9 @@ class NSIdentify : public Module CommandNSIdentify commandnsidentify; public: - NSIdentify(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSIdentify(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsidentify(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp index fddb9c5ad..3e946a1f1 100644 --- a/modules/commands/ns_info.cpp +++ b/modules/commands/ns_info.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSInfo : public Command { private: @@ -126,13 +128,15 @@ class CommandNSInfo : public Command if (na->nc->HasExt("UNCONFIRMED") == false) { - if (na->HasExt("NO_EXPIRE") || !Config->NSExpire) - ; - else - info[_("Expires")] = Anope::strftime(na->last_seen + Config->NSExpire); + time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire"); + if (!na->HasExt("NO_EXPIRE") && nickserv_expire && !Anope::NoExpire) + info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire); } else - info[_("Expires")] = Anope::strftime(na->time_registered + Config->NSUnconfirmedExpire); + { + time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d"); + info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire); + } } FOREACH_MOD(I_OnNickInfo, OnNickInfo(source, na, info, show_hidden)); @@ -164,10 +168,9 @@ class NSInfo : public Module CommandNSInfo commandnsinfo; public: - NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsinfo(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp index b96b21412..69648c2f4 100644 --- a/modules/commands/ns_list.cpp +++ b/modules/commands/ns_list.cpp @@ -31,6 +31,7 @@ class CommandNSList : public Command bool is_servadmin = source.HasCommand("nickserv/list"); int count = 0, from = 0, to = 0; bool suspended, nsnoexpire, unconfirmed; + unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); suspended = nsnoexpire = unconfirmed = false; @@ -99,7 +100,7 @@ class CommandNSList : public Command Anope::string buf = Anope::printf("%s!%s", na->nick.c_str(), !na->last_usermask.empty() ? na->last_usermask.c_str() : "*@*"); if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true)) { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax) { bool isnoexpire = false; if (is_servadmin && na->HasExt("NO_EXPIRE")) @@ -129,7 +130,7 @@ class CommandNSList : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of list - %d/%d matches shown."), nnicks > Config->NSListMax ? Config->NSListMax : nnicks, nnicks); + source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks); return; } @@ -166,11 +167,12 @@ class CommandNSList : public Command " \002LIST #51-100\002\n" " Lists all registered nicks within the given range (51-100).")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -182,11 +184,9 @@ class NSList : public Module CommandNSList commandnslist; public: - NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnslist(this) { - this->SetAuthor("Anope"); - } }; diff --git a/modules/commands/ns_logout.cpp b/modules/commands/ns_logout.cpp index 1147b390f..c149dc1f2 100644 --- a/modules/commands/ns_logout.cpp +++ b/modules/commands/ns_logout.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "nickserv.h" static ServiceReference<NickServService> NickServService("NickServService", "NickServ"); @@ -84,10 +83,9 @@ class NSLogout : public Module CommandNSLogout commandnslogout; public: - NSLogout(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSLogout(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnslogout(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp index 33a97646c..e9455f88a 100644 --- a/modules/commands/ns_recover.cpp +++ b/modules/commands/ns_recover.cpp @@ -56,13 +56,13 @@ class NSRecoverRequest : public IdentifyRequest Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display; } - if (Config->NSRestoreOnRecover) + if (Config->GetModule("ns_recover")->Get<bool>("restoreonrecover")) { if (!u->chans.empty()) { NSRecoverExtensibleInfo *ei = new NSRecoverExtensibleInfo; for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) - (*ei)[(*it)->chan->name] = (*it)->status; + (*ei)[it->first->name] = it->second->status; source.GetUser()->Extend("ns_recover_info", ei); } @@ -201,12 +201,11 @@ class NSRecover : public Module CommandNSRecover commandnsrecover; public: - NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsrecover(this) { - this->SetAuthor("Anope"); - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); Implementation i[] = { I_OnUserNickChange, I_OnJoinChannel, I_OnShutdown, I_OnRestart }; @@ -234,7 +233,7 @@ class NSRecover : public Module void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override { - if (Config->NSRestoreOnRecover) + if (Config->GetModule(this)->Get<bool>("restoreonrecover")) { NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info"); @@ -256,7 +255,7 @@ class NSRecover : public Module void OnJoinChannel(User *u, Channel *c) anope_override { - if (Config->NSRestoreOnRecover) + if (Config->GetModule(this)->Get<bool>("restoreonrecover")) { NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info"); @@ -265,8 +264,8 @@ class NSRecover : public Module std::map<Anope::string, ChannelStatus>::iterator it = ei->find(c->name); if (it != ei->end()) { - for (std::set<Anope::string>::iterator it2 = it->second.modes.begin(), it2_end = it->second.modes.end(); it2 != it2_end; ++it2) - c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(*it2), u->GetUID()); + for (size_t i = 0; i < it->second.Modes().length(); ++i) + c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(it->second.Modes()[i]), u->GetUID()); ei->erase(it); if (ei->empty()) diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp index 2803d459a..da2f6de59 100644 --- a/modules/commands/ns_register.cpp +++ b/modules/commands/ns_register.cpp @@ -58,7 +58,7 @@ class CommandNSConfirm : public Command { IRCD->SendLogin(source.GetUser()); const NickAlias *na = NickAlias::Find(source.GetNick()); - if (!Config->NoNicknameOwnership && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false) source.GetUser()->SetMode(NickServ, "REGISTERED"); } } @@ -101,7 +101,7 @@ class CommandNSRegister : public Command CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2) { this->SetDesc(_("Register a nickname")); - if (Config->NSForceEmail) + if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) this->SetSyntax(_("\037password\037 \037email\037")); else this->SetSyntax(_("\037password\037 \037[email]\037")); @@ -111,12 +111,12 @@ class CommandNSRegister : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { NickAlias *na; - size_t prefixlen = Config->NSGuestNickPrefix.length(); User *u = source.GetUser(); Anope::string u_nick = source.GetNick(); size_t nicklen = u_nick.length(); Anope::string pass = params[0]; Anope::string email = params.size() > 1 ? params[1] : ""; + const Anope::string &nsregister = Config->GetModule(this->owner)->Get<const Anope::string>("registration"); if (Anope::ReadOnly) { @@ -124,15 +124,17 @@ class CommandNSRegister : public Command return; } - if (Config->NSRegistration.equals_ci("disable")) + if (nsregister.equals_ci("disable")) { source.Reply(_("Registration is currently disabled.")); return; } - if (u && !u->HasMode("OPER") && Config->NickRegDelay && Anope::CurTime - u->timestamp < Config->NickRegDelay) + time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay"); + time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay"); + if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay) { - source.Reply(_("You must have been using this nick for at least %d seconds to register."), Config->NickRegDelay); + source.Reply(_("You must have been using this nick for at least %d seconds to register."), nickregdelay); return; } @@ -141,7 +143,8 @@ class CommandNSRegister : public Command /* Guest nick can now have a series of between 1 and 7 digits. * --lara */ - if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u_nick.find_ci(Config->NSGuestNickPrefix) && u_nick.substr(prefixlen).find_first_not_of("1234567890") == Anope::string::npos) + const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string>("guestnickprefix"); + if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos) { source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str()); return; @@ -153,7 +156,7 @@ class CommandNSRegister : public Command return; } - if (Config->RestrictOperNicks) + if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks")) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -165,15 +168,15 @@ class CommandNSRegister : public Command } } - if (Config->NSForceEmail && email.empty()) + if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty()) this->OnSyntaxError(source, ""); - else if (u && Anope::CurTime < u->lastnickreg + Config->NSRegDelay) - source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + Config->NSRegDelay) - Anope::CurTime); + else if (u && Anope::CurTime < u->lastnickreg + reg_delay) + source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + reg_delay) - Anope::CurTime); else if ((na = NickAlias::Find(u_nick))) source.Reply(NICK_ALREADY_REGISTERED, u_nick.c_str()); - else if (pass.equals_ci(u_nick) || (Config->StrictPasswords && pass.length() < 5)) + else if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5)) source.Reply(MORE_OBSCURE_PASSWORD); - else if (pass.length() > Config->PassLen) + else if (pass.length() > Config->GetBlock("options")->Get<unsigned>("passlen")) source.Reply(PASSWORD_TOO_LONG); else if (!email.empty() && !Mail::Validate(email)) source.Reply(MAIL_X_INVALID, email.c_str()); @@ -191,16 +194,13 @@ class CommandNSRegister : public Command na->last_realname = u->realname; u->Login(nc); - - if (Config->NSAddAccessOnReg) - nc->AddAccess(u->Mask()); } Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; - FOREACH_MOD(I_OnNickRegister, OnNickRegister(na)); + FOREACH_MOD(I_OnNickRegister, OnNickRegister(source.GetUser(), na)); - if (Config->NSAddAccessOnReg) + if (na->nc->GetAccessCount()) source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str()); else source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str()); @@ -209,26 +209,27 @@ class CommandNSRegister : public Command if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1) source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str()); - if (Config->NSRegistration.equals_ci("admin")) + if (nsregister.equals_ci("admin")) { nc->ExtendMetadata("UNCONFIRMED"); source.Reply(_("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed.")); } - else if (Config->NSRegistration.equals_ci("mail")) + else if (nsregister.equals_ci("mail")) { nc->ExtendMetadata("UNCONFIRMED"); if (SendRegmail(u, na, source.service)) { - source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); - source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(Config->NSUnconfirmedExpire).c_str()); + time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d"); + source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); + source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(unconfirmed_expire).c_str()); } } - else if (Config->NSRegistration.equals_ci("none")) + else if (nsregister.equals_ci("none")) { if (u) { IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } @@ -259,9 +260,9 @@ class CommandNSRegister : public Command "passwords are vulnerable to trial-and-error searches, so\n" "you should choose a password at least 5 characters long.\n" "Finally, the space character cannot be used in passwords."), - Config->NickServ.c_str(), Config->NickServ.c_str()); + source.service->nick.c_str(), source.service->nick.c_str()); - if (!Config->NSForceEmail) + if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) { source.Reply(" "); source.Reply(_("The \037email\037 parameter is optional and will set the email\n" @@ -285,12 +286,11 @@ class CommandNSResend : public Command public: CommandNSResend(Module *creator) : Command(creator, "nickserv/resend", 0, 0) { - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!Config->NSRegistration.equals_ci("mail")) + if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail")) return; const NickAlias *na = NickAlias::Find(source.GetNick()); @@ -301,7 +301,7 @@ class CommandNSResend : public Command source.Reply(_("Your account is already confirmed.")); else { - if (Anope::CurTime < source.nc->lastmail + Config->NSResendDelay) + if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->owner)->Get<time_t>("resenddelay")) source.Reply(_("Cannot send mail now; please retry a little later.")); else if (SendRegmail(source.GetUser(), na, source.service)) { @@ -318,7 +318,7 @@ class CommandNSResend : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { - if (!Config->NSRegistration.equals_ci("mail")) + if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail")) return false; this->SendSyntax(source); @@ -330,7 +330,7 @@ class CommandNSResend : public Command void OnServHelp(CommandSource &source) anope_override { - if (Config->NSRegistration.equals_ci("mail")) + if (Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail")) Command::OnServHelp(source); } }; @@ -342,13 +342,11 @@ class NSRegister : public Module CommandNSResend commandnsrsend; public: - NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsregister(this), commandnsconfirm(this), commandnsrsend(this) { - this->SetAuthor("Anope"); - - if (Config->NSRegistration.equals_ci("disable")) - throw ModuleException("Module will not load with nickserv:registration disabled."); + if (Config->GetModule(this)->Get<const Anope::string>("registration").equals_ci("disable")) + throw ModuleException("Module " + this->name + " will not load with registration disabled."); } }; @@ -375,15 +373,15 @@ static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi) else codebuf = *code; - Anope::string subject = Language::Translate(na->nc, Config->MailRegistrationSubject.c_str()); - Anope::string message = Language::Translate(na->nc, Config->MailRegistrationMessage.c_str()); + Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_subject").c_str()), + message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_message").c_str()); subject = subject.replace_all_cs("%n", na->nick); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); subject = subject.replace_all_cs("%c", codebuf); message = message.replace_all_cs("%n", na->nick); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); message = message.replace_all_cs("%c", codebuf); return Mail::Send(u, nc, bi, subject, message); diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp index e57261a9f..bf1e8dacf 100644 --- a/modules/commands/ns_resetpass.cpp +++ b/modules/commands/ns_resetpass.cpp @@ -29,7 +29,7 @@ class CommandNSResetPass : public Command { const NickAlias *na; - if (Config->RestrictMail && !source.HasCommand("nickserv/resetpass")) + if (Config->GetBlock("mail")->Get<bool>("restrict") && !source.HasCommand("nickserv/resetpass")) source.Reply(ACCESS_DENIED); else if (!(na = NickAlias::Find(params[0]))) source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); @@ -66,12 +66,10 @@ class NSResetPass : public Module CommandNSResetPass commandnsresetpass; public: - NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsresetpass(this) { - this->SetAuthor("Anope"); - - if (!Config->UseMail) + if (!Config->GetBlock("mail")->Get<bool>("usemail")) throw ModuleException("Not using mail."); @@ -141,15 +139,15 @@ static bool SendResetEmail(User *u, const NickAlias *na, const BotInfo *bi) for (idx = 0; idx < 20; ++idx) passcode += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min]; - Anope::string subject = Language::Translate(na->nc, Config->MailResetSubject.c_str()); - Anope::string message = Language::Translate(na->nc, Config->MailResetMessage.c_str()); + Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_subject").c_str()), + message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_message").c_str()); subject = subject.replace_all_cs("%n", na->nick); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); subject = subject.replace_all_cs("%c", passcode); message = message.replace_all_cs("%n", na->nick); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); message = message.replace_all_cs("%c", passcode); ResetInfo *ri = new ResetInfo; diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp index 252a83262..93024b437 100644 --- a/modules/commands/ns_set.cpp +++ b/modules/commands/ns_set.cpp @@ -11,6 +11,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSSet : public Command { public: @@ -50,7 +52,7 @@ class CommandNSSet : public Command } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -96,7 +98,7 @@ class CommandNSSASet : public Command source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" "on a specific option. The options will be set on the given\n" - "\037nickname\037."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this_name.c_str()); + "\037nickname\037."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), this_name.c_str()); return true; } }; @@ -115,17 +117,19 @@ class CommandNSSetPassword : public Command const Anope::string ¶m = params[1]; unsigned len = param.length(); - if (source.GetNick().equals_ci(param) || (Config->StrictPasswords && len < 5)) + if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5)) { source.Reply(MORE_OBSCURE_PASSWORD); return; } - else if (len > Config->PassLen) + else if (len > Config->GetBlock("options")->Get<unsigned>("passlen")) { source.Reply(PASSWORD_TOO_LONG); return; } + Log(LOG_COMMAND, source, this) << "to change their password"; + Anope::Encrypt(param, source.nc->pass); Anope::string tmp_pass; if (Anope::Decrypt(source.nc->pass, tmp_pass) == 1) @@ -165,22 +169,24 @@ class CommandNSSASetPassword : public Command size_t len = params[1].length(); - if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) { source.Reply(_("You may not change the password of other Services Operators.")); return; } - else if (nc->display.equals_ci(params[1]) || (Config->StrictPasswords && len < 5)) + else if (nc->display.equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5)) { source.Reply(MORE_OBSCURE_PASSWORD); return; } - else if (len > Config->PassLen) + else if (len > Config->GetBlock("options")->Get<unsigned>("passlen")) { source.Reply(PASSWORD_TOO_LONG); return; } + Log(LOG_ADMIN, source, this) << "to change the password of " << nc->display; + Anope::Encrypt(params[1], nc->pass); Anope::string tmp_pass; if (Anope::Decrypt(nc->pass, tmp_pass) == 1) @@ -226,18 +232,18 @@ class CommandNSSetAutoOp : public Command if (param.equals_ci("ON")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autoop for " << na->nc->display; nc->ExtendMetadata("AUTOOP"); source.Reply(_("Services will from now on set status modes on %s in channels."), nc->display.c_str()); } else if (param.equals_ci("OFF")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autoop for " << na->nc->display; nc->Shrink("AUTOOP"); source.Reply(_("Services will no longer set status modes on %s in channels."), nc->display.c_str()); } else this->OnSyntaxError(source, "AUTOOP"); - - return; } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -308,11 +314,13 @@ class CommandNSSetChanstats : public Command if (param.equals_ci("ON")) { + Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable chanstats for " << na->nc->display; na->nc->ExtendMetadata("STATS"); source.Reply(_("Chanstat statistics are now enabled for your nick.")); } else if (param.equals_ci("OFF")) { + Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable chanstats for " << na->nc->display; na->nc->Shrink("STATS"); source.Reply(_("Chanstat statistics are now disabled for your nick.")); } @@ -372,7 +380,7 @@ class CommandNSSetDisplay : public Command { const NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param); - if (!Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) { source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); return; @@ -393,6 +401,8 @@ class CommandNSSetDisplay : public Command if (MOD_RESULT == EVENT_STOP) return; + Log(user_na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the display of " << user_na->nc->display << " to " << na->nick; + user_na->nc->SetDisplay(na); source.Reply(NICK_SET_DISPLAY_CHANGED, user_na->nc->display.c_str()); } @@ -454,15 +464,15 @@ class CommandNSSetEmail : public Command u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code)); - Anope::string subject = Config->MailEmailchangeSubject; - Anope::string message = Config->MailEmailchangeMessage; + Anope::string subject = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_subject"), + message = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_message"); subject = subject.replace_all_cs("%e", u->Account()->email); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); subject = subject.replace_all_cs("%c", code); message = message.replace_all_cs("%e", u->Account()->email); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); message = message.replace_all_cs("%c", code); return Mail::Send(u, u->Account(), bi, subject, message); @@ -485,12 +495,12 @@ class CommandNSSetEmail : public Command } NickCore *nc = na->nc; - if (param.empty() && Config->NSForceEmail) + if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) { source.Reply(_("You cannot unset the e-mail on this network.")); return; } - else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) { source.Reply(_("You may not change the e-mail of other Services Operators.")); return; @@ -506,7 +516,7 @@ class CommandNSSetEmail : public Command if (MOD_RESULT == EVENT_STOP) return; - if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper()) + if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && !source.IsServicesOper()) { source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param)); Anope::string old = source.nc->email; @@ -519,17 +529,17 @@ class CommandNSSetEmail : public Command { if (!param.empty()) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the email of " << nc->display << " to " << param; nc->email = param; source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str()); } else { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the email of " << nc->display; nc->email.clear(); source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str()); } } - - return; } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -597,11 +607,13 @@ class CommandNSSetGreet : public Command if (!param.empty()) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->display; nc->greet = param; source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), nc->greet.c_str()); } else { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->display; nc->greet.clear(); source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str()); } @@ -710,13 +722,15 @@ class CommandNSSetHide : public Command if (arg.equals_ci("ON")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display; nc->ExtendMetadata(flag); - source.Reply(onmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + source.Reply(onmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str()); } else if (arg.equals_ci("OFF")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display; nc->Shrink(flag); - source.Reply(offmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + source.Reply(offmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str()); } else this->OnSyntaxError(source, "HIDE"); @@ -739,7 +753,7 @@ class CommandNSSetHide : public Command "user@host mask (\002USERMASK\002), your services access status\n" "(\002STATUS\002) and last quit message (\002QUIT\002).\n" "The second parameter specifies whether the information should\n" - "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str()); + "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str()); return true; } }; @@ -768,7 +782,7 @@ class CommandNSSASetHide : public CommandNSSetHide "user@host mask (\002USERMASK\002), the services access status\n" "(\002STATUS\002) and last quit message (\002QUIT\002).\n" "The second parameter specifies whether the information should\n" - "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str()); + "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str()); return true; } }; @@ -784,7 +798,7 @@ class CommandNSSetKill : public Command void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) { - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) { source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); return; @@ -808,6 +822,7 @@ class CommandNSSetKill : public Command nc->ExtendMetadata("KILLPROTECT"); nc->Shrink("KILL_QUICK"); nc->Shrink("KILL_IMMED"); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill on for " << nc->display; source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str()); } else if (param.equals_ci("QUICK")) @@ -815,15 +830,17 @@ class CommandNSSetKill : public Command nc->ExtendMetadata("KILLPROTECT"); nc->ExtendMetadata("KILL_QUICK"); nc->Shrink("KILL_IMMED"); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill quick for " << nc->display; source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str()); } else if (param.equals_ci("IMMED")) { - if (Config->NSAllowKillImmed) + if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed")) { nc->ExtendMetadata("KILLPROTECT"); nc->ExtendMetadata("KILL_IMMED"); nc->Shrink("KILL_QUICK"); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill immed for " << nc->display; source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str()); } else @@ -834,6 +851,7 @@ class CommandNSSetKill : public Command nc->Shrink("KILLPROTECT"); nc->Shrink("KILL_QUICK"); nc->Shrink("KILL_IMMED"); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable kill for " << nc->display; source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str()); } else @@ -862,7 +880,7 @@ class CommandNSSetKill : public Command "\002IMMED\002, user's nick will be changed immediately \037without\037 being\n" "warned first or given a chance to change their nick; please\n" "do not use this option unless necessary. Also, your\n" - "network's administrators may have disabled this option."), Config->NickServ.c_str()); + "network's administrators may have disabled this option."), NickServ->nick.c_str()); return true; } }; @@ -896,7 +914,7 @@ class CommandNSSASetKill : public CommandNSSetKill "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n" "warned first or given a chance to change their nick; please\n" "do not use this option unless necessary. Also, your\n" - "network's administrators may have disabled this option."), Config->NickServ.c_str()); + "network's administrators may have disabled this option."), NickServ->nick.c_str()); return true; } }; @@ -936,10 +954,10 @@ class CommandNSSetLanguage : public Command } } + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the langauge of " << nc->display << " to " << param; + nc->language = param != "en" ? param : ""; source.Reply(_("Language changed to \002English\002.")); - - return; } void Execute(CommandSource &source, const std::vector<Anope::string> ¶m) anope_override @@ -1022,7 +1040,7 @@ class CommandNSSetMessage : public Command } NickCore *nc = na->nc; - if (!Config->UsePrivmsg) + if (!Config->GetBlock("options")->Get<bool>("useprivmsg")) { source.Reply(_("You cannot %s on this network."), source.command.c_str()); return; @@ -1035,11 +1053,13 @@ class CommandNSSetMessage : public Command if (param.equals_ci("ON")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display; nc->ExtendMetadata("MSG"); source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str()); } else if (param.equals_ci("OFF")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display; nc->Shrink("MSG"); source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str()); } @@ -1066,7 +1086,7 @@ class CommandNSSetMessage : public Command void OnServHelp(CommandSource &source) anope_override { - if (Config->UsePrivmsg) + if (!Config->GetBlock("options")->Get<bool>("useprivmsg")) Command::OnServHelp(source); } }; @@ -1101,7 +1121,7 @@ class CommandNSSetPrivate : public Command public: CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1) { - this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str())); + this->SetDesc(_("Prevent the nickname from appearing in the LIST command")); this->SetSyntax(_("{ON | OFF}")); } @@ -1122,11 +1142,13 @@ class CommandNSSetPrivate : public Command if (param.equals_ci("ON")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->display; nc->ExtendMetadata("PRIVATE"); source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str()); } else if (param.equals_ci("OFF")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->display; nc->Shrink("PRIVATE"); source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str()); } @@ -1150,7 +1172,7 @@ class CommandNSSetPrivate : public Command "nickname lists generated with %s's \002LIST\002 command.\n" "(However, anyone who knows your nickname can still get\n" "information on it using the \002INFO\002 command.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); + NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1178,7 +1200,7 @@ class CommandNSSASetPrivate : public CommandNSSetPrivate "nickname lists generated with %s's \002LIST\002 command.\n" "(However, anyone who knows the nickname can still get\n" "information on it using the \002INFO\002 command.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); + NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1209,11 +1231,13 @@ class CommandNSSetSecure : public Command if (param.equals_ci("ON")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable secure for " << nc->display; nc->ExtendMetadata("SECURE"); source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str()); } else if (param.equals_ci("OFF")) { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable secure for " << nc->display; nc->Shrink("SECURE"); source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str()); } @@ -1236,7 +1260,7 @@ class CommandNSSetSecure : public Command "regardless of whether your address is on the access\n" "list. However, if you are on the access list, %s\n" "will not auto-kill you regardless of the setting of the\n" - "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str()); + "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1265,7 +1289,7 @@ class CommandNSSASetSecure : public CommandNSSetSecure "regardless of whether your address is on the access\n" "list. However, if you are on the access list, %s\n" "will not auto-kill you regardless of the setting of the\n" - "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str()); + "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1292,18 +1316,18 @@ class CommandNSSASetNoexpire : public Command if (param.equals_ci("ON")) { + Log(LOG_ADMIN, source, this) << "to enable noexpire " << na->nc->display; na->ExtendMetadata("NO_EXPIRE"); source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str()); } else if (param.equals_ci("OFF")) { + Log(LOG_ADMIN, source, this) << "to disable noexpire " << na->nc->display; na->Shrink("NO_EXPIRE"); source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str()); } else this->OnSyntaxError(source, "NOEXPIRE"); - - return; } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -1361,7 +1385,7 @@ class NSSet : public Module CommandNSSASetNoexpire commandnssasetnoexpire; public: - NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsset(this), commandnssaset(this), commandnssetautoop(this), commandnssasetautoop(this), commandnssetchanstats(this), commandnssasetchanstats(this), NSDefChanstats(false), @@ -1377,24 +1401,9 @@ class NSSet : public Module commandnssetsecure(this), commandnssasetsecure(this), commandnssasetnoexpire(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnNickRegister, I_OnPreCommand }; + Implementation i[] = { I_OnPreCommand }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); - } - - void OnReload() anope_override - { - ConfigReader config; - NSDefChanstats = config.ReadFlag("chanstats", "NSDefChanstats", "0", 0); - } - - void OnNickRegister(NickAlias *na) anope_override - { - if (NSDefChanstats) - na->nc->ExtendMetadata("STATS"); } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp index a5a0019b6..ae7c2cb53 100644 --- a/modules/commands/ns_set_misc.cpp +++ b/modules/commands/ns_set_misc.cpp @@ -154,30 +154,28 @@ class NSSetMisc : public Module CommandNSSASetMisc commandnssasetmisc; public: - NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), nsmiscdata_type("NSMiscData", NSMiscData::Unserialize), commandnssetmisc(this), commandnssasetmisc(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnNickInfo }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - descriptions.clear(); - for (int i = 0; i < config.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (config.ReadValue("command", "command", "", i) != "nickserv/set/misc" && config.ReadValue("command", "command", "", i) != "nickserv/saset/misc") + Configuration::Block *block = conf->GetBlock("command", i); + + const Anope::string &cmd = block->Get<const Anope::string>("command"); + + if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc") continue; - Anope::string cname = config.ReadValue("command", "name", "", i); - Anope::string desc = config.ReadValue("command", "misc_description", "", i); + Anope::string cname = block->Get<const Anope::string>("name"); + Anope::string desc = block->Get<const Anope::string>("misc_description"); if (cname.empty() || desc.empty()) continue; diff --git a/modules/commands/ns_status.cpp b/modules/commands/ns_status.cpp index 8fc803896..68568de0a 100644 --- a/modules/commands/ns_status.cpp +++ b/modules/commands/ns_status.cpp @@ -77,10 +77,9 @@ class NSStatus : public Module CommandNSStatus commandnsstatus; public: - NSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsstatus(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp index a4cc7f355..e0bb6bf93 100644 --- a/modules/commands/ns_suspend.cpp +++ b/modules/commands/ns_suspend.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSSuspend : public Command { public: @@ -28,7 +30,7 @@ class CommandNSSuspend : public Command const Anope::string &nick = params[0]; Anope::string expiry = params[1]; Anope::string reason = params.size() > 2 ? params[2] : ""; - time_t expiry_secs = Config->NSSuspendExpire; + time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire"); if (Anope::ReadOnly) { @@ -52,7 +54,7 @@ class CommandNSSuspend : public Command return; } - if (Config->NSSecureAdmins && na->nc->IsServicesOper()) + if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper()) { source.Reply(_("You may not suspend other Services Operators' nicknames.")); return; @@ -170,11 +172,9 @@ class NSSuspend : public Module CommandNSUnSuspend commandnsunsuspend; public: - NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnssuspend(this), commandnsunsuspend(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnPreNickExpire }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp index 309a95087..ee8a2c8cb 100644 --- a/modules/commands/ns_update.cpp +++ b/modules/commands/ns_update.cpp @@ -19,7 +19,6 @@ class CommandNSUpdate : public Command CommandNSUpdate(Module *creator) : Command(creator, "nickserv/update", 0, 0) { this->SetDesc(_("Updates your current status, i.e. it checks for new memos")); - this->SetSyntax(""); this->RequireUser(true); } @@ -36,7 +35,7 @@ class CommandNSUpdate : public Command FOREACH_MOD(I_OnNickUpdate, OnNickUpdate(u)); - source.Reply(_("Status updated (memos, vhost, chmodes, flags)."), Config->NickServ.c_str()); + source.Reply(_("Status updated (memos, vhost, chmodes, flags).")); } bool OnHelp(CommandSource &source, const Anope::string &) anope_override @@ -55,10 +54,9 @@ class NSUpdate : public Module CommandNSUpdate commandnsupdate; public: - NSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + NSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsupdate(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index bdf609b03..b7433d0eb 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -76,7 +76,7 @@ class CommandOSAKill : public Command sep.GetToken(mask); } - time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->AutokillExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -121,16 +121,18 @@ class CommandOSAKill : public Command if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -158,8 +160,11 @@ class CommandOSAKill : public Command return; } + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -185,7 +190,7 @@ class CommandOSAKill : public Command } akills->AddXLine(x); - if (Config->AkillOnAdd) + if (Config->GetModule("operserv")->Get<bool>("akillonadd")) akills->Send(NULL, x); source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str()); @@ -414,11 +419,12 @@ class CommandOSAKill : public Command "be given, even if it is the same as the default. The\n" "current AKILL default expiry time can be found with the\n" "\002STATS AKILL\002 command.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_( " \n" @@ -449,10 +455,9 @@ class OSAKill : public Module CommandOSAKill commandosakill; public: - OSAKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSAKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosakill(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp index 3fea40043..713b5922f 100644 --- a/modules/commands/os_chankill.cpp +++ b/modules/commands/os_chankill.cpp @@ -30,7 +30,6 @@ class CommandOSChanKill : public Command return; Anope::string expiry, channel; - time_t expires; unsigned last_param = 1; Channel *c; @@ -42,7 +41,7 @@ class CommandOSChanKill : public Command last_param = 2; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ChankillExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"); if (!expiry.empty() && isdigit(expiry[expiry.length() - 1])) expires *= 86400; if (expires && expires < 60) @@ -65,7 +64,7 @@ class CommandOSChanKill : public Command if (!reason.empty()) { Anope::string realreason; - if (Config->AddAkiller) + if (Config->GetBlock("operserv")->Get<bool>("addakiller") && !source.GetNick().empty()) realreason = "[" + source.GetNick() + "] " + reason; else realreason = reason; @@ -74,7 +73,7 @@ class CommandOSChanKill : public Command { for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) { - ChanUserContainer *uc = *it++; + ChanUserContainer *uc = it->second; if (uc->user->server == Me || uc->user->HasMode("OPER")) continue; @@ -108,10 +107,9 @@ class OSChanKill : public Module CommandOSChanKill commandoschankill; public: - OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoschankill(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_config.cpp b/modules/commands/os_config.cpp index b9c58b2b0..391d36157 100644 --- a/modules/commands/os_config.cpp +++ b/modules/commands/os_config.cpp @@ -15,22 +15,6 @@ class CommandOSConfig : public Command { - void ChangeHash(ConfigDataHash &hash, const Anope::string &block, const Anope::string &iname, const Anope::string &value) - { - ConfigDataHash::iterator it = hash.find(block); - - KeyValList &list = it->second; - for (unsigned i = 0; i < list.size(); ++i) - { - const Anope::string &item = list[i].first; - if (item == iname) - { - list[i] = std::make_pair(item, value); - break; - } - } - } - public: CommandOSConfig(Module *creator) : Command(creator, "operserv/config", 1, 4) { @@ -44,110 +28,17 @@ class CommandOSConfig : public Command if (what.equals_ci("MODIFY") && params.size() > 3) { - ConfigItems configitems(Config); - - for (unsigned i = 0; !configitems.Values[i].tag.empty(); ++i) + Configuration::Block *block = Config->GetBlock(params[1]); + if (!block) { - ConfigItems::Item *v = &configitems.Values[i]; - if (v->tag.equals_cs(params[1]) && v->value.equals_cs(params[2])) - { - try - { - ValueItem vi(params[3]); - if (!v->validation_function(Config, v->tag, v->value, vi)) - throw ConfigException("Parameter failed to validate."); - - int dt = v->datatype; - - if (dt & DT_NORELOAD) - throw ConfigException("This item can not be changed while Anope is running."); - bool allow_wild = dt & DT_ALLOW_WILD; - dt &= ~(DT_ALLOW_NEWLINE | DT_ALLOW_WILD); - - /* Yay for *massive* copypaste from config.cpp */ - switch (dt) - { - case DT_NOSPACES: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateNoSpaces(vi.GetValue(), v->tag, v->value); - vcs->Set(vi.GetValue()); - break; - } - case DT_HOSTNAME: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateHostname(vi.GetValue(), v->tag, v->value); - vcs->Set(vi.GetValue()); - break; - } - case DT_IPADDRESS: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateIP(vi.GetValue(), v->tag, v->value, allow_wild); - vcs->Set(vi.GetValue()); - break; - } - case DT_STRING: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - vcs->Set(vi.GetValue()); - break; - } - case DT_INTEGER: - { - int val = vi.GetInteger(); - ValueContainerInt *vci = anope_dynamic_static_cast<ValueContainerInt *>(v->val); - vci->Set(&val, sizeof(int)); - break; - } - case DT_UINTEGER: - { - unsigned val = vi.GetInteger(); - ValueContainerUInt *vci = anope_dynamic_static_cast<ValueContainerUInt *>(v->val); - vci->Set(&val, sizeof(unsigned)); - break; - } - case DT_LUINTEGER: - { - unsigned long val = vi.GetInteger(); - ValueContainerLUInt *vci = anope_dynamic_static_cast<ValueContainerLUInt *>(v->val); - vci->Set(&val, sizeof(unsigned long)); - break; - } - case DT_TIME: - { - time_t time = Anope::DoTime(vi.GetValue()); - ValueContainerTime *vci = anope_dynamic_static_cast<ValueContainerTime *>(v->val); - vci->Set(&time, sizeof(time_t)); - break; - } - case DT_BOOLEAN: - { - bool val = vi.GetBool(); - ValueContainerBool *vcb = anope_dynamic_static_cast<ValueContainerBool *>(v->val); - vcb->Set(&val, sizeof(bool)); - break; - } - default: - break; - } - } - catch (const ConfigException &ex) - { - source.Reply(_("Error changing configuration value: ") + ex.GetReason()); - return; - } - - ChangeHash(Config->config_data, params[1], params[2], params[3]); - - Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3]; - source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str()); - return; - } + source.Reply(_("There is no such configuration block %s."), params[1].c_str()); + return; } - source.Reply("There is no configuration value named %s:%s", params[1].c_str(), params[2].c_str()); + block->Set(params[2], params[3]); + + Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3]; + source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str()); } else if (what.equals_ci("VIEW")) { @@ -155,35 +46,30 @@ class CommandOSConfig : public Command const Anope::string show_blocks[] = { "botserv", "chanserv", "defcon", "global", "memoserv", "nickserv", "networkinfo", "operserv", "options", "" }; Log(LOG_ADMIN, source, this) << "VIEW"; - - for (ConfigDataHash::const_iterator it = Config->config_data.begin(), it_end = Config->config_data.end(); it != it_end; ++it) + + for (unsigned i = 0; !show_blocks[i].empty(); ++i) { - const Anope::string &bname = it->first; - const KeyValList &list = it->second; - - bool ok = false; - for (unsigned i = 0; !show_blocks[i].empty(); ++i) - if (bname == show_blocks[i]) - ok = true; - if (ok == false) + Configuration::Block *block = Config->GetBlock(show_blocks[i]); + const Configuration::Block::item_map *items = block->GetItems(); + + if (!items) continue; ListFormatter lflist; lflist.AddColumn("Name").AddColumn("Value"); - for (unsigned i = 0; i < list.size(); ++i) - { - const Anope::string &first = list[i].first, second = list[i].second; + for (Configuration::Block::item_map::const_iterator it = items->begin(), it_end = items->end(); it != it_end; ++it) + { ListFormatter::ListEntry entry; - entry["Name"] = first; - entry["Value"] = second; + entry["Name"] = it->first; + entry["Value"] = it->second; lflist.AddEntry(entry); } std::vector<Anope::string> replies; lflist.Process(replies); - source.Reply(_("%s settings:"), bname.c_str()); + source.Reply(_("%s settings:"), block->GetName().c_str()); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); @@ -193,8 +79,6 @@ class CommandOSConfig : public Command } else this->OnSyntaxError(source, what); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -217,10 +101,9 @@ class OSConfig : public Module CommandOSConfig commandosconfig; public: - OSConfig(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSConfig(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosconfig(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index 5d85c2e70..6d47d3a9f 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -12,8 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "global.h" -#include "os_session.h" +#include "modules/os_session.h" enum DefconLevel { @@ -43,6 +42,10 @@ struct DefconConfig time_t akillexpire, timeout; bool globalondefcon; + unsigned max_session_kill; + time_t session_autokill_expiry; + Anope::string sle_reason, sle_detailsloc; + DefconConfig() { this->DefCon.resize(6); @@ -329,42 +332,39 @@ class OSDefcon : public Module } public: - OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), session_service("SessionService", "session"), akills("XLineManager", "xlinemanager/sgline"), commandosdefcon(this) + OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), session_service("SessionService", "session"), akills("XLineManager", "xlinemanager/sgline"), commandosdefcon(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - - try - { - this->OnReload(); - } - catch (const ConfigException &ex) - { - throw ModuleException(ex.GetReason()); - } } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *block = conf->GetModule(this); DefconConfig dconfig; - dconfig.defaultlevel = config.ReadInteger("defcon", "defaultlevel", 0, 0); - dconfig.defcons[4] = config.ReadValue("defcon", "level4", 0); - dconfig.defcons[3] = config.ReadValue("defcon", "level3", 0); - dconfig.defcons[2] = config.ReadValue("defcon", "level2", 0); - dconfig.defcons[1] = config.ReadValue("defcon", "level1", 0); - dconfig.sessionlimit = config.ReadInteger("defcon", "sessionlimit", 0, 0); - dconfig.akillreason = config.ReadValue("defcon", "akillreason", 0); - dconfig.akillexpire = Anope::DoTime(config.ReadValue("defcon", "akillexpire", 0)); - dconfig.chanmodes = config.ReadValue("defcon", "chanmodes", 0); - dconfig.timeout = Anope::DoTime(config.ReadValue("defcon", "timeout", 0)); - dconfig.globalondefcon = config.ReadFlag("defcon", "globalondefcon", 0); - dconfig.message = config.ReadValue("defcon", "message", 0); - dconfig.offmessage = config.ReadValue("defcon", "offmessage", 0); + dconfig.defaultlevel = block->Get<int>("defaultlevel"); + dconfig.defcons[4] = block->Get<const Anope::string>("level4"); + dconfig.defcons[3] = block->Get<const Anope::string>("level3"); + dconfig.defcons[2] = block->Get<const Anope::string>("level2"); + dconfig.defcons[1] = block->Get<const Anope::string>("level1"); + dconfig.sessionlimit = block->Get<int>("sessionlimit"); + dconfig.akillreason = block->Get<const Anope::string>("akillreason"); + dconfig.akillexpire = block->Get<time_t>("akillexpire"); + dconfig.chanmodes = block->Get<const Anope::string>("chanmodes"); + dconfig.timeout = block->Get<time_t>("timeout"); + dconfig.globalondefcon = block->Get<bool>("globalondefcon"); + dconfig.message = block->Get<const Anope::string>("message"); + dconfig.offmessage = block->Get<const Anope::string>("offmessage"); + + Module *session = ModuleManager::FindModule("os_session"); + block = conf->GetModule(session); + + dconfig.max_session_kill = block->Get<int>("maxsessionkill"); + dconfig.session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry"); + dconfig.sle_reason = block->Get<const Anope::string>("sessionlimitexceeded"); + dconfig.sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc"); if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5) throw ConfigException("The value for <defcon:defaultlevel> must be between 1 and 5"); @@ -491,19 +491,18 @@ class OSDefcon : public Module if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) { Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); - x.by = Config->OperServ; + XLine x("*@" + u->host, OperServ ? OperServ->nick : "defcon", Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); akills->Send(NULL, &x); } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { - u->Kill(Config->OperServ, DConfig.akillreason); + u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason); return; } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { - u->Kill(Config->OperServ, DConfig.akillreason); + u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason); return; } @@ -525,22 +524,24 @@ class OSDefcon : public Module { if (session && session->count > static_cast<unsigned>(DConfig.sessionlimit)) { - if (!Config->SessionLimitExceeded.empty()) - IRCD->SendMessage(OperServ, u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str()); - if (!Config->SessionLimitDetailsLoc.empty()) - IRCD->SendMessage(OperServ, u->nick, "%s", Config->SessionLimitDetailsLoc.c_str()); + if (!DConfig.sle_reason.empty()) + { + Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip); + u->SendMessage(OperServ, message); + } + if (!DConfig.sle_detailsloc.empty()) + u->SendMessage(OperServ, DConfig.sle_detailsloc); ++session->hits; - if (akills && Config->MaxSessionKill && session->hits >= Config->MaxSessionKill) + if (akills && DConfig.max_session_kill && session->hits >= DConfig.max_session_kill) { - XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); + XLine x("*@" + u->host, OperServ ? OperServ->nick : "", Anope::CurTime + DConfig.session_autokill_expiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); akills->Send(NULL, &x); Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << u->host << "\002 due to excessive connections"; } else { - u->Kill(Config->OperServ, "Defcon session limit exceeded"); - u = NULL; /* No guarentee u still exists */ + u->Kill(OperServ ? OperServ->nick : "", "Defcon session limit exceeded"); } } } diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp index d690ae55a..698fa0e1a 100644 --- a/modules/commands/os_dns.cpp +++ b/modules/commands/os_dns.cpp @@ -6,7 +6,7 @@ */ #include "module.h" -#include "../extra/dns.h" +#include "modules/dns.h" static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager"); @@ -214,7 +214,7 @@ class CommandOSDNS : public Command for (unsigned i = 0; i < dns_servers->size(); ++i) { DNSServer *s = dns_servers->at(i); - Server *srv = Server::Find(s->GetName()); + Server *srv = Server::Find(s->GetName(), true); ListFormatter::ListEntry entry; entry["Server"] = s->GetName(); @@ -351,7 +351,7 @@ class CommandOSDNS : public Command return; } - Server *serv = Server::Find(params[1]); + Server *serv = Server::Find(params[1], true); if (!serv || serv == Me || serv->IsJuped()) { source.Reply(_("Server %s is not linked to the network."), params[1].c_str()); @@ -411,7 +411,7 @@ class CommandOSDNS : public Command source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str()); return; } - else if (Server::Find(s->GetName())) + else if (Server::Find(s->GetName(), true)) { source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str()); return; @@ -543,7 +543,7 @@ class CommandOSDNS : public Command source.Reply(_("Server %s does not exist."), params[1].c_str()); return; } - else if (!Server::Find(s->GetName())) + else if (!Server::Find(s->GetName(), true)) { source.Reply(_("Server %s is not currently linked."), s->GetName().c_str()); return; @@ -663,20 +663,17 @@ class ModuleDNS : public Module bool readd_connected_servers; public: - ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), zone_type("DNSZone", DNSZone::Unserialize), dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnNewServer, I_OnServerQuit, I_OnUserConnect, I_OnPreUserLogoff, I_OnDnsRequest }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); - for (unsigned j = 0; j < dns_servers->size(); ++j) { DNSServer *s = dns_servers->at(j); - if (s->Pooled() && Server::Find(s->GetName())) + if (s->Pooled() && Server::Find(s->GetName(), true)) s->SetActive(true); } } @@ -689,16 +686,15 @@ class ModuleDNS : public Module delete dns_servers->at(i - 1); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - - this->ttl = Anope::DoTime(config.ReadValue("os_dns", "ttl", 0)); - this->user_drop_mark = config.ReadInteger("os_dns", "user_drop_mark", 0, false); - this->user_drop_time = Anope::DoTime(config.ReadValue("os_dns", "user_drop_time", 0, false)); - this->user_drop_readd_time = Anope::DoTime(config.ReadValue("os_dns", "user_drop_readd_time", 0, false)); - this->remove_split_servers = config.ReadFlag("os_dns", "remove_split_servers", 0); - this->readd_connected_servers = config.ReadFlag("os_dns", "readd_connected_servers", 0); + Configuration::Block *block = conf->GetModule(this); + this->ttl = block->Get<time_t>("ttl"); + this->user_drop_mark = block->Get<int>("user_drop_mark"); + this->user_drop_time = block->Get<time_t>("user_drop_time"); + this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time"); + this->remove_split_servers = block->Get<bool>("remove_split_servers"); + this->readd_connected_servers = block->Get<bool>("readd_connected_servers"); } void OnNewServer(Server *s) anope_override @@ -785,7 +781,7 @@ class ModuleDNS : public Module } } - void OnDnsRequest(DNS::Packet &req, DNS::Packet *packet) anope_override + void OnDnsRequest(DNS::Query &req, DNS::Query *packet) anope_override { if (req.questions.empty()) return; diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp index e3a0c42b8..6cc00edda 100644 --- a/modules/commands/os_forbid.cpp +++ b/modules/commands/os_forbid.cpp @@ -12,64 +12,71 @@ /*************************************************************************/ #include "module.h" -#include "os_forbid.h" +#include "modules/os_forbid.h" + +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); class MyForbidService : public ForbidService { - Serialize::Checker<std::vector<ForbidData *> > forbid_data; + Serialize::Checker<std::vector<ForbidData *>[FT_SIZE - 1]> forbid_data; + + inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; } public: MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { } void AddForbid(ForbidData *d) anope_override { - this->forbid_data->push_back(d); + this->forbids(d->type).push_back(d); } void RemoveForbid(ForbidData *d) anope_override { - std::vector<ForbidData *>::iterator it = std::find(this->forbid_data->begin(), this->forbid_data->end(), d); - if (it != this->forbid_data->end()) - this->forbid_data->erase(it); + std::vector<ForbidData *>::iterator it = std::find(this->forbids(d->type).begin(), this->forbids(d->type).end(), d); + if (it != this->forbids(d->type).end()) + this->forbids(d->type).erase(it); delete d; } ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) anope_override { - const std::vector<ForbidData *> &forbids = this->GetForbids(); - for (unsigned i = forbids.size(); i > 0; --i) + for (unsigned i = this->forbids(ftype).size(); i > 0; --i) { - ForbidData *d = forbids[i - 1]; + ForbidData *d = this->forbids(ftype)[i - 1]; - if ((ftype == FT_NONE || ftype == d->type) && Anope::Match(mask, d->mask, false, true)) + if (Anope::Match(mask, d->mask, false, true)) return d; } return NULL; } - const std::vector<ForbidData *> &GetForbids() anope_override + std::vector<ForbidData *> GetForbids() anope_override { - for (unsigned i = this->forbid_data->size(); i > 0; --i) - { - ForbidData *d = this->forbid_data->at(i - 1); - - if (d->expires && Anope::CurTime >= d->expires) + std::vector<ForbidData *> f; + for (unsigned j = FT_NICK; j < FT_SIZE; ++j) + for (unsigned i = this->forbids(j).size(); i > 0; --i) { - Anope::string ftype = "none"; - if (d->type == FT_NICK) - ftype = "nick"; - else if (d->type == FT_CHAN) - ftype = "chan"; - else if (d->type == FT_EMAIL) - ftype = "email"; - - Log(LOG_NORMAL, "expire/forbid") << "Expiring forbid for " << d->mask << " type " << ftype; - this->forbid_data->erase(this->forbid_data->begin() + i - 1); - delete d; + ForbidData *d = this->forbids(j).at(i - 1); + + if (d->expires && Anope::CurTime >= d->expires) + { + Anope::string ftype = "none"; + if (d->type == FT_NICK) + ftype = "nick"; + else if (d->type == FT_CHAN) + ftype = "chan"; + else if (d->type == FT_EMAIL) + ftype = "email"; + + Log(LOG_NORMAL, "expire/forbid") << "Expiring forbid for " << d->mask << " type " << ftype; + this->forbids(j).erase(this->forbids(j).begin() + i - 1); + delete d; + } + else + f.push_back(d); } - } - return this->forbid_data; + return f; } }; @@ -93,7 +100,7 @@ class CommandOSForbid : public Command const Anope::string &command = params[0]; const Anope::string &subcommand = params.size() > 1 ? params[1] : ""; - ForbidType ftype = FT_NONE; + ForbidType ftype = FT_SIZE; if (subcommand.equals_ci("NICK")) ftype = FT_NICK; else if (subcommand.equals_ci("CHAN")) @@ -103,7 +110,7 @@ class CommandOSForbid : public Command else if (subcommand.equals_ci("REGISTER")) ftype = FT_REGISTER; - if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_NONE) + if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE) { const Anope::string &expiry = params[2][0] == '+' ? params[2] : ""; const Anope::string &entry = !expiry.empty() ? params[3] : params[2]; @@ -116,12 +123,6 @@ class CommandOSForbid : public Command time_t expiryt = 0; - if (Config->ForceForbidReason && reason.empty()) - { - this->OnSyntaxError(source, ""); - return; - } - if (!expiry.empty()) { expiryt = Anope::DoTime(expiry); @@ -130,7 +131,7 @@ class CommandOSForbid : public Command } NickAlias *target = NickAlias::Find(entry); - if (target != NULL && Config->NSSecureAdmins && target->nc->IsServicesOper()) + if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->nc->IsServicesOper()) { source.Reply(ACCESS_DENIED); return; @@ -156,7 +157,7 @@ class CommandOSForbid : public Command Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand; source.Reply(_("Added a forbid on %s to expire on %s."), entry.c_str(), d->expires ? Anope::strftime(d->expires).c_str() : "never"); } - else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_NONE) + else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE) { const Anope::string &entry = params[2]; @@ -229,11 +230,12 @@ class CommandOSForbid : public Command source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n" "and email addresses. Wildcards are accepted for all entries.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -247,10 +249,9 @@ class OSForbid : public Module CommandOSForbid commandosforbid; public: - OSForbid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSForbid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), forbiddata_type("ForbidData", ForbidData::Unserialize), forbidService(this), commandosforbid(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnUserConnect, I_OnUserNickChange, I_OnJoinChannel, I_OnPreCommand }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); @@ -291,21 +292,19 @@ class OSForbid : public Module ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN); if (d != NULL) { - if (IRCD->CanSQLineChannel) + ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + if (!chanserv) + ; + else if (IRCD->CanSQLineChannel) { - XLine x(c->name, OperServ->nick, Anope::CurTime + Config->CSInhabit, d->reason); + time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s"); + XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason); IRCD->SendSQLine(NULL, &x); } - else if (!c->HasExt("INHABIT")) + else { - /* Join ChanServ and set a timer for this channel to part ChanServ later */ - c->Hold(); - - /* Set +si to prevent rejoin */ - c->SetMode(NULL, "NOEXTERNAL"); - c->SetMode(NULL, "TOPIC"); - c->SetMode(NULL, "SECRET"); - c->SetMode(NULL, "INVITE"); + if (chanserv) + chanserv->Hold(c); } if (d->reason.empty()) diff --git a/modules/commands/os_forbid.h b/modules/commands/os_forbid.h deleted file mode 100644 index b4d1ce7ce..000000000 --- a/modules/commands/os_forbid.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef OS_FORBID_H -#define OS_FORBID_H - -enum ForbidType -{ - FT_NONE, - FT_NICK, - FT_CHAN, - FT_EMAIL, - FT_REGISTER -}; - -struct ForbidData : Serializable -{ - Anope::string mask; - Anope::string creator; - Anope::string reason; - time_t created; - time_t expires; - ForbidType type; - - ForbidData() : Serializable("ForbidData") { } - void Serialize(Serialize::Data &data) const anope_override; - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); -}; - -class ForbidService : public Service -{ - public: - ForbidService(Module *m) : Service(m, "ForbidService", "forbid") { } - - virtual void AddForbid(ForbidData *d) = 0; - - virtual void RemoveForbid(ForbidData *d) = 0; - - virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0; - - virtual const std::vector<ForbidData *> &GetForbids() = 0; -}; - -static ServiceReference<ForbidService> forbid_service("ForbidService", "forbid"); - -void ForbidData::Serialize(Serialize::Data &data) const -{ - data["mask"] << this->mask; - data["creator"] << this->creator; - data["reason"] << this->reason; - data["created"] << this->created; - data["expires"] << this->expires; - data["type"] << this->type; -} - -Serializable* ForbidData::Unserialize(Serializable *obj, Serialize::Data &data) -{ - if (!forbid_service) - return NULL; - - ForbidData *fb; - if (obj) - fb = anope_dynamic_static_cast<ForbidData *>(obj); - else - fb = new ForbidData; - - data["mask"] >> fb->mask; - data["creator"] >> fb->creator; - data["reason"] >> fb->reason; - data["created"] >> fb->created; - data["expires"] >> fb->expires; - unsigned int t; - data["type"] >> t; - fb->type = static_cast<ForbidType>(t); - - if (!obj) - forbid_service->AddForbid(fb); - return fb; -} - -#endif - diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp index 3d30237fa..b7dda73a3 100644 --- a/modules/commands/os_ignore.cpp +++ b/modules/commands/os_ignore.cpp @@ -12,7 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "os_ignore.h" +#include "modules/os_ignore.h" class OSIgnoreService : public IgnoreService { @@ -299,11 +299,12 @@ class CommandOSIgnore : public Command " \n" "Ignores will not be enforced on IRC Operators.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -317,10 +318,9 @@ class OSIgnore : public Module CommandOSIgnore commandosignore; public: - OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), ignoredata_type("IgnoreData", IgnoreData::Unserialize), osignoreservice(this), commandosignore(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnBotPrivmsg }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/commands/os_ignore.h b/modules/commands/os_ignore.h deleted file mode 100644 index 6c3e237ab..000000000 --- a/modules/commands/os_ignore.h +++ /dev/null @@ -1,79 +0,0 @@ -/* OperServ ignore interface - * - * (C) 2003-2013 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - - -struct IgnoreData : Serializable -{ - Anope::string mask; - Anope::string creator; - Anope::string reason; - time_t time; /* When do we stop ignoring them? */ - - IgnoreData() : Serializable("IgnoreData") { } - void Serialize(Serialize::Data &data) const anope_override; - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); -}; - -class IgnoreService : public Service -{ - protected: - std::list<IgnoreData> ignores; - - IgnoreService(Module *c) : Service(c, "IgnoreService", "ignore") { } - - public: - virtual IgnoreData* AddIgnore(const Anope::string &mask, const Anope::string &creator, const Anope::string &reason, time_t delta = Anope::CurTime) = 0; - - virtual bool DelIgnore(const Anope::string &mask) = 0; - - inline void ClearIgnores() { this->ignores.clear(); } - - virtual IgnoreData *Find(const Anope::string &mask) = 0; - - inline std::list<IgnoreData> &GetIgnores() { return this->ignores; } -}; - -static ServiceReference<IgnoreService> ignore_service("IgnoreService", "ignore"); - -void IgnoreData::Serialize(Serialize::Data &data) const -{ - data["mask"] << this->mask; - data["creator"] << this->creator; - data["reason"] << this->reason; - data["time"] << this->time; -} - -Serializable* IgnoreData::Unserialize(Serializable *obj, Serialize::Data &data) -{ - if (!ignore_service) - return NULL; - - if (obj) - { - IgnoreData *ign = anope_dynamic_static_cast<IgnoreData *>(obj); - data["mask"] >> ign->mask; - data["creator"] >> ign->creator; - data["reason"] >> ign->reason; - data["time"] >> ign->time; - return ign; - } - - Anope::string smask, screator, sreason; - time_t t; - - data["mask"] >> smask; - data["creator"] >> screator; - data["reason"] >> sreason; - data["time"] >> t; - - return ignore_service->AddIgnore(smask, screator, sreason, t); -} - diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp index fa79c9098..4f40a5495 100644 --- a/modules/commands/os_jupe.cpp +++ b/modules/commands/os_jupe.cpp @@ -26,7 +26,7 @@ class CommandOSJupe : public Command { const Anope::string &jserver = params[0]; const Anope::string &reason = params.size() > 1 ? params[1] : ""; - Server *server = Server::Find(jserver); + Server *server = Server::Find(jserver, true); if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos) source.Reply(_("Please use a valid server name when juping.")); @@ -66,10 +66,9 @@ class OSJupe : public Module CommandOSJupe commandosjupe; public: - OSJupe(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSJupe(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosjupe(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_kick.cpp b/modules/commands/os_kick.cpp index 37866af74..d9ac75c9a 100644 --- a/modules/commands/os_kick.cpp +++ b/modules/commands/os_kick.cpp @@ -70,10 +70,9 @@ class OSKick : public Module CommandOSKick commandoskick; public: - OSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoskick(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_kill.cpp b/modules/commands/os_kill.cpp index 898e601e6..99a65ae4b 100644 --- a/modules/commands/os_kill.cpp +++ b/modules/commands/os_kill.cpp @@ -36,10 +36,10 @@ class CommandOSKill : public Command { if (reason.empty()) reason = "No reason specified"; - if (Config->AddAkiller) + if (Config->GetBlock("operserv")->Get<bool>("addakiller")) reason = "(" + source.GetNick() + ") " + reason; Log(LOG_ADMIN, source, this) << "on " << u2->nick << " for " << reason; - u2->Kill(Config->OperServ, reason); + u2->Kill(source.service->nick, reason); } } @@ -59,10 +59,9 @@ class OSKill : public Module CommandOSKill commandoskill; public: - OSKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoskill(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp index f4de45203..dc1fd15ed 100644 --- a/modules/commands/os_list.cpp +++ b/modules/commands/os_list.cpp @@ -44,7 +44,7 @@ class CommandOSChanList : public Command for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit) { - ChanUserContainer *cc = *uit; + ChanUserContainer *cc = uit->second; if (!modes.empty()) for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) @@ -103,11 +103,12 @@ class CommandOSChanList : public Command "specified, lists only channels matching \002pattern\002 that have the +s or\n" "+p mode.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -142,7 +143,7 @@ class CommandOSUserList : public Command for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit) { - ChanUserContainer *uc = *cuit; + ChanUserContainer *uc = cuit->second; if (!modes.empty()) for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) @@ -208,11 +209,12 @@ class CommandOSUserList : public Command "that are on the given channel. If INVISIBLE is specified, only users\n" "with the +i flag will be listed.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -225,10 +227,9 @@ class OSList : public Module CommandOSUserList commandosuserlist; public: - OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoschanlist(this), commandosuserlist(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp index 76b9e15ba..30172a0f3 100644 --- a/modules/commands/os_login.cpp +++ b/modules/commands/os_login.cpp @@ -19,7 +19,6 @@ class CommandOSLogin : public Command public: CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1) { - this->SetDesc(Anope::printf(_("Login to %s"), Config->OperServ.c_str())); this->SetSyntax(_("\037password\037")); this->RequireUser(true); } @@ -60,6 +59,11 @@ class CommandOSLogin : public Command "configured without a password."), source.service->nick.c_str()); return true; } + + const Anope::string GetDesc(CommandSource &source) const anope_override + { + return Anope::printf(_("Login to %s"), source.service->nick.c_str()); + } }; class CommandOSLogout : public Command @@ -67,8 +71,6 @@ class CommandOSLogout : public Command public: CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0) { - this->SetDesc(Anope::printf(_("Logout from %s"), Config->OperServ.c_str())); - this->SetSyntax(""); this->RequireUser(true); } @@ -99,6 +101,11 @@ class CommandOSLogout : public Command "with a password."), source.service->nick.c_str()); return true; } + + const Anope::string GetDesc(CommandSource &source) const anope_override + { + return Anope::printf(_("Logout from %s"), source.service->nick.c_str()); + } }; class OSLogin : public Module @@ -107,10 +114,9 @@ class OSLogin : public Module CommandOSLogout commandoslogout; public: - OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoslogin(this), commandoslogout(this) { - this->SetAuthor("Anope"); ModuleManager::Attach(I_IsServicesOper, this); } diff --git a/modules/commands/os_logsearch.cpp b/modules/commands/os_logsearch.cpp index 6eec4ba74..d967da9e8 100644 --- a/modules/commands/os_logsearch.cpp +++ b/modules/commands/os_logsearch.cpp @@ -11,8 +11,6 @@ #include "module.h" -static Anope::string logfile_name; - class CommandOSLogSearch : public Command { static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime) @@ -91,6 +89,7 @@ class CommandOSLogSearch : public Command Log(LOG_ADMIN, source, this) << "for " << search_string; + const Anope::string &logfile_name = Config->GetModule(this->owner)->Get<const Anope::string>("logname"); std::list<Anope::string> matches; for (int d = days - 1; d >= 0; --d) { @@ -148,21 +147,9 @@ class OSLogSearch : public Module CommandOSLogSearch commandoslogsearch; public: - OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoslogsearch(this) { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnReload }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); - } - - void OnReload() anope_override - { - ConfigReader config; - logfile_name = config.ReadValue("logsearch", "name", "services.log", 0); } }; diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp index 33387bff6..8af247da5 100644 --- a/modules/commands/os_mode.cpp +++ b/modules/commands/os_mode.cpp @@ -45,13 +45,13 @@ class CommandOSMode : public Command { for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; if (uc->user->HasMode("OPER")) continue; - for (std::set<Anope::string>::iterator it2 = uc->status.modes.begin(), it2_end = uc->status.modes.end(); it2 != it2_end; ++it2) - c->RemoveMode(c->ci->WhoSends(), *it2, uc->user->GetUID(), false); + for (size_t i = 0; i < uc->status.Modes().length(); ++i) + c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i]), uc->user->GetUID(), false); } source.Reply(_("All modes cleared on %s."), c->name.c_str()); @@ -176,10 +176,9 @@ class OSMode : public Module CommandOSUMode commandosumode; public: - OSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosmode(this), commandosumode(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_modinfo.cpp b/modules/commands/os_modinfo.cpp index 014418e6e..b6f793796 100644 --- a/modules/commands/os_modinfo.cpp +++ b/modules/commands/os_modinfo.cpp @@ -29,7 +29,7 @@ class CommandOSModInfo : public Command Module *m = ModuleManager::FindModule(file); if (m) { - source.Reply(_("Module: \002%s\002 Version: \002%s\002 Author: \002%s\002 loaded: \002%s\002"), m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "?", Anope::strftime(m->created).c_str()); + source.Reply(_("Module: \002%s\002 Version: \002%s\002 Author: \002%s\002 loaded: \002%s\002"), m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "Unknown", Anope::strftime(m->created).c_str()); std::vector<Anope::string> servicekeys = Service::GetServiceKeys("Command"); for (unsigned i = 0; i < servicekeys.size(); ++i) @@ -76,157 +76,115 @@ class CommandOSModList : public Command CommandOSModList(Module *creator) : Command(creator, "operserv/modlist", 0, 1) { this->SetDesc(_("List loaded modules")); - this->SetSyntax(_("[Core|3rd|protocol|encryption|supported]")); + this->SetSyntax(_("[all|third|vendor|database|encryption|pseudoclient|protocol]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { const Anope::string ¶m = !params.empty() ? params[0] : ""; + bool third = false, extra = false, vendor = false, database = false, encryption = false, pseudoclient = false, protocol = false; + + if (param.equals_ci("all")) + third = extra = vendor = database = encryption = pseudoclient = protocol = true; + else if (param.equals_ci("third")) + third = true; + else if (param.equals_ci("vendor")) + vendor = true; + else if (param.equals_ci("database")) + database = true; + else if (param.equals_ci("encryption")) + encryption = true; + else if (param.equals_ci("pseudoclient")) + pseudoclient = true; + else if (param.equals_ci("protocol")) + protocol = true; + else + third = extra = database = encryption = protocol = true; + + Module *protomod = ModuleManager::FindFirstOf(PROTOCOL); + + source.Reply(_("Current module list:")); + int count = 0; - int showCore = 0; - int showThird = 1; - int showProto = 1; - int showEnc = 1; - int showSupported = 1; - int showDB = 1; - - char core[] = "Core"; - char third[] = "3rd"; - char proto[] = "Protocol"; - char enc[] = "Encryption"; - char supported[] = "Supported"; - char db[] = "Database"; - - if (!param.empty()) + for (std::list<Module *>::iterator it = ModuleManager::Modules.begin(), it_end = ModuleManager::Modules.end(); it != it_end; ++it) { - if (param.equals_ci(core)) + Module *m = *it; + + bool show = false; + Anope::string mtype; + + if (m->type & PROTOCOL) { - showCore = 1; - showThird = 0; - showProto = 0; - showEnc = 0; - showSupported = 0; - showDB = 0; + show |= protocol; + if (!mtype.empty()) + mtype += ", "; + mtype += "Protocol"; } - else if (param.equals_ci(third)) + if (m->type & PSEUDOCLIENT) { - showCore = 0; - showThird = 1; - showSupported = 0; - showProto = 0; - showEnc = 0; - showDB = 0; + show |= pseudoclient; + if (!mtype.empty()) + mtype += ", "; + mtype += "Pseudoclient"; } - else if (param.equals_ci(proto)) + if (m->type & ENCRYPTION) { - showCore = 0; - showThird = 0; - showProto = 1; - showEnc = 0; - showSupported = 0; - showDB = 0; + show |= encryption; + if (!mtype.empty()) + mtype += ", "; + mtype += "Encryption"; } - else if (param.equals_ci(supported)) + if (m->type & DATABASE) { - showCore = 0; - showThird = 0; - showProto = 0; - showSupported = 1; - showEnc = 0; - showDB = 0; + show |= database; + if (!mtype.empty()) + mtype += ", "; + mtype += "Database"; } - else if (param.equals_ci(enc)) + if (m->type & VENDOR) { - showCore = 0; - showThird = 0; - showProto = 0; - showSupported = 0; - showEnc = 1; - showDB = 0; + show |= vendor; + if (!mtype.empty()) + mtype += ", "; + mtype += "Vendor"; } - else if (param.equals_ci(db)) + if (m->type & EXTRA) { - showCore = 0; - showThird = 0; - showProto = 0; - showSupported = 0; - showEnc = 0; - showDB = 1; + show |= extra; + if (!mtype.empty()) + mtype += ", "; + mtype += "Extra"; + } + if (m->type & THIRD) + { + show |= third; + if (!mtype.empty()) + mtype += ", "; + mtype += "Third"; } - } - - Module *protocol = ModuleManager::FindFirstOf(PROTOCOL); - source.Reply(_("Current module list:")); + if (!show) + continue; + else if (m->type & PROTOCOL && param.empty() && m != protomod) + continue; - for (std::list<Module *>::iterator it = ModuleManager::Modules.begin(), it_end = ModuleManager::Modules.end(); it != it_end; ++it) - { - Module *m = *it; + ++count; - switch (m->type) - { - case CORE: - if (showCore) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), core); - ++count; - } - break; - case THIRD: - if (showThird) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), third); - ++count; - } - break; - case PROTOCOL: - if (m != protocol) - break; - if (showProto) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), proto); - ++count; - } - break; - case SUPPORTED: - if (showSupported) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), supported); - ++count; - } - break; - case ENCRYPTION: - if (showEnc) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), enc); - ++count; - } - break; - case DATABASE: - if (showDB) - { - source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), db); - ++count; - } - break; - default: - break; - } + source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), mtype.c_str()); } + if (!count) - source.Reply(_("No modules currently loaded.")); + source.Reply(_("No modules currently loaded matching that criteria.")); else source.Reply(_("%d modules loaded."), count); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Lists all currently loaded modules.")); + source.Reply(_("Lists currently loaded modules.")); return true; } }; @@ -237,10 +195,9 @@ class OSModInfo : public Module CommandOSModList commandosmodlist; public: - OSModInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSModInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosmodinfo(this), commandosmodlist(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_module.cpp b/modules/commands/os_module.cpp index aa9673019..0de03971e 100644 --- a/modules/commands/os_module.cpp +++ b/modules/commands/os_module.cpp @@ -180,10 +180,9 @@ class OSModule : public Module CommandOSModUnLoad commandosmodunload; public: - OSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosmodload(this), commandosmodreload(this), commandosmodunload(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); } diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp index 0833fbaa6..e9f70b693 100644 --- a/modules/commands/os_news.cpp +++ b/modules/commands/os_news.cpp @@ -12,8 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "global.h" -#include "os_news.h" +#include "modules/os_news.h" /* List of messages for each news type. This simplifies message sending. */ @@ -271,10 +270,8 @@ class CommandOSLogonNews : public NewsBase "user connects to the network, these messages will be sent\n" "to them. (However, no more than \002%d\002 messages will be\n" "sent in order to avoid flooding the user. If there are\n" - "more news messages, only the most recent will be sent.)\n" - "NewsCount can be configured in services.conf.\n" - " \n" - "LOGONNEWS may only be used by Services Operators."), Config->NewsCount); + "more news messages, only the most recent will be sent."), + Config->GetModule(this->owner)->Get<unsigned>("newscount", "3")); return true; } }; @@ -300,10 +297,8 @@ class CommandOSOperNews : public NewsBase "user opers up (with the /OPER command), these messages will\n" "be sent to them. (However, no more than \002%d\002 messages will\n" "be sent in order to avoid flooding the user. If there are\n" - "more news messages, only the most recent will be sent.)\n" - "NewsCount can be configured in services.conf.\n" - " \n" - "OPERNEWS may only be used by Services Operators."), Config->NewsCount); + "more news messages, only the most recent will be sent."), + Config->GetModule(this->owner)->Get<unsigned>("newscount", "3")); return true; } }; @@ -327,9 +322,7 @@ class CommandOSRandomNews : public NewsBase source.Reply(" "); source.Reply(_("Edits or displays the list of random news messages. When a\n" "user connects to the network, one (and only one) of the\n" - "random news will be randomly chosen and sent to them.\n" - " \n" - "RANDOMNEWS may only be used by Services Operators.")); + "random news will be randomly chosen and sent to them.\n")); return true; } }; @@ -358,7 +351,7 @@ class OSNews : public Module msg = _("[\002Random News\002 - %s] %s"); static unsigned cur_rand_news = 0; - unsigned displayed = 0; + unsigned displayed = 0, news_count = Config->GetModule(this)->Get<unsigned>("newscount", "3"); for (unsigned i = 0, end = newsList.size(); i < end; ++i) { if (Type == NEWS_RANDOM && i != cur_rand_news) @@ -380,7 +373,7 @@ class OSNews : public Module ++cur_rand_news; break; } - else if (displayed >= Config->NewsCount) + else if (displayed >= news_count) break; } @@ -390,11 +383,9 @@ class OSNews : public Module } public: - OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), newsitem_type("NewsItem", NewsItem::Unserialize), newsservice(this), commandoslogonnews(this), commandosopernews(this), commandosrandomnews(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnUserModeSet, I_OnUserConnect }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } diff --git a/modules/commands/os_news.h b/modules/commands/os_news.h deleted file mode 100644 index b1e717455..000000000 --- a/modules/commands/os_news.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef OS_NEWS -#define OS_NEWS - -enum NewsType -{ - NEWS_LOGON, - NEWS_RANDOM, - NEWS_OPER -}; - -struct NewsMessages -{ - NewsType type; - Anope::string name; - const char *msgs[10]; -}; - -struct NewsItem : Serializable -{ - NewsType type; - Anope::string text; - Anope::string who; - time_t time; - - NewsItem() : Serializable("NewsItem") { } - void Serialize(Serialize::Data &data) const anope_override; - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); -}; - -class NewsService : public Service -{ - public: - NewsService(Module *m) : Service(m, "NewsService", "news") { } - - virtual void AddNewsItem(NewsItem *n) = 0; - - virtual void DelNewsItem(NewsItem *n) = 0; - - virtual std::vector<NewsItem *> &GetNewsList(NewsType t) = 0; -}; - -static ServiceReference<NewsService> news_service("NewsService", "news"); - -void NewsItem::Serialize(Serialize::Data &data) const -{ - data["type"] << this->type; - data["text"] << this->text; - data["who"] << this->who; - data["time"] << this->time; -} - -Serializable* NewsItem::Unserialize(Serializable *obj, Serialize::Data &data) -{ - if (!news_service) - return NULL; - - NewsItem *ni; - if (obj) - ni = anope_dynamic_static_cast<NewsItem *>(obj); - else - ni = new NewsItem(); - - unsigned int t; - data["type"] >> t; - ni->type = static_cast<NewsType>(t); - data["text"] >> ni->text; - data["who"] >> ni->who; - data["time"] >> ni->time; - - if (!obj) - news_service->AddNewsItem(ni); - return ni; -} - -#endif // OS_NEWS - diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp index 9e9af1398..204b0e6e8 100644 --- a/modules/commands/os_noop.cpp +++ b/modules/commands/os_noop.cpp @@ -28,7 +28,7 @@ class CommandOSNOOP : public Command const Anope::string &cmd = params[0]; const Anope::string &server = params[1]; - Server *s = Server::Find(server); + Server *s = Server::Find(server, true); if (s == NULL) source.Reply(_("Server %s does not exist."), server.c_str()); else if (s == Me || s->IsJuped()) @@ -49,7 +49,7 @@ class CommandOSNOOP : public Command User *u2 = it->second; if (u2->server == s && u2->HasMode("OPER")) - u2->Kill(Config->OperServ, reason); + u2->Kill(source.service->nick, reason); } } else if (cmd.equals_ci("REVOKE")) @@ -80,10 +80,9 @@ class OSNOOP : public Module CommandOSNOOP commandosnoop; public: - OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosnoop(this) { - this->SetAuthor("Anope"); ModuleManager::Attach(I_OnUserModeSet, this); } @@ -96,7 +95,7 @@ class OSNOOP : public Module if (setter) { Anope::string reason = "NOOP command used by " + *setter; - u->Kill(Config->OperServ, reason); + u->Kill(OperServ ? OperServ->nick : "", reason); } } } diff --git a/modules/commands/os_oline.cpp b/modules/commands/os_oline.cpp index ba6d3f54c..e8f7cee9d 100644 --- a/modules/commands/os_oline.cpp +++ b/modules/commands/os_oline.cpp @@ -67,10 +67,9 @@ class OSOLine : public Module CommandOSOLine commandosoline; public: - OSOLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSOLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosoline(this) { - this->SetAuthor("Anope"); if (!IRCD || !IRCD->CanSVSO) throw ModuleException("Your IRCd does not support OMODE."); diff --git a/modules/commands/os_oper.cpp b/modules/commands/os_oper.cpp index 91efcf575..c3327dd4b 100644 --- a/modules/commands/os_oper.cpp +++ b/modules/commands/os_oper.cpp @@ -207,10 +207,9 @@ class OSOper : public Module CommandOSOper commandosoper; public: - OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), myoper_type("Oper", MyOper::Unserialize), commandosoper(this) { - this->SetAuthor("Anope"); } ~OSOper() diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp index 0370bcd2e..ed04fbea3 100644 --- a/modules/commands/os_reload.cpp +++ b/modules/commands/os_reload.cpp @@ -19,28 +19,22 @@ class CommandOSReload : public Command CommandOSReload(Module *creator) : Command(creator, "operserv/reload", 0, 0) { this->SetDesc(_("Reload services' configuration file")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - ServerConfig *old_config = Config; - try { - Config = new ServerConfig(); - FOREACH_MOD(I_OnReload, OnReload()); - delete old_config; - source.Reply(_("Services' configuration file has been reloaded.")); + Configuration::Conf *new_config = new Configuration::Conf(); + delete Config; + Config = new_config; + source.Reply(_("Services' configuration has been reloaded.")); } catch (const ConfigException &ex) { - Config = old_config; Log(this->owner) << "Error reloading configuration file: " << ex.GetReason(); - source.Reply(_("Error reloading configuration file: ") + ex.GetReason()); + source.Reply(_("Error reloading configuration file: %s"), ex.GetReason().c_str()); } - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -60,10 +54,9 @@ class OSReload : public Module CommandOSReload commandosreload; public: - OSReload(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSReload(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosreload(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index 1edda00d6..1e0e7c59c 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -12,7 +12,30 @@ /*************************************************************************/ #include "module.h" -#include "os_session.h" +#include "modules/os_session.h" + +namespace +{ + /* The default session limit */ + unsigned session_limit; + /* How many times to kill before adding an AKILL */ + unsigned max_session_kill; + /* How long session akills should last */ + time_t session_autokill_expiry; + /* Reason to use for session kills */ + Anope::string sle_reason; + /* Optional second reason */ + Anope::string sle_detailsloc; + + /* Max limit that can be used for exceptions */ + unsigned max_exception_limit; + /* How long before exceptions expire by default */ + time_t exception_expiry; + + /* Number of bits to use when comparing session IPs */ + unsigned ipv4_cidr; + unsigned ipv6_cidr; +} class MySessionService : public SessionService { @@ -61,11 +84,6 @@ class MySessionService : public SessionService return this->Exceptions; } - void AddSession(Session *s) anope_override - { - this->Sessions[s->addr] = s; - } - void DelSession(Session *s) anope_override { this->Sessions.erase(s->addr); @@ -73,13 +91,25 @@ class MySessionService : public SessionService Session *FindSession(const Anope::string &ip) anope_override { - cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); SessionMap::iterator it = this->Sessions.find(c); if (it != this->Sessions.end()) return it->second; return NULL; } + SessionMap::iterator FindSessionIterator(const Anope::string &ip) + { + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + return this->Sessions.find(c); + } + + Session* &FindOrCreateSession(const Anope::string &ip) + { + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + return this->Sessions[c]; + } + SessionMap &GetSessions() anope_override { return this->Sessions; @@ -89,7 +119,7 @@ class MySessionService : public SessionService class ExpireTimer : public Timer { public: - ExpireTimer() : Timer(Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireTimer() : Timer(Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { @@ -211,10 +241,16 @@ class CommandOSSession : public Command else { Exception *exception = session_service->FindException(param); - source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, exception && exception->limit > Config->DefSessionLimit ? exception->limit : Config->DefSessionLimit); + unsigned limit = session_limit; + if (exception) + { + if (!exception->limit) + limit = 0; + else if (exception->limit > limit) + limit = exception->limit; + } + source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, limit); } - - return; } public: CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2) @@ -228,20 +264,14 @@ class CommandOSSession : public Command { const Anope::string &cmd = params[0]; - if (!Config->LimitSessions) - { + if (!session_limit) source.Reply(_("Session limiting is disabled.")); - return; - } - - if (cmd.equals_ci("LIST")) + else if (cmd.equals_ci("LIST")) return this->DoList(source, params); else if (cmd.equals_ci("VIEW")) return this->DoView(source, params); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -296,7 +326,7 @@ class CommandOSException : public Command return; } - time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ExceptionExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry; if (expires < 0) { source.Reply(BAD_EXPIRY_TIME); @@ -312,9 +342,9 @@ class CommandOSException : public Command } catch (const ConvertException &) { } - if (limit > Config->MaxSessionLimit) + if (limit > max_exception_limit) { - source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), Config->MaxSessionLimit); + source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), max_exception_limit); return; } else @@ -541,13 +571,9 @@ class CommandOSException : public Command { const Anope::string &cmd = params[0]; - if (!Config->LimitSessions) - { + if (!session_limit) source.Reply(_("Session limiting is disabled.")); - return; - } - - if (cmd.equals_ci("ADD")) + else if (cmd.equals_ci("ADD")) return this->DoAdd(source, params); else if (cmd.equals_ci("DEL")) return this->DoDel(source, params); @@ -559,8 +585,6 @@ class CommandOSException : public Command return this->DoView(source, params); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -572,10 +596,9 @@ class CommandOSException : public Command "such as shell servers, to carry more than the default number\n" "of clients at a time. Once a host reaches its session limit,\n" "all clients attempting to connect from that host will be\n" - "killed. Before the user is killed, they are notified, via a\n" - "/NOTICE from %s, of a source of help regarding session\n" - "limiting. The content of this notice is a config setting.\n"), - Config->OperServ.c_str()); + "killed. Before the user is killed, they are notified, of a\n" + "source of help regarding session limiting. The content of\n" + "this notice is a config setting.\n")); source.Reply(" "); source.Reply(_("\002EXCEPTION ADD\002 adds the given host mask to the exception list.\n" "Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n" @@ -611,124 +634,139 @@ class OSSession : public Module CommandOSException commandosexception; ServiceReference<XLineManager> akills; - void AddSession(User *u, bool exempt) + public: + OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline") { - Session *session; - try - { - session = this->ss.FindSession(u->ip); - } - catch (const SocketException &) - { + this->SetPermanent(true); + + Implementation i[] = { I_OnReload, I_OnUserConnect, I_OnPreUserLogoff }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + ModuleManager::SetPriority(this, PRIORITY_FIRST); + } + + void OnReload(Configuration::Conf *conf) anope_override + { + Configuration::Block *block = Config->GetModule(this); + + session_limit = block->Get<int>("defaultsessionlimit"); + max_session_kill = block->Get<int>("maxsessionkill"); + session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry"); + sle_reason = block->Get<const Anope::string>("sessionlimitexceeded"); + sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc"); + + max_exception_limit = block->Get<int>("maxsessionlimit"); + exception_expiry = block->Get<time_t>("exceptionexpiry"); + + ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32"); + ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128"); + + if (ipv4_cidr > 32 || ipv6_cidr > 128) + throw ConfigException(this->name + ": session CIDR value out of range"); + } + + void OnUserConnect(User *u, bool &exempt) anope_override + { + if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined()) return; - } - if (session) + try { - bool kill = false; - if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit) + Session* &session = this->ss.FindOrCreateSession(u->ip); + + if (session) { - kill = true; - Exception *exception = this->ss.FindException(u); - if (exception) + bool kill = false; + if (session->count >= session_limit) { - kill = false; - if (exception->limit && session->count >= exception->limit) - kill = true; + kill = true; + Exception *exception = this->ss.FindException(u); + if (exception) + { + kill = false; + if (exception->limit && session->count >= exception->limit) + kill = true; + } } - } - /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was - * decremented in do_quit, which caused problems and fixed here - * - * Now, we create the user struture before calling this to fix some user tracking issues, - * so we must increment this here no matter what because it will either be - * decremented in do_kill or in do_quit - Adam - */ - ++session->count; + /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was + * decremented in do_quit, which caused problems and fixed here + * + * Now, we create the user struture before calling this to fix some user tracking issues, + * so we must increment this here no matter what because it will either be + * decremented when the user is killed or quits - Adam + */ + ++session->count; - if (kill && !exempt) - { - if (OperServ) + if (kill && !exempt) { - if (!Config->SessionLimitExceeded.empty()) - u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->ip.c_str()); - if (!Config->SessionLimitDetailsLoc.empty()) - u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str()); - } + if (OperServ) + { + if (!sle_reason.empty()) + { + Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip); + u->SendMessage(OperServ, message); + } + if (!sle_detailsloc.empty()) + u->SendMessage(OperServ, sle_detailsloc); + } - ++session->hits; - if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills) - { - const Anope::string &akillmask = "*@" + u->ip; - XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID()); - akills->AddXLine(x); - akills->Send(NULL, x); - Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections"; - } - else - { - u->Kill(Config->OperServ, "Session limit exceeded"); - u = NULL; /* No guarentee u still exists */ + ++session->hits; + if (max_session_kill && session->hits >= max_session_kill && akills) + { + const Anope::string &akillmask = "*@" + u->ip; + XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID()); + akills->AddXLine(x); + akills->Send(NULL, x); + Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections"; + } + else + { + u->Kill(OperServ ? OperServ->nick : "", "Session limit exceeded"); + } } } + else + { + session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + } } - else - { - session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); - this->ss.AddSession(session); - } + catch (const SocketException &) { } } - void DelSession(User *u) + void OnPreUserLogoff(User *u) anope_override { - Session *session; + if (!session_limit || !u->server || u->server->IsULined()) + return; + + SessionService::SessionMap::iterator sit; try { - session = this->ss.FindSession(u->ip); + sit = this->ss.FindSessionIterator(u->ip); } catch (const SocketException &) { return; } - if (!session) + + SessionService::SessionMap &sessions = this->ss.GetSessions(); + + if (sit == sessions.end()) { Log(LOG_DEBUG) << "Tried to delete non-existant session: " << u->ip; return; } + Session *session = sit->second; + if (session->count > 1) { --session->count; return; } - this->ss.DelSession(session); delete session; - } - - public: - OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline") - { - this->SetAuthor("Anope"); - this->SetPermanent(true); - - Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - ModuleManager::SetPriority(this, PRIORITY_FIRST); - } - - void OnUserConnect(User *user, bool &exempt) anope_override - { - if (!user->Quitting() && Config->LimitSessions) - this->AddSession(user, exempt); - } - - void OnPreUserLogoff(User *u) anope_override - { - if (Config->LimitSessions && (!u->server || !u->server->IsULined())) - this->DelSession(u); + sessions.erase(sit); } }; diff --git a/modules/commands/os_session.h b/modules/commands/os_session.h deleted file mode 100644 index 6d1dd917d..000000000 --- a/modules/commands/os_session.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef OS_SESSION_H -#define OS_SESSION_H - -struct Session -{ - cidr addr; /* A cidr (sockaddrs + len) representing this session */ - unsigned count; /* Number of clients with this host */ - unsigned hits; /* Number of subsequent kills for a host */ - - Session(const Anope::string &ip, int len) : addr(ip, len), count(1), hits(0) { } -}; - -struct Exception : Serializable -{ - Anope::string mask; /* Hosts to which this exception applies */ - unsigned limit; /* Session limit for exception */ - Anope::string who; /* Nick of person who added the exception */ - Anope::string reason; /* Reason for exception's addition */ - time_t time; /* When this exception was added */ - time_t expires; /* Time when it expires. 0 == no expiry */ - - Exception() : Serializable("Exception") { } - void Serialize(Serialize::Data &data) const anope_override; - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); -}; - -class SessionService : public Service -{ - public: - typedef std::tr1::unordered_map<cidr, Session *, cidr::hash> SessionMap; - typedef std::vector<Exception *> ExceptionVector; - - SessionService(Module *m) : Service(m, "SessionService", "session") { } - - virtual void AddException(Exception *e) = 0; - - virtual void DelException(Exception *e) = 0; - - virtual Exception *FindException(User *u) = 0; - - virtual Exception *FindException(const Anope::string &host) = 0; - - virtual ExceptionVector &GetExceptions() = 0; - - virtual void AddSession(Session *s) = 0; - - virtual void DelSession(Session *s) = 0; - - virtual Session *FindSession(const Anope::string &mask) = 0; - - virtual SessionMap &GetSessions() = 0; -}; - -static ServiceReference<SessionService> session_service("SessionService", "session"); - -void Exception::Serialize(Serialize::Data &data) const -{ - data["mask"] << this->mask; - data["limit"] << this->limit; - data["who"] << this->who; - data["reason"] << this->reason; - data["time"] << this->time; - data["expires"] << this->expires; -} - -Serializable* Exception::Unserialize(Serializable *obj, Serialize::Data &data) -{ - if (!session_service) - return NULL; - - Exception *ex; - if (obj) - ex = anope_dynamic_static_cast<Exception *>(obj); - else - ex = new Exception; - data["mask"] >> ex->mask; - data["limit"] >> ex->limit; - data["who"] >> ex->who; - data["reason"] >> ex->reason; - data["time"] >> ex->time; - data["expires"] >> ex->expires; - - if (!obj) - session_service->AddException(ex); - return ex; -} - -#endif - diff --git a/modules/commands/os_set.cpp b/modules/commands/os_set.cpp index 90d4f70d9..6fc05ab60 100644 --- a/modules/commands/os_set.cpp +++ b/modules/commands/os_set.cpp @@ -78,22 +78,23 @@ class CommandOSSet : public Command * * Rob **/ - if (!Config->SuperAdmin) - source.Reply(_("SuperAdmin can not be set because it is not enabled in the configuration.")); + bool super_admin = Config->GetModule(this->owner)->Get<bool>("superadmin"); + if (!super_admin) + source.Reply(_("Super admin can not be set because it is not enabled in the configuration.")); else if (setting.equals_ci("ON")) { source.GetUser()->super_admin = true; - source.Reply(_("You are now a SuperAdmin.")); + source.Reply(_("You are now a super admin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN ON"; } else if (setting.equals_ci("OFF")) { source.GetUser()->super_admin = false; - source.Reply(_("You are no longer a SuperAdmin.")); + source.Reply(_("You are no longer a super admin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN OFF"; } else - source.Reply(_("Setting for SuperAdmin must be \002ON\002 or \002OFF\002.")); + source.Reply(_("Setting for super admin must be \002ON\002 or \002OFF\002.")); return; } @@ -202,12 +203,12 @@ class CommandOSSet : public Command " READONLY Set read-only or read-write mode\n" " DEBUG Activate or deactivate debug mode\n" " NOEXPIRE Activate or deactivate no expire mode\n" - " SUPERADMIN Activate or deactivate SuperAdmin mode\n" + " SUPERADMIN Activate or deactivate super admin mode\n" " LIST List the options")); } else if (subcommand.equals_ci("LIST")) source.Reply(_("Syntax: \002LIST\n" - "Display the various %s settings"), Config->OperServ.c_str()); + "Display the various %s settings"), source.service->nick.c_str()); else if (subcommand.equals_ci("READONLY")) source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n" " \n" @@ -246,11 +247,9 @@ class OSSet : public Module CommandOSSet commandosset; public: - OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosset(this) { - this->SetAuthor("Anope"); - } }; diff --git a/modules/commands/os_shutdown.cpp b/modules/commands/os_shutdown.cpp index 29d1713d5..833c78491 100644 --- a/modules/commands/os_shutdown.cpp +++ b/modules/commands/os_shutdown.cpp @@ -19,7 +19,6 @@ class CommandOSQuit : public Command CommandOSQuit(Module *creator) : Command(creator, "operserv/quit", 0, 0) { this->SetDesc(_("Terminate Services WITHOUT saving")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -47,7 +46,6 @@ class CommandOSRestart : public Command CommandOSRestart(Module *creator) : Command(creator, "operserv/restart", 0, 0) { this->SetDesc(_("Save databases and restart Services")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -73,7 +71,6 @@ class CommandOSShutdown : public Command CommandOSShutdown(Module *creator) : Command(creator, "operserv/shutdown", 0, 0) { this->SetDesc(_("Terminate services with save")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -100,10 +97,9 @@ class OSShutdown : public Module CommandOSShutdown commandosshutdown; public: - OSShutdown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSShutdown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosquit(this), commandosrestart(this), commandosshutdown(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp index 779b8bbf5..8b975a6c7 100644 --- a/modules/commands/os_stats.cpp +++ b/modules/commands/os_stats.cpp @@ -12,7 +12,7 @@ /*************************************************************************/ #include "module.h" -#include "os_session.h" +#include "modules/os_session.h" struct Stats : Serializable { @@ -62,7 +62,7 @@ class CommandOSStats : public Command { /* AKILLs */ source.Reply(_("Current number of AKILLs: \002%d\002"), akills->GetCount()); - timeout = Config->AutokillExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default AKILL expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -82,7 +82,7 @@ class CommandOSStats : public Command { /* SNLINEs */ source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount()); - timeout = Config->SNLineExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default SNLINE expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -102,7 +102,7 @@ class CommandOSStats : public Command { /* SQLINEs */ source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount()); - timeout = Config->SQLineExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default SQLINE expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -118,7 +118,6 @@ class CommandOSStats : public Command else source.Reply(_("Default SQLINE expiry time: \002No expiration\002")); } - return; } void DoStatsReset(CommandSource &source) @@ -255,10 +254,9 @@ class OSStats : public Module Stats stats_saver; public: - OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosstats(this), stats_type("Stats", Stats::Unserialize) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp index 0a0ae9638..9fb1d63c3 100644 --- a/modules/commands/os_svs.cpp +++ b/modules/commands/os_svs.cpp @@ -34,11 +34,12 @@ class CommandOSSVSNick : public Command return; } - /* Truncate long nicknames to Config->NickLen characters */ - if (newnick.length() > Config->NickLen) + /* Truncate long nicknames to nicklen characters */ + unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"); + if (newnick.length() > nicklen) { - source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), Config->NickLen, newnick.c_str()); - newnick = params[1].substr(0, Config->NickLen); + source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), nicklen, newnick.c_str()); + newnick = params[1].substr(0, nicklen); } /* Check for valid characters */ @@ -166,10 +167,9 @@ class OSSVS : public Module CommandOSSVSPart commandossvspart; public: - OSSVS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSSVS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandossvsnick(this), commandossvsjoin(this), commandossvspart(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 2a98edf1d..55ba83455 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -258,7 +258,6 @@ class CommandOSSNLine : public CommandOSSXLineBase unsigned last_param = 2; Anope::string param, expiry; - time_t expires; param = params.size() > 1 ? params[1] : ""; if (!param.empty() && param[0] == '+') @@ -268,7 +267,7 @@ class CommandOSSNLine : public CommandOSSXLineBase last_param = 3; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SNLineExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -312,16 +311,18 @@ class CommandOSSNLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -352,8 +353,11 @@ class CommandOSSNLine : public CommandOSSXLineBase if (mask[masklen - 1] == ' ') mask.erase(masklen - 1); + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -380,7 +384,7 @@ class CommandOSSNLine : public CommandOSSXLineBase this->xlm()->AddXLine(x); - if (Config->KillonSNline) + if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes")) { this->xlm()->Send(source.GetUser(), x); @@ -391,7 +395,7 @@ class CommandOSSNLine : public CommandOSSXLineBase User *user = it->second; if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->realname, x->mask, false, true)) - user->Kill(Config->ServerName, rreason); + user->Kill(Me->GetName(), rreason); } } @@ -434,11 +438,12 @@ class CommandOSSNLine : public CommandOSSXLineBase "\002STATS AKILL\002 command.\n" "Note: because the realname mask may contain spaces, the\n" "separator between it and the reason is a colon.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_(" \n" "The \002SNLINE DEL\002 command removes the given mask from the\n" @@ -480,7 +485,6 @@ class CommandOSSQLine : public CommandOSSXLineBase unsigned last_param = 2; Anope::string expiry, mask; - time_t expires; mask = params.size() > 1 ? params[1] : ""; if (!mask.empty() && mask[0] == '+') @@ -490,7 +494,7 @@ class CommandOSSQLine : public CommandOSSXLineBase last_param = 3; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SQLineExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -523,16 +527,18 @@ class CommandOSSQLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -556,8 +562,11 @@ class CommandOSSQLine : public CommandOSSXLineBase return; } + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -583,7 +592,8 @@ class CommandOSSQLine : public CommandOSSXLineBase } this->xlm()->AddXLine(x); - if (Config->KillonSQline) + + if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes")) { Anope::string rreason = "Q-Lined: " + reason; @@ -599,7 +609,7 @@ class CommandOSSQLine : public CommandOSSXLineBase std::vector<User *> users; for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; User *user = uc->user; if (!user->HasMode("OPER") && user->server != Me) @@ -617,7 +627,7 @@ class CommandOSSQLine : public CommandOSSXLineBase User *user = it->second; if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->nick, x->mask, false, true)) - user->Kill(Config->ServerName, rreason); + user->Kill(Me->GetName(), rreason); } } @@ -664,11 +674,12 @@ class CommandOSSQLine : public CommandOSSXLineBase "must be given, even if it is the same as the default. The\n" "current SQLINE default expiry time can be found with the\n" "\002STATS AKILL\002 command.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_(" \n" "The \002SQLINE DEL\002 command removes the given mask from the\n" @@ -699,10 +710,9 @@ class OSSXLine : public Module CommandOSSQLine commandossqline; public: - OSSXLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSSXLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandossnline(this), commandossqline(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/commands/os_update.cpp b/modules/commands/os_update.cpp index f71ebca55..bce2feeed 100644 --- a/modules/commands/os_update.cpp +++ b/modules/commands/os_update.cpp @@ -19,7 +19,6 @@ class CommandOSUpdate : public Command CommandOSUpdate(Module *creator) : Command(creator, "operserv/update", 0, 0) { this->SetDesc(_("Force the Services databases to be updated immediately")); - this->SetSyntax(""); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -44,10 +43,9 @@ class OSUpdate : public Module CommandOSUpdate commandosupdate; public: - OSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosupdate(this) { - this->SetAuthor("Anope"); } }; diff --git a/modules/cs_statusupdate.cpp b/modules/cs_statusupdate.cpp new file mode 100644 index 000000000..130c0c3dc --- /dev/null +++ b/modules/cs_statusupdate.cpp @@ -0,0 +1,66 @@ +/* + * (C) 2003-2013 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#include "module.h" + +class StatusUpdate : public Module +{ + public: + StatusUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + { + + Implementation i[] = { I_OnAccessAdd, I_OnAccessDel }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + + void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override + { + if (ci->c) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + User *user = it->second->user; + + if (user->server != Me && access->Matches(user, user->Account())) + { + for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i) + { + ChannelModeStatus *cms = ModeManager::GetStatusChannelModesByRank()[i]; + if (!access->HasPriv("AUTO" + cms->name)) + ci->c->RemoveMode(NULL, cms, user->GetUID()); + } + ci->c->SetCorrectModes(user, true, false); + } + } + } + + void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override + { + if (ci->c) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + User *user = it->second->user; + + if (user->server != Me && access->Matches(user, user->Account())) + { + /* Get user's current access and remove the entry about to be deleted */ + AccessGroup ag = ci->AccessFor(user); + AccessGroup::iterator iter = std::find(ag.begin(), ag.end(), access); + if (iter != ag.end()) + ag.erase(iter); + + for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i) + { + ChannelModeStatus *cms = ModeManager::GetStatusChannelModesByRank()[i]; + if (!ag.HasPriv("AUTO" + cms->name)) + ci->c->RemoveMode(NULL, cms, user->GetUID()); + } + } + } + } +}; + +MODULE_INIT(StatusUpdate) diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp index a7e65f1cb..f7cc3df59 100644 --- a/modules/database/db_flatfile.cpp +++ b/modules/database/db_flatfile.cpp @@ -102,12 +102,10 @@ class LoadData : public Serialize::Data class DBFlatFile : public Module, public Pipe { - Anope::string database_file; /* Day the last backup was on */ int last_day; /* Backup file names */ std::map<Anope::string, std::list<Anope::string> > backups; - bool use_fork; bool loaded; void BackupDatabase() @@ -121,7 +119,7 @@ class DBFlatFile : public Module, public Pipe const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder(); std::set<Anope::string> dbs; - dbs.insert(database_file); + dbs.insert(Config->GetModule(this)->Get<const Anope::string>("database")); for (unsigned i = 0; i < type_order.size(); ++i) { @@ -146,7 +144,7 @@ class DBFlatFile : public Module, public Pipe { Log(this) << "Unable to back up database " << *it << "!"; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; continue; @@ -154,7 +152,8 @@ class DBFlatFile : public Module, public Pipe backups[*it].push_back(newname); - if (Config->KeepBackups > 0 && backups[*it].size() > static_cast<unsigned>(Config->KeepBackups)) + unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups"); + if (keepbackups > 0 && backups[*it].size() > keepbackups) { unlink(backups[*it].front().c_str()); backups[*it].pop_front(); @@ -164,14 +163,11 @@ class DBFlatFile : public Module, public Pipe } public: - DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), last_day(0), use_fork(false), loaded(false) + DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), loaded(false) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate }; + Implementation i[] = { I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } void OnNotify() anope_override @@ -190,23 +186,16 @@ class DBFlatFile : public Module, public Pipe Log(this) << "Error saving databases: " << buf; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; } - void OnReload() anope_override - { - ConfigReader config; - database_file = config.ReadValue("db_flatfile", "database", "anope.db", 0); - use_fork = config.ReadFlag("db_flatfile", "fork", "no", 0); - } - EventReturn OnLoadDatabase() anope_override { const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder(); std::set<Anope::string> tried_dbs; - const Anope::string &db_name = Anope::DataDir + "/" + database_file; + const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database"); std::fstream fd(db_name.c_str(), std::ios_base::in); if (!fd.is_open()) @@ -257,7 +246,7 @@ class DBFlatFile : public Module, public Pipe int i = -1; #ifndef _WIN32 - if (use_fork) + if (Config->GetModule(this)->Get<bool>("fork")) { i = fork(); if (i > 0) @@ -283,7 +272,7 @@ class DBFlatFile : public Module, public Pipe if (s_type->GetOwner()) db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db"; else - db_name = Anope::DataDir + "/" + database_file; + db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database"); if (Anope::IsFile(db_name)) rename(db_name.c_str(), (db_name + ".tmp").c_str()); @@ -315,7 +304,7 @@ class DBFlatFile : public Module, public Pipe for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it) { std::fstream *f = it->second; - const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : database_file); + const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : Config->GetModule(this)->Get<const Anope::string>("database")); if (!f->is_open() || !f->good()) { @@ -360,7 +349,7 @@ class DBFlatFile : public Module, public Pipe if (stype->GetOwner()) db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db"; else - db_name = Anope::DataDir + "/" + database_file; + db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database"); std::fstream fd(db_name.c_str(), std::ios_base::in); if (!fd.is_open()) diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp index 03c80e6bd..64faafe10 100644 --- a/modules/database/db_old.cpp +++ b/modules/database/db_old.cpp @@ -11,7 +11,7 @@ /*************************************************************************/ #include "module.h" -#include "../commands/os_session.h" +#include "modules/os_session.h" #define READ(x) \ if (true) \ @@ -222,7 +222,7 @@ static Anope::string GetLevelName(int level) case 6: return "AUTOVOICE"; case 7: - return "OPDEOP"; + return "OP"; case 8: return "LIST"; case 9: @@ -256,7 +256,7 @@ static Anope::string GetLevelName(int level) case 23: return "AUTOPROTECT"; case 24: - return "OPDEOPME"; + return "OPME"; case 25: return "HALFOPME"; case 26: @@ -1092,15 +1092,13 @@ static void LoadExceptions() class DBOld : public Module { public: - DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE) + DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnLoadDatabase, I_OnUplinkSync }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - ConfigReader conf; - hashm = conf.ReadValue("db_old", "hash", "", 0); + hashm = Config->GetModule(this)->Get<const Anope::string>("hash"); if (hashm != "md5" && hashm != "oldmd5" && hashm != "sha1" && hashm != "plain" && hashm != "sha256") throw ModuleException("Invalid hash method"); diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp index 99bdf947a..809fcc2e5 100644 --- a/modules/database/db_plain.cpp +++ b/modules/database/db_plain.cpp @@ -11,7 +11,7 @@ /*************************************************************************/ #include "module.h" -#include "../commands/os_session.h" +#include "modules/os_session.h" Anope::string DatabaseFile; Anope::string BackupFile; @@ -136,7 +136,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co try { if (key.equals_ci("BANTYPE")) - ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : Config->CSDefBantype; + ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : 2; else if (key.equals_ci("MEMOMAX")) ci->memos.memomax = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : -1; else if (key.equals_ci("FOUNDER")) @@ -587,22 +587,14 @@ class DBPlain : public Module /* Backup file names */ std::list<Anope::string> Backups; public: - DBPlain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE) + DBPlain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - OnReload(); - LastDay = 0; } - ~DBPlain() - { - } - void BackupDatabase() { /* Do not backup a database that doesn't exist */ @@ -626,7 +618,7 @@ class DBPlain : public Module { Log() << "Unable to back up database!"; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; return; @@ -634,7 +626,7 @@ class DBPlain : public Module Backups.push_back(newname); - unsigned KeepBackups = Config->KeepBackups; + unsigned KeepBackups = Config->GetModule(this)->Get<unsigned>("keepbackups"); if (KeepBackups && Backups.size() > KeepBackups) { unlink(Backups.front().c_str()); @@ -643,11 +635,12 @@ class DBPlain : public Module } } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - DatabaseFile = Anope::DataDir + "/" + config.ReadValue("db_plain", "database", "anope.db", 0); - BackupFile = Anope::DataDir + "/backups/" + config.ReadValue("db_plain", "database", "anope.db", 0); + DatabaseFile = Anope::DataDir + "/" + conf->GetModule(this)->Get<const Anope::string>("database"); + if (DatabaseFile.empty()) + DatabaseFile = "anope.db"; + BackupFile = Anope::DataDir + "/backups/" + DatabaseFile; } EventReturn OnLoadDatabase() anope_override diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp index 78b05a52d..bb4d5277b 100644 --- a/modules/database/db_sql.cpp +++ b/modules/database/db_sql.cpp @@ -9,7 +9,7 @@ */ #include "module.h" -#include "../extra/sql.h" +#include "modules/sql.h" using namespace SQL; @@ -89,15 +89,12 @@ class DBSQL : public Module, public Pipe } public: - DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false), loaded(false), imported(false) + DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false), loaded(false), imported(false) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate, I_OnSerializeTypeCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); - if (ModuleManager::FindModule("db_sql_live") != NULL) throw ModuleException("db_sql can not be loaded after db_sql_live"); } @@ -149,13 +146,12 @@ class DBSQL : public Module, public Pipe this->imported = true; } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - Anope::string engine = config.ReadValue("db_sql", "engine", "", 0); - this->sql = ServiceReference<Provider>("SQL::Provider", engine); - this->prefix = config.ReadValue("db_sql", "prefix", "anope_db_", 0); - this->import = config.ReadFlag("db_sql", "import", "false", 0); + Configuration::Block *block = conf->GetModule(this); + this->sql = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string>("engine")); + this->prefix = block->Get<const Anope::string>("prefix", "anope_db_"); + this->import = block->Get<bool>("import"); } void OnShutdown() anope_override diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp index c7c48937a..1a53f98d0 100644 --- a/modules/database/db_sql_live.cpp +++ b/modules/database/db_sql_live.cpp @@ -1,13 +1,11 @@ #include "module.h" -#include "../extra/sql.h" -#include "../commands/os_session.h" +#include "modules/sql.h" using namespace SQL; class DBMySQL : public Module, public Pipe { private: - Anope::string engine; Anope::string prefix; ServiceReference<Provider> SQL; time_t lastwarn; @@ -29,7 +27,7 @@ class DBMySQL : public Module, public Pipe } else { - if (Anope::CurTime - Config->UpdateTimeout > lastwarn) + if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout") > lastwarn) { Log() << "Unable to locate SQL reference, going to readonly..."; Anope::ReadOnly = this->ro = true; @@ -66,7 +64,7 @@ class DBMySQL : public Module, public Pipe } public: - DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), SQL("", "") + DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), SQL("", "") { this->lastwarn = 0; this->ro = false; @@ -75,8 +73,6 @@ class DBMySQL : public Module, public Pipe Implementation i[] = { I_OnReload, I_OnShutdown, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializeCheck, I_OnSerializableUpdate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - OnReload(); - if (ModuleManager::FindFirstOf(DATABASE) != this) throw ModuleException("If db_sql_live is loaded it must be the first database module loaded."); } @@ -132,12 +128,11 @@ class DBMySQL : public Module, public Pipe init = false; } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - this->engine = config.ReadValue("db_sql", "engine", "", 0); - this->SQL = ServiceReference<Provider>("SQL::Provider", this->engine); - this->prefix = config.ReadValue("db_sql", "prefix", "anope_db_", 0); + Configuration::Block *block = conf->GetModule(this); + this->SQL = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string>("engine")); + this->prefix = block->Get<const Anope::string>("prefix", "anope_db_"); } void OnSerializableConstruct(Serializable *obj) anope_override diff --git a/modules/encryption/enc_md5.cpp b/modules/encryption/enc_md5.cpp index c1cf9449e..3bcdb599c 100644 --- a/modules/encryption/enc_md5.cpp +++ b/modules/encryption/enc_md5.cpp @@ -344,10 +344,9 @@ class EMD5 : public Module MD5Provider md5provider; public: - EMD5(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION), + EMD5(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR), md5provider(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnEncrypt, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/encryption/enc_none.cpp b/modules/encryption/enc_none.cpp index fe8b03679..5f219000c 100644 --- a/modules/encryption/enc_none.cpp +++ b/modules/encryption/enc_none.cpp @@ -12,9 +12,8 @@ class ENone : public Module { public: - ENone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION) + ENone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/encryption/enc_old.cpp b/modules/encryption/enc_old.cpp index dad8bb91f..037a2fffc 100644 --- a/modules/encryption/enc_old.cpp +++ b/modules/encryption/enc_old.cpp @@ -41,10 +41,9 @@ class EOld : public Module inline static char XTOI(char c) { return c > 9 ? c - 'A' + 10 : c - '0'; } public: - EOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION), + EOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR), oldmd5provider(this) { - this->SetAuthor("Anope"); ModuleManager::LoadModule("enc_md5", User::Find(creator)); if (!md5) diff --git a/modules/encryption/enc_sha1.cpp b/modules/encryption/enc_sha1.cpp index 0c9c70830..c1f032874 100644 --- a/modules/encryption/enc_sha1.cpp +++ b/modules/encryption/enc_sha1.cpp @@ -197,10 +197,9 @@ class ESHA1 : public Module SHA1Provider sha1provider; public: - ESHA1(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION), + ESHA1(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR), sha1provider(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnEncrypt, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/encryption/enc_sha256.cpp b/modules/encryption/enc_sha256.cpp index 0ed0c7786..85fbaf223 100644 --- a/modules/encryption/enc_sha256.cpp +++ b/modules/encryption/enc_sha256.cpp @@ -273,10 +273,9 @@ class ESHA256 : public Module } public: - ESHA256(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION), + ESHA256(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, ENCRYPTION | VENDOR), sha256provider(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnEncrypt, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/extra/CMakeLists.txt b/modules/extra/CMakeLists.txt new file mode 100644 index 000000000..6c50f8605 --- /dev/null +++ b/modules/extra/CMakeLists.txt @@ -0,0 +1,3 @@ +# This file is here to prevent the building of the extras directory. +# Users who want to build the contents of this directory should copy +# or symlink files out of it. diff --git a/modules/extra/cs_statusupdate.cpp b/modules/extra/cs_statusupdate.cpp deleted file mode 100644 index 97faae851..000000000 --- a/modules/extra/cs_statusupdate.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) 2003-2013 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "module.h" - -static struct ModeInfo -{ - Anope::string priv; - Anope::string name; -} modeInfo[] = { - { "AUTOOWNER", "OWNER" }, - { "AUTOPROTECT", "PROTECT" }, - { "AUTOOP", "OP" }, - { "AUTOHALFOP", "HALFOP" }, - { "AUTOVOICE", "VOICE" }, - { "", "" } -}; - -class StatusUpdate : public Module -{ - public: - StatusUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) - { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnAccessAdd, I_OnAccessDel }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - } - - void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override - { - if (ci->c) - for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) - { - User *user = (*it)->user; - - if (access->Matches(user, user->Account())) - { - for (int i = 0; !modeInfo[i].priv.empty(); ++i) - if (!access->HasPriv(modeInfo[i].priv)) - ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick); - ci->c->SetCorrectModes(user, true, false); - } - } - } - - void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override - { - if (ci->c) - for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) - { - User *user = (*it)->user; - - if (access->Matches(user, user->Account())) - { - for (int i = 0; !modeInfo[i].priv.empty(); ++i) - if (access->HasPriv(modeInfo[i].priv)) - ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick); - } - } - } -}; - -MODULE_INIT(StatusUpdate) diff --git a/modules/extra/dns.h b/modules/extra/dns.h deleted file mode 100644 index 469bb0e82..000000000 --- a/modules/extra/dns.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * - * (C) 2003-2013 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - */ - -#ifndef DNS_H -#define DNS_H - -namespace DNS -{ - /** Valid query types - */ - enum QueryType - { - /* Nothing */ - QUERY_NONE, - /* A simple A lookup */ - QUERY_A = 1, - /* An authoritative name server */ - QUERY_NS = 2, - /* A CNAME lookup */ - QUERY_CNAME = 5, - /* Start of a zone of authority */ - QUERY_SOA = 6, - /* Reverse DNS lookup */ - QUERY_PTR = 12, - /* IPv6 AAAA lookup */ - QUERY_AAAA = 28, - /* Zone transfer */ - QUERY_AXFR = 252 - }; - - /** Flags that can be AND'd into DNSPacket::flags to receive certain values - */ - enum - { - QUERYFLAGS_QR = 0x8000, - QUERYFLAGS_OPCODE = 0x7800, - QUERYFLAGS_AA = 0x400, - QUERYFLAGS_TC = 0x200, - QUERYFLAGS_RD = 0x100, - QUERYFLAGS_RA = 0x80, - QUERYFLAGS_Z = 0x70, - QUERYFLAGS_RCODE = 0xF - }; - - enum Error - { - ERROR_NONE, - ERROR_UNKNOWN, - ERROR_UNLOADED, - ERROR_TIMEDOUT, - ERROR_NOT_AN_ANSWER, - ERROR_NONSTANDARD_QUERY, - ERROR_FORMAT_ERROR, - ERROR_SERVER_FAILURE, - ERROR_DOMAIN_NOT_FOUND, - ERROR_NOT_IMPLEMENTED, - ERROR_REFUSED, - ERROR_NO_RECORDS, - ERROR_INVALIDTYPE - }; - - struct Question - { - Anope::string name; - QueryType type; - unsigned short qclass; - - Question() : type(QUERY_NONE), qclass(0) { } - Question(const Anope::string &n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { } - }; - - struct ResourceRecord : public Question - { - unsigned int ttl; - Anope::string rdata; - time_t created; - - ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(Anope::CurTime) { } - ResourceRecord(const Question &q) : Question(q), ttl(0), created(Anope::CurTime) { } - }; - - struct Query - { - std::vector<Question> questions; - std::vector<ResourceRecord> answers, authorities, additional; - Error error; - - Query() : error(ERROR_NONE) { } - Query(const Question &q) : error(ERROR_NONE) { questions.push_back(q); } - }; - - class Packet : public Query - { - public: - static const int POINTER = 0xC0; - static const int LABEL = 0x3F; - static const int HEADER_LENGTH = 12; - - virtual ~Packet() { } - }; - - class ReplySocket; - class Request; - - /** DNS manager - */ - class Manager : public Service - { - public: - Manager(Module *creator) : Service(creator, "DNS::Manager", "dns/manager") { } - virtual ~Manager() { } - - virtual void Process(Request *req) = 0; - virtual void RemoveRequest(Request *req) = 0; - - virtual bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from) = 0; - - virtual void UpdateSerial() = 0; - virtual uint32_t GetSerial() const = 0; - }; - - /** A DNS query. - */ - class Request : public Timer, public Question - { - Manager *manager; - public: - /* Use result cache if available */ - bool use_cache; - /* Request id */ - unsigned short id; - /* Creator of this request */ - Module *creator; - - Request(Manager *mgr, Module *c, const Anope::string &addr, QueryType qt, bool cache = false) : Timer(0), Question(addr, qt), manager(mgr), - use_cache(cache), id(0), creator(c) { } - - virtual ~Request() - { - manager->RemoveRequest(this); - } - - /** Called when this request succeeds - * @param r The query sent back from the nameserver - */ - virtual void OnLookupComplete(const Query *r) = 0; - - /** Called when this request fails or times out. - * @param r The query sent back from the nameserver, check the error code. - */ - virtual void OnError(const Query *r) { } - - /** Used to time out the query, xalls OnError and lets the TimerManager - * delete this request. - */ - void Tick(time_t) anope_override - { - Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name; - Query rr(*this); - rr.error = ERROR_TIMEDOUT; - this->OnError(&rr); - } - }; - -} // namespace DNS - -#endif // DNS_H - - diff --git a/modules/extra/httpd.h b/modules/extra/httpd.h deleted file mode 100644 index 6127a51e0..000000000 --- a/modules/extra/httpd.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef ANOPE_HTTPD_H -#define ANOPE_HTTPD_H - -enum HTTPError -{ - HTTP_ERROR_OK = 200, - HTTP_FOUND = 302, - HTTP_BAD_REQUEST = 400, - HTTP_PAGE_NOT_FOUND = 404, - HTTP_NOT_SUPPORTED = 505 -}; - -/* A message to someone */ -struct HTTPReply -{ - HTTPError error; - Anope::string content_type; - std::map<Anope::string, Anope::string> headers; - typedef std::list<std::pair<Anope::string, Anope::string> > cookie; - std::vector<cookie> cookies; - - HTTPReply() : error(HTTP_ERROR_OK), length(0) { } - - HTTPReply(const HTTPReply& other) : error(other.error), length(other.length) - { - content_type = other.content_type; - headers = other.headers; - cookies = other.cookies; - - for (unsigned i = 0; i < other.out.size(); ++i) - out.push_back(new Data(other.out[i]->buf, other.out[i]->len)); - } - - ~HTTPReply() - { - for (unsigned i = 0; i < out.size(); ++i) - delete out[i]; - out.clear(); - } - - struct Data - { - char *buf; - size_t len; - - Data(const char *b, size_t l) - { - this->buf = new char[l]; - memcpy(this->buf, b, l); - this->len = l; - } - - ~Data() - { - delete [] buf; - } - }; - - std::deque<Data *> out; - size_t length; - - void Write(const Anope::string &message) - { - this->out.push_back(new Data(message.c_str(), message.length())); - this->length += message.length(); - } - - void Write(const char *b, size_t l) - { - this->out.push_back(new Data(b, l)); - this->length += l; - } -}; - -/* A message from soneone */ -struct HTTPMessage -{ - std::map<Anope::string, Anope::string> headers; - std::map<Anope::string, Anope::string> cookies; - std::map<Anope::string, Anope::string> get_data; - std::map<Anope::string, Anope::string> post_data; - Anope::string content; -}; - -class HTTPClient; -class HTTPProvider; - -class HTTPPage : public Base -{ - Anope::string url; - Anope::string content_type; - - public: - HTTPPage(const Anope::string &u, const Anope::string &ct = "text/html") : url(u), content_type(ct) { } - - const Anope::string &GetURL() const { return this->url; } - - const Anope::string &GetContentType() const { return this->content_type; } - - /** Called when this page is requested - * @param The server this page is on - * @param The page name - * @param The client requesting the page - * @param The HTTP header sent from the client to request the page - * @param The HTTP header that will be sent back to the client - */ - virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; -}; - -class HTTPClient : public ClientSocket, public BinarySocket, public Base -{ - protected: - void WriteClient(const Anope::string &message) - { - BinarySocket::Write(message + "\r\n"); - } - - public: - HTTPClient(ListenSocket *l, int f, const sockaddrs &a) : ClientSocket(l, a), BinarySocket() { } - - virtual const Anope::string GetIP() - { - return this->clientaddr.addr(); - } - - virtual void SendError(HTTPError err, const Anope::string &msg) = 0; - virtual void SendReply(HTTPReply *) = 0; -}; - -class HTTPProvider : public ListenSocket, public Service -{ - Anope::string ip; - unsigned short port; - public: - Anope::string ext_ip; - std::vector<Anope::string> ext_headers; - - HTTPProvider(Module *c, const Anope::string &n, const Anope::string &i, const unsigned short p) : ListenSocket(i, p, i.find(':') != Anope::string::npos), Service(c, "HTTPProvider", n), ip(i), port(p) { } - - const Anope::string &GetIP() const - { - return this->ip; - } - - unsigned short GetPort() const - { - return this->port; - } - - virtual bool RegisterPage(HTTPPage *page) = 0; - virtual void UnregisterPage(HTTPPage *page) = 0; - virtual HTTPPage* FindPage(const Anope::string &name) = 0; -}; - -namespace HTTPUtils -{ - inline Anope::string URLDecode(const Anope::string &url) - { - Anope::string decoded; - - for (unsigned i = 0; i < url.length(); ++i) - { - const char& c = url[i]; - - if (c == '%' && i + 2 < url.length()) - { - Anope::string dest; - Anope::Unhex(url.substr(i + 1, 2), dest); - decoded += dest; - i += 2; - } - else if (c == '+') - decoded += ' '; - else - decoded += c; - } - - return decoded; - } - - inline Anope::string URLEncode(const Anope::string &url) - { - Anope::string encoded; - - for (unsigned i = 0; i < url.length(); ++i) - { - const char& c = url[i]; - - if (isalnum(c) || c == '.' || c == '-' || c == '*' || c == '_') - encoded += c; - else if (c == ' ') - encoded += '+'; - else - encoded += "%" + Anope::Hex(c); - } - - return encoded; - } - - inline Anope::string Escape(const Anope::string &src) - { - Anope::string dst; - - for (unsigned i = 0; i < src.length(); ++i) - { - switch (src[i]) - { - case '<': - dst += "<"; - break; - case '>': - dst += ">"; - break; - case '"': - dst += """; - break; - default: - dst += src[i]; - } - } - - return dst; - } -} - -#endif // ANOPE_HTTPD_H diff --git a/modules/extra/ldap.h b/modules/extra/ldap.h deleted file mode 100644 index 65be27687..000000000 --- a/modules/extra/ldap.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef ANOPE_LDAP_H -#define ANOPE_LDAP_H - -typedef int LDAPQuery; - -class LDAPException : public ModuleException -{ - public: - LDAPException(const Anope::string &reason) : ModuleException(reason) { } - - virtual ~LDAPException() throw() { } -}; - -struct LDAPModification -{ - enum LDAPOperation - { - LDAP_ADD, - LDAP_DEL, - LDAP_REPLACE - }; - - LDAPOperation op; - Anope::string name; - std::vector<Anope::string> values; -}; -typedef std::vector<LDAPModification> LDAPMods; - -struct LDAPAttributes : public std::map<Anope::string, std::vector<Anope::string> > -{ - size_t size(const Anope::string &attr) const - { - const std::vector<Anope::string>& array = this->getArray(attr); - return array.size(); - } - - const std::vector<Anope::string> keys() const - { - std::vector<Anope::string> k; - for (const_iterator it = this->begin(), it_end = this->end(); it != it_end; ++it) - k.push_back(it->first); - return k; - } - - const Anope::string &get(const Anope::string &attr) const - { - const std::vector<Anope::string>& array = this->getArray(attr); - if (array.empty()) - throw LDAPException("Empty attribute " + attr + " in LDAPResult::get"); - return array[0]; - } - - const std::vector<Anope::string>& getArray(const Anope::string &attr) const - { - const_iterator it = this->find(attr); - if (it == this->end()) - throw LDAPException("Unknown attribute " + attr + " in LDAPResult::getArray"); - return it->second; - } -}; - -struct LDAPResult -{ - std::vector<LDAPAttributes> messages; - Anope::string error; - - enum QueryType - { - QUERY_UNKNOWN, - QUERY_BIND, - QUERY_SEARCH, - QUERY_ADD, - QUERY_DELETE, - QUERY_MODIFY - }; - - QueryType type; - LDAPQuery id; - - LDAPResult() - { - this->type = QUERY_UNKNOWN; - this->id = -1; - } - - size_t size() const - { - return this->messages.size(); - } - - bool empty() const - { - return this->messages.empty(); - } - - const LDAPAttributes &get(size_t sz) const - { - if (sz >= this->messages.size()) - throw LDAPException("Index out of range"); - return this->messages[sz]; - } - - const Anope::string &getError() const - { - return this->error; - } -}; - -class LDAPInterface -{ - public: - Module *owner; - - LDAPInterface(Module *m) : owner(m) { } - virtual ~LDAPInterface() { } - - virtual void OnResult(const LDAPResult &r) = 0; - virtual void OnError(const LDAPResult &err) = 0; - virtual void OnDelete() { } -}; - -class LDAPProvider : public Service -{ - public: - LDAPProvider(Module *c, const Anope::string &n) : Service(c, "LDAPProvider", n) { } - - /** Attempt to bind to the LDAP server as an admin - * @param i The LDAPInterface the result is sent to - * @return The query ID - */ - virtual LDAPQuery BindAsAdmin(LDAPInterface *i) = 0; - - /** Bind to LDAP - * @param i The LDAPInterface the result is sent to - * @param who The binddn - * @param pass The password - * @return The query ID - */ - virtual LDAPQuery Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) = 0; - - /** Search ldap for the specified filter - * @param i The LDAPInterface the result is sent to - * @param base The base DN to search - * @param filter The filter to apply - * @return The query ID - */ - virtual LDAPQuery Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) = 0; - - /** Add an entry to LDAP - * @param i The LDAPInterface the result is sent to - * @param dn The dn of the entry to add - * @param attributes The attributes - * @return The query ID - */ - virtual LDAPQuery Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) = 0; - - /** Delete an entry from LDAP - * @param i The LDAPInterface the result is sent to - * @param dn The dn of the entry to delete - * @return The query ID - */ - virtual LDAPQuery Del(LDAPInterface *i, const Anope::string &dn) = 0; - - /** Modify an existing entry in LDAP - * @param i The LDAPInterface the result is sent to - * @param base The base DN to modify - * @param attributes The attributes to modify - * @return The query ID - */ - virtual LDAPQuery Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) = 0; -}; - -#endif // ANOPE_LDAP_H diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp index 3c964b55c..3d3430752 100644 --- a/modules/extra/m_chanstats.cpp +++ b/modules/extra/m_chanstats.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "../extra/sql.h" +#include "modules/sql.h" class MySQLInterface : public SQL::Interface { @@ -334,12 +334,11 @@ class MChanstats : public Module public: MChanstats(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, CORE), sql("", ""), sqlinterface(this) + Module(modname, creator, EXTRA | VENDOR), sql("", ""), sqlinterface(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnPrivmsg, - I_OnUserKicked, + I_OnPreUserKicked, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnTopicUpdated, @@ -348,18 +347,17 @@ class MChanstats : public Module I_OnChanDrop, I_OnReload}; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - prefix = config.ReadValue("chanstats", "prefix", "anope_", 0); - SmileysHappy = config.ReadValue("chanstats", "SmileysHappy", ":) :-) ;) :D :-D", 0); - SmileysSad = config.ReadValue("chanstats", "SmileysSad", ":( :-( ;( ;-(", 0); - SmileysOther = config.ReadValue("chanstats", "SmileysOther", ":/", 0); + Configuration::Block *block = conf->GetModule(this); + prefix = block->Get<const Anope::string>("prefix", "anope_"); + SmileysHappy = block->Get<const Anope::string>("SmileysHappy"); + SmileysSad = block->Get<const Anope::string>("SmileysSad"); + SmileysOther = block->Get<const Anope::string>("SmileysOther"); - Anope::string engine = config.ReadValue("chanstats", "engine", "", 0); + Anope::string engine = block->Get<const Anope::string>("engine"); this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); if (sql) this->CheckTables(); @@ -402,24 +400,24 @@ class MChanstats : public Module this->RunQuery(query); } public: - void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) anope_override + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override { - if (!c->ci || !c->ci->HasExt("STATS")) + if (!cu->chan->ci || !cu->chan->ci->HasExt("STATS")) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);"; - query.SetValue("channel", c->name); - query.SetValue("nick", GetDisplay(target)); + query.SetValue("channel", cu->chan->name); + query.SetValue("nick", GetDisplay(cu->user)); this->RunQuery(query); query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);"; - query.SetValue("channel", c->name); + query.SetValue("channel", cu->chan->name); query.SetValue("nick", GetDisplay(source.GetUser())); this->RunQuery(query); } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override { - if (!c->ci || !c->ci->HasExt("STATS") || (msg[0] == Config->BSFantasyCharacter[0])) + if (!c->ci || !c->ci->HasExt("STATS")) return; size_t letters = msg.length(); diff --git a/modules/extra/m_httpd.cpp b/modules/extra/m_httpd.cpp index f1e5392c5..5a4260149 100644 --- a/modules/extra/m_httpd.cpp +++ b/modules/extra/m_httpd.cpp @@ -6,8 +6,8 @@ */ #include "module.h" -#include "httpd.h" -#include "ssl.h" +#include "modules/httpd.h" +#include "modules/ssl.h" static Anope::string BuildDate() { @@ -331,14 +331,11 @@ class HTTPD : public Module ServiceReference<SSLService> sslref; std::map<Anope::string, HTTPProvider *> providers; public: - HTTPD(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), sslref("SSLService", "ssl") + HTTPD(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), sslref("SSLService", "ssl") { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } ~HTTPD() @@ -355,22 +352,24 @@ class HTTPD : public Module this->providers.clear(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; std::set<Anope::string> existing; - for (int i = 0, num = config.Enumerate("httpd"); i < num; ++i) + for (int i = 0; i < conf->CountBlock("httpd"); ++i) { - Anope::string hname = config.ReadValue("httpd", "name", "httpd/main", i); + Configuration::Block *block = conf->GetBlock("httpd", i); + + + const Anope::string &hname = block->Get<const Anope::string>("name", "httpd/main"); existing.insert(hname); - Anope::string ip = config.ReadValue("httpd", "ip", "", i); - int port = config.ReadInteger("httpd", "port", "8080", i, true); - int timeout = config.ReadInteger("httpd", "timeout", "30", i, true); - bool ssl = config.ReadFlag("httpd", "ssl", "no", i); - Anope::string ext_ip = config.ReadValue("httpd", "extforward_ip", "", i); - Anope::string ext_header = config.ReadValue("httpd", "extforward_header", "", i); + Anope::string ip = block->Get<const Anope::string>("ip"); + int port = block->Get<int>("port", "8080"); + int timeout = block->Get<int>("timeout", "30"); + bool ssl = block->Get<bool>("ssl", "no"); + Anope::string ext_ip = block->Get<const Anope::string>("extforward_ip"); + Anope::string ext_header = block->Get<const Anope::string>("extforward_header"); if (ip.empty()) { diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp index d53e04992..4168193a3 100644 --- a/modules/extra/m_ldap.cpp +++ b/modules/extra/m_ldap.cpp @@ -1,7 +1,7 @@ /* RequiredLibraries: ldap,lber */ #include "module.h" -#include "ldap.h" +#include "modules/ldap.h" #include <ldap.h> static Pipe *me; @@ -403,14 +403,12 @@ class ModuleLDAP : public Module, public Pipe std::map<Anope::string, LDAPService *> LDAPServices; public: - ModuleLDAP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleLDAP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { me = this; Implementation i[] = { I_OnReload, I_OnModuleUnload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } ~ModuleLDAP() @@ -425,9 +423,8 @@ class ModuleLDAP : public Module, public Pipe LDAPServices.clear(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; int i, num; for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end();) @@ -436,13 +433,9 @@ class ModuleLDAP : public Module, public Pipe LDAPService *s = it->second; ++it; - for (i = 0, num = config.Enumerate("ldap"); i < num; ++i) - { - if (config.ReadValue("ldap", "name", "main", i) == cname) - { + for (i = 0; i < Config->CountBlock("ldap"); ++i) + if (Config->GetBlock("ldap", i)->Get<const Anope::string>("name", "ldap/main") == cname) break; - } - } if (i == num) { @@ -454,16 +447,16 @@ class ModuleLDAP : public Module, public Pipe } } - for (i = 0, num = config.Enumerate("ldap"); i < num; ++i) + for (i = 0; i < Config->CountBlock("ldap"); ++i) { - Anope::string connname = config.ReadValue("ldap", "name", "main", i); + const Anope::string &connname = Config->GetBlock("ldap", i)->Get<const Anope::string>("name", "ldap/main"); if (this->LDAPServices.find(connname) == this->LDAPServices.end()) { - Anope::string server = config.ReadValue("ldap", "server", "127.0.0.1", i); - int port = config.ReadInteger("ldap", "port", "389", i, true); - Anope::string admin_binddn = config.ReadValue("ldap", "admin_binddn", "", i); - Anope::string admin_password = config.ReadValue("ldap", "admin_password", "", i); + const Anope::string &server = Config->GetBlock("ldap", i)->Get<const Anope::string>("server", "127.0.0.1"); + int port = Config->GetBlock("ldap", i)->Get<int>("port", "389"); + const Anope::string &admin_binddn = Config->GetBlock("ldap", i)->Get<const Anope::string>("admin_binddn"); + const Anope::string &admin_password = Config->GetBlock("ldap", i)->Get<const Anope::string>("admin_password"); try { diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp index 5ddd9da2d..4bd76ff09 100644 --- a/modules/extra/m_ldap_authentication.cpp +++ b/modules/extra/m_ldap_authentication.cpp @@ -1,6 +1,5 @@ #include "module.h" -#include "nickserv.h" -#include "ldap.h" +#include "modules/ldap.h" static Module *me; @@ -104,14 +103,9 @@ class IdentifyInterface : public LDAPInterface if (na == NULL) { na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount())); - if (ii->user) - { - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(ii->user->Mask()); - - if (NickServ) - ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); - } + FOREACH_MOD(I_OnNickRegister, OnNickRegister(ii->user, na)); + if (ii->user && NickServ) + ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } // encrypt and store the password in the nickcore Anope::Encrypt(ii->req->GetPassword(), na->nc->pass); @@ -216,35 +210,32 @@ class NSIdentifyLDAP : public Module Anope::string disable_email_reason; public: NSIdentifyLDAP(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, SUPPORTED), ldap("LDAPProvider", "ldap/main"), iinterface(this), oninterface(this), orinterface(this) + Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), iinterface(this), oninterface(this), orinterface(this) { - this->SetAuthor("Anope"); me = this; Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication, I_OnNickIdentify, I_OnNickRegister }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); - - OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *config = Config->GetModule(this); - basedn = config.ReadValue("m_ldap_authentication", "basedn", "", 0); - search_filter = config.ReadValue("m_ldap_authentication", "search_filter", "", 0); - object_class = config.ReadValue("m_ldap_authentication", "object_class", "", 0); - username_attribute = config.ReadValue("m_ldap_authentication", "username_attribute", "", 0); - this->password_attribute = config.ReadValue("m_ldap_authentication", "password_attribute", "", 0); - email_attribute = config.ReadValue("m_ldap_authentication", "email_attribute", "", 0); - this->disable_register_reason = config.ReadValue("m_ldap_authentication", "disable_register_reason", "", 0); - this->disable_email_reason = config.ReadValue("m_ldap_authentication", "disable_email_reason", "", 0); + basedn = conf->Get<const Anope::string>("basedn"); + search_filter = conf->Get<const Anope::string>("search_filter"); + object_class = conf->Get<const Anope::string>("object_class"); + username_attribute = conf->Get<const Anope::string>("username_attribute"); + this->password_attribute = conf->Get<const Anope::string>("password_attribute"); + email_attribute = conf->Get<const Anope::string>("email_attribute"); + this->disable_register_reason = conf->Get<const Anope::string>("disable_register_reason"); + this->disable_email_reason = conf->Get<const Anope::string>("disable_email_reason"); if (!email_attribute.empty()) /* Don't complain to users about how they need to update their email, we will do it for them */ - Config->NSForceEmail = false; + Config->GetBlock("nickserv")->Set("forceemail", "false"); } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override @@ -301,7 +292,7 @@ class NSIdentifyLDAP : public Module } } - void OnNickRegister(NickAlias *na) anope_override + void OnNickRegister(User *, NickAlias *na) anope_override { if (!this->disable_register_reason.empty() || !this->ldap) return; diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp index ed2f5900a..43ee81408 100644 --- a/modules/extra/m_ldap_oper.cpp +++ b/modules/extra/m_ldap_oper.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "ldap.h" +#include "modules/ldap.h" static std::set<Oper *> my_opers; static Anope::string opertype_attribute; @@ -86,25 +86,22 @@ class LDAPOper : public Module Anope::string filter; public: LDAPOper(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, SUPPORTED), ldap("LDAPProvider", "ldap/main"), iinterface(this) + Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), iinterface(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnDelCore }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *config = Config->GetModule(this); - this->binddn = config.ReadValue("m_ldap_oper", "binddn", "", 0); - this->password = config.ReadValue("m_ldap_oper", "password", "", 0); - this->basedn = config.ReadValue("m_ldap_oper", "basedn", "", 0); - this->filter = config.ReadValue("m_ldap_oper", "filter", "", 0); - opertype_attribute = config.ReadValue("m_ldap_oper", "opertype_attribute", "", 0); + this->binddn = config->Get<const Anope::string>("binddn"); + this->password = config->Get<const Anope::string>("password"); + this->basedn = config->Get<const Anope::string>("basedn"); + this->filter = config->Get<const Anope::string>("filter"); + opertype_attribute = config->Get<const Anope::string>("opertype_attribute"); for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it) delete *it; diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index e072f8dfe..a61f11e8b 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -1,9 +1,9 @@ /* RequiredLibraries: mysqlclient */ #include "module.h" +#include "modules/sql.h" #define NO_CLIENT_LONG_LONG #include <mysql/mysql.h> -#include "sql.h" using namespace SQL; @@ -165,7 +165,7 @@ class ModuleSQL : public Module, public Pipe /* The thread used to execute queries */ DispatcherThread *DThread; - ModuleSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { me = this; @@ -174,8 +174,6 @@ class ModuleSQL : public Module, public Pipe DThread = new DispatcherThread(); DThread->Start(); - - OnReload(); } ~ModuleSQL() @@ -190,9 +188,9 @@ class ModuleSQL : public Module, public Pipe delete DThread; } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *config = Config->GetModule(this); int i, num; for (std::map<Anope::string, MySQLService *>::iterator it = this->MySQLServices.begin(); it != this->MySQLServices.end();) @@ -201,13 +199,9 @@ class ModuleSQL : public Module, public Pipe MySQLService *s = it->second; ++it; - for (i = 0, num = config.Enumerate("mysql"); i < num; ++i) - { - if (config.ReadValue("mysql", "name", "main", i) == cname) - { + for (i = 0; i < Config->CountBlock("mysql"); ++i) + if (Config->GetBlock("mysql", i)->Get<const Anope::string>("name", "main") == cname) break; - } - } if (i == num) { @@ -218,17 +212,18 @@ class ModuleSQL : public Module, public Pipe } } - for (i = 0, num = config.Enumerate("mysql"); i < num; ++i) + for (i = 0; i < Config->CountBlock("mysql"); ++i) { - Anope::string connname = config.ReadValue("mysql", "name", "mysql/main", i); + Configuration::Block *block = Config->GetBlock("mysql", i); + const Anope::string &connname = block->Get<const Anope::string>("name", "mysql/main"); if (this->MySQLServices.find(connname) == this->MySQLServices.end()) { - Anope::string database = config.ReadValue("mysql", "database", "anope", i); - Anope::string server = config.ReadValue("mysql", "server", "127.0.0.1", i); - Anope::string user = config.ReadValue("mysql", "username", "anope", i); - Anope::string password = config.ReadValue("mysql", "password", "", i); - int port = config.ReadInteger("mysql", "port", "3306", i, true); + const Anope::string &database = block->Get<const Anope::string>("database", "anope"); + const Anope::string &server = block->Get<const Anope::string>("server", "127.0.0.1"); + const Anope::string &user = block->Get<const Anope::string>("username", "anope"); + const Anope::string &password = block->Get<const Anope::string>("password"); + int port = block->Get<int>("port", "3306"); try { diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index b77da2d3d..075f9067e 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -86,7 +86,7 @@ class ProxyConnect : public ConnectionSocket reason = reason.replace_all_cs("%p", stringify(this->conaddr.port())); Log(OperServ) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")"; - XLine *x = new XLine("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID()); + XLine *x = new XLine("*@" + this->conaddr.addr(), OperServ ? OperServ->nick : "", Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID()); if (add_to_akill && akills) { akills->AddXLine(x); @@ -127,13 +127,13 @@ class HTTPProxyConnect : public ProxyConnect, public BufferedSocket bool ProcessRead() anope_override { - BufferedSocket::ProcessRead(); + bool b = BufferedSocket::ProcessRead(); if (this->GetLine() == ProxyCheckString) { this->Ban(); return false; } - return true; + return b; } }; @@ -221,24 +221,14 @@ class ModuleProxyScan : public Module } connectionTimeout; public: - ModuleProxyScan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleProxyScan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), connectionTimeout(this, 5) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnUserConnect }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); this->listener = NULL; - - try - { - OnReload(); - } - catch (const ConfigException &ex) - { - throw ModuleException(ex.GetReason()); - } } ~ModuleProxyScan() @@ -263,36 +253,36 @@ class ModuleProxyScan : public Module delete this->listener; } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *config = Config->GetModule(this); - Anope::string s_target_ip = config.ReadValue("m_proxyscan", "target_ip", "", 0); + Anope::string s_target_ip = config->Get<const Anope::string>("target_ip"); if (s_target_ip.empty()) - throw ConfigException("m_proxyscan:target_ip may not be empty"); + throw ConfigException(this->name + " target_ip may not be empty"); - int s_target_port = config.ReadInteger("m_proxyscan", "target_port", "-1", 0, true); + int s_target_port = config->Get<int>("target_port", "-1"); if (s_target_port <= 0) - throw ConfigException("m_proxyscan:target_port may not be empty and must be a positive number"); + throw ConfigException(this->name + " target_port may not be empty and must be a positive number"); - Anope::string s_listen_ip = config.ReadValue("m_proxyscan", "listen_ip", "", 0); + Anope::string s_listen_ip = config->Get<const Anope::string>("listen_ip"); if (s_listen_ip.empty()) - throw ConfigException("m_proxyscan:listen_ip may not be empty"); + throw ConfigException(this->name + " listen_ip may not be empty"); - int s_listen_port = config.ReadInteger("m_proxyscan", "listen_port", "-1", 0, true); + int s_listen_port = config->Get<int>("listen_port", "-1"); if (s_listen_port <= 0) - throw ConfigException("m_proxyscan:listen_port may not be empty and must be a positive number"); + throw ConfigException(this->name + " listen_port may not be empty and must be a positive number"); target_ip = s_target_ip; target_port = s_target_port; this->listen_ip = s_listen_ip; this->listen_port = s_listen_port; - this->con_notice = config.ReadValue("m_proxyscan", "connect_notice", "", 0); - this->con_source = config.ReadValue("m_proxyscan", "connect_source", "", 0); - add_to_akill = config.ReadFlag("m_proxyscan", "add_to_akill", "true", 0); - this->connectionTimeout.SetSecs(config.ReadInteger("m_proxyscan", "timeout", "5", 0, true)); + this->con_notice = config->Get<const Anope::string>("connect_notice"); + this->con_source = config->Get<const Anope::string>("connect_source"); + add_to_akill = config->Get<bool>("add_to_akill", "true"); + this->connectionTimeout.SetSecs(config->Get<time_t>("timeout", "5s")); - ProxyCheckString = Config->NetworkName + " proxy check"; + ProxyCheckString = Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname") + " proxy check"; delete this->listener; this->listener = NULL; try @@ -305,12 +295,13 @@ class ModuleProxyScan : public Module } this->proxyscans.clear(); - for (int i = 0; i < config.Enumerate("proxyscan"); ++i) + for (int i = 0; i < conf->CountBlock("proxyscan"); ++i) { + Configuration::Block *block = conf->GetBlock("proxyscan", i); ProxyCheck p; Anope::string token; - commasepstream sep(config.ReadValue("proxyscan", "type", "", i)); + commasepstream sep(block->Get<const Anope::string>("type")); while (sep.GetToken(token)) { if (!token.equals_ci("HTTP") && !token.equals_ci("SOCKS5")) @@ -320,7 +311,7 @@ class ModuleProxyScan : public Module if (p.types.empty()) continue; - commasepstream sep2(config.ReadValue("proxyscan", "port", "", i)); + commasepstream sep2(block->Get<const Anope::string>("port")); while (sep2.GetToken(token)) { try @@ -333,8 +324,8 @@ class ModuleProxyScan : public Module if (p.ports.empty()) continue; - p.duration = Anope::DoTime(config.ReadValue("proxyscan", "time", "4h", i)); - p.reason = config.ReadValue("proxyscan", "reason", "", i); + p.duration = block->Get<time_t>("time", "4h"); + p.reason = block->Get<const Anope::string>("reason"); if (p.reason.empty()) continue; diff --git a/modules/extra/m_regex_pcre.cpp b/modules/extra/m_regex_pcre.cpp index 998a7692d..b6bf88af1 100644 --- a/modules/extra/m_regex_pcre.cpp +++ b/modules/extra/m_regex_pcre.cpp @@ -44,10 +44,9 @@ class ModuleRegexPCRE : public Module PCRERegexProvider pcre_regex_provider; public: - ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), pcre_regex_provider(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); } }; diff --git a/modules/extra/m_regex_posix.cpp b/modules/extra/m_regex_posix.cpp index 409a057ba..551d978b8 100644 --- a/modules/extra/m_regex_posix.cpp +++ b/modules/extra/m_regex_posix.cpp @@ -46,10 +46,9 @@ class ModuleRegexPOSIX : public Module POSIXRegexProvider posix_regex_provider; public: - ModuleRegexPOSIX(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleRegexPOSIX(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), posix_regex_provider(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); } }; diff --git a/modules/extra/m_regex_tre.cpp b/modules/extra/m_regex_tre.cpp index 8cfbd3b18..760097b08 100644 --- a/modules/extra/m_regex_tre.cpp +++ b/modules/extra/m_regex_tre.cpp @@ -47,10 +47,9 @@ class ModuleRegexTRE : public Module TRERegexProvider tre_regex_provider; public: - ModuleRegexTRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleRegexTRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), tre_regex_provider(this) { - this->SetAuthor("Anope"); this->SetPermanent(true); } }; diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp index abdd745a5..ecc8700f6 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/m_sql_authentication.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "sql.h" +#include "modules/sql.h" static Module *me; @@ -41,14 +41,9 @@ class SQLAuthenticationResult : public SQL::Interface if (na == NULL) { na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount())); - if (user) - { - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(user->Mask()); - - if (NickServ) - user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); - } + FOREACH_MOD(I_OnNickRegister, OnNickRegister(user, na)); + if (user && NickServ) + user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } if (!email.empty() && email != na->nc->email) @@ -78,25 +73,20 @@ class ModuleSQLAuthentication : public Module ServiceReference<SQL::Provider> SQL; public: - ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { - this->SetAuthor("Anope"); - me = this; Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - - this->engine = config.ReadValue("m_sql_authentication", "engine", "", 0); - this->query = config.ReadValue("m_sql_authentication", "query", "", 0); - this->disable_reason = config.ReadValue("m_sql_authentication", "disable_reason", "", 0); + Configuration::Block *config = conf->GetModule(this); + this->engine = config->Get<const Anope::string>("engine"); + this->query = config->Get<const Anope::string>("query"); + this->disable_reason = config->Get<const Anope::string>("disable_reason"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp index f786ad36d..0289e9a22 100644 --- a/modules/extra/m_sql_oper.cpp +++ b/modules/extra/m_sql_oper.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "sql.h" +#include "modules/sql.h" class SQLOperResult : public SQL::Interface { @@ -94,22 +94,19 @@ class ModuleSQLOper : public Module ServiceReference<SQL::Provider> SQL; public: - ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnNickIdentify }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; + Configuration::Block *config = conf->GetModule(this); - this->engine = config.ReadValue("m_sql_oper", "engine", "", 0); - this->query = config.ReadValue("m_sql_oper", "query", "", 0); + this->engine = config->Get<const Anope::string>("engine"); + this->query = config->Get<const Anope::string>("query"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 69fd16b9f..bea4d8d95 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -1,8 +1,8 @@ /* RequiredLibraries: sqlite3 */ #include "module.h" +#include "modules/sql.h" #include <sqlite3.h> -#include "sql.h" using namespace SQL; @@ -64,12 +64,10 @@ class ModuleSQLite : public Module /* SQL connections */ std::map<Anope::string, SQLiteService *> SQLiteServices; public: - ModuleSQLite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleSQLite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } ~ModuleSQLite() @@ -79,19 +77,19 @@ class ModuleSQLite : public Module SQLiteServices.clear(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - int i, num; + Configuration::Block *config = conf->GetModule(this); for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();) { const Anope::string &cname = it->first; SQLiteService *s = it->second; + int i, num; ++it; - for (i = 0, num = config.Enumerate("sqlite"); i < num; ++i) - if (config.ReadValue("sqlite", "name", "sqlite/main", i) == cname) + for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i) + if (config->GetBlock("sqlite", i)->Get<const Anope::string>("name", "sqlite/main") == cname) break; if (i == num) @@ -103,13 +101,14 @@ class ModuleSQLite : public Module } } - for (i = 0, num = config.Enumerate("sqlite"); i < num; ++i) + for (int i = 0; i < config->CountBlock("sqlite"); ++i) { - Anope::string connname = config.ReadValue("sqlite", "name", "sqlite/main", i); + Configuration::Block *block = config->GetBlock("sqlite", i); + Anope::string connname = block->Get<const Anope::string>("name", "sqlite/main"); if (this->SQLiteServices.find(connname) == this->SQLiteServices.end()) { - Anope::string database = Anope::DataDir + "/" + config.ReadValue("sqlite", "database", "anope", i); + Anope::string database = Anope::DataDir + "/" + block->Get<const Anope::string>("database", "anope"); try { diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp index 7158a5ce5..19b0aaf8f 100644 --- a/modules/extra/m_ssl.cpp +++ b/modules/extra/m_ssl.cpp @@ -1,7 +1,7 @@ /* RequiredLibraries: ssl,crypto */ #include "module.h" -#include "ssl.h" +#include "modules/ssl.h" #define OPENSSL_NO_SHA512 #include <openssl/bio.h> @@ -92,11 +92,10 @@ class SSLModule : public Module public: MySSLService service; - SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), service(this, "ssl") + SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), service(this, "ssl") { me = this; - this->SetAuthor("Anope"); this->SetPermanent(true); SSL_library_init(); @@ -108,7 +107,41 @@ class SSLModule : public Module if (!client_ctx || !server_ctx) throw ModuleException("Error initializing SSL CTX"); - this->OnReload(); + SSL_CTX_set_mode(client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + SSL_CTX_set_mode(server_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + + SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept); + SSL_CTX_set_verify(server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept); + + Anope::string context_name = "Anope"; + SSL_CTX_set_session_id_context(client_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); + SSL_CTX_set_session_id_context(server_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); + + ModuleManager::Attach(I_OnReload, this); + ModuleManager::Attach(I_OnPreServerConnect, this); + } + + ~SSLModule() + { + for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;) + { + Socket *s = it->second; + ++it; + + if (dynamic_cast<SSLSocketIO *>(s->io)) + delete s; + } + + SSL_CTX_free(client_ctx); + SSL_CTX_free(server_ctx); + } + + void OnReload(Configuration::Conf *conf) anope_override + { + Configuration::Block *config = conf->GetModule(this); + + this->certfile = config->Get<const Anope::string>("cert", "data/anope.crt"); + this->keyfile = config->Get<const Anope::string>("key", "data/anope.key"); if (Anope::IsFile(this->certfile.c_str())) { @@ -116,7 +149,7 @@ class SSLModule : public Module { SSL_CTX_free(client_ctx); SSL_CTX_free(server_ctx); - throw ModuleException("Error loading certificate"); + throw ConfigException("Error loading certificate"); } else Log(LOG_DEBUG) << "m_ssl: Successfully loaded certificate " << this->certfile; @@ -130,7 +163,7 @@ class SSLModule : public Module { SSL_CTX_free(client_ctx); SSL_CTX_free(server_ctx); - throw ModuleException("Error loading private key"); + throw ConfigException("Error loading private key"); } else Log(LOG_DEBUG) << "m_ssl: Successfully loaded private key " << this->keyfile; @@ -141,54 +174,19 @@ class SSLModule : public Module { SSL_CTX_free(client_ctx); SSL_CTX_free(server_ctx); - throw ModuleException("Error loading private key " + this->keyfile + " - file not found"); + throw ConfigException("Error loading private key " + this->keyfile + " - file not found"); } else Log() << "Unable to open private key " << this->keyfile; } - SSL_CTX_set_mode(client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - SSL_CTX_set_mode(server_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept); - SSL_CTX_set_verify(server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept); - - Anope::string context_name = "Anope"; - SSL_CTX_set_session_id_context(client_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); - SSL_CTX_set_session_id_context(server_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); - - ModuleManager::Attach(I_OnReload, this); - ModuleManager::Attach(I_OnPreServerConnect, this); - } - - ~SSLModule() - { - for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;) - { - Socket *s = it->second; - ++it; - - if (dynamic_cast<SSLSocketIO *>(s->io)) - delete s; - } - - SSL_CTX_free(client_ctx); - SSL_CTX_free(server_ctx); - } - - void OnReload() anope_override - { - ConfigReader config; - - this->certfile = config.ReadValue("ssl", "cert", "data/anope.crt", 0); - this->keyfile = config.ReadValue("ssl", "key", "data/anope.key", 0); } void OnPreServerConnect() anope_override { - ConfigReader config; + Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink); - if (config.ReadFlag("uplink", "ssl", "no", Anope::CurrentUplink)) + if (config->Get<bool>("ssl")) { this->service.Init(UplinkSock); } diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp index a3b999a5e..c1a9bc1d5 100644 --- a/modules/extra/m_xmlrpc.cpp +++ b/modules/extra/m_xmlrpc.cpp @@ -1,7 +1,7 @@ #include "module.h" -#include "xmlrpc.h" -#include "httpd.h" +#include "modules/xmlrpc.h" +#include "modules/httpd.h" class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage { @@ -161,13 +161,11 @@ class ModuleXMLRPC : public Module public: MyXMLRPCServiceInterface xmlrpcinterface; - ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), xmlrpcinterface(this, "xmlrpc") + ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), + httpref("HTTPProvider", "httpd/main"), xmlrpcinterface(this, "xmlrpc") { - OnReload(); - if (!httpref) throw ModuleException("Unable to find http reference, is m_httpd loaded?"); - httpref->RegisterPage(&xmlrpcinterface); Implementation i[] = { I_OnReload }; @@ -179,12 +177,6 @@ class ModuleXMLRPC : public Module if (httpref) httpref->UnregisterPage(&xmlrpcinterface); } - - void OnReload() anope_override - { - ConfigReader config; - httpref = ServiceReference<HTTPProvider>("HTTPProvider", "httpd/main"); - } }; MODULE_INIT(ModuleXMLRPC) diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp index e4b761cc7..b6b47c6f4 100644 --- a/modules/extra/m_xmlrpc_main.cpp +++ b/modules/extra/m_xmlrpc_main.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "xmlrpc.h" +#include "modules/xmlrpc.h" static Module *me; @@ -174,7 +174,7 @@ class MyXMLRPCEvent : public XMLRPCEvent Anope::string users; for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) { - ChanUserContainer *uc = *it; + ChanUserContainer *uc = it->second; users += uc->status.BuildModePrefixList() + uc->user->nick + " "; } if (!users.empty()) @@ -226,7 +226,7 @@ class MyXMLRPCEvent : public XMLRPCEvent Anope::string channels; for (User::ChanUserList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it) { - ChanUserContainer *cc = *it; + ChanUserContainer *cc = it->second; channels += cc->status.BuildModePrefixList() + cc->chan->name + " "; } if (!channels.empty()) @@ -239,14 +239,15 @@ class MyXMLRPCEvent : public XMLRPCEvent void DoOperType(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) { - for (std::list<OperType *>::const_iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i) { + OperType *ot = Config->MyOperTypes[i]; Anope::string perms; - for (std::list<Anope::string>::const_iterator it2 = (*it)->GetPrivs().begin(), it2_end = (*it)->GetPrivs().end(); it2 != it2_end; ++it2) + for (std::list<Anope::string>::const_iterator it2 = ot->GetPrivs().begin(), it2_end = ot->GetPrivs().end(); it2 != it2_end; ++it2) perms += " " + *it2; - for (std::list<Anope::string>::const_iterator it2 = (*it)->GetCommands().begin(), it2_end = (*it)->GetCommands().end(); it2 != it2_end; ++it2) + for (std::list<Anope::string>::const_iterator it2 = ot->GetCommands().begin(), it2_end = ot->GetCommands().end(); it2 != it2_end; ++it2) perms += " " + *it2; - request.reply((*it)->GetName(), perms); + request.reply(ot->GetName(), perms); } } }; @@ -258,7 +259,7 @@ class ModuleXMLRPCMain : public Module MyXMLRPCEvent stats; public: - ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), xmlrpc("XMLRPCServiceInterface", "xmlrpc") + ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), xmlrpc("XMLRPCServiceInterface", "xmlrpc") { me = this; diff --git a/modules/extra/sql.h b/modules/extra/sql.h deleted file mode 100644 index 1c8fdd3aa..000000000 --- a/modules/extra/sql.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * (C) 2003-2013 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -namespace SQL -{ - - class Data : public Serialize::Data - { - public: - typedef std::map<Anope::string, std::stringstream *> Map; - Map data; - std::map<Anope::string, Type> types; - - ~Data() - { - Clear(); - } - - std::iostream& operator[](const Anope::string &key) anope_override - { - std::stringstream *&ss = data[key]; - if (!ss) - ss = new std::stringstream(); - return *ss; - } - - std::set<Anope::string> KeySet() const anope_override - { - std::set<Anope::string> keys; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - keys.insert(it->first); - return keys; - } - - size_t Hash() const anope_override - { - size_t hash = 0; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - if (!it->second->str().empty()) - hash ^= Anope::hash_cs()(it->second->str()); - return hash; - } - - std::map<Anope::string, std::iostream *> GetData() const - { - std::map<Anope::string, std::iostream *> d; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - d[it->first] = it->second; - return d; - } - - void Clear() - { - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - delete it->second; - this->data.clear(); - } - - void SetType(const Anope::string &key, Type t) anope_override - { - this->types[key] = t; - } - - Type GetType(const Anope::string &key) const anope_override - { - std::map<Anope::string, Type>::const_iterator it = this->types.find(key); - if (it != this->types.end()) - return it->second; - return DT_TEXT; - } - }; - - /** A SQL exception, can be thrown at various points - */ - class Exception : public ModuleException - { - public: - Exception(const Anope::string &reason) : ModuleException(reason) { } - - virtual ~Exception() throw() { } - }; - - /** A SQL query - */ - - struct QueryData - { - Anope::string data; - bool escape; - }; - - struct Query - { - Anope::string query; - std::map<Anope::string, QueryData> parameters; - - Query() { } - Query(const Anope::string &q) : query(q) { } - - Query& operator=(const Anope::string &q) - { - this->query = q; - this->parameters.clear(); - return *this; - } - - bool operator==(const Query &other) const - { - return this->query == other.query; - } - - inline bool operator!=(const Query &other) const - { - return !(*this == other); - } - - template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true) - { - try - { - Anope::string string_value = stringify(value); - this->parameters[key].data = string_value; - this->parameters[key].escape = escape; - } - catch (const ConvertException &ex) { } - } - }; - - /** A result from a SQL query - */ - class Result - { - protected: - /* Rows, column, item */ - std::vector<std::map<Anope::string, Anope::string> > entries; - Query query; - Anope::string error; - public: - unsigned int id; - Anope::string finished_query; - - Result() : id(0) { } - Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { } - - inline operator bool() const { return this->error.empty(); } - - inline const unsigned int GetID() const { return this->id; } - inline const Query &GetQuery() const { return this->query; } - inline const Anope::string &GetError() const { return this->error; } - - int Rows() const { return this->entries.size(); } - - const std::map<Anope::string, Anope::string> &Row(size_t index) const - { - try - { - return this->entries.at(index); - } - catch (const std::out_of_range &) - { - throw Exception("Out of bounds access to SQLResult"); - } - } - - const Anope::string Get(size_t index, const Anope::string &col) const - { - const std::map<Anope::string, Anope::string> rows = this->Row(index); - - std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col); - if (it == rows.end()) - throw Exception("Unknown column name in SQLResult: " + col); - - return it->second; - } - }; - - /* An interface used by modules to retrieve the results - */ - class Interface - { - public: - Module *owner; - - Interface(Module *m) : owner(m) { } - virtual ~Interface() { } - - virtual void OnResult(const Result &r) = 0; - virtual void OnError(const Result &r) = 0; - }; - - /** Class providing the SQL service, modules call this to execute queries - */ - class Provider : public Service - { - public: - Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { } - - virtual void Run(Interface *i, const Query &query) = 0; - - virtual Result RunQuery(const Query &query) = 0; - - virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0; - - virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0; - - virtual Query GetTables(const Anope::string &prefix) = 0; - - virtual Anope::string FromUnixtime(time_t) = 0; - }; - -} - diff --git a/modules/extra/ssl.h b/modules/extra/ssl.h deleted file mode 100644 index 6eb97582c..000000000 --- a/modules/extra/ssl.h +++ /dev/null @@ -1,9 +0,0 @@ - -class SSLService : public Service -{ - public: - SSLService(Module *o, const Anope::string &n) : Service(o, "SSLService", n) { } - - virtual void Init(Socket *s) = 0; -}; - diff --git a/modules/extra/webcpanel/CMakeLists.txt b/modules/extra/webcpanel/CMakeLists.txt index 4437156ad..247973f61 100644 --- a/modules/extra/webcpanel/CMakeLists.txt +++ b/modules/extra/webcpanel/CMakeLists.txt @@ -1,3 +1,4 @@ +build_subdir(${CMAKE_CURRENT_SOURCE_DIR}) install(DIRECTORY templates DESTINATION "${DB_DIR}/modules/webcpanel" diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp index 33250035e..0df2ecfc1 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.cpp +++ b/modules/extra/webcpanel/pages/chanserv/access.cpp @@ -44,7 +44,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/access", params, replacements); } else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false) { @@ -75,8 +75,10 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s } } - if (ci->GetAccessCount() >= Config->CSAccessMax) - replacements["MESSAGES"] = "Sorry, you can only have " + stringify(Config->CSAccessMax) + " access entries on a channel."; + + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) + replacements["MESSAGES"] = "Sorry, you can only have " + stringify(access_max) + " access entries on a channel."; else if (!denied) { ChanAccess *new_acc = a->Create(); diff --git a/modules/extra/webcpanel/pages/chanserv/akick.cpp b/modules/extra/webcpanel/pages/chanserv/akick.cpp index 95fb8fb30..06aede8e7 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.cpp +++ b/modules/extra/webcpanel/pages/chanserv/akick.cpp @@ -40,7 +40,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements); } else if (message.post_data["mask"].empty() == false) { @@ -51,7 +51,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st if (message.post_data["reason"].empty() == false) params.push_back(message.get_data["reason"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements); } replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname); diff --git a/modules/extra/webcpanel/pages/chanserv/drop.cpp b/modules/extra/webcpanel/pages/chanserv/drop.cpp index 5462aa131..f18700651 100644 --- a/modules/extra/webcpanel/pages/chanserv/drop.cpp +++ b/modules/extra/webcpanel/pages/chanserv/drop.cpp @@ -21,7 +21,7 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str std::vector<Anope::string> params; params.push_back(HTTPUtils::URLDecode(message.post_data["channel"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/drop", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/drop", params, replacements); } else replacements["MESSAGES"] = "Invalid Confirmation"; } diff --git a/modules/extra/webcpanel/pages/confirm.cpp b/modules/extra/webcpanel/pages/confirm.cpp index 1f5d61cc1..ab86ee5c9 100644 --- a/modules/extra/webcpanel/pages/confirm.cpp +++ b/modules/extra/webcpanel/pages/confirm.cpp @@ -21,7 +21,7 @@ bool WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &pa if (!email.empty()) params.push_back(email); - WebPanel::RunCommand(user, NULL, Config->NickServ, "nickserv/register", params, replacements); + WebPanel::RunCommand(user, NULL, ::NickServ->nick, "nickserv/register", params, replacements); } TemplateFileServer page("confirm.html"); diff --git a/modules/extra/webcpanel/pages/confirm.h b/modules/extra/webcpanel/pages/confirm.h index e0966fce3..e2bbf8d88 100644 --- a/modules/extra/webcpanel/pages/confirm.h +++ b/modules/extra/webcpanel/pages/confirm.h @@ -5,7 +5,7 @@ * Please read COPYING and README for further details. */ -#include "../../httpd.h" +#include "modules/httpd.h" namespace WebCPanel { diff --git a/modules/extra/webcpanel/pages/hostserv/request.cpp b/modules/extra/webcpanel/pages/hostserv/request.cpp index 6335b1a56..30a396a9b 100644 --- a/modules/extra/webcpanel/pages/hostserv/request.cpp +++ b/modules/extra/webcpanel/pages/hostserv/request.cpp @@ -18,7 +18,7 @@ bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope:: std::vector<Anope::string> params; params.push_back(HTTPUtils::URLDecode(message.post_data["req"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->HostServ, "hostserv/request", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::HostServ->nick, "hostserv/request", params, replacements, "CMDR"); } if (na->HasVhost()) diff --git a/modules/extra/webcpanel/pages/index.h b/modules/extra/webcpanel/pages/index.h index 201b12a78..cd6372ed7 100644 --- a/modules/extra/webcpanel/pages/index.h +++ b/modules/extra/webcpanel/pages/index.h @@ -5,7 +5,7 @@ * Please read COPYING and README for further details. */ -#include "../../httpd.h" +#include "modules/httpd.h" namespace WebCPanel { diff --git a/modules/extra/webcpanel/pages/memoserv/memos.cpp b/modules/extra/webcpanel/pages/memoserv/memos.cpp index 671820ced..9324bea56 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.cpp +++ b/modules/extra/webcpanel/pages/memoserv/memos.cpp @@ -57,7 +57,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"])); params.push_back(HTTPUtils::URLDecode(message.post_data["message"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/send", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/send", params, replacements, "CMDR"); } if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0) { @@ -66,7 +66,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st params.push_back(chname); params.push_back(message.get_data["number"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/del", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/del", params, replacements, "CMDR"); } if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0) { diff --git a/modules/extra/webcpanel/pages/nickserv/access.cpp b/modules/extra/webcpanel/pages/nickserv/access.cpp index de0e544f7..41dc0f429 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.cpp +++ b/modules/extra/webcpanel/pages/nickserv/access.cpp @@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("ADD"); params.push_back(message.post_data["access"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements); } else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0) { @@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements); } for (unsigned i = 0; i < na->nc->access.size(); ++i) diff --git a/modules/extra/webcpanel/pages/nickserv/cert.cpp b/modules/extra/webcpanel/pages/nickserv/cert.cpp index fc13e2ce5..44849a302 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.cpp +++ b/modules/extra/webcpanel/pages/nickserv/cert.cpp @@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str params.push_back("ADD"); params.push_back(message.post_data["certfp"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements); } else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0) { @@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements); } for (unsigned i = 0; i < na->nc->cert.size(); ++i) diff --git a/modules/extra/webcpanel/pages/operserv/akill.cpp b/modules/extra/webcpanel/pages/operserv/akill.cpp index 87b8f94fb..ae9824bce 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.cpp +++ b/modules/extra/webcpanel/pages/operserv/akill.cpp @@ -34,7 +34,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]); cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]); params.push_back(cmdstr.str()); - WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements); } if (message.get_data["del"] == "1" && message.get_data.count("number") > 0) @@ -42,7 +42,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st std::vector<Anope::string> params; params.push_back("DEL"); params.push_back(HTTPUtils::URLDecode(message.get_data["number"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements); } for (unsigned i = 0, end = akills->GetCount(); i < end; ++i) diff --git a/modules/extra/webcpanel/pages/register.cpp b/modules/extra/webcpanel/pages/register.cpp index 409069348..730db612d 100644 --- a/modules/extra/webcpanel/pages/register.cpp +++ b/modules/extra/webcpanel/pages/register.cpp @@ -13,7 +13,7 @@ bool WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &p replacements["TITLE"] = page_title; - if (!Config->NSForceEmail) + if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) replacements["EMAIL_TYPE"] = "hidden"; TemplateFileServer page("register.html"); diff --git a/modules/extra/webcpanel/pages/register.h b/modules/extra/webcpanel/pages/register.h index 35e373a9a..855d4bbc0 100644 --- a/modules/extra/webcpanel/pages/register.h +++ b/modules/extra/webcpanel/pages/register.h @@ -5,7 +5,7 @@ * Please read COPYING and README for further details. */ -#include "../../httpd.h" +#include "modules/httpd.h" namespace WebCPanel { diff --git a/modules/extra/webcpanel/static_fileserver.h b/modules/extra/webcpanel/static_fileserver.h index 9bb274f5e..d2aabde8e 100644 --- a/modules/extra/webcpanel/static_fileserver.h +++ b/modules/extra/webcpanel/static_fileserver.h @@ -5,7 +5,7 @@ * Please read COPYING and README for further details. */ -#include "../httpd.h" +#include "modules/httpd.h" /* A basic file server. Used for serving static content on disk. */ class StaticFileServer : public HTTPPage diff --git a/modules/extra/webcpanel/template_fileserver.h b/modules/extra/webcpanel/template_fileserver.h index 44e2fe708..4f94ddce2 100644 --- a/modules/extra/webcpanel/template_fileserver.h +++ b/modules/extra/webcpanel/template_fileserver.h @@ -5,7 +5,7 @@ * Please read COPYING and README for further details. */ -#include "../httpd.h" +#include "modules/httpd.h" /* A basic file server. Used for serving non-static non-binary content on disk. */ class TemplateFileServer diff --git a/modules/extra/webcpanel/webcpanel.cpp b/modules/extra/webcpanel/webcpanel.cpp index 77e99dd4e..88606cf67 100644 --- a/modules/extra/webcpanel/webcpanel.cpp +++ b/modules/extra/webcpanel/webcpanel.cpp @@ -41,24 +41,23 @@ class ModuleWebCPanel : public Module public: - ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), + ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), panel(this, "webcpanel"), style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"), index("/"), logout("/logout"), _register("/register"), confirm("/confirm"), - nickserv_info(Config->NickServ, "/nickserv/info"), nickserv_cert(Config->NickServ, "/nickserv/cert"), nickserv_access(Config->NickServ, "/nickserv/access"), nickserv_alist(Config->NickServ, "/nickserv/alist"), - chanserv_info(Config->ChanServ, "/chanserv/info"), chanserv_set(Config->ChanServ, "/chanserv/set"), chanserv_access(Config->ChanServ, "/chanserv/access"), chanserv_akick(Config->ChanServ, "/chanserv/akick"), - chanserv_drop(Config->ChanServ, "/chanserv/drop"), memoserv_memos(Config->MemoServ, "/memoserv/memos"), hostserv_request(Config->HostServ, "/hostserv/request"), operserv_akill(Config->OperServ, "/operserv/akill") + nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"), + chanserv_info("ChanServ", "/chanserv/info"), chanserv_set("ChanServ", "/chanserv/set"), chanserv_access("ChanServ", "/chanserv/access"), chanserv_akick("ChanServ", "/chanserv/akick"), + chanserv_drop("ChanServ", "/chanserv/drop"), memoserv_memos("MemoServ", "/memoserv/memos"), hostserv_request("HostServ", "/hostserv/request"), operserv_akill("OperServ", "/operserv/akill") { - this->SetAuthor("Anope"); me = this; - ConfigReader reader; - provider_name = reader.ReadValue("webcpanel", "server", "httpd/main", 0); - template_name = reader.ReadValue("webcpanel", "template", "template", 0); + Configuration::Block *block = Config->GetModule(this); + provider_name = block->Get<const Anope::string>("server", "httpd/main"); + template_name = block->Get<const Anope::string>("template", "default"); template_base = Anope::DataDir + "/modules/webcpanel/templates/" + template_name; - page_title = reader.ReadValue("webcpanel", "title", "Anope IRC Services", 0); - use_ssl = reader.ReadFlag("webcpanel", "ssl", "no", 0); // This is dumb, is there a better way to do this? + page_title = block->Get<const Anope::string>("title", "Anope IRC Services"); + use_ssl = block->Get<bool>("ssl", "no"); // This is dumb, is there a better way to do this? ServiceReference<HTTPProvider> provider("HTTPProvider", provider_name); if (!provider) @@ -73,10 +72,10 @@ class ModuleWebCPanel : public Module provider->RegisterPage(&this->_register); provider->RegisterPage(&this->confirm); - if (Config->NickServ.empty() == false) + if (NickServ) { Section s; - s.name = Config->NickServ; + s.name = NickServ->nick; SubSection ss; ss.name = "Information"; @@ -104,10 +103,11 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->ChanServ.empty() == false) + + if (ChanServ) { Section s; - s.name = Config->ChanServ; + s.name = ChanServ->nick; SubSection ss; ss.name = "Channels"; @@ -138,10 +138,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->MemoServ.empty() == false) + if (MemoServ) { Section s; - s.name = Config->MemoServ; + s.name = MemoServ->nick; SubSection ss; ss.name = "Memos"; @@ -152,10 +152,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->HostServ.empty() == false) + if (HostServ) { Section s; - s.name = Config->HostServ; + s.name = HostServ->nick; SubSection ss; ss.name = "vHost Request"; @@ -166,10 +166,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->OperServ.empty() == false) + if (OperServ) { Section s; - s.name = Config->OperServ; + s.name = OperServ->nick; SubSection ss; ss.name = "Akill"; diff --git a/modules/extra/webcpanel/webcpanel.h b/modules/extra/webcpanel/webcpanel.h index 74a8805d4..359bde32b 100644 --- a/modules/extra/webcpanel/webcpanel.h +++ b/modules/extra/webcpanel/webcpanel.h @@ -6,7 +6,7 @@ */ #include "module.h" -#include "../httpd.h" +#include "modules/httpd.h" #include "static_fileserver.h" #include "template_fileserver.h" diff --git a/modules/extra/xmlrpc.h b/modules/extra/xmlrpc.h deleted file mode 100644 index d5a5ea4a7..000000000 --- a/modules/extra/xmlrpc.h +++ /dev/null @@ -1,40 +0,0 @@ -#include "httpd.h" - -class XMLRPCRequest -{ - std::map<Anope::string, Anope::string> replies; - - public: - Anope::string name; - Anope::string id; - std::deque<Anope::string> data; - HTTPReply& r; - - XMLRPCRequest(HTTPReply &_r) : r(_r) { } - inline void reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.insert(std::make_pair(dname, ddata)); } - inline const std::map<Anope::string, Anope::string> &get_replies() { return this->replies; } -}; - -class XMLRPCServiceInterface; - -class XMLRPCEvent -{ - public: - virtual ~XMLRPCEvent() { } - virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) = 0; -}; - -class XMLRPCServiceInterface : public Service -{ - public: - XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "XMLRPCServiceInterface", sname) { } - - virtual void Register(XMLRPCEvent *event) = 0; - - virtual void Unregister(XMLRPCEvent *event) = 0; - - virtual Anope::string Sanitize(const Anope::string &string) = 0; - - virtual void Reply(XMLRPCRequest &request) = 0; -}; - diff --git a/modules/extra/m_dns.cpp b/modules/m_dns.cpp index 90f9bee9e..9b0157069 100644 --- a/modules/extra/m_dns.cpp +++ b/modules/m_dns.cpp @@ -11,7 +11,7 @@ */ #include "module.h" -#include "dns.h" +#include "modules/dns.h" using namespace DNS; @@ -24,11 +24,11 @@ namespace /** A full packet sent or recieved to/from the nameserver */ -class MyPacket : public Packet +class Packet : public Query { void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name) { - if (name.length() + 2 > output_size) + if (pos + name.length() + 2 > output_size) throw SocketException("Unable to pack name"); Log(LOG_DEBUG_2) << "Resolver: PackName packing " << name; @@ -99,6 +99,9 @@ class MyPacket : public Packet /* +1 pos either to one byte after the compression pointer or one byte after the ending \0 */ ++pos; + if (name.empty()) + throw SocketException("Unable to unpack name - no name"); + Log(LOG_DEBUG_2) << "Resolver: UnpackName successfully unpacked " << name; return name; @@ -184,6 +187,10 @@ class MyPacket : public Packet } public: + static const int POINTER = 0xC0; + static const int LABEL = 0x3F; + static const int HEADER_LENGTH = 12; + Manager *manager; /* Source or destination of the packet */ sockaddrs addr; @@ -192,7 +199,7 @@ class MyPacket : public Packet /* Flags on the packet */ unsigned short flags; - MyPacket(Manager *m, sockaddrs *a) : manager(m), id(0), flags(0) + Packet(Manager *m, sockaddrs *a) : manager(m), id(0), flags(0) { if (a) addr = *a; @@ -436,7 +443,7 @@ namespace DNS { public: virtual ~ReplySocket() { } - virtual void Reply(MyPacket *p) = 0; + virtual void Reply(Packet *p) = 0; }; } @@ -448,7 +455,7 @@ class TCPSocket : public ListenSocket { Manager *manager; TCPSocket *tcpsock; - MyPacket *packet; + Packet *packet; unsigned char packet_buffer[524]; int length; @@ -468,7 +475,7 @@ class TCPSocket : public ListenSocket /* Times out after a few seconds */ void Tick(time_t) anope_override { } - void Reply(MyPacket *p) anope_override + void Reply(Packet *p) anope_override { delete packet; packet = p; @@ -538,7 +545,7 @@ class TCPSocket : public ListenSocket class UDPSocket : public ReplySocket { Manager *manager; - std::deque<MyPacket *> packets; + std::deque<Packet *> packets; public: UDPSocket(Manager *m, const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos, SOCK_DGRAM), manager(m) { } @@ -549,13 +556,13 @@ class UDPSocket : public ReplySocket delete packets[i]; } - void Reply(MyPacket *p) anope_override + void Reply(Packet *p) anope_override { packets.push_back(p); SocketEngine::Change(this, true, SF_WRITABLE); } - std::deque<MyPacket *>& GetPackets() { return packets; } + std::deque<Packet *>& GetPackets() { return packets; } bool ProcessRead() anope_override { @@ -572,7 +579,7 @@ class UDPSocket : public ReplySocket { Log(LOG_DEBUG_2) << "Resolver: Writing to DNS UDP socket"; - MyPacket *r = !packets.empty() ? packets.front() : NULL; + Packet *r = !packets.empty() ? packets.front() : NULL; if (r != NULL) { try @@ -599,7 +606,7 @@ class MyManager : public Manager, public Timer { uint32_t serial; - typedef std::multimap<Anope::string, ResourceRecord, ci::less> cache_map; + typedef std::tr1::unordered_map<Question, Query, Question::hash> cache_map; cache_map cache; TCPSocket *tcpsock; @@ -690,11 +697,11 @@ class MyManager : public Manager, public Timer req->SetSecs(timeout); - MyPacket *p = new MyPacket(this, &this->addrs); + Packet *p = new Packet(this, &this->addrs); p->flags = QUERYFLAGS_RD; - p->id = req->id; p->questions.push_back(*req); + this->udpsock->Reply(p); } @@ -708,7 +715,7 @@ class MyManager : public Manager, public Timer if (length < Packet::HEADER_LENGTH) return true; - MyPacket recv_packet(this, from); + Packet recv_packet(this, from); try { @@ -730,7 +737,7 @@ class MyManager : public Manager, public Timer return true; } - MyPacket *packet = new MyPacket(recv_packet); + Packet *packet = new Packet(recv_packet); packet->flags |= QUERYFLAGS_QR; /* This is a reponse */ packet->flags |= QUERYFLAGS_AA; /* And we are authoritative */ @@ -838,7 +845,7 @@ class MyManager : public Manager, public Timer recv_packet.error = error; request->OnError(&recv_packet); } - else if (recv_packet.answers.empty()) + else if (recv_packet.questions.empty() || recv_packet.answers.empty()) { Log(LOG_DEBUG_2) << "Resolver: No resource records returned"; recv_packet.error = ERROR_NO_RECORDS; @@ -865,26 +872,14 @@ class MyManager : public Manager, public Timer return serial; } - /** Add a record to the dns cache - * @param r The record - */ - void AddCache(Query &r) - { - for (unsigned i = 0; i < r.answers.size(); ++i) - { - ResourceRecord &rr = r.answers[i]; - Log(LOG_DEBUG_3) << "Resolver cache: added cache for " << rr.name << " -> " << rr.rdata << ", ttl: " << rr.ttl; - this->cache.insert(std::make_pair(rr.name, rr)); - } - } - void Tick(time_t now) anope_override { Log(LOG_DEBUG_2) << "Resolver: Purging DNS cache"; for (cache_map::iterator it = this->cache.begin(), it_next; it != this->cache.end(); it = it_next) { - ResourceRecord &req = it->second; + const Query &q = it->second; + const ResourceRecord &req = q.answers[0]; it_next = it; ++it_next; @@ -894,29 +889,28 @@ class MyManager : public Manager, public Timer } private: + /** Add a record to the dns cache + * @param r The record + */ + void AddCache(Query &r) + { + const ResourceRecord &rr = r.answers[0]; + Log(LOG_DEBUG_3) << "Resolver cache: added cache for " << rr.name << " -> " << rr.rdata << ", ttl: " << rr.ttl; + this->cache[r.questions[0]] = r; + } + /** Check the DNS cache to see if request can be handled by a cached result * @return true if a cached result was found. */ bool CheckCache(Request *request) { - cache_map::iterator it = this->cache.find(request->name); + cache_map::iterator it = this->cache.find(*request); if (it != this->cache.end()) { - Query record(*request); - - for (cache_map::iterator it_end = this->cache.upper_bound(request->name); it != it_end; ++it) - { - ResourceRecord &rec = it->second; - if (rec.created + static_cast<time_t>(rec.ttl) >= Anope::CurTime) - record.answers.push_back(rec); - } - - if (!record.answers.empty()) - { - Log(LOG_DEBUG_3) << "Resolver: Using cached result for " << request->name; - request->OnLookupComplete(&record); - return true; - } + Query &record = it->second; + Log(LOG_DEBUG_3) << "Resolver: Using cached result for " << request->name; + request->OnLookupComplete(&record); + return true; } return false; @@ -933,27 +927,24 @@ class ModuleDNS : public Module int port; public: - ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), manager(this) + ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), manager(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnModuleUnload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - - nameserver = config.ReadValue("dns", "nameserver", "127.0.0.1", 0); - timeout = Anope::DoTime(config.ReadValue("dns", "timeout", "5", 0)); - ip = config.ReadValue("dns", "ip", "0.0.0.0", 0); - port = config.ReadInteger("dns", "port", "53", 0, false); - admin = config.ReadValue("dns", "admin", "admin@example.com", 0); - nameservers = config.ReadValue("dns", "nameservers", "ns1.example.com", 0); - refresh = config.ReadInteger("dns", "refresh", "3600", 0, false); + Configuration::Block *block = conf->GetModule(this); + + nameserver = block->Get<const Anope::string>("nameserver", "127.0.0.1"); + timeout = block->Get<time_t>("timeout", "5"); + ip = block->Get<const Anope::string>("ip", "0.0.0.0"); + port = block->Get<int>("port", "53"); + admin = block->Get<const Anope::string>("admin", "admin@example.com"); + nameservers = block->Get<const Anope::string>("nameservers", "ns1.example.com"); + refresh = block->Get<int>("refresh", "3600"); if (Anope::IsFile(nameserver)) { diff --git a/modules/extra/m_dnsbl.cpp b/modules/m_dnsbl.cpp index 49d39d980..b6ebcfb55 100644 --- a/modules/extra/m_dnsbl.cpp +++ b/modules/m_dnsbl.cpp @@ -6,7 +6,7 @@ */ #include "module.h" -#include "dns.h" +#include "modules/dns.h" using namespace DNS; @@ -63,10 +63,10 @@ class DNSBLResolver : public Request reason = reason.replace_all_cs("%h", user->host); reason = reason.replace_all_cs("%i", user->ip); reason = reason.replace_all_cs("%r", record_reason); - reason = reason.replace_all_cs("%N", Config->NetworkName); + reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); Log(OperServ) << "DNSBL: " << user->GetMask() << " (" << user->ip << ") appears in " << this->blacklist.name; - XLine *x = new XLine("*@" + user->ip, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); + XLine *x = new XLine("*@" + user->ip, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); if (this->add_to_akill && akills) { akills->AddXLine(x); @@ -88,39 +88,34 @@ class ModuleDNSBL : public Module bool add_to_akill; public: - ModuleDNSBL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleDNSBL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnReload, I_OnUserConnect }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - - this->check_on_connect = config.ReadFlag("m_dnsbl", "check_on_connect", "no", 0); - this->check_on_netburst = config.ReadFlag("m_dnsbl", "check_on_netburst", "no", 0); - this->add_to_akill = config.ReadFlag("m_dnsbl", "add_to_akill", "yes", 0); + Configuration::Block *block = conf->GetModule(this); + this->check_on_connect = block->Get<bool>("check_on_connect"); + this->check_on_netburst = block->Get<bool>("check_on_netburst"); + this->add_to_akill = block->Get<bool>("add_to_akill", "yes"); this->blacklists.clear(); - for (int i = 0, num = config.Enumerate("blacklist"); i < num; ++i) + for (int i = 0, num = conf->CountBlock("blacklist"); i < num; ++i) { - Anope::string bname = config.ReadValue("blacklist", "name", "", i); + Configuration::Block *bl = conf->GetBlock("blacklist", i); + + Anope::string bname = bl->Get<const Anope::string>("name"); if (bname.empty()) continue; - Anope::string sbantime = config.ReadValue("blacklist", "time", "4h", i); - time_t bantime = Anope::DoTime(sbantime); - if (bantime < 0) - bantime = 9000; - Anope::string reason = config.ReadValue("blacklist", "reason", "", i); + time_t bantime = bl->Get<time_t>("time", "4h"); + Anope::string reason = bl->Get<const Anope::string>("reason"); std::map<int, Anope::string> replies; for (int j = 0; j < 256; ++j) { - Anope::string k = config.ReadValue("blacklist", stringify(j), "", i); + Anope::string k = bl->Get<const Anope::string>(stringify(j)); if (!k.empty()) replies[j] = k; } @@ -158,14 +153,16 @@ class ModuleDNSBL : public Module { const Blacklist &b = this->blacklists[i]; + Anope::string dnsbl_host = user_ip.addr() + "." + b.name; + DNSBLResolver *res = NULL; try { - Anope::string dnsbl_host = user_ip.addr() + "." + b.name; - DNSBLResolver *res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill); + res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill); dnsmanager->Process(res); } catch (const SocketException &ex) { + delete res; Log(this) << ex.GetReason(); } } diff --git a/modules/extra/m_helpchan.cpp b/modules/m_helpchan.cpp index 32d1859fc..eaf6eb777 100644 --- a/modules/extra/m_helpchan.cpp +++ b/modules/m_helpchan.cpp @@ -9,38 +9,25 @@ class HelpChannel : public Module { - Anope::string HelpChan; - public: - HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnChannelModeSet, I_OnReload }; + Implementation i[] = { I_OnChannelModeSet }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); } EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (mname == "OP" && c && c->ci && c->name.equals_ci(this->HelpChan)) + if (mname == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string>("helpchannel"))) { User *u = User::Find(param); - if (u && c->ci->AccessFor(u).HasPriv("OPDEOPME")) + if (u && c->ci->AccessFor(u).HasPriv("OPME")) u->SetMode(OperServ, "HELPOP"); } return EVENT_CONTINUE; } - - void OnReload() anope_override - { - ConfigReader config; - - this->HelpChan = config.ReadValue("m_helpchan", "helpchannel", "", 0); - } }; MODULE_INIT(HelpChannel) diff --git a/modules/extra/m_rewrite.cpp b/modules/m_rewrite.cpp index 2df259e3d..8131a1729 100644 --- a/modules/extra/m_rewrite.cpp +++ b/modules/m_rewrite.cpp @@ -153,33 +153,29 @@ class ModuleRewrite : public Module RewriteCommand cmdrewrite; public: - ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), cmdrewrite(this) + ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), cmdrewrite(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); } - void OnReload() anope_override + void OnReload(Configuration::Conf *conf) anope_override { - ConfigReader config; - Rewrite::rewrites.clear(); - for (int i = 0; i < config.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (!config.ReadFlag("command", "rewrite", "no", i)) + Configuration::Block *block = conf->GetBlock("command", i); + + if (!block->Get<bool>("rewrite")) continue; Rewrite rw; - rw.client = config.ReadValue("command", "service", "", i); - rw.source_message = config.ReadValue("command", "rewrite_source", "", i), - rw.target_message = config.ReadValue("command", "rewrite_target", "", i); - rw.desc = config.ReadValue("command", "rewrite_description", "", i); + rw.client = block->Get<const Anope::string>("service"); + rw.source_message = block->Get<const Anope::string>("rewrite_source"); + rw.target_message = block->Get<const Anope::string>("rewrite_target"); + rw.desc = block->Get<const Anope::string>("rewrite_description"); if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty()) continue; diff --git a/modules/extra/ns_maxemail.cpp b/modules/ns_maxemail.cpp index fda500a07..fc678e8a5 100644 --- a/modules/extra/ns_maxemail.cpp +++ b/modules/ns_maxemail.cpp @@ -14,20 +14,20 @@ class NSMaxEmail : public Module { - int NSEmailMax; - bool CheckLimitReached(CommandSource &source, const Anope::string &email) { - if (this->NSEmailMax < 1 || email.empty()) + int NSEmailMax = Config->GetModule(this)->Get<int>("maxemails"); + + if (NSEmailMax < 1 || email.empty()) return false; - if (this->CountEmail(email, source.nc) < this->NSEmailMax) + if (this->CountEmail(email, source.nc) < NSEmailMax) return false; - if (this->NSEmailMax == 1) + if (NSEmailMax == 1) source.Reply(_("The given email address has reached its usage limit of 1 user.")); else - source.Reply(_("The given email address has reached its usage limit of %d users."), this->NSEmailMax); + source.Reply(_("The given email address has reached its usage limit of %d users."), NSEmailMax); return true; } @@ -51,21 +51,8 @@ class NSMaxEmail : public Module } public: - NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) - { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnReload, I_OnPreCommand }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - OnReload(); - } - - void OnReload() anope_override + NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - ConfigReader config; - this->NSEmailMax = config.ReadInteger("ns_maxemail", "maxemails", "0", 0, false); - Log(LOG_DEBUG) << "[ns_maxemail] NSEmailMax set to " << NSEmailMax; } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 8c2c131a6..6aa097433 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -79,9 +79,9 @@ class BahamutIRCdProto : public IRCDProto } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t time) anope_override { - UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user"; + UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << time << " :Being held for registered user"; } /* SVSHOLD - release */ @@ -143,16 +143,14 @@ class BahamutIRCdProto : public IRCDProto return; /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLineDel(x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser(); } @@ -170,7 +168,7 @@ class BahamutIRCdProto : public IRCDProto } /* JOIN - SJOIN */ - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(user) << "SJOIN " << c->creation_time << " " << c->name; if (status) @@ -182,12 +180,11 @@ class BahamutIRCdProto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.modes.count(ModeManager::ChannelModes[i]->name)) - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -217,16 +214,14 @@ class BahamutIRCdProto : public IRCDProto } /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLine(u, x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->expires - Anope::CurTime; @@ -270,7 +265,7 @@ class BahamutIRCdProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " :TS"; + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " :TS"; UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3"; SendServer(Me); /* @@ -448,14 +443,7 @@ struct IRCDMessageSJoin : IRCDMessage for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));) { buf.erase(buf.begin()); - ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); - if (!cm) - { - Log() << "Received unknown mode prefix " << cm << " in SJOIN string"; - continue; - } - - sju.first.modes.insert(cm->name); + sju.first.AddMode(ch); } sju.second = User::Find(buf); @@ -494,6 +482,7 @@ class ProtoBahamut : public Module Message::Away message_away; Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; Message::Kill message_kill; @@ -554,17 +543,16 @@ class ProtoBahamut : public Module } public: - ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_join(this), - message_kick(this), message_kill(this), message_motd(this), message_part(this), - message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), - message_stats(this), message_time(this), message_version(this), message_whois(this), + message_away(this), message_capab(this), message_error(this), message_invite(this), + message_join(this), message_kick(this), message_kill(this), message_motd(this), + message_part(this), message_ping(this), message_privmsg(this), message_quit(this), + message_squit(this), message_stats(this), message_time(this), message_version(this), message_whois(this), message_burst(this), message_mode(this, "MODE"), message_svsmode(this, "SVSMODE"), message_nick(this), message_server(this), message_sjoin(this), message_topic(this) { - this->SetAuthor("Anope"); this->AddModes(); diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index 6f41abcc5..1fb017fef 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -11,6 +11,7 @@ #include "module.h" +static bool sasl = true; static Anope::string UplinkSID; static ServiceReference<IRCDProto> ratbox("IRCDProto", "ratbox"); @@ -52,7 +53,7 @@ class CharybdisProto : public IRCDProto void SendAkill(User *u, XLine *x) anope_override { ratbox->SendAkill(u, x); } void SendAkillDel(const XLine *x) anope_override { ratbox->SendAkillDel(x); } void SendSQLineDel(const XLine *x) anope_override { ratbox->SendSQLineDel(x); } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { ratbox->SendJoin(user, c, status); } + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { ratbox->SendJoin(user, c, status); } void SendServer(const Server *server) anope_override { ratbox->SendServer(server); } void SendChannel(Channel *c) anope_override { ratbox->SendChannel(c); } void SendTopic(BotInfo *bi, Channel *c) anope_override { ratbox->SendTopic(bi, c); } @@ -64,7 +65,7 @@ class CharybdisProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* * Received: CAPAB :BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN * KNOCK MLOCK QS RSFNC SAVE SERVICES TB UNKLN @@ -109,14 +110,6 @@ class CharybdisProto : public IRCDProto UplinkSocket::Message(Me) << "EUID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " * * :" << u->realname; } - void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override - { - if (bi) - UplinkSocket::Message(bi) << "MODE " << u->GetUID() << " " << buf; - else - UplinkSocket::Message(Me) << "MODE " << u->GetUID() << " " << buf; - } - void SendLogin(User *u) anope_override { if (!u->Account()) @@ -136,12 +129,12 @@ class CharybdisProto : public IRCDProto << " " << newnick << " " << when << " " << u->timestamp; } - void SendSVSHold(const Anope::string &nick) + void SendSVSHold(const Anope::string &nick, time_t delay) anope_override { - UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << Config->NSReleaseTimeout << " " << nick; + UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << delay << " " << nick; } - void SendSVSHoldDel(const Anope::string &nick) + void SendSVSHoldDel(const Anope::string &nick) anope_override { UplinkSocket::Message(Me) << "ENCAP * NICKDELAY 0 " << nick; } @@ -191,7 +184,7 @@ struct IRCDMessageEncap : IRCDMessage * * Charybdis only accepts messages from SASL agents; these must have umode +S */ - if (params[1] == "SASL" && Config->NSSASL && params.size() == 6) + if (params[1] == "SASL" && sasl && params.size() == 6) { class CharybdisSASLIdentifyRequest : public IdentifyRequest { @@ -306,7 +299,7 @@ struct IRCDMessageServer : IRCDMessage if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -332,6 +325,7 @@ class ProtoCharybdis : public Module Message::Away message_away; Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Kick message_kick; Message::Kill message_kill; Message::Mode message_mode; @@ -357,6 +351,8 @@ class ProtoCharybdis : public Module IRCDMessagePass message_pass; IRCDMessageServer message_server; + bool use_server_side_mlock; + void AddModes() { /* Add user modes */ @@ -390,12 +386,12 @@ class ProtoCharybdis : public Module } public: - ProtoCharybdis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoCharybdis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_kick(this), message_kill(this), - message_mode(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), - message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), - message_version(this), message_whois(this), + message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), + message_kill(this), message_mode(this), message_motd(this), message_part(this), message_ping(this), + message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this), + message_topic(this), message_version(this), message_whois(this), message_bmask("IRCDMessage", "charybdis/bmask", "ratbox/bmask"), message_join("IRCDMessage", "charybdis/join", "ratbox/join"), @@ -409,9 +405,8 @@ class ProtoCharybdis : public Module message_encap(this), message_euid(this), message_pass(this), message_server(this) { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnChannelCreate, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnChannelCreate, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK) @@ -430,9 +425,15 @@ class ProtoCharybdis : public Module ModuleManager::UnloadModule(m_ratbox, NULL); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnChannelCreate(Channel *c) anope_override { - if (c->ci && Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0) + if (use_server_side_mlock && c->ci && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes; @@ -442,7 +443,7 @@ class ProtoCharybdis : public Module EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -454,7 +455,7 @@ class ProtoCharybdis : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index ac3f88c41..1a50b89a6 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -88,7 +88,7 @@ class HybridProto : public IRCDProto UplinkSocket::Message(OperServ) << "UNRESV * " << x->mask; } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { /* * Note that we must send our modes with the SJOIN and @@ -160,7 +160,7 @@ class HybridProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* * As of October 13, 2012, ircd-hybrid-8 does support the following capabilities @@ -234,7 +234,7 @@ class HybridProto : public IRCDProto { ChannelStatus status; - status.modes.insert("OP"); + status.AddMode('o'); bi->Join(c, &status); } @@ -249,9 +249,9 @@ class HybridProto : public IRCDProto UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when; } - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - XLine x(nick, OperServ->nick, Anope::CurTime + Config->NSReleaseTimeout, "Being held for registered user"); + XLine x(nick, OperServ->nick, Anope::CurTime + t, "Being held for registered user"); this->SendSQLine(NULL, &x); } @@ -271,24 +271,14 @@ struct IRCDMessageBMask : IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { Channel *c = Channel::Find(params[1]); + ChannelMode *mode = ModeManager::FindChannelModeByChar(params[2][0]); - if (c) + if (c && mode) { - ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"), - *except = ModeManager::FindChannelModeByName("EXCEPT"), - *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE"); - spacesepstream bans(params[3]); Anope::string token; while (bans.GetToken(token)) - { - if (ban && params[2].equals_cs("b")) - c->SetModeInternal(source, ban, token); - else if (except && params[2].equals_cs("e")) - c->SetModeInternal(source, except, token); - else if (invex && params[2].equals_cs("I")) - c->SetModeInternal(source, invex, token); - } + c->SetModeInternal(source, mode, token); } } }; @@ -367,7 +357,7 @@ struct IRCDMessageServer : IRCDMessage new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -382,7 +372,7 @@ struct IRCDMessageSID : IRCDMessage unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -412,15 +402,7 @@ struct IRCDMessageSJoin : IRCDMessage for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));) { buf.erase(buf.begin()); - ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); - - if (!cm) - { - Log() << "Received unknown mode prefix " << ch << " in SJOIN string"; - continue; - } - - sju.first.modes.insert(cm->name); + sju.first.AddMode(ch); } sju.second = User::Find(buf); @@ -540,6 +522,7 @@ class ProtoHybrid : public Module Message::Away message_away; Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Kick message_kick; Message::Kill message_kill; Message::Mode message_mode; @@ -610,28 +593,23 @@ class ProtoHybrid : public Module } public: - ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_kick(this), message_kill(this), - message_mode(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), - message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), - message_version(this), message_whois(this), + message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), + message_kill(this), message_mode(this), message_motd(this), message_part(this), message_ping(this), + message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this), + message_topic(this), message_version(this), message_whois(this), message_bmask(this), message_eob(this), message_join(this), message_nick(this), message_pass(this), message_pong(this), message_server(this), message_sid(this), message_sjoin(this), message_svsmode(this), message_tburst(this), message_tmode(this), message_uid(this) { - this->SetAuthor("Anope"); this->AddModes(); ModuleManager::Attach(I_OnUserNickChange, this); - if (Config->Numeric.empty()) - { - Anope::string numeric = Servers::TS6_SID_Retrieve(); - Me->SetSID(numeric); - Config->Numeric = numeric; - } + if (Me->GetSID() == Me->GetName()) + Me->SetSID(Servers::TS6_SID_Retrieve()); for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) it->second->GenerateUID(); diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 0761f478c..12a22e724 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -80,16 +80,14 @@ class InspIRCdProto : public IRCDProto return; /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLineDel(x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } UplinkSocket::Message(OperServ) << "GLINE " << x->mask; } @@ -136,16 +134,14 @@ class InspIRCdProto : public IRCDProto } /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLine(u, x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->expires - Anope::CurTime; @@ -181,14 +177,6 @@ class InspIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "FMODE " << dest->name << " " << dest->creation_time << " " << buf; } - void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override - { - if (bi) - UplinkSocket::Message(bi) << "MODE " << u->nick << " " << buf; - else - UplinkSocket::Message(Me) << "MODE " << u->nick << " " << buf; - } - void SendClientIntroduction(const User *u) anope_override { Anope::string modes = "+" + u->GetModes(); @@ -203,7 +191,7 @@ class InspIRCdProto : public IRCDProto } /* JOIN */ - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(user) << "JOIN " << c->name << " " << c->creation_time; if (status) @@ -215,12 +203,11 @@ class InspIRCdProto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.modes.count(ModeManager::ChannelModes[i]->name)) - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -252,7 +239,7 @@ class InspIRCdProto : public IRCDProto void SendConnect() anope_override { - current_pass = Config->Uplinks[Anope::CurrentUplink]->password; + current_pass = Config->Uplinks[Anope::CurrentUplink].password; SendServer(Me); UplinkSocket::Message() << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); @@ -260,9 +247,9 @@ class InspIRCdProto : public IRCDProto } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << "s :Being held for registered user"; + UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << t << "s :Being held for registered user"; } /* SVSHOLD - release */ @@ -536,6 +523,8 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeStatus("", modes[t], chars[t], level--)); } } + + ModeManager::RebuildStatusModes(); } else if (capab.find("MAXMODES=") != Anope::string::npos) { @@ -653,7 +642,7 @@ struct IRCDMessageFJoin : IRCDMessage continue; } - sju.first.modes.insert(cm->name); + sju.first.AddMode(cm->mchar); } /* Erase the , */ buf.erase(buf.begin()); @@ -801,7 +790,7 @@ struct IRCDMessageRSQuit : IRCDMessage Server *s; /* Horrible workaround to an insp bug (#) in how RSQUITs are sent - mark */ - if (params.size() > 1 && Config->ServerName.equals_cs(params[0])) + if (params.size() > 1 && params[0] == Me->GetName()) s = Server::Find(params[1]); else s = Server::Find(params[0]); @@ -828,6 +817,7 @@ class ProtoInspIRCd : public Module /* Core message handlers */ Message::Away message_away; Message::Error message_error; + Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; Message::Kill message_kill; @@ -870,11 +860,12 @@ class ProtoInspIRCd : public Module } public: - ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_error(this), message_join(this), message_kick(this), message_kill(this), - message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), - message_squit(this), message_stats(this), message_time(this), message_topic(this), message_version(this), + message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), + message_kill(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), + message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), + message_version(this), message_capab(this), message_chgident(this, "CHGIDENT"), message_setident(this, "SETIDENT"), message_chgname(this, "CHGNAME"), message_setname(this, "SETNAME"), message_endburst(this), @@ -882,7 +873,6 @@ class ProtoInspIRCd : public Module message_fmode(this), message_ftopic(this), message_idle(this), message_mode(this), message_nick(this), message_opertype(this), message_rsquit(this), message_server(this) { - this->SetAuthor("Anope"); Servers::Capab.insert("NOQUIT"); diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index a79edf291..c3fa04b85 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -180,16 +180,15 @@ class InspIRCd12Proto : public IRCDProto } /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLine(u, x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } + SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->by, x->GetReason()); } @@ -203,11 +202,6 @@ class InspIRCd12Proto : public IRCDProto UplinkSocket::Message(source) << "FMODE " << dest->name << " " << dest->creation_time << " " << buf; } - void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override - { - UplinkSocket::Message(bi) << "MODE " << u->GetUID() << " " << buf; - } - void SendClientIntroduction(const User *u) anope_override { Anope::string modes = "+" + u->GetModes(); @@ -217,11 +211,11 @@ class InspIRCd12Proto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(const Server *server) anope_override { - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink]->password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription(); + UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink].password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription(); } /* JOIN */ - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(Me) << "FJOIN " << c->name << " " << c->creation_time << " +" << c->GetModes(true, true) << " :," << user->GetUID(); /* Note that we can send this with the FJOIN but choose not to @@ -237,19 +231,11 @@ class InspIRCd12Proto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - { - ChannelMode *cm = ModeManager::ChannelModes[i]; - - if (cs.modes.count(cm->name) || cs.modes.count(cm->mchar)) - { - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); - cs.modes.insert(cm->name); - } - } + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -284,13 +270,13 @@ class InspIRCd12Proto : public IRCDProto SendServer(Me); UplinkSocket::Message(Me) << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString(); + UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Me->GetName() << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString(); } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user"; + UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << t << " :Being held for registered user"; } /* SVSHOLD - release */ @@ -386,7 +372,7 @@ class InspIRCdExtBan : public ChannelModeList public: InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } - bool Matches(const User *u, const Entry *e) anope_override + bool Matches(User *u, const Entry *e) anope_override { const Anope::string &mask = e->GetMask(); @@ -726,6 +712,8 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeStatus("", modes[t], chars[t], level--)); } } + + ModeManager::RebuildStatusModes(); } else if (capab.find("MAXMODES=") != Anope::string::npos) { @@ -839,20 +827,14 @@ struct IRCDMessageFJoin : IRCDMessage Message::Join::SJoinUser sju; /* Loop through prefixes and find modes for them */ - for (char c; (c = buf[0]) != ',';) + for (char c; (c = buf[0]) != ',' && c;) { buf.erase(buf.begin()); - ChannelMode *cm = ModeManager::FindChannelModeByChar(c); - if (!cm) - { - Log() << "Received unknown mode prefix " << c << " in FJOIN string"; - continue; - } - - sju.first.modes.insert(cm->name); + sju.first.AddMode(c); } /* Erase the , */ - buf.erase(buf.begin()); + if (!buf.empty()) + buf.erase(buf.begin()); sju.second = User::Find(buf); if (!sju.second) @@ -947,7 +929,7 @@ struct IRCDMessageMetadata : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if @@ -1188,6 +1170,7 @@ class ProtoInspIRCd : public Module /* Core message handlers */ Message::Away message_away; Message::Error message_error; + Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; Message::Kill message_kill; @@ -1221,30 +1204,25 @@ class ProtoInspIRCd : public Module IRCDMessageUID message_uid; public: - ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_error(this), message_join(this), message_kick(this), message_kill(this), - message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), - message_squit(this), message_stats(this), message_topic(this), + message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), message_kill(this), + message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), + message_stats(this), message_topic(this), message_chgident(this), message_setname(this, "SETNAME"), message_chgname(this, "FNAME"), message_capab(this), message_endburst(this), message_fhost(this, "FHOST"), message_sethost(this, "SETHOST"), message_fjoin(this), message_fmode(this), message_ftopic(this), message_idle(this), message_metadata(this), message_mode(this), message_nick(this), message_opertype(this), message_rsquit(this), message_setident(this), message_server(this), message_time(this), message_uid(this) { - this->SetAuthor("Anope"); Implementation i[] = { I_OnUserNickChange }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); Servers::Capab.insert("NOQUIT"); - if (Config->Numeric.empty()) - { - Anope::string numeric = Servers::TS6_SID_Retrieve(); - Me->SetSID(numeric); - Config->Numeric = numeric; - } + if (Me->GetSID() == Me->GetName()) + Me->SetSID(Servers::TS6_SID_Retrieve()); for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) it->second->GenerateUID(); diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index ee5ab721f..702bf6eea 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -13,6 +13,7 @@ #include "module.h" +static bool sasl = true; static unsigned int spanningtree_proto_ver = 0; static ServiceReference<IRCDProto> insp12("IRCDProto", "inspircd12"); @@ -52,14 +53,13 @@ class InspIRCd20Proto : public IRCDProto void SendAkill(User *u, XLine *x) anope_override { insp12->SendAkill(u, x); } void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) anope_override { insp12->SendNumericInternal(numeric, dest, buf); } void SendModeInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) anope_override { insp12->SendModeInternal(source, dest, buf); } - void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override { insp12->SendModeInternal(bi, u, buf); } void SendClientIntroduction(const User *u) anope_override { insp12->SendClientIntroduction(u); } void SendServer(const Server *server) anope_override { insp12->SendServer(server); } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { insp12->SendJoin(user, c, status); } + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { insp12->SendJoin(user, c, status); } void SendSQLineDel(const XLine *x) anope_override { insp12->SendSQLineDel(x); } void SendSQLine(User *u, const XLine *x) anope_override { insp12->SendSQLine(u, x); } void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendVhost(u, vident, vhost); } - void SendSVSHold(const Anope::string &nick) anope_override { insp12->SendSVSHold(nick); } + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { insp12->SendSVSHold(nick, t); } void SendSVSHoldDel(const Anope::string &nick) anope_override { insp12->SendSVSHoldDel(nick); } void SendSZLineDel(const XLine *x) anope_override { insp12->SendSZLineDel(x); } void SendSZLine(User *u, const XLine *x) anope_override { insp12->SendSZLine(u, x); } @@ -80,7 +80,7 @@ class InspIRCdExtBan : public ChannelModeList public: InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } - bool Matches(const User *u, const Entry *e) anope_override + bool Matches(User *u, const Entry *e) anope_override { const Anope::string &mask = e->GetMask(); @@ -111,7 +111,7 @@ class InspIRCdExtBan : public ChannelModeList { ChanUserContainer *uc = c->FindUser(u); if (uc != NULL) - if (cm == NULL || uc->status.modes.count(cm->name)) + if (cm == NULL || uc->status.HasMode(cm->mchar)) return true; } } @@ -260,6 +260,8 @@ class ChannelModeRedirect : public ChannelModeParam struct IRCDMessageCapab : Message::Capab { + std::map<char, Anope::string> chmodes, umodes; + IRCDMessageCapab(Module *creator) : Message::Capab(creator, "CAPAB") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -278,6 +280,8 @@ struct IRCDMessageCapab : Message::Capab } /* reset CAPAB */ + chmodes.clear(); + umodes.clear(); Servers::Capab.insert("SERVERS"); Servers::Capab.insert("CHGHOST"); Servers::Capab.insert("CHGIDENT"); @@ -381,13 +385,13 @@ struct IRCDMessageCapab : Message::Capab cm = new ChannelModeStatus("VOICE", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); /* Unknown status mode, (customprefix) - add it */ else if (modechar.length() == 2) - cm = new ChannelModeStatus("", modechar[1], modechar[0]); - /* else don't do anything here, we will get it in CAPAB CAPABILITIES */ + cm = new ChannelModeStatus(modename.upper(), modechar[1], modechar[0]); + /* Unknown non status mode, add it to our list for later */ + else + chmodes[modechar[0]] = modename.upper(); if (cm) ModeManager::AddChannelMode(cm); - else - Log() << "Unrecognized mode string in CAPAB CHANMODES: " << capab; } } if (params[0].equals_cs("USERMODES") && params.size() > 1) @@ -440,11 +444,11 @@ struct IRCDMessageCapab : Message::Capab um = new UserMode("STRIPCOLOR", modechar[0]); else if (modename.equals_cs("wallops")) um = new UserMode("WALLOPS", modechar[0]); + else + umodes[modechar[0]] = modename.upper(); if (um) ModeManager::AddUserMode(um); - else - Log() << "Unrecognized mode string in CAPAB USERMODES: " << capab; } } else if (params[0].equals_cs("MODULES") && params.size() > 1) @@ -459,8 +463,9 @@ struct IRCDMessageCapab : Message::Capab else if (module.find("m_rline.so") == 0) { Servers::Capab.insert("RLINE"); - if (!Config->RegexEngine.empty() && module.length() > 11 && Config->RegexEngine != module.substr(11)) - Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << Config->RegexEngine << ". This may cause inconsistencies."; + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); + if (!regexengine.empty() && module.length() > 11 && regexengine != module.substr(11)) + Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << regexengine << ". This may cause inconsistencies."; } else if (module.equals_cs("m_topiclock.so")) Servers::Capab.insert("TOPICLOCK"); @@ -498,7 +503,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList(chmodes[modebuf[t]], modebuf[t])); } sep.GetToken(modebuf); @@ -506,7 +511,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t])); } sep.GetToken(modebuf); @@ -514,7 +519,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeParam("", modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam(chmodes[modebuf[t]], modebuf[t], true)); } sep.GetToken(modebuf); @@ -522,7 +527,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelMode("", modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode(chmodes[modebuf[t]], modebuf[t])); } } else if (capab.find("USERMODES") != Anope::string::npos) @@ -536,11 +541,11 @@ struct IRCDMessageCapab : Message::Capab if (sep.GetToken(modebuf)) for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserModeParam("", modebuf[t])); + ModeManager::AddUserMode(new UserModeParam(umodes[modebuf[t]], modebuf[t])); if (sep.GetToken(modebuf)) for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserMode("", modebuf[t])); + ModeManager::AddUserMode(new UserMode(umodes[modebuf[t]], modebuf[t])); } else if (capab.find("MAXMODES=") != Anope::string::npos) { @@ -564,7 +569,11 @@ struct IRCDMessageCapab : Message::Capab ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); cms->level = level--; + + Log(LOG_DEBUG) << cms->name << " is now level " << cms->level; } + + ModeManager::RebuildStatusModes(); } } } @@ -590,8 +599,9 @@ struct IRCDMessageCapab : Message::Capab Log() << "CHGHOST missing, Usage disabled until module is loaded."; if (!Servers::Capab.count("CHGIDENT")) Log() << "CHGIDENT missing, Usage disabled until module is loaded."; - if (!Servers::Capab.count("TOPICLOCK") && Config->UseServerSideTopicLock) - Log() << "m_topiclock missing, server side topic locking disabled until module is loaded."; + + chmodes.clear(); + umodes.clear(); } Message::Capab::Run(source, params); @@ -634,7 +644,7 @@ struct IRCDMessageEncap : IRCDMessage u->SetRealname(params[3]); UplinkSocket::Message(u) << "FNAME " << params[3]; } - else if (Config->NSSASL && params[1] == "SASL" && params.size() == 6) + else if (sasl && params[1] == "SASL" && params.size() == 6) { class InspIRCDSASLIdentifyRequest : public IdentifyRequest { @@ -717,6 +727,7 @@ class ProtoInspIRCd : public Module /* Core message handlers */ Message::Away message_away; Message::Error message_error; + Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; Message::Kill message_kill; @@ -740,17 +751,19 @@ class ProtoInspIRCd : public Module IRCDMessageEncap message_encap; IRCDMessageFIdent message_fident; + bool use_server_side_topiclock, use_server_side_mlock; + void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value) { UplinkSocket::Message(Me) << "METADATA " << c->name << " " << metadataname << " :" << value; } public: - ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_error(this), message_join(this), message_kick(this), message_kill(this), - message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), - message_squit(this), message_stats(this), message_topic(this), + message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), + message_kill(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), + message_quit(this), message_squit(this), message_stats(this), message_topic(this), message_endburst("IRCDMessage", "inspircd20/endburst", "inspircd12/endburst"), message_fhost("IRCDMessage", "inspircd20/fhost", "inspircd12/fhost"), @@ -769,7 +782,6 @@ class ProtoInspIRCd : public Module message_capab(this), message_encap(this), message_fident(this) { - this->SetAuthor("Anope"); if (ModuleManager::LoadModule("inspircd12", User::Find(creator)) != MOD_ERR_OK) throw ModuleException("Unable to load inspircd12"); @@ -780,7 +792,7 @@ class ProtoInspIRCd : public Module throw ModuleException("No protocol interface for insp12"); ModuleManager::DetachAll(m_insp12); - Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -789,6 +801,13 @@ class ProtoInspIRCd : public Module ModuleManager::UnloadModule(m_insp12, NULL); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock"); + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnUserNickChange(User *u, const Anope::string &) anope_override { u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); @@ -796,19 +815,18 @@ class ProtoInspIRCd : public Module void OnChannelCreate(Channel *c) anope_override { - if (c->ci && (Config->UseServerSideMLock || Config->UseServerSideTopicLock)) - this->OnChanRegistered(c->ci); + this->OnChanRegistered(c->ci); } void OnChanRegistered(ChannelInfo *ci) anope_override { - if (Config->UseServerSideMLock && ci->c) + if (use_server_side_mlock && ci->c) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); SendChannelMetadata(ci->c, "mlock", modes); } - if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c) + if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c) { Anope::string on = ci->HasExt("TOPICLOCK") ? "1" : ""; SendChannelMetadata(ci->c, "topiclock", on); @@ -817,17 +835,17 @@ class ProtoInspIRCd : public Module void OnDelChan(ChannelInfo *ci) anope_override { - if (Config->UseServerSideMLock && ci->c) + if (use_server_side_mlock && ci->c) SendChannelMetadata(ci->c, "mlock", ""); - if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c) + if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c) SendChannelMetadata(ci->c, "topiclock", ""); } EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM)) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; SendChannelMetadata(ci->c, "mlock", modes); @@ -839,7 +857,7 @@ class ProtoInspIRCd : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM)) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); SendChannelMetadata(ci->c, "mlock", modes); @@ -852,7 +870,6 @@ class ProtoInspIRCd : public Module { if (cmd->name == "chanserv/topic" && ci->c) { - if (setting == "topiclock on") SendChannelMetadata(ci->c, "topiclock", "1"); else if (setting == "topiclock off") diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index e54a4f8f7..3d1a727e7 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -53,7 +53,7 @@ class ngIRCdProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P"; + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P"; /* Make myself known to myself in the serverlist */ SendServer(Me); /* finish the enhanced server handshake and register the connection */ @@ -83,7 +83,7 @@ class ngIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "WALLOPS :" << buf; } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(user) << "JOIN " << c->name; if (status) @@ -95,12 +95,11 @@ class ngIRCdProto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.modes.count(ModeManager::ChannelModes[i]->name)) - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -124,14 +123,6 @@ class ngIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "MODE " << dest->name << " " << buf; } - void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override - { - if (bi) - UplinkSocket::Message(bi) << "MODE " << u->nick << " " << buf; - else - UplinkSocket::Message(Me) << "MODE " << u->nick << " " << buf; - } - void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf) anope_override { if (!buf.empty()) @@ -193,11 +184,10 @@ struct IRCDMessage005 : IRCDMessage } else if (parameter == "NICKLEN") { - unsigned newlen = convertTo<unsigned>(data); - if (Config->NickLen != newlen) + unsigned newlen = convertTo<unsigned>(data), len = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"); + if (len != newlen) { - Log() << "NickLen changed from " << Config->NickLen << " to " << newlen; - Config->NickLen = newlen; + Log() << "Warning: NICKLEN is " << newlen << " but networkinfo:nicklen is " << len; } } } @@ -245,10 +235,8 @@ struct IRCDMessageChaninfo : IRCDMessage */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - - Channel *c = Channel::Find(params[0]); - if (!c) - c = new Channel(params[0]); + bool created; + Channel *c = Channel::FindOrCreate(params[0], created); Anope::string modes = params[1]; @@ -470,15 +458,8 @@ struct IRCDMessageNJoin : IRCDMessage /* Get prefixes from the nick */ for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));) { - ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); buf.erase(buf.begin()); - if (!cm) - { - Log(LOG_DEBUG) << "Received unknown mode prefix " << ch << " in NJOIN string."; - continue; - } - - sju.first.modes.insert(cm->name); + sju.first.AddMode(ch); } sju.second = User::Find(buf); @@ -558,7 +539,7 @@ struct IRCDMessageServer : IRCDMessage * when receiving a new server and then finish sync once we * get a pong back from that server. */ - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -588,6 +569,7 @@ class ProtongIRCd : public Module /* Core message handlers */ Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Kick message_kick; Message::Kill message_kill; Message::MOTD message_motd; @@ -659,17 +641,16 @@ class ProtongIRCd : public Module } public: - ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_capab(this), message_error(this), message_kick(this), message_kill(this), message_motd(this), - message_part(this), message_ping(this), message_privmsg(this), message_squery(this, "SQUERY"), + message_capab(this), message_error(this), message_invite(this), message_kick(this), message_kill(this), + message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_squery(this, "SQUERY"), message_quit(this), message_squit(this), message_stats(this), message_time(this), message_version(this), message_005(this), message_376(this), message_chaninfo(this), message_join(this), message_metadata(this), message_mode(this), message_nick(this), message_njoin(this), message_pong(this), message_server(this), message_topic(this) { - this->SetAuthor("Anope"); Servers::Capab.insert("QS"); diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index d117389e7..484f6a4bc 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -45,10 +45,10 @@ class PlexusProto : public IRCDProto void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); } void SendServer(const Server *server) anope_override { hybrid->SendServer(server); } void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); } - void SendSVSHold(const Anope::string &nick) anope_override { hybrid->SendSVSHold(nick); } + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); } void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :" << user->GetUID(); if (status) @@ -60,12 +60,11 @@ class PlexusProto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.modes.count(ModeManager::ChannelModes[i]->name)) - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -91,7 +90,7 @@ class PlexusProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* CAPAB * QS - Can handle quit storm removal * EX - Can do channel +e exemptions @@ -187,7 +186,7 @@ struct IRCDMessageEncap : IRCDMessage if (u && nc) { u->Login(nc); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } @@ -299,6 +298,7 @@ class ProtoPlexus : public Module Message::Away message_away; Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Kick message_kick; Message::Kill message_kill; Message::Mode message_mode; @@ -354,9 +354,9 @@ class ProtoPlexus : public Module } public: - ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_kick(this), message_kill(this), + message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), message_kill(this), message_mode(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), message_version(this), message_whois(this), @@ -368,7 +368,6 @@ class ProtoPlexus : public Module message_encap(this), message_pass(this), message_server(this), message_uid(this) { - this->SetAuthor("Anope"); if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK) throw ModuleException("Unable to load hybrid"); diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 247b8777a..2b971b23f 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -37,7 +37,7 @@ class RatboxProto : public IRCDProto void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); } void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); } void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); } - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); } + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); } void SendServer(const Server *server) anope_override { hybrid->SendServer(server); } void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override { hybrid->SendModeInternal(bi, u, buf); } void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); } @@ -45,7 +45,7 @@ class RatboxProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* QS - Can handle quit storm removal EX - Can do channel +e exemptions @@ -107,7 +107,7 @@ struct IRCDMessageEncap : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } @@ -134,7 +134,7 @@ struct IRCDMessageServer : IRCDMessage if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -185,6 +185,7 @@ class ProtoRatbox : public Module Message::Away message_away; Message::Capab message_capab; Message::Error message_error; + Message::Invite message_invite; Message::Kick message_kick; Message::Kill message_kill; Message::Mode message_mode; @@ -216,6 +217,7 @@ class ProtoRatbox : public Module /* user modes */ ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER")); ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("REGPRIV")); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'S')); /* v/h/o/a/q */ ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("HALFOP")); @@ -228,12 +230,12 @@ class ProtoRatbox : public Module } public: - ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_kick(this), message_kill(this), - message_mode(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), - message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), - message_version(this), message_whois(this), + message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), + message_kill(this), message_mode(this), message_motd(this), message_part(this), message_ping(this), + message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this), + message_topic(this), message_version(this), message_whois(this), message_bmask("IRCDMessage", "ratbox/bmask", "hybrid/bmask"), message_join("IRCDMessage", "ratbox/join", "hybrid/join"), message_nick("IRCDMessage", "ratbox/nick", "hybrid/nick"), message_pong("IRCDMessage", "ratbox/pong", "hybrid/pong"), @@ -242,7 +244,6 @@ class ProtoRatbox : public Module message_encap(this), message_pass(this), message_server(this), message_tburst(this), message_uid(this) { - this->SetAuthor("Anope"); if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK) throw ModuleException("Unable to load hybrid"); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 984277c14..4186ee5d0 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -13,6 +13,8 @@ #include "module.h" +static bool sasl = true; + class UnrealIRCdProto : public IRCDProto { public: @@ -44,18 +46,16 @@ class UnrealIRCdProto : public IRCDProto return; /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLineDel(x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } - UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << Config->OperServ; + UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by; } void SendTopic(BotInfo *whosets, Channel *c) anope_override @@ -108,16 +108,14 @@ class UnrealIRCdProto : public IRCDProto } /* ZLine if we can instead */ - try - { - if (x->GetUser() == "*") + if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos) + try { sockaddrs(x->GetHost()); IRCD->SendSZLine(u, x); return; } - } - catch (const SocketException &) { } + catch (const SocketException &) { } // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->expires - Anope::CurTime; @@ -147,14 +145,14 @@ class UnrealIRCdProto : public IRCDProto /* Unreal 3.2 actually sends some info about itself in the descript area */ void SendServer(const Server *server) anope_override { - if (!Config->Numeric.empty()) - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << Config->Numeric << " " << server->GetDescription(); + if (!server->GetSID().empty() && server == Me) + UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << server->GetSID() << " " << server->GetDescription(); else UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription(); } /* JOIN */ - void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override + void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->nick; if (status) @@ -166,12 +164,11 @@ class UnrealIRCdProto : public IRCDProto */ ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status.modes.clear(); + uc->status.Clear(); BotInfo *setter = BotInfo::Find(user->nick); - for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.modes.count(ModeManager::ChannelModes[i]->name)) - c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); } } @@ -230,24 +227,24 @@ class UnrealIRCdProto : public IRCDProto VL = Version Info NS = Config->Numeric Server */ - if (!Config->Numeric.empty()) - UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL"; - else - UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK"; - UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink]->password; + Anope::string protoctl = "NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL"; + if (!Me->GetSID().empty()) + protoctl += " VL"; + UplinkSocket::Message() << "PROTOCTL " << protoctl; + UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink].password; SendServer(Me); } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message() << "TKL + Q H " << nick << " " << Config->ServerName << " " << Anope::CurTime + Config->NSReleaseTimeout << " " << Anope::CurTime << " :Being held for registered user"; + UplinkSocket::Message() << "TKL + Q H " << nick << " " << Me->GetName() << " " << Anope::CurTime + t << " " << Anope::CurTime << " :Being held for registered user"; } /* SVSHOLD - release */ void SendSVSHoldDel(const Anope::string &nick) anope_override { - UplinkSocket::Message() << "TKL - Q * " << nick << " " << Config->ServerName; + UplinkSocket::Message() << "TKL - Q * " << nick << " " << Me->GetName(); } /* UNSGLINE */ @@ -262,7 +259,7 @@ class UnrealIRCdProto : public IRCDProto /* UNSZLINE */ void SendSZLineDel(const XLine *x) anope_override { - UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << Config->OperServ; + UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << x->by; } /* SZLINE */ @@ -384,7 +381,7 @@ class UnrealExtBan : public ChannelModeList public: UnrealExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } - bool Matches(const User *u, const Entry *e) anope_override + bool Matches(User *u, const Entry *e) anope_override { const Anope::string &mask = e->GetMask(); @@ -407,7 +404,7 @@ class UnrealExtBan : public ChannelModeList { ChanUserContainer *uc = c->FindUser(u); if (uc != NULL) - if (cm == NULL || uc->status.modes.count(cm->name)) + if (cm == NULL || uc->status.HasMode(cm->mchar)) return true; } } @@ -897,7 +894,7 @@ struct IRCDMessageSASL : IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { size_t p = params[1].find('!'); - if (!Config->NSSASL || p == Anope::string::npos) + if (!sasl || p == Anope::string::npos) return; if (params[2] == "S") @@ -1001,7 +998,7 @@ struct IRCDMessageServer : IRCDMessage else new Server(source.GetServer(), params[0], hops, params[2]); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -1050,15 +1047,8 @@ struct IRCDMessageSJoin : IRCDMessage /* Get prefixes from the nick */ for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));) { + sju.first.AddMode(ch); buf.erase(buf.begin()); - ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); - if (!cm) - { - Log(LOG_DEBUG) << "Received unknown mode prefix " << ch << " in SJOIN string"; - continue; - } - - sju.first.modes.insert(cm->name); } sju.second = User::Find(buf); @@ -1136,6 +1126,7 @@ class ProtoUnreal : public Module /* Core message handlers */ Message::Away message_away; Message::Error message_error; + Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; Message::Kill message_kill; @@ -1169,6 +1160,8 @@ class ProtoUnreal : public Module IRCDMessageTopic message_topic; IRCDMessageUmode2 message_umode2; + bool use_server_side_mlock; + void AddModes() { ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); @@ -1208,11 +1201,11 @@ class ProtoUnreal : public Module } public: - ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), + ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ircd_proto(this), - message_away(this), message_error(this), message_join(this), message_kick(this), message_kill(this), - message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this), - message_squit(this), message_stats(this), message_time(this), message_version(this), + message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this), + message_kill(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this), + message_quit(this), message_squit(this), message_stats(this), message_time(this), message_version(this), message_whois(this), message_capab(this), message_chghost(this), message_chgident(this), message_chgname(this), message_mode(this, "MODE"), @@ -1220,15 +1213,20 @@ class ProtoUnreal : public Module message_sasl(this), message_sdesc(this), message_sethost(this), message_setident(this), message_setname(this), message_server(this), message_sjoin(this), message_topic(this), message_umode2(this) { - this->SetAuthor("Anope"); this->AddModes(); - Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnUserNickChange(User *u, const Anope::string &) anope_override { u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); @@ -1238,7 +1236,7 @@ class ProtoUnreal : public Module void OnChannelCreate(Channel *c) anope_override { - if (Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0 && c->ci) + if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && c->ci) { Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes; @@ -1247,7 +1245,7 @@ class ProtoUnreal : public Module void OnChanRegistered(ChannelInfo *ci) anope_override { - if (!ci->c || !Config->UseServerSideMLock) + if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK")) return; Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -1255,7 +1253,7 @@ class ProtoUnreal : public Module void OnDelChan(ChannelInfo *ci) anope_override { - if (!ci->c || !Config->UseServerSideMLock) + if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK")) return; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :"; } @@ -1263,7 +1261,7 @@ class ProtoUnreal : public Module EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -1275,7 +1273,7 @@ class ProtoUnreal : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp index 2f157b809..bae03eb7e 100644 --- a/modules/pseudoclients/botserv.cpp +++ b/modules/pseudoclients/botserv.cpp @@ -16,16 +16,10 @@ class BotServCore : public Module { public: - BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR) { - this->SetAuthor("Anope"); - - BotServ = BotInfo::Find(Config->BotServ); - if (!BotServ) - throw ModuleException("No bot named " + Config->BotServ); - - Implementation i[] = { I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, - I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet }; + Implementation i[] = { I_OnReload, I_OnSetCorrectModes, I_OnBotAssign, I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, + I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet, I_OnCreateChan, I_OnUserKicked }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -34,6 +28,40 @@ class BotServCore : public Module BotServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (bsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(bsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + bsnick); + + BotServ = bi; + } + + void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool give_modes) anope_override + { + /* Do not allow removing bot modes on our service bots */ + if (chan->ci && chan->ci->bi == user) + { + const Anope::string &botmodes = Config->GetModule(this)->Get<const Anope::string>("botmodes"); + for (unsigned i = 0; i < botmodes.length(); ++i) + chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->bi->GetUID()); + } + } + + void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override + { + if (Me->IsSynced() && ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers")) + { + ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes")); + bi->Join(ci->c, &status); + } + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == BotServ) @@ -71,9 +99,7 @@ class BotServCore : public Module if (!realbuf.find(c->ci->bi->nick)) params.erase(params.begin()); - else if (Config->BSFantasyCharacter.empty()) - ; - else if (!realbuf.find_first_of(Config->BSFantasyCharacter)) + else if (!realbuf.find_first_of(Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!"))) params[0].erase(params[0].begin()); else return; @@ -159,6 +185,42 @@ class BotServCore : public Module void OnJoinChannel(User *user, Channel *c) anope_override { + if (!Config || !IRCD) + return; + + BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL; + if (bi && Config->GetModule(this)->Get<bool>("smartjoin")) + { + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN"); + + /* We check for bans */ + for (; bans.first != bans.second; ++bans.first) + { + Entry ban("BAN", bans.first->second); + if (ban.Matches(user)) + c->RemoveMode(NULL, "BAN", ban.GetMask()); + } + + Anope::string Limit; + unsigned limit = 0; + try + { + if (c->GetParam("LIMIT", Limit)) + limit = convertTo<unsigned>(Limit); + } + catch (const ConvertException &) { } + + /* Should we be invited? */ + if (c->HasMode("INVITE") || (limit && c->users.size() >= limit)) + { + ChannelMode *cm = ModeManager::FindChannelModeByName("OP"); + char symbol = cm ? anope_dynamic_static_cast<ChannelModeStatus *>(cm)->symbol : 0; + IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str()); + } + + ModeManager::ProcessModes(); + } + if (user->server != Me && c->ci && c->ci->bi) { /** @@ -167,8 +229,11 @@ class BotServCore : public Module * make it into the channel, leaving the channel botless even for * legit users - Rob **/ - if (c->users.size() >= Config->BSMinUsers && !c->FindUser(c->ci->bi)) - c->ci->bi->Join(c, &ModeManager::DefaultBotModes); + if (c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers") && !c->FindUser(c->ci->bi)) + { + ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes")); + c->ci->bi->Join(c, &status); + } /* Only display the greet if the main uplink we're connected * to has synced, or we'll get greet-floods when the net * recovers from a netsplit. -GD @@ -198,7 +263,7 @@ class BotServCore : public Module return; /* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */ - if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->BSMinUsers && c->FindUser(c->ci->bi)) + if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->GetModule(this)->Get<unsigned>("minusers") && c->FindUser(c->ci->bi)) c->ci->bi->Part(c->ci->c); } @@ -210,17 +275,18 @@ class BotServCore : public Module if (source.c) { source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n" - "Fantasy commands are tied to existing commands, usually on \002%s\002,\n" - "and provide a more convenient way to execute commands. Commands that\n" + "Fantasy commands are commands that can be executed from messaging a\n" + "channel, and provide a more convenient way to execute commands. Commands that\n" "require a channel as a parameter will automatically have that parameter\n" - "given.\n"), source.service->nick.c_str(), Config->ChanServ.c_str()); - if (!Config->BSFantasyCharacter.empty()) + "given.\n"), source.service->nick.c_str()); + const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!"); + if (!fantasycharacters.empty()) source.Reply(_(" \n" - "Fantasy commands may be prefixed with one of the following characters: %s\n"), Config->BSFantasyCharacter.c_str()); + "Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str()); source.Reply(_(" \n" "Available commands are:")); } - else if (source.service->nick == Config->BotServ) + else if (*source.service == BotServ) { source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n" "It has been created for users that can't host or\n" @@ -229,8 +295,8 @@ class BotServCore : public Module "below; to use them, type \002%s%s \037command\037\002. For\n" "more information on a specific command, type\n" "\002%s%s %s \037command\037\002.\n "), - Config->BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), - Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), source.command.c_str()); + BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), + Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str()); } return EVENT_CONTINUE; @@ -238,21 +304,22 @@ class BotServCore : public Module void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->BotServ) + if (!params.empty() || source.c || source.service != BotServ) return; source.Reply(_(" \n" "Bot will join a channel whenever there is at least\n" - "\002%d\002 user(s) on it."), Config->BSMinUsers); - if (!Config->BSFantasyCharacter.empty()) - source.Reply(_("Additionally, all %s commands can be used if fantasy\n" - "is enabled by prefixing the command name with one of\n" - "the following characters: %s"), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); + "\002%d\002 user(s) on it."), Config->GetModule(this)->Get<unsigned>("minusers")); + const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!"); + if (!fantasycharacters.empty()) + source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n" + "can be executed by prefixing the command name with\n" + "one of the following characters: %s"), fantasycharacters.c_str()); } EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (Config->BSSmartJoin && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) + if (Config->GetModule(this)->Get<bool>("smartjoin") && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) { BotInfo *bi = c->ci->bi; @@ -263,6 +330,26 @@ class BotServCore : public Module return EVENT_CONTINUE; } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + /* Set default bot flags */ + spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy")); + for (Anope::string token; sep.GetToken(token);) + this->ExtendMetadata("BS_" + token); + } + + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override + { + } + + void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override + { + BotInfo *bi = BotInfo::Find(target->nick); + if (bi) + /* Bots get rejoined */ + bi->Join(channel, &status); + } }; MODULE_INIT(BotServCore) diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 7b59c0597..a93271581 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -16,11 +16,13 @@ class ExpireCallback : public Timer { public: - ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { - if (!Config->CSExpire || Anope::NoExpire || Anope::ReadOnly) + time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d"); + + if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly) return; for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ) @@ -30,13 +32,13 @@ class ExpireCallback : public Timer bool expire = false; - if (Anope::CurTime - ci->last_used >= Config->CSExpire) + if (Anope::CurTime - ci->last_used >= chanserv_expire) { if (ci->c) { time_t last_used = ci->last_used; - for (User::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit) - ci->AccessFor((*cit)->user); + for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit) + ci->AccessFor(cit->second->user); expire = last_used == ci->last_used; } else @@ -62,20 +64,81 @@ class ExpireCallback : public Timer } }; +class MyChanServService : public ChanServService +{ + public: + MyChanServService(Module *m) : ChanServService(m) { } + + void Hold(Channel *c) anope_override + { + /** A timer used to keep the BotServ bot/ChanServ in the channel + * after kicking the last user in a channel + */ + class ChanServTimer : public Timer + { + Reference<Channel> c; + + public: + /** Constructor + * @param chan The channel + */ + ChanServTimer(Module *m, Channel *chan) : Timer(m, Config->GetModule(this->GetOwner())->Get<time_t>("inhabit", "15s")), c(chan) + { + if (!ChanServ || !c) + return; + c->Extend("INHABIT"); + if (!c->ci || !c->ci->bi) + ChanServ->Join(c); + else if (!c->FindUser(c->ci->bi)) + c->ci->bi->Join(c); + + /* Set +ntsi to prevent rejoin */ + c->SetMode(NULL, "NOEXTERNAL"); + c->SetMode(NULL, "TOPIC"); + c->SetMode(NULL, "SECRET"); + c->SetMode(NULL, "INVITE"); + } + + /** Called when the delay is up + * @param The current time + */ + void Tick(time_t) anope_override + { + if (!c) + return; + + c->Shrink("INHABIT"); + + if (!c->ci || !c->ci->bi) + { + if (ChanServ) + ChanServ->Part(c); + } + else + c->ci->bi->Part(c); + } + }; + + if (c->HasExt("INHABIT")) + return; + + new ChanServTimer(this->owner, c); + } +}; + class ChanServCore : public Module { + MyChanServService chanserv; ExpireCallback expires; + std::vector<Anope::string> defaults; public: - ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), expires(this) + ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), + chanserv(this), expires(this) { - this->SetAuthor("Anope"); - - ChanServ = BotInfo::Find(Config->ChanServ); - if (!ChanServ) - throw ModuleException("No bot named " + Config->ChanServ); - - Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp, I_OnCheckModes }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, + I_OnPreHelp, I_OnPostHelp, I_OnCheckModes, I_OnCreateChan, I_OnCanSet, + I_OnChannelSync, I_OnBotKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -84,6 +147,31 @@ class ChanServCore : public Module ChanServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &channick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (channick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(channick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + channick); + + ChanServ = bi; + + spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy")).GetTokens(defaults); + if (defaults.empty()) + { + defaults.push_back("KEEPTOPIC"); + defaults.push_back("SECURE"); + defaults.push_back("SECUREFOUNDER"); + defaults.push_back("SIGNKICK"); + } + else if (defaults[0].equals_ci("none")) + defaults.erase(defaults.begin()); + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == ChanServ) @@ -92,7 +180,7 @@ class ChanServCore : public Module EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->CSOpersOnly && bi == ChanServ && !u->HasMode("OPER")) + if (bi == ChanServ && Config->GetModule(this)->Get<bool>("operonly") && !u->HasMode("OPER")) { u->SendMessage(bi, ACCESS_DENIED); return EVENT_STOP; @@ -105,6 +193,7 @@ class ChanServCore : public Module { std::deque<ChannelInfo *> chans; nc->GetChannelReferences(chans); + int max_reg = Config->GetModule(this)->Get<int>("maxregistered"); for (unsigned i = 0; i < chans.size(); ++i) { @@ -113,7 +202,7 @@ class ChanServCore : public Module if (ci->GetFounder() == nc) { NickCore *newowner = NULL; - if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !Config->CSMaxReg || ci->GetSuccessor()->channelcount < Config->CSMaxReg)) + if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->channelcount < max_reg)) newowner = ci->GetSuccessor(); else { @@ -123,7 +212,7 @@ class ChanServCore : public Module const ChanAccess *ca = ci->GetAccess(j); const NickCore *anc = NickCore::Find(ca->mask); - if (!anc || (!anc->IsServicesOper() && Config->CSMaxReg && anc->channelcount >= Config->CSMaxReg) || (anc == nc)) + if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc)) continue; if (!highest || *ca > *highest) highest = ca; @@ -176,7 +265,7 @@ class ChanServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->ChanServ) + if (!params.empty() || source.c || source.service != ChanServ) return EVENT_CONTINUE; source.Reply(_("\002%s\002 allows you to register and control various\n" "aspects of channels. %s can often prevent\n" @@ -185,19 +274,20 @@ class ChanServCore : public Module "commands are listed below; to use them, type\n" "\002%s%s \037command\037\002. For more information on a\n" "specific command, type \002%s%s HELP \037command\037\002.\n "), - Config->ChanServ.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->ChanServ.c_str(), source.command.c_str()); + ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), source.command.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->ChanServ) + if (!params.empty() || source.c || source.service != ChanServ) return; - if (Config->CSExpire >= 86400) + time_t expire = Config->GetModule(this)->Get<time_t>("expire", "14d"); + if (expire >= 86400) source.Reply(_(" \n" "Note that any channel which is not used for %d days\n" "(i.e. which no user on the channel's access list enters\n" - "for that period of time) will be automatically dropped."), Config->CSExpire / 86400); + "for that period of time) will be automatically dropped."), expire / 86400); if (source.IsServicesOper()) source.Reply(_(" \n" "Services Operators can also, depending on their access drop\n" @@ -207,12 +297,84 @@ class ChanServCore : public Module EventReturn OnCheckModes(Channel *c) anope_override { - if (!Config->CSRequire.empty()) + const Anope::string &require = Config->GetModule(this)->Get<const Anope::string>("require", "r"); + if (!require.empty()) { if (c->ci) - c->SetModes(NULL, false, "+%s", Config->CSRequire.c_str()); + c->SetModes(NULL, false, "+%s", require.c_str()); else - c->SetModes(NULL, false, "-%s", Config->CSRequire.c_str()); + c->SetModes(NULL, false, "-%s", require.c_str()); + } + + return EVENT_CONTINUE; + } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2"); + + /* Set default chan flags */ + for (unsigned i = 0; i < defaults.size(); ++i) + this->ExtendMetadata(defaults[i]); + + { + Anope::string modes; + spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nrt")); + if (sep.GetToken(modes)) + { + bool add = true; + for (unsigned i = 0; i < modes.length(); ++i) + { + if (modes[i] == '+') + add = true; + else if (modes[i] == '-') + add = false; + else + { + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]); + Anope::string param; + if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param))) + ci->SetMLock(cm, add, param); + } + } + } + } + } + + EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_override + { + if (Config->GetModule(this)->Get<const Anope::string>("nomlock").find(cm->mchar) != Anope::string::npos + || Config->GetModule(this)->Get<const Anope::string>("require", "r").find(cm->mchar) || Anope::string::npos) + return EVENT_STOP; + return EVENT_CONTINUE; + } + + void OnChannelSync(Channel *c) anope_override + { + if (!c->HasMode("PERM") && (c->users.empty() || (c->users.size() == 1 && c->ci && c->ci->bi && *c->ci->bi == c->users.begin()->second->user))) + { + chanserv.Hold(c); + } + if (c->ci) + { + c->CheckModes(); + + if (Me && Me->IsSynced()) + c->ci->RestoreTopic(); + } + } + + EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason) + { + /* If the channel isn't syncing and doesn't have any users, join ChanServ + * Note that the user AND POSSIBLY the botserv bot exist here + * ChanServ always enforces channels like this to keep people from deleting bots etc + * that are holding channels. + */ + if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->HasExt("SYNCING")) + { + /* Join ChanServ and set a timer for this channel to part ChanServ later */ + chanserv.Hold(c); } return EVENT_CONTINUE; diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp index 62a3d1609..67cb594c5 100644 --- a/modules/pseudoclients/global.cpp +++ b/modules/pseudoclients/global.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "global.h" class MyGlobalService : public GlobalService { @@ -34,30 +33,24 @@ class MyGlobalService : public GlobalService Anope::string rmessage; - if (!source.empty() && !Config->AnonymousGlobal) + if (!source.empty() && !Config->GetModule("global")->Get<bool>("anonymousglobal")) rmessage = "[" + source + "] " + message; else rmessage = message; - this->ServerGlobal(sender, Me->GetLinks().front(), rmessage); + this->ServerGlobal(sender, Servers::GetUplink(), rmessage); } }; class GlobalCore : public Module { - MyGlobalService myglobalservice; + MyGlobalService global; public: - GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - myglobalservice(this) + GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), + global(this) { - this->SetAuthor("Anope"); - - Global = BotInfo::Find(Config->Global); - if (!Global) - throw ModuleException("No bot named " + Config->Global); - - Implementation i[] = { I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -66,6 +59,20 @@ class GlobalCore : public Module Global = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &glnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (glnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(glnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + glnick); + + Global = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == Global) @@ -74,27 +81,30 @@ class GlobalCore : public Module void OnRestart() anope_override { - if (Config->GlobalOnCycle) - this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown"); + if (!gl.empty()) + this->global.SendGlobal(Global, "", gl); } void OnShutdown() anope_override { - if (Config->GlobalOnCycle) - this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycledown"); + if (!gl.empty()) + this->global.SendGlobal(Global, "", gl); } void OnNewServer(Server *s) anope_override { - if (Config->GlobalOnCycle && !Config->GlobalOnCycleUP.empty()) - s->Notice(Global, Config->GlobalOnCycleUP); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string>("globaloncycleup"); + if (!gl.empty() && !Me->IsSynced()) + s->Notice(Global, gl); } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->Global) + if (!params.empty() || source.c || source.service != Global) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->Global.c_str()); + source.Reply(_("%s commands:"), Global->nick.c_str()); return EVENT_CONTINUE; } }; diff --git a/modules/pseudoclients/global.h b/modules/pseudoclients/global.h deleted file mode 100644 index fccd96558..000000000 --- a/modules/pseudoclients/global.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef GLOBAL_H -#define GLOBAL_H - -class GlobalService : public Service -{ - public: - GlobalService(Module *m) : Service(m, "GlobalService", "Global") { } - - /** Send out a global message to all users - * @param sender Our client which should send the global - * @param source The sender of the global - * @param message The message - */ - virtual void SendGlobal(const BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0; -}; - -#endif // GLOBAL_H - diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp index f11526e7a..cd3c84d55 100644 --- a/modules/pseudoclients/hostserv.cpp +++ b/modules/pseudoclients/hostserv.cpp @@ -16,18 +16,13 @@ class HostServCore : public Module { public: - HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR) { - this->SetAuthor("Anope"); if (!IRCD || !IRCD->CanSetVHost) throw ModuleException("Your IRCd does not support vhosts"); - HostServ = BotInfo::Find(Config->HostServ); - if (!HostServ) - throw ModuleException("No bot named " + Config->HostServ); - - Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -36,6 +31,20 @@ class HostServCore : public Module HostServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &hsnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (hsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(hsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + hsnick); + + HostServ = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == HostServ) @@ -77,9 +86,9 @@ class HostServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->HostServ) + if (!params.empty() || source.c || source.service != HostServ) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->HostServ.c_str()); + source.Reply(_("%s commands:"), HostServ->nick.c_str()); return EVENT_CONTINUE; } }; diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp index 73dd48b94..1988961cd 100644 --- a/modules/pseudoclients/memoserv.cpp +++ b/modules/pseudoclients/memoserv.cpp @@ -12,24 +12,23 @@ /*************************************************************************/ #include "module.h" -#include "memoserv.h" static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m) { - Anope::string subject = Language::Translate(nc, Config->MailMemoSubject.c_str()); - Anope::string message = Language::Translate(nc, Config->MailMemoMessage.c_str()); + Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()), + message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str()); subject = subject.replace_all_cs("%n", nc->display); subject = subject.replace_all_cs("%s", m->sender); subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); subject = subject.replace_all_cs("%t", m->text); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); message = message.replace_all_cs("%n", nc->display); message = message.replace_all_cs("%s", m->sender); message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); message = message.replace_all_cs("%t", m->text); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); return Mail::Send(nc, subject, message); } @@ -50,7 +49,8 @@ class MyMemoServService : public MemoServService User *sender = User::Find(source); if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force) { - if (Config->MSSendDelay > 0 && sender->lastmemosend + Config->MSSendDelay > Anope::CurTime) + time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); + if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime) return MEMO_TOO_FAST; else if (!mi->memomax) return MEMO_TARGET_FULL; @@ -81,12 +81,12 @@ class MyMemoServService : public MemoServService { for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - ChanUserContainer *cu = *it; + ChanUserContainer *cu = it->second; if (ci->AccessFor(cu->user).HasPriv("MEMO")) { if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE")) - cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos->size()); + cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size()); } } } @@ -102,7 +102,7 @@ class MyMemoServService : public MemoServService const NickAlias *na = nc->aliases->at(i); User *user = User::Find(na->nick); if (user && user->IsIdentified()) - user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), mi->memos->size()); + user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size()); } } @@ -138,18 +138,12 @@ class MyMemoServService : public MemoServService class MemoServCore : public Module { - MyMemoServService mymemoserv; + MyMemoServService memoserv; public: - MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - mymemoserv(this) + MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), + memoserv(this) { - this->SetAuthor("Anope"); - - MemoServ = BotInfo::Find(Config->MemoServ); - if (!MemoServ) - throw ModuleException("No bot named " + Config->MemoServ); - - Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; + Implementation i[] = { I_OnNickCoreCreate, I_OnCreateChan, I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -158,6 +152,30 @@ class MemoServCore : public Module MemoServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (msnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(msnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + msnick); + + MemoServ = bi; + } + + void OnNickCoreCreate(NickCore *nc) anope_override + { + nc->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos"); + } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + ci->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos"); + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == MemoServ) @@ -166,12 +184,12 @@ class MemoServCore : public Module void OnNickIdentify(User *u) anope_override { - this->mymemoserv.Check(u); + this->memoserv.Check(u); } void OnJoinChannel(User *u, Channel *c) anope_override { - if (c->ci && c->ci->AccessFor(u).HasPriv("MEMO") && c->ci->memos.memos->size() > 0) + if (c->ci && !c->ci->memos.memos->empty() && c->ci->AccessFor(u).HasPriv("MEMO")) { if (c->ci->memos.memos->size() == 1) u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str()); @@ -183,37 +201,37 @@ class MemoServCore : public Module void OnUserAway(User *u, const Anope::string &message) anope_override { if (message.empty()) - this->mymemoserv.Check(u); + this->memoserv.Check(u); } void OnNickUpdate(User *u) anope_override { - this->mymemoserv.Check(u); + this->memoserv.Check(u); } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->MemoServ) + if (!params.empty() || source.c || source.service != MemoServ) return EVENT_CONTINUE; source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n" "messages to other IRC users, whether they are online at\n" "the time or not, or to channels(*). Both the sender's\n" "nickname and the target nickname or channel must be\n" "registered in order to send a memo.\n" - "%s's commands include:"), Config->MemoServ.c_str(), Config->MemoServ.c_str()); + "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->MemoServ) + if (!params.empty() || source.c || source.service != MemoServ) return; source.Reply(_(" \n" "Type \002%s%s HELP \037command\037\002 for help on any of the\n" "above commands.\n" "(*) By default, any user with at least level 10 access on a\n" " channel can read that channel's memos. This can be\n" - " changed with the %s \002LEVELS\002 command."), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), Config->ChanServ.c_str()); + " changed with the %s \002LEVELS\002 command."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ChanServ->nick.c_str()); } }; diff --git a/modules/pseudoclients/memoserv.h b/modules/pseudoclients/memoserv.h deleted file mode 100644 index 71ca064de..000000000 --- a/modules/pseudoclients/memoserv.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef MEMOSERV_H -#define MEMOSERV_H - -class MemoServService : public Service -{ - public: - enum MemoResult - { - MEMO_SUCCESS, - MEMO_INVALID_TARGET, - MEMO_TOO_FAST, - MEMO_TARGET_FULL - }; - - MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ") { } - - /** Sends a memo. - * @param source The source of the memo, can be anythin. - * @param target The target of the memo, nick or channel. - * @param message Memo text - * @param force true to force the memo, restrictions/delays etc are not checked - */ - virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force = false) = 0; - - /** Check for new memos and notify the user if there are any - * @param u The user - */ - virtual void Check(User *u) = 0; -}; - -#endif // MEMOSERV_H - diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp index e221c19c0..e45ad6abf 100644 --- a/modules/pseudoclients/nickserv.cpp +++ b/modules/pseudoclients/nickserv.cpp @@ -12,7 +12,6 @@ /*************************************************************************/ #include "module.h" -#include "nickserv.h" class NickServCollide; @@ -98,15 +97,15 @@ class MyNickServService : public NickServService return; } - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) return; if (u->IsRecognized(false) || !na->nc->HasExt("KILL_IMMED")) { if (na->nc->HasExt("SECURE")) - u->SendMessage(NickServ, NICK_IS_SECURE, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); else - u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); } if (na->nc->HasExt("KILLPROTECT") && !u->IsRecognized(false)) @@ -118,13 +117,15 @@ class MyNickServService : public NickServService } else if (na->nc->HasExt("KILL_QUICK")) { - u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKillQuick, u->Account()).c_str()); - new NickServCollide(u, Config->NSKillQuick); + time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "60s"); + u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str()); + new NickServCollide(u, killquick); } else { - u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKill, u->Account()).c_str()); - new NickServCollide(u, Config->NSKill); + time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "20s"); + u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str()); + new NickServCollide(u, kill); } } @@ -134,7 +135,7 @@ class MyNickServService : public NickServService { const NickAlias *u_na = NickAlias::Find(user->nick); user->Login(na->nc); - if (u_na && *u_na->nc == *na->nc && !Config->NoNicknameOwnership && na->nc->HasExt("UNCONFIRMED") == false) + if (u_na && *u_na->nc == *na->nc && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false) user->SetMode(NickServ, "REGISTERED"); } }; @@ -142,13 +143,16 @@ class MyNickServService : public NickServService class ExpireCallback : public Timer { public: - ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { if (Anope::NoExpire || Anope::ReadOnly) return; + time_t unconfirmed_expire = Config->GetModule(this->GetOwner())->Get<time_t>("unconfirmedexpire", "1d"); + time_t nickserv_expire = Config->GetModule(this->GetOwner())->Get<time_t>("expire"); + for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ) { NickAlias *na = it->second; @@ -161,9 +165,9 @@ class ExpireCallback : public Timer bool expire = false; if (na->nc->HasExt("UNCONFIRMED")) - if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire) + if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire) expire = true; - if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire) + if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire) expire = true; if (na->HasExt("NO_EXPIRE")) expire = false; @@ -185,20 +189,16 @@ class ExpireCallback : public Timer class NickServCore : public Module { - MyNickServService mynickserv; + MyNickServService nickserv; ExpireCallback expires; + std::vector<Anope::string> defaults; public: - NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), mynickserv(this), expires(this) + NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), nickserv(this), expires(this) { - this->SetAuthor("Anope"); - - NickServ = BotInfo::Find(Config->NickServ); - if (!NickServ) - throw ModuleException("No bot named " + Config->NickServ); - - Implementation i[] = { I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, - I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, + I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, + I_OnNickCoreCreate, I_OnUserQuit }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -207,6 +207,28 @@ class NickServCore : public Module NickServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &nsnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (nsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(nsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + nsnick); + + NickServ = bi; + + spacesepstream(conf->GetModule(this)->Get<const Anope::string>("defaults", "secure memo_signon memo_receive")).GetTokens(defaults); + if (defaults.empty()) + { + defaults.push_back("SECURE"); + defaults.push_back("MEMO_SIGNON"); + defaults.push_back("MEMO_RECEIVE"); + } + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == NickServ) @@ -247,33 +269,36 @@ class NickServCore : public Module void OnNickIdentify(User *u) anope_override { - if (!Config->NoNicknameOwnership) + Configuration::Block *block = Config->GetModule(this); + + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership")) { const NickAlias *this_na = NickAlias::Find(u->nick); if (this_na && this_na->nc == u->Account() && u->Account()->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } - if (Config->NSModeOnID) + if (block->Get<bool>("modeonid", "yes")) for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) { - ChanUserContainer *cc = *it; + ChanUserContainer *cc = it->second; Channel *c = cc->chan; if (c) c->SetCorrectModes(u, true, true); } - if (!Config->NSModesOnID.empty()) - u->SetModes(NickServ, "%s", Config->NSModesOnID.c_str()); + const Anope::string &modesonid = block->Get<const Anope::string>("modesonid"); + if (!modesonid.empty()) + u->SetModes(NickServ, "%s", modesonid.c_str()); - if (Config->NSForceEmail && u->Account()->email.empty()) + if (block->Get<bool>("forceemail") && u->Account()->email.empty()) { u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n" "This e-mail will allow you to retrieve your password in\n" "case you forget it.")); u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n" "Your privacy is respected; this e-mail won't be given to\n" - "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + "any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); } if (u->Account()->HasExt("UNCONFIRMED")) @@ -281,8 +306,9 @@ class NickServCore : public Module u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered.")); const NickAlias *this_na = NickAlias::Find(u->Account()->display); time_t time_registered = Anope::CurTime - this_na->time_registered; - if (Config->NSUnconfirmedExpire > time_registered) - u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(Config->NSUnconfirmedExpire - time_registered).c_str()); + time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d"); + if (unconfirmed_expire > time_registered) + u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(unconfirmed_expire - time_registered).c_str()); } } @@ -296,7 +322,7 @@ class NickServCore : public Module { for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) { - ChanUserContainer *cc = *it; + ChanUserContainer *cc = it->second; Channel *c = cc->chan; if (c) c->SetCorrectModes(u, true, true); @@ -309,10 +335,11 @@ class NickServCore : public Module return; const NickAlias *na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && !na) - u->SendMessage(NickServ, Config->NSUnregisteredNotice); + const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string>("unregistered_notice"); + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na) + u->SendMessage(NickServ, unregistered_notice); else if (na) - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } void OnPostUserLogoff(User *u) anope_override @@ -328,7 +355,7 @@ class NickServCore : public Module { User *u = it->second; if (u->server == s && !u->IsIdentified()) - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } } @@ -341,13 +368,13 @@ class NickServCore : public Module /* Remove +r, but keep an account associated with the user */ u->RemoveMode(NickServ, "REGISTERED"); - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } else { /* Reset +r and re-send account (even though it really should be set at this point) */ IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display; } @@ -364,45 +391,67 @@ class NickServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->NickServ) + if (!params.empty() || source.c || source.service != NickServ) return EVENT_CONTINUE; - if (!Config->NoNicknameOwnership) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership")) source.Reply(_("\002%s\002 allows you to register a nickname and\n" "prevent others from using it. The following\n" "commands allow for registration and maintenance of\n" "nicknames; to use them, type \002%s%s \037command\037\002.\n" "For more information on a specific command, type\n" - "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str()); else source.Reply(_("\002%s\002 allows you to register an account.\n" "The following commands allow for registration and maintenance of\n" "accounts; to use them, type \002%s%s \037command\037\002.\n" "For more information on a specific command, type\n" - "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->NickServ) + if (!params.empty() || source.c || source.service != NickServ) return; if (source.IsServicesOper()) source.Reply(_(" \n" "Services Operators can also drop any nickname without needing\n" "to identify for the nick, and may view the access list for\n" "any nickname.")); - if (Config->NSExpire >= 86400) + time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire"); + if (nickserv_expire >= 86400) source.Reply(_(" \n" "Accounts that are not used anymore are subject to \n" "the automatic expiration, i.e. they will be deleted\n" - "after %d days if not used."), Config->NSExpire / 86400); + "after %d days if not used."), nickserv_expire / 86400); source.Reply(_(" \n" "\002NOTICE:\002 This service is intended to provide a way for\n" "IRC users to ensure their identity is not compromised.\n" "It is \002NOT\002 intended to facilitate \"stealing\" of\n" "nicknames or other malicious actions. Abuse of %s\n" "will result in, at minimum, loss of the abused\n" - "nickname(s)."), Config->NickServ.c_str()); + "nickname(s)."), NickServ->nick.c_str()); + } + + void OnNickCoreCreate(NickCore *nc) + { + /* Set default flags */ + for (unsigned i = 0; i < defaults.size(); ++i) + this->ExtendMetadata(defaults[i].upper()); + } + + void OnUserQuit(User *u, const Anope::string &msg) + { + if (u->server && !u->server->GetQuitReason().empty() && Config->GetModule(this)->Get<bool>("hidenetsplitquit")) + return; + + /* Update last quit and last seen for the user */ + NickAlias *na = NickAlias::Find(u->nick); + if (na && !na->nc->HasExt("SUSPENDED") && (u->IsRecognized() || u->IsIdentified(true))) + { + na->last_seen = Anope::CurTime; + na->last_quit = msg; + } } }; diff --git a/modules/pseudoclients/nickserv.h b/modules/pseudoclients/nickserv.h deleted file mode 100644 index 63923de2b..000000000 --- a/modules/pseudoclients/nickserv.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NICKSERV_H -#define NICKSERV_H - -class NickServService : public Service -{ - public: - NickServService(Module *m) : Service(m, "NickServService", "NickServ") { } - - virtual void Validate(User *u) = 0; - virtual void Login(User *u, NickAlias *na) = 0; -}; - -#endif // NICKSERV_H - diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 10908ef03..0720110cb 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -35,19 +35,7 @@ class SGLineManager : public XLineManager void SendDel(XLine *x) anope_override { - try - { - if (!IRCD->CanSZLine) - throw SocketException("SZLine is not supported"); - else if (x->GetUser() != "*") - throw SocketException("Can not ZLine a username"); - sockaddrs(x->GetHost()); - IRCD->SendSZLineDel(x); - } - catch (const SocketException &) - { - IRCD->SendAkillDel(x); - } + IRCD->SendAkillDel(x); } bool Check(User *u, const XLine *x) anope_override @@ -70,7 +58,7 @@ class SGLineManager : public XLineManager if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal())) return false; - if (!x->GetHost().empty()) + if (x->GetHost().find('/') != Anope::string::npos) { try { @@ -82,7 +70,7 @@ class SGLineManager : public XLineManager catch (const SocketException &) { } } - if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost())) + if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip, x->GetHost())) return true; return false; @@ -170,16 +158,10 @@ class OperServCore : public Module SNLineManager snlines; public: - OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), sglines(this), sqlines(this), snlines(this) { - this->SetAuthor("Anope"); - - OperServ = BotInfo::Find(Config->OperServ); - if (!OperServ) - throw ModuleException("No bot named " + Config->OperServ); - - Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); /* Yes, these are in this order for a reason. Most violent->least violent. */ @@ -201,6 +183,20 @@ class OperServCore : public Module XLineManager::UnregisterXLineManager(&snlines); } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &osnick = conf->GetModule(this)->Get<const Anope::string>("client"); + + if (osnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(osnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + osnick); + + OperServ = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == OperServ) @@ -209,10 +205,10 @@ class OperServCore : public Module EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->OSOpersOnly && !u->HasMode("OPER") && bi->nick == Config->OperServ) + if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly")) { u->SendMessage(bi, ACCESS_DENIED); - Log(OperServ, "bados") << "Denied access to " << Config->OperServ << " from " << u->GetMask() << " (non-oper)"; + Log(OperServ, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)"; return EVENT_STOP; } @@ -256,9 +252,9 @@ class OperServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->OperServ) + if (!params.empty() || source.c || source.service != OperServ) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->OperServ.c_str()); + source.Reply(_("%s commands:"), OperServ->nick.c_str()); return EVENT_CONTINUE; } }; |