X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=874d8bef41be410222bf3807a239ce342885deb6;hb=eb334f8c69872cc0de28ffd85b41555f196a23dd;hp=4d6023c1c1c7eaf1a25954e4185f64028f8bc77c;hpb=1f83b592eae17726783d4cf7afebe36d96bb4b95;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 4d6023c1c..874d8bef4 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -185,7 +185,6 @@ const char* ModeParser::Grant(userrec *d,chanrec *chan,int MASK) { if (n->second & MASK) { - ServerInstance->Log(DEBUG,"User already has privilage %d (privset: %d)", MASK, n->second); return ""; } n->second = n->second | MASK; @@ -201,13 +200,8 @@ const char* ModeParser::Grant(userrec *d,chanrec *chan,int MASK) n->first->AddVoicedUser(d); break; } - ServerInstance->Log(DEBUG,"grant: %s %s",n->first->name,d->nick); return d->nick; } - else - { - ServerInstance->Log(DEBUG,"Channel %s not in users joined list", chan->name); - } return ""; } @@ -236,7 +230,6 @@ const char* ModeParser::Revoke(userrec *d,chanrec *chan,int MASK) n->first->DelVoicedUser(d); break; } - ServerInstance->Log(DEBUG,"revoke: %s %s",n->first->name,d->nick); return d->nick; } return ""; @@ -253,11 +246,17 @@ void ModeParser::DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec } else if (targetuser) { - if ((targetuser == user) || (*user->oper)) + if (targetuser->Visibility && !targetuser->Visibility->VisibleTo(user)) + { + user->WriteServ("401 %s %s :No such nick/channel",user->nick, text); + return; + } + + if ((targetuser == user) || (IS_OPER(user))) { /* Display user's current mode string */ user->WriteServ("221 %s :+%s",targetuser->nick,targetuser->FormatModes()); - if (*targetuser->oper) + if (IS_OPER(targetuser)) user->WriteServ("008 %s +%s :Server notice mask", targetuser->nick, targetuser->FormatNoticeMasks()); return; } @@ -281,8 +280,6 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool chanrec* targetchannel = ServerInstance->FindChan(parameters[0]); userrec* targetuser = ServerInstance->FindNick(parameters[0]); - ServerInstance->Log(DEBUG,"ModeParser::Process start: pcnt=%d",pcnt); - LastParse = ""; /* Special case for displaying the list for listmodes, @@ -290,37 +287,80 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool */ if ((targetchannel) && (pcnt == 2)) { - ServerInstance->Log(DEBUG,"Spool list"); const char* mode = parameters[1]; + int nonlistmodes_found = 0; + bool sent[256]; + mask = MASK_CHANNEL; + + memset(&sent, 0, 256); + while (mode && *mode) { + unsigned char mletter = *mode; + if (*mode == '+') { mode++; continue; } + /* Ensure the user doesnt request the same mode twice, + * so they cant flood themselves off out of idiocy. + */ + if (!sent[mletter]) + { + sent[mletter] = true; + } + else + { + mode++; + continue; + } + ModeHandler *mh = this->FindMode(*mode, MODETYPE_CHANNEL); + bool display = true; if ((mh) && (mh->IsListMode())) { - mh->DisplayList(user, targetchannel); + if (ServerInstance->Config->HideModeLists[mletter] && (targetchannel->GetStatus(user) < STATUS_HOP)) + { + user->WriteServ("482 %s %s :Only half-operators and above may view the +%c list",user->nick, targetchannel->name, *mode++); + continue; + } + + /** See below for a description of what craq this is :D + */ + unsigned char handler_id = (*mode - 65) | mask; + + for(ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + { + std::string dummyparam; + + if (!((*watchers)->BeforeMode(user, NULL, targetchannel, dummyparam, true, MODETYPE_CHANNEL))) + display = false; + } + + if (display) + mh->DisplayList(user, targetchannel); } + else + nonlistmodes_found++; mode++; } + + /* We didnt have any modes that were non-list, we can return here */ + if (!nonlistmodes_found) + return; } if (pcnt == 1) { - ServerInstance->Log(DEBUG,"Mode list request"); this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0]); } else if (pcnt > 1) { - ServerInstance->Log(DEBUG,"More than one parameter"); - if (targetchannel) { type = MODETYPE_CHANNEL; @@ -333,8 +373,6 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool if ((IS_LOCAL(user)) && (targetchannel->GetStatus(user) < STATUS_HOP)) { /* We don't have halfop */ - ServerInstance->Log(DEBUG,"The user is not a halfop or above, checking other reasons for being able to set the modes"); - int MOD_RESULT = 0; FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE)); if (MOD_RESULT == ACR_DENY) @@ -435,19 +473,13 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool { bool abort = false; - for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) - { - if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == MODEACTION_DENY) - abort = true; - } - if ((modehandlers[handler_id]->GetModeType() == type) && (!abort)) + if (modehandlers[handler_id]->GetModeType() == type) { if (modehandlers[handler_id]->GetNumParams(adding)) { /* This mode expects a parameter, do we have any parameters left in our list to use? */ if (parameter_counter < pcnt) { - ServerInstance->Log(DEBUG,"parameter_counter = %d, pcnt = %d", parameter_counter, pcnt); parameter = parameters[parameter_counter++]; /* Yerk, invalid! */ @@ -459,14 +491,49 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool /* No parameter, continue to the next mode */ continue; } + + bool had_parameter = !parameter.empty(); + + for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + { + if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == false) + { + abort = true; + break; + } + /* A module whacked the parameter completely, and there was one. abort. */ + if ((had_parameter) && (parameter.empty())) + { + abort = true; + break; + } + } + + if (abort) + continue; + } + else + { + /* Fix by brain: mode watchers not being called for parameterless modes */ + for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + { + if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == false) + { + abort = true; + break; + } + } + + if (abort) + continue; } /* It's an oper only mode, check if theyre an oper. If they arent, * eat any parameter that came with the mode, and continue to next */ - if ((IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!*user->oper)) + if ((IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!IS_OPER(user))) { - user->WriteServ("481 %s :Permission Denied- Only IRC operators may %sset %s mode %c", user->nick, + user->WriteServ("481 %s :Permission Denied - Only IRC operators may %sset %s mode %c", user->nick, adding ? "" : "un", type == MODETYPE_CHANNEL ? "channel" : "user", modehandlers[handler_id]->GetModeChar()); continue; @@ -475,7 +542,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool /* Call the handler for the mode */ ModeAction ma = modehandlers[handler_id]->OnModeChange(user, targetuser, targetchannel, parameter, adding); - if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter == "")) + if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter.empty())) { /* The handler nuked the parameter and they are supposed to have one. * We CANT continue now, even if they actually returned MODEACTION_ALLOW, @@ -498,7 +565,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool output_sequence.push_back(modechar); /* Is there a valid parameter for this mode? If so add it to the parameter list */ - if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter != "")) + if ((modehandlers[handler_id]->GetNumParams(adding)) && (!parameter.empty())) { parameter_list << " " << parameter; parameter_count++; @@ -537,8 +604,9 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool break; } } + /* Was there at least one valid mode in the sequence? */ - if (output_sequence != "") + if (!output_sequence.empty()) { if (servermode) { @@ -557,7 +625,6 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool { if (type == MODETYPE_CHANNEL) { - ServerInstance->Log(DEBUG,"Write output sequence and parameters to channel: %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str()); targetchannel->WriteChannel(user,"MODE %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str()); FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str())); this->LastParse = targetchannel->name; @@ -641,7 +708,6 @@ bool ModeParser::AddMode(ModeHandler* mh, unsigned const char modeletter) return false; modehandlers[pos] = mh; - ServerInstance->Log(DEBUG,"ModeParser::AddMode: added mode %c",mh->GetModeChar()); return true; } @@ -832,7 +898,7 @@ std::string ModeParser::ChanModes() return type1 + "," + type2 + "," + type3 + "," + type4; } -bool ModeParser::PrefixComparison(const prefixtype one, const prefixtype two) +bool ModeParser::PrefixComparison(prefixtype one, prefixtype two) { return one.second > two.second; } @@ -881,7 +947,6 @@ bool ModeParser::AddModeWatcher(ModeWatcher* mw) pos = (mw->GetModeChar()-65) | mask; modewatchers[pos].push_back(mw); - ServerInstance->Log(DEBUG,"ModeParser::AddModeWatcher: watching mode %c",mw->GetModeChar()); return true; } @@ -904,12 +969,10 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw) if (a == modewatchers[pos].end()) { - ServerInstance->Log(DEBUG, "ModeParser::DelModeWatcher: Couldn't find watcher for mode %c in list", mw->GetModeChar()); return false; } modewatchers[pos].erase(a); - ServerInstance->Log(DEBUG,"ModeParser::DelModeWatcher: stopped watching mode %c",mw->GetModeChar()); return true; } @@ -951,6 +1014,33 @@ void ModeHandler::RemoveMode(chanrec* channel) ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance) { + struct Initializer + { + char modechar; + ModeHandler* handler; + }; + + Initializer modes[] = { + { 's', new ModeChannelSecret(Instance) }, + { 'p', new ModeChannelPrivate(Instance) }, + { 'm', new ModeChannelModerated(Instance) }, + { 't', new ModeChannelTopicOps(Instance) }, + { 'n', new ModeChannelNoExternal(Instance) }, + { 'i', new ModeChannelInviteOnly(Instance) }, + { 'k', new ModeChannelKey(Instance) }, + { 'l', new ModeChannelLimit(Instance) }, + { 'b', new ModeChannelBan(Instance) }, + { 'o', new ModeChannelOp(Instance) }, + { 'h', new ModeChannelHalfOp(Instance) }, + { 'v', new ModeChannelVoice(Instance) }, + { 's', new ModeUserServerNotice(Instance) }, + { 'w', new ModeUserWallops(Instance) }, + { 'i', new ModeUserInvisible(Instance) }, + { 'o', new ModeUserOperator(Instance) }, + { 'n', new ModeUserServerNoticeMask(Instance) }, + { 0, NULL } + }; + /* Clear mode list */ memset(modehandlers, 0, sizeof(modehandlers)); memset(modewatchers, 0, sizeof(modewatchers)); @@ -959,29 +1049,6 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance) LastParse = ""; /* Initialise the RFC mode letters */ - - /* Start with channel simple modes, no params */ - this->AddMode(new ModeChannelSecret(Instance), 's'); - this->AddMode(new ModeChannelPrivate(Instance), 'p'); - this->AddMode(new ModeChannelModerated(Instance), 'm'); - this->AddMode(new ModeChannelTopicOps(Instance), 't'); - this->AddMode(new ModeChannelNoExternal(Instance), 'n'); - this->AddMode(new ModeChannelInviteOnly(Instance), 'i'); - - /* Cannel modes with params */ - this->AddMode(new ModeChannelKey(Instance), 'k'); - this->AddMode(new ModeChannelLimit(Instance), 'l'); - - /* Channel listmodes */ - this->AddMode(new ModeChannelBan(Instance), 'b'); - this->AddMode(new ModeChannelOp(Instance), 'o'); - this->AddMode(new ModeChannelHalfOp(Instance), 'h'); - this->AddMode(new ModeChannelVoice(Instance), 'v'); - - /* Now for usermodes */ - this->AddMode(new ModeUserServerNotice(Instance), 's'); - this->AddMode(new ModeUserWallops(Instance), 'w'); - this->AddMode(new ModeUserInvisible(Instance), 'i'); - this->AddMode(new ModeUserOperator(Instance), 'o'); - this->AddMode(new ModeUserServerNoticeMask(Instance), 'n'); + for (int index = 0; modes[index].modechar; index++) + this->AddMode(modes[index].handler, modes[index].modechar); }