]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Clean up the FileReader class and all of the modules that use it.
[user/henk/code/inspircd.git] / src / mode.cpp
index 845b23fb0614a395223cd59262a5bbbeb69d3e4d..b4bb72c42a9480de52378bfd9e6ceb2e625e0a5d 100644 (file)
 
 
 #include "inspircd.h"
-#include "inspstring.h"
-
-/* +s (secret) */
-#include "modes/cmode_s.h"
-/* +p (private) */
-#include "modes/cmode_p.h"
-/* +b (bans) */
-#include "modes/cmode_b.h"
-/* +m (moderated) */
-#include "modes/cmode_m.h"
-/* +t (only (half) ops can change topic) */
-#include "modes/cmode_t.h"
-/* +n (no external messages) */
-#include "modes/cmode_n.h"
-/* +i (invite only) */
-#include "modes/cmode_i.h"
-/* +k (keyed channel) */
-#include "modes/cmode_k.h"
-/* +l (channel user limit) */
-#include "modes/cmode_l.h"
-/* +o (channel op) */
-#include "modes/cmode_o.h"
-/* +v (channel voice) */
-#include "modes/cmode_v.h"
-/* +w (see wallops) */
-#include "modes/umode_w.h"
-/* +i (invisible) */
-#include "modes/umode_i.h"
-/* +o (operator) */
-#include "modes/umode_o.h"
-/* +s (server notice masks) */
-#include "modes/umode_s.h"
+#include "builtinmodes.h"
 
 ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type)
        : ServiceProvider(Creator, Name, SERVICE_MODE), m_paramtype(TR_TEXT),
@@ -215,22 +184,6 @@ void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, Mo
 {
 }
 
-User* ModeParser::SanityChecks(User *user, const char *dest, Channel *chan, int)
-{
-       User *d;
-       if ((!user) || (!dest) || (!chan) || (!*dest))
-       {
-               return NULL;
-       }
-       d = ServerInstance->FindNick(dest);
-       if (!d)
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), dest);
-               return NULL;
-       }
-       return d;
-}
-
 void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targetchannel, const char* text)
 {
        if (targetchannel)
@@ -246,7 +199,7 @@ void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targ
                {
                        /* Display user's current mode string */
                        user->WriteNumeric(RPL_UMODEIS, "%s :+%s",targetuser->nick.c_str(),targetuser->FormatModes());
-                       if (IS_OPER(targetuser))
+                       if ((targetuser->IsOper()))
                                user->WriteNumeric(RPL_SNOMASKIS, "%s +%s :Server notice mask", targetuser->nick.c_str(), targetuser->FormatNoticeMasks());
                        return;
                }
@@ -327,7 +280,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                        return MODEACTION_DENY;
        }
 
-       if (IS_LOCAL(user) && !IS_OPER(user))
+       if (IS_LOCAL(user) && !user->IsOper())
        {
                char* disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes;
                if (disabled[modechar - 'A'])
@@ -341,10 +294,10 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        if (adding && IS_LOCAL(user) && mh->NeedsOper() && !user->HasModePermission(modechar, type))
        {
                /* It's an oper only mode, and they don't have access to it. */
-               if (IS_OPER(user))
+               if (user->IsOper())
                {
                        user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to set %s mode %c",
-                                       user->nick.c_str(), user->oper->NameStr(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
+                                       user->nick.c_str(), user->oper->name.c_str(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
                }
                else
                {
@@ -395,7 +348,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
        LastParseParams.clear();
        LastParseTranslate.clear();
 
-       if (!targetchannel && !targetuser)
+       if ((!targetchannel) && ((!targetuser) || (IS_SERVER(targetuser))))
        {
                user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(),target.c_str());
                return;
@@ -450,7 +403,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                        continue;
                }
 
-               std::string parameter = "";
+               std::string parameter;
                int pcnt = mh->GetNumParams(adding);
                if (pcnt && param_at == parameters.size())
                {
@@ -660,6 +613,7 @@ bool ModeParser::AddMode(ModeHandler* mh)
                return false;
 
        modehandlers[pos] = mh;
+       RecreateModeListFor004Numeric();
        return true;
 }
 
@@ -683,20 +637,26 @@ bool ModeParser::DelMode(ModeHandler* mh)
        switch (mh->GetModeType())
        {
                case MODETYPE_USER:
-                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
+                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); )
                        {
-                               mh->RemoveMode(i->second);
+                               User* user = i->second;
+                               ++i;
+                               mh->RemoveMode(user);
                        }
                break;
                case MODETYPE_CHANNEL:
-                       for (chan_hash::iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
+                       for (chan_hash::iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); )
                        {
-                               mh->RemoveMode(i->second);
+                               // The channel may not be in the hash after RemoveMode(), see m_permchannels
+                               Channel* chan = i->second;
+                               ++i;
+                               mh->RemoveMode(chan);
                        }
                break;
        }
 
        modehandlers[pos] = NULL;
+       RecreateModeListFor004Numeric();
 
        return true;
 }
@@ -715,52 +675,25 @@ ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
        return modehandlers[pos];
 }
 
