summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mode.h12
-rw-r--r--include/modes/cmode_l.h6
-rw-r--r--src/mode.cpp19
-rw-r--r--src/modes/cmode_l.cpp38
-rw-r--r--src/modules/m_kicknorejoin.cpp84
5 files changed, 58 insertions, 101 deletions
diff --git a/include/mode.h b/include/mode.h
index f1768f559..a633cebca 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -105,7 +105,7 @@ class CoreExport ModeHandler : public classbase
/**
* The mode letter you're implementing.
*/
- const char mode;
+ char mode;
/** Mode prefix, or 0
*/
@@ -325,6 +325,16 @@ class CoreExport SimpleChannelModeHandler : public ModeHandler
virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
};
+class CoreExport ParamChannelModeHandler : public ModeHandler
+{
+ public:
+ ParamChannelModeHandler(Module* Creator, const std::string& Name, char modeletter)
+ : ModeHandler(Creator, Name, modeletter, PARAM_SETONLY, MODETYPE_CHANNEL) {}
+ virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
+ /** Validate the parameter - you may change the value to normalize it. Return true if it is valid. */
+ virtual bool ParamValidate(std::string& parameter);
+};
+
/**
* The ModeWatcher class can be used to alter the behaviour of a mode implemented
* by the core or by another module. To use ModeWatcher, derive a class from it,
diff --git a/include/modes/cmode_l.h b/include/modes/cmode_l.h
index dc93396d7..80e863057 100644
--- a/include/modes/cmode_l.h
+++ b/include/modes/cmode_l.h
@@ -13,14 +13,12 @@
#include "mode.h"
-class InspIRCd;
-
/** Channel mode +l
*/
-class ModeChannelLimit : public ModeHandler
+class ModeChannelLimit : public ParamChannelModeHandler
{
public:
ModeChannelLimit();
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
+ bool ParamValidate(std::string& parameter);
bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel* channel);
};
diff --git a/src/mode.cpp b/src/mode.cpp
index fb154d5e2..e9635364e 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -176,6 +176,25 @@ ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Chan
return MODEACTION_DENY;
}
+ModeAction ParamChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+{
+ if (adding && !ParamValidate(parameter))
+ return MODEACTION_DENY;
+ std::string now = channel->GetModeParameter(this);
+ if (parameter == now)
+ return MODEACTION_DENY;
+ if (adding)
+ channel->SetModeParam(this, parameter);
+ else
+ channel->SetModeParam(this, "");
+ return MODEACTION_ALLOW;
+}
+
+bool ParamChannelModeHandler::ParamValidate(std::string& parameter)
+{
+ return true;
+}
+
ModeWatcher::ModeWatcher(Module* Creator, char modeletter, ModeType type)
: mode(modeletter), m_type(type), creator(Creator)
{
diff --git a/src/modes/cmode_l.cpp b/src/modes/cmode_l.cpp
index fce195200..53a06949d 100644
--- a/src/modes/cmode_l.cpp
+++ b/src/modes/cmode_l.cpp
@@ -17,7 +17,7 @@
#include "users.h"
#include "modes/cmode_l.h"
-ModeChannelLimit::ModeChannelLimit() : ModeHandler(NULL, "limit", 'l', PARAM_SETONLY, MODETYPE_CHANNEL)
+ModeChannelLimit::ModeChannelLimit() : ParamChannelModeHandler(NULL, "limit", 'l')
{
}
@@ -27,37 +27,13 @@ bool ModeChannelLimit::ResolveModeConflict(std::string &their_param, const std::
return (atoi(their_param.c_str()) < atoi(our_param.c_str()));
}
-ModeAction ModeChannelLimit::OnModeChange(User*, User*, Channel* channel, std::string &parameter, bool adding)
+bool ModeChannelLimit::ParamValidate(std::string &parameter)
{
- if (adding)
- {
- /* Setting a new limit, sanity check */
- long limit = atoi(parameter.c_str());
+ int limit = atoi(parameter.c_str());
- /* Wrap low values at 32768 */
- if (limit < 0)
- limit = 0x7FFF;
+ if (limit < 0)
+ return false;
- parameter = ConvToStr(limit);
-
- /* Set new limit */
- channel->SetModeParam('l', parameter);
-
- return MODEACTION_ALLOW;
- }
- else
- {
- /* Check if theres a limit here to remove.
- * If there isnt, dont allow the -l
- */
- if (channel->GetModeParameter('l').empty())
- {
- parameter = "";
- return MODEACTION_DENY;
- }
-
- /* Removing old limit, no checks here */
- channel->SetModeParam('l', "");
- return MODEACTION_ALLOW;
- }
+ parameter = ConvToStr(limit);
+ return true;
}
diff --git a/src/modules/m_kicknorejoin.cpp b/src/modules/m_kicknorejoin.cpp
index aee4bf869..708ff17a8 100644
--- a/src/modules/m_kicknorejoin.cpp
+++ b/src/modules/m_kicknorejoin.cpp
@@ -15,78 +15,31 @@
/* $ModDesc: Provides channel mode +J (delay rejoin after kick) */
-static inline int strtoint(const std::string &str)
-{
- std::istringstream ss(str);
- int result;
- ss >> result;
- return result;
-}
-
typedef std::map<User*, time_t> delaylist;
/** Handles channel mode +J
*/
-class KickRejoin : public ModeHandler
+class KickRejoin : public ParamChannelModeHandler
{
public:
SimpleExtItem<delaylist> ext;
- KickRejoin(Module* Creator) : ModeHandler(Creator, "kicknorejoin", 'J', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("norejoinusers", Creator) { }
+ KickRejoin(Module* Creator) : ParamChannelModeHandler(Creator, "kicknorejoin", 'J'), ext("norejoinusers", Creator) { }
+
+ bool ParamValidate(std::string& parameter)
+ {
+ int v = atoi(parameter.c_str());
+ if (v <= 0)
+ return false;
+ parameter = ConvToStr(v);
+ return true;
+ }
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
{
- if (!adding)
- {
+ ModeAction rv = ParamChannelModeHandler::OnModeChange(source, dest, channel, parameter, adding);
+ if (rv == MODEACTION_ALLOW && !adding)
ext.unset(channel);
-
- if (!channel->IsModeSet('J'))
- {
- return MODEACTION_DENY;
- }
- else
- {
- channel->SetModeParam('J', "");
- return MODEACTION_ALLOW;
- }
- }
- else if (atoi(parameter.c_str()) > 0)
- {
- if (!channel->IsModeSet('J'))
- {
- parameter = ConvToStr(atoi(parameter.c_str()));
- channel->SetModeParam('J', parameter);
- return MODEACTION_ALLOW;
- }
- else
- {
- std::string cur_param = channel->GetModeParameter('J');
- if (cur_param == parameter)
- {
- // mode params match, don't change mode
- return MODEACTION_DENY;
- }
- else
- {
- // new mode param, replace old with new
- parameter = ConvToStr(atoi(parameter.c_str()));
- if (parameter != "0")
- {
- channel->SetModeParam('J', parameter);
- return MODEACTION_ALLOW;
- }
- else
- {
- /* Fix to jamie's fix, dont allow +J 0 on the new value! */
- return MODEACTION_DENY;
- }
- }
- }
- }
- else
- {
- return MODEACTION_DENY;
- }
+ return rv;
}
};
@@ -121,7 +74,8 @@ public:
{
if (iter->first == user)
{
- user->WriteNumeric(ERR_DELAYREJOIN, "%s %s :You must wait %s seconds after being kicked to rejoin (+J)", user->nick.c_str(), chan->name.c_str(), chan->GetModeParameter('J').c_str());
+ user->WriteNumeric(ERR_DELAYREJOIN, "%s %s :You must wait %s seconds after being kicked to rejoin (+J)",
+ user->nick.c_str(), chan->name.c_str(), chan->GetModeParameter(&kr).c_str());
return MOD_RES_DENY;
}
}
@@ -144,7 +98,7 @@ public:
void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts)
{
- if (memb->chan->IsModeSet('J') && (source != memb->user))
+ if (memb->chan->IsModeSet(&kr) && (source != memb->user))
{
delaylist* dl = kr.ext.get(memb->chan);
if (dl)
@@ -152,7 +106,7 @@ public:
dl = new delaylist;
kr.ext.set(memb->chan, dl);
}
- (*dl)[memb->user] = ServerInstance->Time() + strtoint(memb->chan->GetModeParameter('J'));
+ (*dl)[memb->user] = ServerInstance->Time() + atoi(memb->chan->GetModeParameter(&kr).c_str());
}
}
@@ -162,7 +116,7 @@ public:
Version GetVersion()
{
- return Version("Channel mode J, kick-no-rejoin", VF_COMMON | VF_VENDOR);
+ return Version("Channel mode to delay rejoin after kick", VF_COMMON | VF_VENDOR);
}
};