From b9e99da4dafd836e995970216835cefe3716a01a Mon Sep 17 00:00:00 2001 From: brain Date: Tue, 29 Aug 2006 18:26:55 +0000 Subject: Snomask support cometh! and it leave a sticky white mess all over the floor :( git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@5062 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/inspircd.h | 7 +++++- include/snomasks.h | 10 +++++++- include/users.h | 7 ++++-- src/inspircd.cpp | 1 + src/modes/umode_n.cpp | 10 ++++++-- src/modules/m_globops.cpp | 46 ++++++------------------------------ src/snomasks.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++ src/users.cpp | 28 +++++++++++++++------- 8 files changed, 115 insertions(+), 53 deletions(-) diff --git a/include/inspircd.h b/include/inspircd.h index 965cf44fc..dfc36a720 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -25,9 +25,9 @@ #include "channels.h" #include "socket.h" #include "mode.h" - #include "socketengine.h" #include "command_parse.h" +#include "snomasks.h" /** Returned by some functions to indicate failure, * and the exit code of the program if it terminates. @@ -373,6 +373,11 @@ class InspIRCd : public classbase */ ServerConfig* Config; + /** Snomask manager - handles routing of snomask messages + * to opers. + */ + SnomaskManager* SNO; + /** Client list, a hash_map containing all clients, local and remote */ user_hash clientlist; diff --git a/include/snomasks.h b/include/snomasks.h index ab8980c26..a6ee0d050 100644 --- a/include/snomasks.h +++ b/include/snomasks.h @@ -19,18 +19,26 @@ #include #include +#include #include "configreader.h" #include "inspircd.h" +typedef std::map SnoList; + class SnomaskManager : public Extensible { private: InspIRCd* ServerInstance; + SnoList SnoMasks; public: SnomaskManager(InspIRCd* Instance); ~SnomaskManager(); - + bool EnableSnomask(char letter, const std::string &description); + bool DisableSnomask(char letter); + void WriteToSnoMask(char letter, const std::string &text); + void WriteToSnoMask(char letter, const char* text, ...); + bool IsEnabled(char letter); }; #endif diff --git a/include/users.h b/include/users.h index 83ea9bf3f..731cb785a 100644 --- a/include/users.h +++ b/include/users.h @@ -46,6 +46,7 @@ enum UserModes { UM_WALLOPS = 'w'-65, UM_INVISIBLE = 'i'-65, UM_OPERATOR = 'o'-65, + UM_SNOMASK = 'n'-65, }; enum RegistrationState { @@ -372,9 +373,11 @@ class userrec : public connection /** Process a snomask modifier string, e.g. +abc-de * @param sm A sequence of notice mask characters - * @return True if the notice masks were successfully applied + * @return The cleaned mode sequence which can be output, + * e.g. in the above example if masks c and e are not + * valid, this function will return +ab-d */ - bool userrec::ProcessNoticeMasks(const char *sm); + std::string userrec::ProcessNoticeMasks(const char *sm); /** Returns true if a notice mask is set * @param sm A notice mask character to check diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 79ae8b7bc..328306744 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -183,6 +183,7 @@ InspIRCd::InspIRCd(int argc, char** argv) factory.resize(255); this->Config = new ServerConfig(this); + this->SNO = new SnomaskManager(this); this->Start(); this->TIME = this->OLDTIME = this->startup_time = time(NULL); srand(this->TIME); diff --git a/src/modes/umode_n.cpp b/src/modes/umode_n.cpp index e3370fa56..7bb8dbbf0 100644 --- a/src/modes/umode_n.cpp +++ b/src/modes/umode_n.cpp @@ -15,12 +15,18 @@ ModeAction ModeUserServerNoticeMask::OnModeChange(userrec* source, userrec* dest return MODEACTION_DENY; /* Set the bitfields */ - if (dest->modes[UM_SERVERNOTICE] != adding) + if (adding) { - dest->modes[UM_SERVERNOTICE] = adding; + parameter = dest->ProcessNoticeMasks(parameter.c_str()); + return MODEACTION_ALLOW; + } + else if (dest->modes[UM_SNOMASK] != false) + { + dest->modes[UM_SNOMASK] = false; return MODEACTION_ALLOW; } /* Allow the change */ return MODEACTION_DENY; } + diff --git a/src/modules/m_globops.cpp b/src/modules/m_globops.cpp index 77a35294a..f0a879d4b 100644 --- a/src/modules/m_globops.cpp +++ b/src/modules/m_globops.cpp @@ -32,76 +32,44 @@ using namespace std; class cmd_globops : public command_t { public: - cmd_globops (InspIRCd* Instance) : command_t(Instance,"GLOBOPS",'o',1) + cmd_globops (InspIRCd* Instance) : command_t(Instance,"GLOBOPS",'o',1) { this->source = "m_globops.so"; syntax = ""; } - + void Handle (const char** parameters, int pcnt, userrec *user) { - std::string line = "*** GLOBOPS - From " + std::string(user->nick) + ": "; + std::string line = "From " + std::string(user->nick) + ": "; for (int i = 0; i < pcnt; i++) { line = line + std::string(parameters[i]) + " "; } - ServerInstance->WriteMode("og",WM_AND,line.c_str()); + ServerInstance->SNO->WriteToSnoMask('g',line); } }; -class ModeGlobops : public ModeHandler -{ - public: - ModeGlobops(InspIRCd* Instance) : ModeHandler(Instance, 'g', 0, 0, false, MODETYPE_USER, true) { } - - ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('g')) - { - dest->SetMode('P',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('g')) - { - dest->SetMode('P',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } -}; - - class ModuleGlobops : public Module { cmd_globops* mycommand; - ModeGlobops* mg; public: ModuleGlobops(InspIRCd* Me) : Module::Module(Me) { - - mg = new ModeGlobops(ServerInstance); - ServerInstance->AddMode(mg, 'g'); mycommand = new cmd_globops(ServerInstance); ServerInstance->AddCommand(mycommand); + ServerInstance->SNO->EnableSnomask('g',"GLOBOPS"); } virtual ~ModuleGlobops() { + ServerInstance->SNO->DisableSnomask('g'); DELETE(mycommand); - DELETE(mg); } virtual Version GetVersion() { - return Version(1,0,0,1,VF_STATIC|VF_VENDOR); + return Version(1,0,0,1,VF_VENDOR); } void Implements(char* List) diff --git a/src/snomasks.cpp b/src/snomasks.cpp index 6750ebcc6..650403a53 100644 --- a/src/snomasks.cpp +++ b/src/snomasks.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "configreader.h" #include "users.h" #include "modules.h" @@ -25,9 +26,67 @@ SnomaskManager::SnomaskManager(InspIRCd* Instance) : ServerInstance(Instance) { + SnoMasks.clear(); } SnomaskManager::~SnomaskManager() { } +bool SnomaskManager::EnableSnomask(char letter, const std::string &type) +{ + if (SnoMasks.find(letter) == SnoMasks.end()) + { + SnoMasks[letter] = type; + return true; + } + return false; +} + +bool SnomaskManager::DisableSnomask(char letter) +{ + SnoList::iterator n = SnoMasks.find(letter); + if (n != SnoMasks.end()) + { + SnoMasks.erase(n); + return true; + } + return false; +} + +void SnomaskManager::WriteToSnoMask(char letter, const std::string &text) +{ + /* Only send to snomask chars which are enabled */ + SnoList::iterator n = SnoMasks.find(letter); + if (n != SnoMasks.end()) + { + /* Only opers can receive snotices, so we iterate the oper list */ + for (std::vector::iterator i = ServerInstance->all_opers.begin(); i != ServerInstance->all_opers.end(); i++) + { + userrec* a = *i; + if (IS_LOCAL(a) && a->modes[UM_SERVERNOTICE] && a->modes[UM_SNOMASK] && a->IsNoticeMaskSet(n->first)) + { + /* send server notices to all with +ns */ + a->WriteServ("NOTICE %s :*** %s: %s",a->nick, n->second.c_str(), text.c_str()); + } + } + } +} + +void SnomaskManager::WriteToSnoMask(char letter, const char* text, ...) +{ + char textbuffer[MAXBUF]; + va_list argsPtr; + + va_start(argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + + this->WriteToSnoMask(letter, std::string(textbuffer)); +} + +bool SnomaskManager::IsEnabled(char letter) +{ + return (SnoMasks.find(letter) != SnoMasks.end()); +} + diff --git a/src/users.cpp b/src/users.cpp index 09a8c37a5..27eb0a1f6 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -92,10 +92,11 @@ bool DoneClassesAndTypes(ServerConfig* conf, const char* tag) return true; } -bool userrec::ProcessNoticeMasks(const char *sm) +std::string userrec::ProcessNoticeMasks(const char *sm) { - bool adding = true; + bool adding = true, oldadding = false; const char *c = sm; + std::string output = ""; while (c && *c) { @@ -103,20 +104,31 @@ bool userrec::ProcessNoticeMasks(const char *sm) { case '+': adding = true; - break; + break; case '-': adding = false; - break; + break; default: - if ((*c >= 'A') && (*c <= 'z')) - this->SetNoticeMask(*c, adding); - break; + if ((*c >= 'A') && (*c <= 'z') && (ServerInstance->SNO->IsEnabled(*c))) + { + if ((IsNoticeMaskSet(*c) && adding) || (!IsNoticeMaskSet(*c) && !adding)) + { + if ((oldadding != adding) || (sm == c)) + output += (adding ? '+' : '-'); + + this->SetNoticeMask(*c, adding); + + output += *c; + } + } + oldadding = adding; + break; } *c++; } - return true; + return output; } void userrec::StartDNSLookup() -- cgit v1.2.3