X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=a7effa642d2fef7ff97a43b51bdccdc7e40b381f;hb=b844d1cbbe79585facc69b9247baa8427cff0b62;hp=ea51ce71dec18367e64bb103726d4ce02a0a010f;hpb=15d46952214cfdc679cda1d463e11d1ab95329da;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index ea51ce71d..a7effa642 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -2,20 +2,15 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * - * - * Written by Craig Edwards, Craig McLure, and others. + * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * See: http://www.inspircd.org/wiki/index.php/Credits + * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ -using namespace std; - #include "inspircd.h" #include "users.h" #include "modules.h" @@ -58,7 +53,7 @@ using namespace std; #include "modes/umode_n.h" ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix) - : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix) + : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix), count(0) { } @@ -76,6 +71,16 @@ unsigned int ModeHandler::GetPrefixRank() return 0; } +unsigned int ModeHandler::GetCount() +{ + return 0; +} + +void ModeHandler::ChangeCount(int modifier) +{ + count += modifier; +} + ModeType ModeHandler::GetModeType() { return m_type; @@ -175,31 +180,27 @@ const char* ModeParser::Grant(userrec *d,chanrec *chan,int MASK) if (!chan) return ""; - for (std::vector::const_iterator i = d->chans.begin(); i != d->chans.end(); i++) + UCListIter n = d->chans.find(chan); + if (n != d->chans.end()) { - ucrec* n = (ucrec*)(*i); - if (n->channel == chan) + if (n->second & MASK) { - if (n->uc_modes & MASK) - { - return ""; - } - n->uc_modes = n->uc_modes | MASK; - switch (MASK) - { - case UCMODE_OP: - n->channel->AddOppedUser(d); - break; - case UCMODE_HOP: - n->channel->AddHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->channel->AddVoicedUser(d); - break; - } - ServerInstance->Log(DEBUG,"grant: %s %s",n->channel->name,d->nick); - return d->nick; + return ""; + } + n->second = n->second | MASK; + switch (MASK) + { + case UCMODE_OP: + n->first->AddOppedUser(d); + break; + case UCMODE_HOP: + n->first->AddHalfoppedUser(d); + break; + case UCMODE_VOICE: + n->first->AddVoicedUser(d); + break; } + return d->nick; } return ""; } @@ -209,31 +210,27 @@ const char* ModeParser::Revoke(userrec *d,chanrec *chan,int MASK) if (!chan) return ""; - for (std::vector::const_iterator i = d->chans.begin(); i != d->chans.end(); i++) + UCListIter n = d->chans.find(chan); + if (n != d->chans.end()) { - ucrec* n = (ucrec*)(*i); - if (n->channel == chan) + if ((n->second & MASK) == 0) { - if ((n->uc_modes & MASK) == 0) - { - return ""; - } - n->uc_modes ^= MASK; - switch (MASK) - { - case UCMODE_OP: - n->channel->DelOppedUser(d); - break; - case UCMODE_HOP: - n->channel->DelHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->channel->DelVoicedUser(d); - break; - } - ServerInstance->Log(DEBUG,"revoke: %s %s",n->channel->name,d->nick); - return d->nick; + return ""; } + n->second ^= MASK; + switch (MASK) + { + case UCMODE_OP: + n->first->DelOppedUser(d); + break; + case UCMODE_HOP: + n->first->DelHalfoppedUser(d); + break; + case UCMODE_VOICE: + n->first->DelVoicedUser(d); + break; + } + return d->nick; } return ""; } @@ -260,6 +257,7 @@ void ModeParser::DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec else { user->WriteServ("502 %s :Can't change mode for other users", user->nick); + return; } } @@ -276,10 +274,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); - for (int j = 0; j < pcnt; j++) - ServerInstance->Log(DEBUG," parameters[%d] = '%s'", j, parameters[j]); - LastParse = ""; /* Special case for displaying the list for listmodes, @@ -287,28 +281,56 @@ 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]; - if (*mode == '+') - mode++; - unsigned char handler_id = ((*mode) - 65) | MASK_CHANNEL; - ModeHandler* mh = modehandlers[handler_id]; - if ((mh) && (mh->IsListMode())) + int nonlistmodes_found = 0; + + mask = MASK_CHANNEL; + + while (mode && *mode) { - mh->DisplayList(user, targetchannel); - return; + if (*mode == '+') + { + mode++; + continue; + } + + ModeHandler *mh = this->FindMode(*mode, MODETYPE_CHANNEL); + bool display = true; + + if ((mh) && (mh->IsListMode())) + { + /** 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; @@ -321,8 +343,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) @@ -368,6 +388,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool unsigned char handler_id = 0; int parameter_counter = 2; /* Index of first parameter */ int parameter_count = 0; + bool last_successful_state_change = false; /* A mode sequence that doesnt start with + or -. Assume +. - Thanks for the suggestion spike (bug#132) */ if ((*mode_sequence.begin() != '+') && (*mode_sequence.begin() != '-')) @@ -377,8 +398,6 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool { unsigned char modechar = *letter; - ServerInstance->Log(DEBUG,"Process letter %c", modechar); - switch (modechar) { /* NB: @@ -395,12 +414,16 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool if ((!adding) || (!output_sequence.length())) state_change = true; adding = true; + if (!output_sequence.length()) + last_successful_state_change = false; continue; break; case '-': if ((adding) || (!output_sequence.length())) state_change = true; adding = false; + if (!output_sequence.length()) + last_successful_state_change = true; continue; break; default: @@ -420,19 +443,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! */ @@ -444,6 +461,26 @@ 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; } /* It's an oper only mode, check if theyre an oper. If they arent, @@ -473,7 +510,11 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool { /* We're about to output a valid mode letter - was there previously a pending state-change? */ if (state_change) - output_sequence.append(adding ? "+" : "-"); + { + if (adding != last_successful_state_change) + output_sequence.append(adding ? "+" : "-"); + last_successful_state_change = adding; + } /* Add the mode letter */ output_sequence.push_back(modechar); @@ -538,7 +579,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; @@ -622,7 +662,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; } @@ -643,13 +682,13 @@ bool ModeParser::DelMode(ModeHandler* mh) switch (mh->GetModeType()) { case MODETYPE_USER: - for (user_hash::iterator i = ServerInstance->clientlist.begin(); i != ServerInstance->clientlist.end(); i++) + for (user_hash::iterator i = ServerInstance->clientlist->begin(); i != ServerInstance->clientlist->end(); i++) { mh->RemoveMode(i->second); } 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(); i++) { mh->RemoveMode(i->second); } @@ -862,8 +901,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; } @@ -885,12 +922,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; }