X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=6ee841301d1dd61baa574227e5a6a932490af8a0;hb=76ebc88ccd6fef0bf2d97b607829fb3466e273af;hp=18580a21e477a25ddced51149522f2723470cf92;hpb=2816a3ff87c3c15848dfe7f71391a454992ecefe;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 18580a21e..6ee841301 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -3,13 +3,13 @@ * +------------------------------------+ * * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * + * E-mail: + * + * * * Written by Craig Edwards, Craig McLure, and others. * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -24,7 +24,6 @@ using namespace std; #include "connection.h" #include "users.h" #include "modules.h" -#include "message.h" #include "inspstring.h" #include "helperfuncs.h" #include "commands.h" @@ -66,16 +65,8 @@ using namespace std; /* +n (notice mask - our implementation of snomasks) */ #include "modes/umode_n.h" -extern int MODCOUNT; -extern std::vector modules; -extern std::vector factory; -extern InspIRCd* ServerInstance; -extern ServerConfig* Config; - -extern time_t TIME; - -ModeHandler::ModeHandler(char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly) - : mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly) +ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly) + : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly) { } @@ -113,6 +104,18 @@ ModeAction ModeHandler::OnModeChange(userrec* source, userrec* dest, chanrec* ch return MODEACTION_DENY; } +ModePair ModeHandler::ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter) +{ + if (dest) + { + return std::make_pair(dest->IsModeSet(this->mode), ""); + } + else + { + return std::make_pair(channel->IsModeSet(this->mode), ""); + } +} + void ModeHandler::DisplayList(userrec* user, chanrec* channel) { } @@ -122,7 +125,7 @@ bool ModeHandler::CheckTimeStamp(time_t theirs, time_t ours, const std::string & return (ours < theirs); } -ModeWatcher::ModeWatcher(char modeletter, ModeType type) : mode(modeletter), m_type(type) +ModeWatcher::ModeWatcher(InspIRCd* Instance, char modeletter, ModeType type) : ServerInstance(Instance), mode(modeletter), m_type(type) { } @@ -156,10 +159,10 @@ userrec* ModeParser::SanityChecks(userrec *user,const char *dest,chanrec *chan,i { return NULL; } - d = Find(dest); + d = ServerInstance->FindNick(dest); if (!d) { - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); + user->WriteServ("401 %s %s :No such nick/channel",user->nick, dest); return NULL; } return d; @@ -238,31 +241,50 @@ void ModeParser::DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec if (targetchannel) { /* Display channel's current mode string */ - WriteServ(user->fd,"324 %s %s +%s",user->nick, targetchannel->name, chanmodes(targetchannel, targetchannel->HasUser(user))); - WriteServ(user->fd,"329 %s %s %d", user->nick, targetchannel->name, targetchannel->created); + user->WriteServ("324 %s %s +%s",user->nick, targetchannel->name, targetchannel->ChanModes(targetchannel->HasUser(user))); + user->WriteServ("329 %s %s %d", user->nick, targetchannel->name, targetchannel->created); return; } else if (targetuser) { /* Display user's current mode string */ - WriteServ(user->fd,"221 %s :+%s",targetuser->nick,targetuser->FormatModes()); + user->WriteServ("221 %s :+%s",targetuser->nick,targetuser->FormatModes()); + user->WriteServ("008 %s :+%s", targetuser->nick, targetuser->FormatNoticeMasks()); return; } + /* No such nick/channel */ - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, text); + user->WriteServ("401 %s %s :No such nick/channel",user->nick, text); return; } -void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool servermode) +void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool servermode) { std::string target = parameters[0]; ModeType type = MODETYPE_USER; unsigned char mask = 0; - chanrec* targetchannel = FindChan(parameters[0]); - userrec* targetuser = Find(parameters[0]); + chanrec* targetchannel = ServerInstance->FindChan(parameters[0]); + userrec* targetuser = ServerInstance->FindNick(parameters[0]); log(DEBUG,"ModeParser::Process start"); + /* Special case for displaying the list for listmodes, + * e.g. MODE #chan b, or MODE #chan +b without a parameter + */ + if ((targetchannel) && (pcnt == 2)) + { + 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())) + { + mh->DisplayList(user, targetchannel); + return; + } + } + if (pcnt == 1) { this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0]); @@ -278,7 +300,7 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server * (e.g. are they a (half)op? */ - if (cstatus(user, targetchannel) < STATUS_HOP) + if ((IS_LOCAL(user)) && (targetchannel->GetStatus(user) < STATUS_HOP)) { /* We don't have halfop */ log(DEBUG,"The user is not a halfop or above, checking other reasons for being able to set the modes"); @@ -290,7 +312,7 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server * NOT a uline and NOT a servermode, * OR, NOT halfop or above. */ - WriteServ(user->fd,"482 %s %s :You're not a channel (half)operator",user->nick, targetchannel->name); + user->WriteServ("482 %s %s :You're not a channel (half)operator",user->nick, targetchannel->name); return; } } @@ -303,28 +325,10 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server else { /* No such nick/channel */ - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); + user->WriteServ("401 %s %s :No such nick/channel",user->nick, parameters[0]); return; } - /* Special case for displaying the list for listmodes, - * e.g. MODE #chan b, or MODE #chan +b without a parameter - */ - if ((type== MODETYPE_CHANNEL) && (pcnt == 2)) - { - char* mode = parameters[1]; - if (*mode == '+') - mode++; - - unsigned char handler_id = ((*mode) - 65) | mask; - ModeHandler* mh = modehandlers[handler_id]; - - if ((mh) && (mh->IsListMode())) - { - mh->DisplayList(user, targetchannel); - } - } - std::string mode_sequence = parameters[1]; std::string parameter = ""; std::ostringstream parameter_list; @@ -442,7 +446,7 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server else { /* No mode handler? Unknown mode character then. */ - WriteServ(user->fd,"472 %s %c :is unknown mode char to me",user->nick, modechar); + user->WriteServ("472 %s %c :is unknown mode char to me",user->nick, modechar); } break; } @@ -454,11 +458,11 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server { if (type == MODETYPE_CHANNEL) { - WriteChannelWithServ(Config->ServerName,targetchannel,"MODE %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str()); + targetchannel->WriteChannelWithServ(ServerInstance->Config->ServerName, "MODE %s %s%s", targetchannel->name, output_sequence.c_str(), parameter_list.str().c_str()); } else { - WriteServ(targetuser->fd,"MODE %s %s",targetuser->nick,output_sequence.c_str()); + targetuser->WriteServ("MODE %s %s",targetuser->nick,output_sequence.c_str()); } } else @@ -466,12 +470,12 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server if (type == MODETYPE_CHANNEL) { log(DEBUG,"Write output sequence and parameters to channel: %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str()); - WriteChannel(targetchannel,user,"MODE %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())); } else { - WriteTo(user,targetuser,"MODE %s %s",targetuser->nick,output_sequence.c_str()); + user->WriteTo(targetuser,"MODE %s %s",targetuser->nick,output_sequence.c_str()); FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence)); } } @@ -480,7 +484,7 @@ void ModeParser::Process(char **parameters, int pcnt, userrec *user, bool server } -void cmd_mode::Handle (char **parameters, int pcnt, userrec *user) +void cmd_mode::Handle (const char** parameters, int pcnt, userrec *user) { if (!user) return; @@ -546,6 +550,68 @@ bool ModeParser::AddMode(ModeHandler* mh, unsigned const char modeletter) return true; } +ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt) +{ + unsigned char mask = 0; + unsigned char pos = 0; + + if ((modeletter < 'A') || (modeletter > 'z')) + return NULL; + + mt == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL; + pos = (modeletter-65) | mask; + + return modehandlers[pos]; +} + +std::string ModeParser::UserModeList() +{ + char modestr[256]; + int pointer = 0; + + for (unsigned char mode = 'A'; mode <= 'z'; mode++) + { + unsigned char pos = (mode-65) | MASK_USER; + + if (modehandlers[pos]) + modestr[pointer++] = mode; + } + modestr[pointer++] = 0; + return modestr; +} + +std::string ModeParser::ChannelModeList() +{ + char modestr[256]; + int pointer = 0; + + for (unsigned char mode = 'A'; mode <= 'z'; mode++) + { + unsigned char pos = (mode-65) | MASK_CHANNEL; + + if (modehandlers[pos]) + modestr[pointer++] = mode; + } + modestr[pointer++] = 0; + return modestr; +} + +std::string ModeParser::ParaModeList() +{ + char modestr[256]; + int pointer = 0; + + for (unsigned char mode = 'A'; mode <= 'z'; mode++) + { + unsigned char pos = (mode-65) | MASK_CHANNEL; + + if ((modehandlers[pos]) && (modehandlers[pos]->GetNumParams(true))) + modestr[pointer++] = mode; + } + modestr[pointer++] = 0; + return modestr; +} + bool ModeParser::AddModeWatcher(ModeWatcher* mw) { unsigned char mask = 0; @@ -591,7 +657,7 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw) return true; } -ModeParser::ModeParser() +ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance) { /* Clear mode list */ memset(modehandlers, 0, sizeof(modehandlers)); @@ -600,28 +666,52 @@ ModeParser::ModeParser() /* Initialise the RFC mode letters */ /* Start with channel simple modes, no params */ - this->AddMode(new ModeChannelSecret, 's'); - this->AddMode(new ModeChannelPrivate, 'p'); - this->AddMode(new ModeChannelModerated, 'm'); - this->AddMode(new ModeChannelTopicOps, 't'); - this->AddMode(new ModeChannelNoExternal, 'n'); - this->AddMode(new ModeChannelInviteOnly, 'i'); + 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, 'k'); - this->AddMode(new ModeChannelLimit, 'l'); + this->AddMode(new ModeChannelKey(Instance), 'k'); + this->AddMode(new ModeChannelLimit(Instance), 'l'); /* Channel listmodes */ - this->AddMode(new ModeChannelBan, 'b'); - this->AddMode(new ModeChannelOp, 'o'); - this->AddMode(new ModeChannelHalfOp, 'h'); - this->AddMode(new ModeChannelVoice, 'v'); + 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, 's'); - this->AddMode(new ModeUserWallops, 'w'); - this->AddMode(new ModeUserInvisible, 'i'); - this->AddMode(new ModeUserOperator, 'o'); - this->AddMode(new ModeUserServerNoticeMask, 'n'); + 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'); +} + +bool ModeParser::InsertMode(std::string &output, const char* mode, unsigned short section) +{ + unsigned short currsection = 1; + unsigned int pos = output.find("CHANMODES=", 0) + 10; // +10 for the length of "CHANMODES=" + + if(section > 4 || section == 0) + { + log(DEBUG, "InsertMode: CHANMODES doesn't have a section %dh :/", section); + return false; + } + + for(; pos < output.size(); pos++) + { + if(section == currsection) + break; + + if(output[pos] == ',') + currsection++; + } + + output.insert(pos, mode); + return true; }