X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmode.cpp;h=0bb97cc9ead29633407cce38333e0c7335fc77ed;hb=36e701f4abfa6d8fc4f096be023a681a6b7cec2e;hp=98b0f98540449f4543628c7620da7b5d54310014;hpb=b76ff64daeeb1e1081cff93c611f730e5b1b051e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 98b0f9854..0bb97cc9e 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -24,7 +24,6 @@ #include "inspircd.h" -#include "builtinmodes.h" ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type, Class mclass) : ServiceProvider(Creator, Name, SERVICE_MODE) @@ -90,6 +89,11 @@ void ModeHandler::DisplayEmptyList(User*, Channel*) void ModeHandler::OnParameterMissing(User* user, User* dest, Channel* channel) { + const std::string message = InspIRCd::Format("You must specify a parameter for the %s mode", name.c_str()); + if (channel) + user->WriteNumeric(Numerics::InvalidModeParameter(channel, this, "*", message)); + else + user->WriteNumeric(Numerics::InvalidModeParameter(dest, this, "*", message)); } bool ModeHandler::ResolveModeConflict(std::string& theirs, const std::string& ours, Channel*) @@ -434,14 +438,9 @@ void ModeParser::Process(User* user, Channel* targetchannel, User* targetuser, M unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags, unsigned int beginindex) { - LastParse.clear(); LastChangeList.clear(); unsigned int modes_processed = 0; - std::string output_mode; - std::string output_parameters; - - char output_pm = '\0'; // current output state, '+' or '-' Modes::ChangeList::List& list = changelist.getlist(); for (Modes::ChangeList::List::iterator i = list.begin()+beginindex; i != list.end(); ++i) { @@ -450,6 +449,12 @@ unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* Modes::Change& item = *i; ModeHandler* mh = item.mh; + // If a mode change has been given for a mode that does not exist then reject + // it. This can happen when core_reloadmodule attempts to restore a mode that + // no longer exists. + if (!mh) + continue; + // If the mode is supposed to have a parameter then we first take a look at item.param // and, if we were asked to, also handle mode merges now if (mh->NeedsParam(item.adding)) @@ -468,43 +473,30 @@ unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* if (ma != MODEACTION_ALLOW) continue; - char needed_pm = item.adding ? '+' : '-'; - if (needed_pm != output_pm) - { - output_pm = needed_pm; - output_mode.append(1, output_pm); - } - output_mode.push_back(mh->GetModeChar()); - - if (!item.param.empty()) - { - output_parameters.push_back(' '); - output_parameters.append(item.param); - } LastChangeList.push(mh, item.adding, item.param); - if ((output_mode.length() + output_parameters.length() > 450) - || (output_mode.length() > 100) - || (LastChangeList.size() >= ServerInstance->Config->Limits.MaxModes)) + if (LastChangeList.size() >= ServerInstance->Config->Limits.MaxModes) { /* mode sequence is getting too long */ break; } } - if (!output_mode.empty()) + if (!LastChangeList.empty()) { - LastParse = targetchannel ? targetchannel->name : targetuser->nick; - LastParse.append(" "); - LastParse.append(output_mode); - LastParse.append(output_parameters); - + ClientProtocol::Events::Mode modeevent(user, targetchannel, targetuser, LastChangeList); if (targetchannel) - targetchannel->WriteChannel(user, "MODE " + LastParse); + { + targetchannel->Write(modeevent); + } else - targetuser->WriteFrom(user, "MODE " + LastParse); + { + LocalUser* localtarget = IS_LOCAL(targetuser); + if (localtarget) + localtarget->Send(modeevent); + } - FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags, output_mode)); + FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags)); } return modes_processed; @@ -638,8 +630,6 @@ void ModeParser::AddMode(ModeHandler* mh) mhlist.prefix.push_back(pm); else if (mh->IsListModeBase()) mhlist.list.push_back(mh->IsListModeBase()); - - RecreateModeListFor004Numeric(); } bool ModeParser::DelMode(ModeHandler* mh) @@ -697,8 +687,6 @@ bool ModeParser::DelMode(ModeHandler* mh) mhlist.prefix.erase(std::find(mhlist.prefix.begin(), mhlist.prefix.end(), mh->IsPrefixMode())); else if (mh->IsListModeBase()) mhlist.list.erase(std::find(mhlist.list.begin(), mhlist.list.end(), mh->IsListModeBase())); - - RecreateModeListFor004Numeric(); return true; } @@ -728,27 +716,6 @@ PrefixMode* ModeParser::FindPrefixMode(unsigned char modeletter) return mh->IsPrefixMode(); } -std::string ModeParser::CreateModeList(ModeType mt, bool needparam) -{ - std::string modestr; - - for (unsigned char mode = 'A'; mode <= 'z'; mode++) - { - ModeHandler* mh = modehandlers[mt][mode-65]; - if ((mh) && ((!needparam) || (mh->NeedsParam(true)))) - modestr.push_back(mode); - } - - return modestr; -} - -void ModeParser::RecreateModeListFor004Numeric() -{ - Cached004ModeList[0] = CreateModeList(MODETYPE_USER); - Cached004ModeList[1] = CreateModeList(MODETYPE_CHANNEL); - Cached004ModeList[2] = CreateModeList(MODETYPE_CHANNEL, true); -} - PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter) { const PrefixModeList& list = GetPrefixModes(); @@ -894,53 +861,6 @@ void PrefixMode::RemoveMode(Channel* chan, Modes::ChangeList& changelist) } } -struct builtin_modes -{ - SimpleChannelModeHandler s; - SimpleChannelModeHandler p; - SimpleChannelModeHandler m; - SimpleChannelModeHandler t; - - SimpleChannelModeHandler n; - SimpleChannelModeHandler i; - ModeChannelKey k; - ModeChannelLimit l; - - ModeChannelBan b; - ModeChannelOp o; - ModeChannelVoice v; - - SimpleUserModeHandler ui; - ModeUserOperator uo; - ModeUserServerNoticeMask us; - - builtin_modes() - : s(NULL, "secret", 's') - , p(NULL, "private", 'p') - , m(NULL, "moderated", 'm') - , t(NULL, "topiclock", 't') - , n(NULL, "noextmsg", 'n') - , i(NULL, "inviteonly", 'i') - , ui(NULL, "invisible", 'i') - { - } - - void init() - { - ServiceProvider* modes[] = { &s, &p, &m, &t, &n, &i, &k, &l, &b, &o, &v, - &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(); -} - bool ModeParser::IsModeChar(char chr) { return ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z'));