X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_customprefix.cpp;h=53b0376b241a353eeb8f5eaeb72df41ef18064a4;hb=80e81e3b81b779901fd9d67f8ae030ee30c0bcec;hp=97c2e697d98e8c85457737e1c79d84886facd480;hpb=26e7bb0b9a17a595d9935a1cae41b44504ad213e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_customprefix.cpp b/src/modules/m_customprefix.cpp index 97c2e697d..53b0376b2 100644 --- a/src/modules/m_customprefix.cpp +++ b/src/modules/m_customprefix.cpp @@ -1,6 +1,9 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2013-2014 Attila Molnar + * Copyright (C) 2013, 2017-2018 Sadie Powell + * Copyright (C) 2012, 2019 Robby * Copyright (C) 2010 Daniel De Graaf * * This file is part of InspIRCd. InspIRCd is free software: you can @@ -19,77 +22,23 @@ #include "inspircd.h" -/* $ModDesc: Allows custom prefix modes to be created. */ - -class CustomPrefixMode : public ModeHandler +class CustomPrefixMode : public PrefixMode { public: reference tag; - int rank; - bool depriv; - CustomPrefixMode(Module* parent, ConfigTag* Tag) - : ModeHandler(parent, Tag->getString("name"), 0, PARAM_ALWAYS, MODETYPE_CHANNEL), tag(Tag) - { - list = true; - m_paramtype = TR_NICK; - std::string v = tag->getString("prefix"); - prefix = v.c_str()[0]; - v = tag->getString("letter"); - mode = v.c_str()[0]; - rank = tag->getInt("rank"); - levelrequired = tag->getInt("ranktoset", rank); - depriv = tag->getBool("depriv", true); - } - - unsigned int GetPrefixRank() - { - return rank; - } - ModResult AccessCheck(User* src, Channel*, std::string& value, bool adding) + CustomPrefixMode(Module* parent, const std::string& Name, char Letter, char Prefix, ConfigTag* Tag) + : PrefixMode(parent, Name, Letter, 0, Prefix) + , tag(Tag) { - if (!adding && src->nick == value && depriv) - return MOD_RES_ALLOW; - return MOD_RES_PASSTHRU; - } - - void RemoveMode(Channel* channel, irc::modestacker* stack) - { - const UserMembList* cl = channel->GetUsers(); - std::vector mode_junk; - mode_junk.push_back(channel->name); - irc::modestacker modestack(false); - std::vector stackresult; - - for (UserMembCIter i = cl->begin(); i != cl->end(); i++) - { - if (i->second->hasMode(mode)) - { - if (stack) - stack->Push(this->GetModeChar(), i->first->nick); - else - modestack.Push(this->GetModeChar(), i->first->nick); - } - } - - if (stack) - return; - - while (modestack.GetStackedLine(stackresult)) - { - mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end()); - ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient); - mode_junk.erase(mode_junk.begin() + 1, mode_junk.end()); - } - } - - void RemoveMode(User* user, irc::modestacker* stack) - { - } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - return MODEACTION_ALLOW; + unsigned long rank = tag->getUInt("rank", 0, 0, UINT_MAX); + unsigned long setrank = tag->getUInt("ranktoset", prefixrank, rank, UINT_MAX); + unsigned long unsetrank = tag->getUInt("ranktounset", setrank, setrank, UINT_MAX); + bool depriv = tag->getBool("depriv", true); + this->Update(rank, setrank, unsetrank, depriv); + + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Created the %s prefix: letter=%c prefix=%c rank=%u ranktoset=%u ranktounset=%i depriv=%d", + name.c_str(), GetModeChar(), GetPrefix(), GetPrefixRank(), GetLevelRequired(true), GetLevelRequired(false), CanSelfRemove()); } }; @@ -97,39 +46,67 @@ class ModuleCustomPrefix : public Module { std::vector modes; public: - void init() + void init() CXX11_OVERRIDE { ConfigTagList tags = ServerInstance->Config->ConfTags("customprefix"); - while (tags.first != tags.second) + for (ConfigIter iter = tags.first; iter != tags.second; ++iter) { - ConfigTag* tag = tags.first->second; - tags.first++; - CustomPrefixMode* mh = new CustomPrefixMode(this, tag); - modes.push_back(mh); - if (mh->rank <= 0) - throw ModuleException("Rank must be specified for prefix at " + tag->getTagLocation()); - if (!isalpha(mh->GetModeChar())) - throw ModuleException("Mode must be a letter for prefix at " + tag->getTagLocation()); + ConfigTag* tag = iter->second; + + const std::string name = tag->getString("name"); + if (name.empty()) + throw ModuleException(" must be specified at " + tag->getTagLocation()); + + if (tag->getBool("change")) + { + ModeHandler* mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL); + if (!mh) + throw ModuleException(" specified for a nonexistent mode at " + tag->getTagLocation()); + + PrefixMode* pm = mh->IsPrefixMode(); + if (!pm) + throw ModuleException(" specified for a non-prefix mode at " + tag->getTagLocation()); + + unsigned long rank = tag->getUInt("rank", pm->GetPrefixRank(), 0, UINT_MAX); + unsigned long setrank = tag->getUInt("ranktoset", pm->GetLevelRequired(true), rank, UINT_MAX); + unsigned long unsetrank = tag->getUInt("ranktounset", pm->GetLevelRequired(false), setrank, UINT_MAX); + bool depriv = tag->getBool("depriv", pm->CanSelfRemove()); + pm->Update(rank, setrank, unsetrank, depriv); + + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Changed the %s prefix: depriv=%u rank=%u ranktoset=%u ranktounset=%u", + pm->name.c_str(), pm->CanSelfRemove(), pm->GetPrefixRank(), pm->GetLevelRequired(true), pm->GetLevelRequired(false)); + continue; + } + + const std::string letter = tag->getString("letter"); + if (letter.length() != 1) + throw ModuleException(" must be set to a mode character at " + tag->getTagLocation()); + + const std::string prefix = tag->getString("prefix"); + if (prefix.length() != 1) + throw ModuleException(" must be set to a mode prefix at " + tag->getTagLocation()); + try { + CustomPrefixMode* mh = new CustomPrefixMode(this, name, letter[0], prefix[0], tag); + modes.push_back(mh); ServerInstance->Modules->AddService(*mh); } catch (ModuleException& e) { - throw ModuleException(e.err + " (while creating mode from " + tag->getTagLocation() + ")"); + throw ModuleException(e.GetReason() + " (while creating mode from " + tag->getTagLocation() + ")"); } } } ~ModuleCustomPrefix() { - for (std::vector::iterator i = modes.begin(); i != modes.end(); i++) - delete *i; + stdalgo::delete_all(modes); } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { - return Version("Provides custom prefix channel modes", VF_VENDOR); + return Version("Allows the server administrator to configure custom channel prefix modes.", VF_VENDOR); } };