00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "inspircd.h"
00020 #include "inspstring.h"
00021
00022
00023 #include "modes/cmode_s.h"
00024
00025 #include "modes/cmode_p.h"
00026
00027 #include "modes/cmode_b.h"
00028
00029 #include "modes/cmode_m.h"
00030
00031 #include "modes/cmode_t.h"
00032
00033 #include "modes/cmode_n.h"
00034
00035 #include "modes/cmode_i.h"
00036
00037 #include "modes/cmode_k.h"
00038
00039 #include "modes/cmode_l.h"
00040
00041 #include "modes/cmode_o.h"
00042
00043 #include "modes/cmode_h.h"
00044
00045 #include "modes/cmode_v.h"
00046
00047 #include "modes/umode_w.h"
00048
00049 #include "modes/umode_i.h"
00050
00051 #include "modes/umode_o.h"
00052
00053 #include "modes/umode_s.h"
00054
00055 ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired)
00056 : 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), prefixneeded(prefixrequired)
00057 {
00058 }
00059
00060 ModeHandler::~ModeHandler()
00061 {
00062 }
00063
00064 bool ModeHandler::IsListMode()
00065 {
00066 return list;
00067 }
00068
00069 char ModeHandler::GetNeededPrefix()
00070 {
00071 return prefixneeded;
00072 }
00073
00074 void ModeHandler::SetNeededPrefix(char needsprefix)
00075 {
00076 prefixneeded = needsprefix;
00077 }
00078
00079 unsigned int ModeHandler::GetPrefixRank()
00080 {
00081 return 0;
00082 }
00083
00084 unsigned int ModeHandler::GetCount()
00085 {
00086 return 0;
00087 }
00088
00089 void ModeHandler::ChangeCount(int modifier)
00090 {
00091 count += modifier;
00092 ServerInstance->Logs->Log("MODE", DEBUG,"Change count for mode %c is now %d", mode, count);
00093 }
00094
00095 ModeType ModeHandler::GetModeType()
00096 {
00097 return m_type;
00098 }
00099
00100 bool ModeHandler::NeedsOper()
00101 {
00102 return oper;
00103 }
00104
00105 char ModeHandler::GetPrefix()
00106 {
00107 return prefix;
00108 }
00109
00110 int ModeHandler::GetNumParams(bool adding)
00111 {
00112 return adding ? n_params_on : n_params_off;
00113 }
00114
00115 char ModeHandler::GetModeChar()
00116 {
00117 return mode;
00118 }
00119
00120 ModeAction ModeHandler::OnModeChange(User*, User*, Channel*, std::string&, bool, bool)
00121 {
00122 return MODEACTION_DENY;
00123 }
00124
00125 ModePair ModeHandler::ModeSet(User*, User* dest, Channel* channel, const std::string&)
00126 {
00127 if (dest)
00128 {
00129 return std::make_pair(dest->IsModeSet(this->mode), "");
00130 }
00131 else
00132 {
00133 return std::make_pair(channel->IsModeSet(this->mode), "");
00134 }
00135 }
00136
00137 void ModeHandler::DisplayList(User*, Channel*)
00138 {
00139 }
00140
00141 void ModeHandler::DisplayEmptyList(User*, Channel*)
00142 {
00143 }
00144
00145 void ModeHandler::OnParameterMissing(User* user, User* dest, Channel* channel)
00146 {
00147 }
00148
00149 bool ModeHandler::CheckTimeStamp(time_t theirs, time_t ours, const std::string&, const std::string&, Channel*)
00150 {
00151 return (ours < theirs);
00152 }
00153
00154 SimpleUserModeHandler::SimpleUserModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_USER, false)
00155 {
00156 }
00157
00158 SimpleUserModeHandler::~SimpleUserModeHandler()
00159 {
00160 }
00161
00162 SimpleChannelModeHandler::~SimpleChannelModeHandler()
00163 {
00164 }
00165
00166 SimpleChannelModeHandler::SimpleChannelModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_CHANNEL, false)
00167 {
00168 }
00169
00170 ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding, bool servermode)
00171 {
00172
00173 if (source != dest)
00174 return MODEACTION_DENY;
00175
00176 if (adding)
00177 {
00178 if (!dest->IsModeSet(this->GetModeChar()))
00179 {
00180 dest->SetMode(this->GetModeChar(),true);
00181 return MODEACTION_ALLOW;
00182 }
00183 }
00184 else
00185 {
00186 if (dest->IsModeSet(this->GetModeChar()))
00187 {
00188 dest->SetMode(this->GetModeChar(),false);
00189 return MODEACTION_ALLOW;
00190 }
00191 }
00192
00193 return MODEACTION_DENY;
00194 }
00195
00196
00197 ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding, bool servermode)
00198 {
00199 if (adding)
00200 {
00201 if (!channel->IsModeSet(this->GetModeChar()))
00202 {
00203 channel->SetMode(this->GetModeChar(),true);
00204 return MODEACTION_ALLOW;
00205 }
00206 }
00207 else
00208 {
00209 if (channel->IsModeSet(this->GetModeChar()))
00210 {
00211 channel->SetMode(this->GetModeChar(),false);
00212 return MODEACTION_ALLOW;
00213 }
00214 }
00215
00216 return MODEACTION_DENY;
00217 }
00218
00219 ModeWatcher::ModeWatcher(InspIRCd* Instance, char modeletter, ModeType type) : ServerInstance(Instance), mode(modeletter), m_type(type)
00220 {
00221 }
00222
00223 ModeWatcher::~ModeWatcher()
00224 {
00225 }
00226
00227 char ModeWatcher::GetModeChar()
00228 {
00229 return mode;
00230 }
00231
00232 ModeType ModeWatcher::GetModeType()
00233 {
00234 return m_type;
00235 }
00236
00237 bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool, ModeType, bool)
00238 {
00239 return true;
00240 }
00241
00242 void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, ModeType, bool)
00243 {
00244 }
00245
00246 User* ModeParser::SanityChecks(User *user, const char *dest, Channel *chan, int)
00247 {
00248 User *d;
00249 if ((!user) || (!dest) || (!chan) || (!*dest))
00250 {
00251 return NULL;
00252 }
00253 d = ServerInstance->FindNick(dest);
00254 if (!d)
00255 {
00256 user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), dest);
00257 return NULL;
00258 }
00259 return d;
00260 }
00261
00262 const char* ModeParser::Grant(User *d,Channel *chan,int MASK)
00263 {
00264 if (!chan)
00265 return "";
00266
00267 UCListIter n = d->chans.find(chan);
00268 if (n != d->chans.end())
00269 {
00270 if (n->second & MASK)
00271 {
00272 return "";
00273 }
00274 n->second = n->second | MASK;
00275 switch (MASK)
00276 {
00277 case UCMODE_OP:
00278 n->first->AddOppedUser(d);
00279 break;
00280 case UCMODE_HOP:
00281 n->first->AddHalfoppedUser(d);
00282 break;
00283 case UCMODE_VOICE:
00284 n->first->AddVoicedUser(d);
00285 break;
00286 }
00287 return d->nick.c_str();
00288 }
00289 return "";
00290 }
00291
00292 const char* ModeParser::Revoke(User *d,Channel *chan,int MASK)
00293 {
00294 if (!chan)
00295 return "";
00296
00297 UCListIter n = d->chans.find(chan);
00298 if (n != d->chans.end())
00299 {
00300 if ((n->second & MASK) == 0)
00301 {
00302 return "";
00303 }
00304 n->second ^= MASK;
00305 switch (MASK)
00306 {
00307 case UCMODE_OP:
00308 n->first->DelOppedUser(d);
00309 break;
00310 case UCMODE_HOP:
00311 n->first->DelHalfoppedUser(d);
00312 break;
00313 case UCMODE_VOICE:
00314 n->first->DelVoicedUser(d);
00315 break;
00316 }
00317 return d->nick.c_str();
00318 }
00319 return "";
00320 }
00321
00322 void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targetchannel, const char* text)
00323 {
00324 if (targetchannel)
00325 {
00326
00327 user->WriteNumeric(RPL_CHANNELMODEIS, "%s %s +%s",user->nick.c_str(), targetchannel->name.c_str(), targetchannel->ChanModes(targetchannel->HasUser(user)));
00328 user->WriteNumeric(RPL_CHANNELCREATED, "%s %s %lu", user->nick.c_str(), targetchannel->name.c_str(), (unsigned long)targetchannel->age);
00329 return;
00330 }
00331 else if (targetuser)
00332 {
00333 if (targetuser->Visibility && !targetuser->Visibility->VisibleTo(user))
00334 {
00335 user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), text);
00336 return;
00337 }
00338
00339 if ((targetuser == user) || (IS_OPER(user)))
00340 {
00341
00342 user->WriteNumeric(RPL_UMODEIS, "%s :+%s",targetuser->nick.c_str(),targetuser->FormatModes());
00343 if (IS_OPER(targetuser))
00344 user->WriteNumeric(RPL_SNOMASKIS, "%s +%s :Server notice mask", targetuser->nick.c_str(), targetuser->FormatNoticeMasks());
00345 return;
00346 }
00347 else
00348 {
00349 user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
00350 return;
00351 }
00352 }
00353
00354
00355 user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), text);
00356 return;
00357 }
00358
00359 void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool servermode)
00360 {
00361 std::string target = parameters[0];
00362 ModeType type = MODETYPE_USER;
00363 unsigned char mask = 0;
00364 Channel* targetchannel = ServerInstance->FindChan(parameters[0]);
00365 User* targetuser = ServerInstance->FindNick(parameters[0]);
00366
00367 LastParse.clear();
00368
00369
00370
00371
00372 if ((targetchannel) && (parameters.size() == 2))
00373 {
00374 const char* mode = parameters[1].c_str();
00375 int nonlistmodes_found = 0;
00376
00377 seq++;
00378
00379 mask = MASK_CHANNEL;
00380
00381 while (mode && *mode)
00382 {
00383 unsigned char mletter = *mode;
00384
00385 if (*mode == '+')
00386 {
00387 mode++;
00388 continue;
00389 }
00390
00391
00392
00393
00394 if (sent[mletter] != seq)
00395 {
00396 sent[mletter] = seq;
00397 }
00398 else
00399 {
00400 mode++;
00401 continue;
00402 }
00403
00404 ModeHandler *mh = this->FindMode(*mode, MODETYPE_CHANNEL);
00405 bool display = true;
00406
00407 if ((mh) && (mh->IsListMode()))
00408 {
00409 int MOD_RESULT = 0;
00410 FOREACH_RESULT(I_OnRawMode, OnRawMode(user, targetchannel, *mode, "", true, 0));
00411 if (MOD_RESULT == ACR_DENY)
00412 {
00413 mode++;
00414 continue;
00415 }
00416
00417 if (!IS_OPER(user))
00418 {
00419 if (ServerInstance->Config->HideModeLists[mletter] && (targetchannel->GetStatus(user) < STATUS_HOP))
00420 {
00421 user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only half-operators and above may view the +%c list",user->nick.c_str(), targetchannel->name.c_str(), *mode++);
00422 mh->DisplayEmptyList(user, targetchannel);
00423 continue;
00424 }
00425 }
00426
00429 unsigned char handler_id = (*mode - 65) | mask;
00430
00431 for(ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
00432 {
00433 std::string dummyparam;
00434
00435 if (!((*watchers)->BeforeMode(user, NULL, targetchannel, dummyparam, true, MODETYPE_CHANNEL)))
00436 display = false;
00437 }
00438
00439 if (display)
00440 mh->DisplayList(user, targetchannel);
00441 }
00442 else
00443 nonlistmodes_found++;
00444
00445 mode++;
00446 }
00447
00448
00449 if (!nonlistmodes_found)
00450 return;
00451 }
00452
00453 if (parameters.size() == 1)
00454 {
00455 this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0].c_str());
00456 }
00457 else if (parameters.size() > 1)
00458 {
00459 bool SkipAccessChecks = false;
00460
00461 if (targetchannel)
00462 {
00463 type = MODETYPE_CHANNEL;
00464 mask = MASK_CHANNEL;
00465
00466
00467
00468
00469
00470 if ((IS_LOCAL(user)) && (!ServerInstance->ULine(user->server)) && (!servermode))
00471 {
00472
00473 int MOD_RESULT = 0;
00474 FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE));
00475 if (MOD_RESULT == ACR_DENY)
00476 return;
00477 SkipAccessChecks = (MOD_RESULT == ACR_ALLOW);
00478 }
00479 }
00480 else if (targetuser)
00481 {
00482 type = MODETYPE_USER;
00483 mask = MASK_USER;
00484 if ((user != targetuser) && (!ServerInstance->ULine(user->server)))
00485 {
00486 user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
00487 return;
00488 }
00489 }
00490 else
00491 {
00492
00493 user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), parameters[0].c_str());
00494 return;
00495 }
00496
00497 std::string mode_sequence = parameters[1];
00498 std::string parameter;
00499 std::ostringstream parameter_list;
00500 std::string output_sequence;
00501 bool adding = true, state_change = false;
00502 unsigned char handler_id = 0;
00503 unsigned int parameter_counter = 2;
00504 unsigned int parameter_count = 0;
00505 bool last_successful_state_change = false;
00506
00507
00508 if ((*mode_sequence.begin() != '+') && (*mode_sequence.begin() != '-'))
00509 mode_sequence.insert(0, "+");
00510
00511 for (std::string::const_iterator letter = mode_sequence.begin(); letter != mode_sequence.end(); letter++)
00512 {
00513 unsigned char modechar = *letter;
00514
00515 switch (modechar)
00516 {
00517
00518
00519
00520
00521
00522
00523
00524 case '+':
00525
00526
00527
00528 if ((!adding) || (!output_sequence.length()))
00529 state_change = true;
00530 adding = true;
00531 if (!output_sequence.length())
00532 last_successful_state_change = false;
00533 continue;
00534 break;
00535 case '-':
00536 if ((adding) || (!output_sequence.length()))
00537 state_change = true;
00538 adding = false;
00539 if (!output_sequence.length())
00540 last_successful_state_change = true;
00541 continue;
00542 break;
00543 default:
00544
00554 handler_id = (modechar - 65) | mask;
00555
00556 if (modehandlers[handler_id])
00557 {
00558 bool abort = false;
00559
00560 if (modehandlers[handler_id]->GetModeType() == type)
00561 {
00562 int MOD_RESULT = 0;
00563
00564 if (modehandlers[handler_id]->GetNumParams(adding))
00565 {
00566
00567 if (parameter_counter < parameters.size())
00568 {
00569 parameter = parameters[parameter_counter++];
00570
00571
00572 if ((parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
00573 parameter.clear();
00574 }
00575 else
00576 {
00577
00578 modehandlers[handler_id]->OnParameterMissing(user, targetuser, targetchannel);
00579 continue;
00580 }
00581
00582 FOREACH_RESULT(I_OnRawMode, OnRawMode(user, targetchannel, modechar, parameter, adding, 1, servermode));
00583 }
00584 else
00585 {
00586 FOREACH_RESULT(I_OnRawMode, OnRawMode(user, targetchannel, modechar, "", adding, 0, servermode));
00587 }
00588
00589 if (IS_LOCAL(user) && (MOD_RESULT == ACR_DENY))
00590 continue;
00591
00592 if (!SkipAccessChecks && IS_LOCAL(user) && (MOD_RESULT != ACR_ALLOW))
00593 {
00594
00595 if ((type == MODETYPE_CHANNEL) && (modehandlers[handler_id]->GetNeededPrefix()))
00596 {
00597 char needed = modehandlers[handler_id]->GetNeededPrefix();
00598 ModeHandler* prefixmode = FindPrefix(needed);
00599
00600
00601
00602
00603
00604
00605 if (needed && !prefixmode)
00606 prefixmode = FindPrefix('%');
00607
00608 unsigned int neededrank = prefixmode->GetPrefixRank();
00609
00610
00611
00612
00613
00614 std::string modestring = targetchannel->GetAllPrefixChars(user);
00615 char ml = (modestring.empty() ? '\0' : modestring[0]);
00616 ModeHandler* ourmode = FindPrefix(ml);
00617 if (!ourmode || ourmode->GetPrefixRank() < neededrank)
00618 {
00619
00620 user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have channel privilege %c or above to %sset channel mode %c",
00621 user->nick.c_str(), targetchannel->name.c_str(), needed, adding ? "" : "un", modechar);
00622 continue;
00623 }
00624 }
00625 }
00626
00627 bool had_parameter = !parameter.empty();
00628
00629 for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
00630 {
00631 if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type, servermode) == false)
00632 {
00633 abort = true;
00634 break;
00635 }
00636
00637 if ((had_parameter) && (parameter.empty()))
00638 {
00639 abort = true;
00640 break;
00641 }
00642 }
00643
00644 if (abort)
00645 continue;
00646
00647
00648
00649 if (IS_LOCAL(user) && !IS_OPER(user) && ((type == MODETYPE_CHANNEL ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes)[modehandlers[handler_id]->GetModeChar() - 'A']))
00650 {
00651 user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - %s mode %c has been locked by the administrator",
00652 user->nick.c_str(),
00653 type == MODETYPE_CHANNEL ? "channel" : "user",
00654 modehandlers[handler_id]->GetModeChar());
00655 continue;
00656 }
00657
00658
00659
00660
00661 if (adding && (IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!user->HasModePermission(modehandlers[handler_id]->GetModeChar(), type)))
00662 {
00663 if (IS_OPER(user))
00664 {
00665 user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to set %s mode %c",
00666 user->nick.c_str(),
00667 user->oper.c_str(),
00668 type == MODETYPE_CHANNEL ? "channel" : "user",
00669 modehandlers[handler_id]->GetModeChar());
00670 }
00671 else
00672 {
00673 user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Only operators may set %s mode %c",
00674 user->nick.c_str(),
00675 type == MODETYPE_CHANNEL ? "channel" : "user",
00676 modehandlers[handler_id]->GetModeChar());
00677 }
00678 continue;
00679 }
00680
00681
00682 ModeAction ma = modehandlers[handler_id]->OnModeChange(user, targetuser, targetchannel, parameter, adding, servermode);
00683
00684 if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter.empty()))
00685 {
00686
00687
00688
00689
00690 continue;
00691 }
00692
00693 if (ma == MODEACTION_ALLOW)
00694 {
00695
00696 if (state_change)
00697 {
00698 if (adding != last_successful_state_change)
00699 output_sequence.append(adding ? "+" : "-");
00700 last_successful_state_change = adding;
00701 }
00702
00703
00704 output_sequence.push_back(modechar);
00705
00706 modehandlers[handler_id]->ChangeCount(adding ? 1 : -1);
00707
00708
00709 if ((modehandlers[handler_id]->GetNumParams(adding)) && (!parameter.empty()))
00710 {
00711 parameter_list << " " << parameter;
00712 parameter_count++;
00713
00714 if (modehandlers[handler_id]->GetPrefix() && targetchannel)
00715 {
00716 User* user_to_prefix = ServerInstance->FindNick(parameter);
00717 if (user_to_prefix)
00718 targetchannel->SetPrefix(user_to_prefix, modehandlers[handler_id]->GetPrefix(),
00719 modehandlers[handler_id]->GetPrefixRank(), adding);
00720 }
00721 }
00722
00723
00724 for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
00725 (*watchers)->AfterMode(user, targetuser, targetchannel, parameter, adding, type, servermode);
00726
00727
00728 state_change = false;
00729
00730 if ((output_sequence.length() + parameter_list.str().length() > 450) || (output_sequence.length() > 100)
00731 || (parameter_count > ServerInstance->Config->Limits.MaxModes))
00732 {
00733
00734 letter = mode_sequence.end() - 1;
00735 continue;
00736 }
00737 }
00738 }
00739 }
00740 else
00741 {
00742
00743 user->WriteServ("%d %s %c :is unknown mode char to me", type == MODETYPE_CHANNEL ? 472 : 501, user->nick.c_str(), modechar);
00744 }
00745 break;
00746 }
00747 }
00748
00749
00750 if (!output_sequence.empty())
00751 {
00752 if (servermode)
00753 {
00754 if (type == MODETYPE_CHANNEL)
00755 {
00756 targetchannel->WriteChannelWithServ(ServerInstance->Config->ServerName, "MODE %s %s%s", targetchannel->name.c_str(), output_sequence.c_str(), parameter_list.str().c_str());
00757 this->LastParse = targetchannel->name;
00758 }
00759 else
00760 {
00761 targetuser->WriteServ("MODE %s %s%s",targetuser->nick.c_str(),output_sequence.c_str(), parameter_list.str().c_str());
00762 this->LastParse = targetuser->nick;
00763 }
00764 }
00765 else
00766 {
00767 if (type == MODETYPE_CHANNEL)
00768 {
00769 targetchannel->WriteChannel(user, "MODE %s %s%s", targetchannel->name.c_str(), output_sequence.c_str(), parameter_list.str().c_str());
00770 FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str()));
00771 this->LastParse = targetchannel->name;
00772 }
00773 else
00774 {
00775 user->WriteTo(targetuser, "MODE %s %s%s", targetuser->nick.c_str(), output_sequence.c_str(), parameter_list.str().c_str());
00776 FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str()));
00777 this->LastParse = targetuser->nick;
00778 }
00779 }
00780
00781 LastParse.append(" ");
00782 LastParse.append(output_sequence);
00783 LastParse.append(parameter_list.str());
00784 }
00785 }
00786 }
00787
00788 const std::string& ModeParser::GetLastParse()
00789 {
00790 return LastParse;
00791 }
00792
00793 void ModeParser::CleanMask(std::string &mask)
00794 {
00795 std::string::size_type pos_of_pling = mask.find_first_of('!');
00796 std::string::size_type pos_of_at = mask.find_first_of('@');
00797 std::string::size_type pos_of_dot = mask.find_first_of('.');
00798 std::string::size_type pos_of_colons = mask.find("::");
00799
00800 if (mask.length() >= 2 && mask[1] == ':')
00801 return;
00802
00803 if ((pos_of_pling == std::string::npos) && (pos_of_at == std::string::npos))
00804 {
00805
00806 if ((pos_of_dot == std::string::npos) && (pos_of_colons == std::string::npos) && mask[0] != ':')
00807 {
00808
00809 mask.append("!*@*");
00810 }
00811 else
00812 {
00813
00814 mask = "*!*@" + mask;
00815 }
00816 }
00817 else if ((pos_of_pling == std::string::npos) && (pos_of_at != std::string::npos))
00818 {
00819
00820 mask = "*!" + mask;
00821 }
00822 else if ((pos_of_pling != std::string::npos) && (pos_of_at == std::string::npos))
00823 {
00824
00825 mask.append("@*");
00826 }
00827 }
00828
00829 bool ModeParser::AddMode(ModeHandler* mh)
00830 {
00831 unsigned char mask = 0;
00832 unsigned char pos = 0;
00833
00834
00835
00836
00837
00838 if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z') || (mh->GetPrefix() > 126))
00839 return false;
00840
00841
00842
00843
00844
00845 if ((mh->GetPrefix() == ',') || (mh->GetPrefix() == ':') || (mh->GetPrefix() == '#'))
00846 return false;
00847
00848 mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
00849 pos = (mh->GetModeChar()-65) | mask;
00850
00851 if (modehandlers[pos])
00852 return false;
00853
00854 modehandlers[pos] = mh;
00855 return true;
00856 }
00857
00858 bool ModeParser::DelMode(ModeHandler* mh)
00859 {
00860 unsigned char mask = 0;
00861 unsigned char pos = 0;
00862
00863 if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
00864 return false;
00865
00866 mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
00867 pos = (mh->GetModeChar()-65) | mask;
00868
00869 if (!modehandlers[pos])
00870 return false;
00871
00872
00873
00874
00875 switch (mh->GetModeType())
00876 {
00877 case MODETYPE_USER:
00878 for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
00879 {
00880 mh->RemoveMode(i->second);
00881 }
00882 break;
00883 case MODETYPE_CHANNEL:
00884 for (chan_hash::iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
00885 {
00886 mh->RemoveMode(i->second);
00887 }
00888 break;
00889 }
00890
00891 modehandlers[pos] = NULL;
00892
00893 return true;
00894 }
00895
00896 ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
00897 {
00898 unsigned char mask = 0;
00899 unsigned char pos = 0;
00900
00901 if ((modeletter < 'A') || (modeletter > 'z'))
00902 return NULL;
00903
00904 mt == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
00905 pos = (modeletter-65) | mask;
00906
00907 return modehandlers[pos];
00908 }
00909
00910 std::string ModeParser::UserModeList()
00911 {
00912 char modestr[256];
00913 int pointer = 0;
00914
00915 for (unsigned char mode = 'A'; mode <= 'z'; mode++)
00916 {
00917 unsigned char pos = (mode-65) | MASK_USER;
00918
00919 if (modehandlers[pos])
00920 modestr[pointer++] = mode;
00921 }
00922 modestr[pointer++] = 0;
00923 return modestr;
00924 }
00925
00926 std::string ModeParser::ChannelModeList()
00927 {
00928 char modestr[256];
00929 int pointer = 0;
00930
00931 for (unsigned char mode = 'A'; mode <= 'z'; mode++)
00932 {
00933 if ((!ServerInstance->Config->AllowHalfop) && (mode == 'h'))
00934 continue;
00935
00936 unsigned char pos = (mode-65) | MASK_CHANNEL;
00937
00938 if (modehandlers[pos])
00939 modestr[pointer++] = mode;
00940 }
00941 modestr[pointer++] = 0;
00942 return modestr;
00943 }
00944
00945 std::string ModeParser::ParaModeList()
00946 {
00947 char modestr[256];
00948 int pointer = 0;
00949
00950 for (unsigned char mode = 'A'; mode <= 'z'; mode++)
00951 {
00952 if ((!ServerInstanc