-std::string ModeParser::UserModeList()
+std::string ModeParser::CreateModeList(ModeType mt, bool needparam)
 {
-       char modestr[256];
-       int pointer = 0;
+       std::string modestr;
+       unsigned char mask = ((mt == MODETYPE_CHANNEL) ? MASK_CHANNEL : MASK_USER);
 
        for (unsigned char mode = 'A'; mode <= 'z'; mode++)
        {
-               unsigned char pos = (mode-65) | MASK_USER;
+               unsigned char pos = (mode-65) | mask;
 
-               if (modehandlers[pos])
-                       modestr[pointer++] = mode;
+               if ((modehandlers[pos]) && ((!needparam) || (modehandlers[pos]->GetNumParams(true))))
+                       modestr.push_back(mode);
        }
-       modestr[pointer++] = 0;
-       return modestr;
-}
 
-std::string ModeParser::ChannelModeList()
-{
-       char modestr[256];
-       int pointer = 0;
-
-       for (unsigned char mode = 'A'; mode <= 'z'; mode++)
-       {
-               unsigned char pos = (mode-65) | MASK_CHANNEL;
-
-               if (modehandlers[pos])
-                       modestr[pointer++] = mode;
-       }
-       modestr[pointer++] = 0;
        return modestr;
 }
 
-std::string ModeParser::ParaModeList()
+void ModeParser::RecreateModeListFor004Numeric()
 {
-       char modestr[256];
-       int pointer = 0;
-
-       for (unsigned char mode = 'A'; mode <= 'z'; mode++)
-       {
-               unsigned char pos = (mode-65) | MASK_CHANNEL;
-
-               if ((modehandlers[pos]) && (modehandlers[pos]->GetNumParams(true)))
-                       modestr[pointer++] = mode;
-       }
-       modestr[pointer++] = 0;
-       return modestr;
+       Cached004ModeList = CreateModeList(MODETYPE_USER) + " " + CreateModeList(MODETYPE_CHANNEL) + " " + CreateModeList(MODETYPE_CHANNEL, true);
 }
 
 ModeHandler* ModeParser::FindPrefix(unsigned const char pfxletter)
@@ -959,28 +892,22 @@ struct builtin_modes
        ModeUserOperator uo;
        ModeUserServerNoticeMask us;
 
-       void init(ModeParser* modes)
+       void init()
        {
-               modes->AddMode(&s);
-               modes->AddMode(&p);
-               modes->AddMode(&m);
-               modes->AddMode(&t);
-               modes->AddMode(&n);
-               modes->AddMode(&i);
-               modes->AddMode(&k);
-               modes->AddMode(&l);
-               modes->AddMode(&b);
-               modes->AddMode(&o);
-               modes->AddMode(&v);
-               modes->AddMode(&uw);
-               modes->AddMode(&ui);
-               modes->AddMode(&uo);
-               modes->AddMode(&us);
+               ServiceProvider* modes[] = { &s, &p, &m, &t, &n, &i, &k, &l, &b, &o, &v,
+                                                                        &uw, &ui, &uo, &us };
+               ServerInstance->Modules->AddServices(modes, sizeof(modes)/sizeof(ServiceProvider*));
        }
 };
 
 static builtin_modes static_modes;
 
+void ModeParser::InitBuiltinModes()
+{
+       static_modes.init();
+       static_modes.b.DoRehash();
+}
+
 ModeParser::ModeParser()
 {
        /* Clear mode handler list */
@@ -991,8 +918,6 @@ ModeParser::ModeParser()
 
        seq = 0;
        memset(&sent, 0, sizeof(sent));
-
-       static_modes.init(this);
 }
 
 ModeParser::~ModeParser()