- break;
- default:
-
- /**
- * Watch carefully for the sleight of hand trick.
- * 65 is the ascii value of 'A'. We take this from
- * the char we're looking at to get a number between
- * 1 and 127. We then logic-or it to get the hashed
- * position, dependent on wether its a channel or
- * a user mode. This is a little stranger, but a lot
- * faster, than using a map of pairs.
- */
- handler_id = (modechar - 65) | mask;
-
- if (modehandlers[handler_id])
- {
- 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]->GetNumParams(adding))
- {
- /* This mode expects a parameter, do we have any parameters left in our list to use? */
- if (parameter_counter < pcnt)
- {
- parameter = parameters[parameter_counter++];
-
- /* Yerk, invalid! */
- if ((parameter.rfind(':') != std::string::npos) || (parameter.rfind(' ') != std::string::npos))
- parameter = "";
- }
- else
- {
- /* No parameter, continue to the next mode */
- 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))
- continue;
-
- /* Call the handler for the mode */
- ModeAction ma = modehandlers[handler_id]->OnModeChange(user, targetuser, targetchannel, parameter, adding);
-
- if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter == ""))
- {
- /* The handler nuked the parameter and they are supposed to have one.
- * We CANT continue now, even if they actually returned MODEACTION_ALLOW,
- * so we bail to the next mode character.
- */
- continue;
- }
-
- if (ma == MODEACTION_ALLOW)
- {
- /* We're about to output a valid mode letter - was there previously a pending state-change? */
- if (state_change)
- output_sequence.append(adding ? "+" : "-");
-
- /* Add the mode letter */
- 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 != ""))
- {
- parameter_list << " " << parameter;
- /* Does this mode have a prefix? */
- if (modehandlers[handler_id]->GetPrefix() && targetchannel)
- {
- userrec* user_to_prefix = ServerInstance->FindNick(parameter);
- if (user_to_prefix)
- targetchannel->SetPrefix(user_to_prefix, modehandlers[handler_id]->GetPrefix(),
- modehandlers[handler_id]->GetPrefixRank(), adding);
- }
- }
-
- /* Call all the AfterMode events in the mode watchers for this mode */
- for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
- (*watchers)->AfterMode(user, targetuser, targetchannel, parameter, adding, type);
-
- /* Reset the state change flag */
- state_change = false;
- }
- }
- }
- else
- {
- /* No mode handler? Unknown mode character then. */
- user->WriteServ("472 %s %c :is unknown mode char to me",user->nick, modechar);
- }
- break;