/* +s (server notice masks) */
#include "modes/umode_s.h"
-ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired, TranslateType translate)
- : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), m_paramtype(translate), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired)
+ModeHandler::ModeHandler(InspIRCd* Instance, Module* Creator, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired, TranslateType translate)
+ : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), m_paramtype(translate), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired), creator(Creator)
{
}
return "";
}
-ModeAction ModeHandler::OnModeChange(User*, User*, Channel*, std::string&, bool, bool)
+ModeAction ModeHandler::OnModeChange(User*, User*, Channel*, std::string&, bool)
{
return MODEACTION_DENY;
}
return (theirs < ours);
}
-SimpleUserModeHandler::SimpleUserModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_USER, false)
-{
-}
-
-SimpleUserModeHandler::~SimpleUserModeHandler()
-{
-}
-
-SimpleChannelModeHandler::~SimpleChannelModeHandler()
-{
-}
-
-SimpleChannelModeHandler::SimpleChannelModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_CHANNEL, false)
-{
-}
-
-ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding, bool servermode)
+ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
{
if (adding)
{
}
-ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding, bool servermode)
+ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
{
if (adding)
{
return m_type;
}
-bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool, ModeType, bool)
+bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool, ModeType)
{
return true;
}
-void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, ModeType, bool)
+void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, ModeType)
{
}
}
else
{
- if (targetuser->Visibility && !targetuser->Visibility->VisibleTo(user))
- {
- user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), text);
- return;
- }
-
if (targetuser == user || user->HasPrivPermission("users/auspex"))
{
/* Display user's current mode string */
}
else
{
- user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
+ user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't view modes for other users", user->nick.c_str());
return;
}
}
}
ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool adding, const unsigned char modechar,
- std::string ¶meter, bool servermode, bool SkipACL)
+ std::string ¶meter, bool SkipACL)
{
ModeType type = chan ? MODETYPE_CHANNEL : MODETYPE_USER;
unsigned char mask = chan ? MASK_CHANNEL : MASK_USER;
ModeHandler *mh = FindMode(modechar, type);
int pcnt = mh->GetNumParams(adding);
- int MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode, OnRawMode(user, chan, modechar, parameter, adding, pcnt, servermode));
+ ModResult MOD_RESULT;
+ FIRST_MOD_RESULT(ServerInstance, OnRawMode, MOD_RESULT, (user, chan, modechar, parameter, adding, pcnt));
- if (IS_LOCAL(user) && (MOD_RESULT == ACR_DENY))
+ if (IS_LOCAL(user) && (MOD_RESULT == MOD_RES_DENY))
return MODEACTION_DENY;
- if (chan && !SkipACL && (MOD_RESULT != ACR_ALLOW))
+ if (chan && !SkipACL && (MOD_RESULT != MOD_RES_ALLOW))
{
char needed = mh->GetNeededPrefix();
ModeHandler* prefixmode = FindPrefix(needed);
for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
{
- if ((*watchers)->BeforeMode(user, targetuser, chan, parameter, adding, type, servermode) == false)
+ if ((*watchers)->BeforeMode(user, targetuser, chan, parameter, adding, type) == false)
return MODEACTION_DENY;
/* A module whacked the parameter completely, and there was one. abort. */
if (pcnt && parameter.empty())
}
/* Call the handler for the mode */
- ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding, servermode);
+ ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding);
if (pcnt && parameter.empty())
return MODEACTION_DENY;
}
for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
- (*watchers)->AfterMode(user, targetuser, chan, parameter, adding, type, servermode);
+ (*watchers)->AfterMode(user, targetuser, chan, parameter, adding, type);
return MODEACTION_ALLOW;
}
-void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool servermode, bool merge)
+void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool merge)
{
std::string target = parameters[0];
Channel* targetchannel = ServerInstance->FindChan(target);
bool SkipAccessChecks = false;
- if (servermode || !IS_LOCAL(user) || ServerInstance->ULine(user->server))
+ if (!IS_LOCAL(user) || ServerInstance->ULine(user->server))
{
SkipAccessChecks = true;
}
- else if (targetchannel)
+ else
{
/* Overall access control hook for mode change */
+ int hook = targetchannel ? AC_GENERAL_MODE : AC_GENERAL_UMODE;
+
LastParse = mode_sequence;
- int MOD_RESULT = 0;
- FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE));
+ ModResult MOD_RESULT;
+ FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user, targetuser, targetchannel, hook));
LastParse.clear();
- if (MOD_RESULT == ACR_DENY)
+ if (MOD_RESULT == MOD_RES_DENY)
return;
- SkipAccessChecks = (MOD_RESULT == ACR_ALLOW);
+ SkipAccessChecks = (MOD_RESULT == MOD_RES_ALLOW);
}
- else
+
+ if (targetuser && !SkipAccessChecks && user != targetuser)
{
- if (user != targetuser)
- {
- user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
- return;
- }
+ user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
+ return;
}
-
std::string output_mode;
std::ostringstream output_parameters;
LastParseParams.push_back(output_mode);
}
}
- ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, servermode, SkipAccessChecks);
+ ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, SkipAccessChecks);
if (ma != MODEACTION_ALLOW)
continue;
LastParse.append(output_mode);
LastParse.append(output_parameters.str());
- if (!user && targetchannel)
- targetchannel->WriteChannelWithServ(ServerInstance->Config->ServerName, "MODE %s", LastParse.c_str());
- else if (!user && targetuser)
- targetuser->WriteServ("MODE %s", LastParse.c_str());
- else if (targetchannel)
+ if (targetchannel)
{
targetchannel->WriteChannel(user, "MODE %s", LastParse.c_str());
FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, LastParseParams, LastParseTranslate));
}
- else if (targetuser)
+ else
{
targetuser->WriteFrom(user, "MODE %s", LastParse.c_str());
FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, LastParseParams, LastParseTranslate));
if (!mh || !mh->IsListMode())
return;
- int MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode, OnRawMode(user, chan, mletter, "", true, 0));
- if (MOD_RESULT == ACR_DENY)
+ ModResult MOD_RESULT;
+ FIRST_MOD_RESULT(ServerInstance, OnRawMode, MOD_RESULT, (user, chan, mletter, "", true, 0));
+ if (MOD_RESULT == MOD_RES_DENY)
continue;
bool display = true;
sprintf(moderemove,"-%c",this->GetModeChar());
parameters.push_back(user->nick);
parameters.push_back(moderemove);
- ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient, true);
+ ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient);
}
}
}
new ModeChannelPrivate(Instance),
new ModeChannelModerated(Instance),
new ModeChannelTopicOps(Instance),
+
new ModeChannelNoExternal(Instance),
new ModeChannelInviteOnly(Instance),
new ModeChannelKey(Instance),
new ModeChannelLimit(Instance),
+
new ModeChannelBan(Instance),
new ModeChannelOp(Instance),
new ModeChannelHalfOp(Instance),
new ModeChannelVoice(Instance),
+
new ModeUserWallops(Instance),
new ModeUserInvisible(Instance),
new ModeUserOperator(Instance),
new ModeUserServerNoticeMask(Instance),
- NULL
+#define BUILTIN_MODE_COUNT 16
};
/* Clear mode handler list */
LastParse.clear();
/* Initialise the RFC mode letters */
- for (int index = 0; modes[index]; index++)
+ for (int index = 0; index < BUILTIN_MODE_COUNT; index++)
this->AddMode(modes[index]);
seq = 0;
memset(&sent, 0, sizeof(sent));
}
+
+ModeParser::~ModeParser()
+{
+ int count = 0;
+ for(int i=0; i < 256; i++)
+ {
+ ModeHandler* mh = modehandlers[i];
+ if (mh)
+ {
+ count++;
+ delete mh;
+ }
+ }
+ if (count != BUILTIN_MODE_COUNT)
+ throw CoreException("Mode handler found non-core modes remaining at deallocation");
+}