* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- * E-mail:
- * <brain@chatspike.net>
- * <Craig@chatspike.net>
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
*
* 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.
*
* ---------------------------------------------------
*/
#include "connection.h"
#include "users.h"
#include "modules.h"
-#include "message.h"
#include "inspstring.h"
#include "helperfuncs.h"
#include "commands.h"
/* +n (notice mask - our implementation of snomasks) */
#include "modes/umode_n.h"
-extern int MODCOUNT;
-extern std::vector<Module*> modules;
-extern std::vector<ircd_module*> 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)
{
}
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)
{
}
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)
{
}
{
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;
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());
- WriteServ(user->fd, "008 %s :+%s", targetuser->nick, targetuser->FormatNoticeMasks());
+ 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;
}
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]);
* (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");
* 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;
}
}
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))
- {
- const 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;
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;
}
{
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
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));
}
}
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;
return true;
}
-ModeParser::ModeParser()
+ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
{
/* Clear mode list */
memset(modehandlers, 0, sizeof(modehandlers));
/* 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;
}