summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_chanhistory.cpp83
-rw-r--r--src/modules/m_delaymsg.cpp63
-rw-r--r--src/modules/m_joinflood.cpp64
-rw-r--r--src/modules/m_kicknorejoin.cpp76
-rw-r--r--src/modules/m_messageflood.cpp66
-rw-r--r--src/modules/m_nickflood.cpp62
-rw-r--r--src/modules/m_redirect.cpp66
-rw-r--r--src/modules/m_repeat.cpp127
8 files changed, 281 insertions, 326 deletions
diff --git a/src/modules/m_chanhistory.cpp b/src/modules/m_chanhistory.cpp
index 24c6237b3..f6e7ea40e 100644
--- a/src/modules/m_chanhistory.cpp
+++ b/src/modules/m_chanhistory.cpp
@@ -30,10 +30,13 @@ struct HistoryList
{
std::deque<HistoryItem> lines;
unsigned int maxlen, maxtime;
- HistoryList(unsigned int len, unsigned int time) : maxlen(len), maxtime(time) {}
+ std::string param;
+
+ HistoryList(unsigned int len, unsigned int time, const std::string& oparam)
+ : maxlen(len), maxtime(time), param(oparam) { }
};
-class HistoryMode : public ModeHandler
+class HistoryMode : public ParamMode<HistoryMode, SimpleExtItem<HistoryList> >
{
bool IsValidDuration(const std::string& duration)
{
@@ -50,57 +53,53 @@ class HistoryMode : public ModeHandler
}
public:
- SimpleExtItem<HistoryList> ext;
unsigned int maxlines;
- HistoryMode(Module* Creator) : ModeHandler(Creator, "history", 'H', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("history", Creator) { }
+ HistoryMode(Module* Creator)
+ : ParamMode<HistoryMode, SimpleExtItem<HistoryList> >(Creator, "history", 'H')
+ {
+ }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
+ std::string::size_type colon = parameter.find(':');
+ if (colon == std::string::npos)
+ return MODEACTION_DENY;
+
+ std::string duration = parameter.substr(colon+1);
+ if ((IS_LOCAL(source)) && ((duration.length() > 10) || (!IsValidDuration(duration))))
+ return MODEACTION_DENY;
+
+ unsigned int len = ConvToInt(parameter.substr(0, colon));
+ int time = InspIRCd::Duration(duration);
+ if (len == 0 || time < 0)
+ return MODEACTION_DENY;
+ if (len > maxlines && IS_LOCAL(source))
+ return MODEACTION_DENY;
+ if (len > maxlines)
+ len = maxlines;
+
+ HistoryList* history = ext.get(channel);
+ if (history)
{
- std::string::size_type colon = parameter.find(':');
- if (colon == std::string::npos)
- return MODEACTION_DENY;
-
- std::string duration = parameter.substr(colon+1);
- if ((IS_LOCAL(source)) && ((duration.length() > 10) || (!IsValidDuration(duration))))
- return MODEACTION_DENY;
-
- unsigned int len = ConvToInt(parameter.substr(0, colon));
- int time = InspIRCd::Duration(duration);
- if (len == 0 || time < 0)
- return MODEACTION_DENY;
- if (len > maxlines && IS_LOCAL(source))
- return MODEACTION_DENY;
- if (len > maxlines)
- len = maxlines;
- if (parameter == channel->GetModeParameter(this))
- return MODEACTION_DENY;
-
- HistoryList* history = ext.get(channel);
- if (history)
- {
- // Shrink the list if the new line number limit is lower than the old one
- if (len < history->lines.size())
- history->lines.erase(history->lines.begin(), history->lines.begin() + (history->lines.size() - len));
+ // Shrink the list if the new line number limit is lower than the old one
+ if (len < history->lines.size())
+ history->lines.erase(history->lines.begin(), history->lines.begin() + (history->lines.size() - len));
- history->maxlen = len;
- history->maxtime = time;
- }
- else
- {
- ext.set(channel, new HistoryList(len, time));
- }
+ history->maxlen = len;
+ history->maxtime = time;
+ history->param = parameter;
}
else
{
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
- ext.unset(channel);
+ ext.set(channel, new HistoryList(len, time, parameter));
}
return MODEACTION_ALLOW;
}
+
+ void SerializeParam(Channel* chan, const HistoryList* history, std::string& out)
+ {
+ out.append(history->param);
+ }
};
class ModuleChanHistory : public Module
diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp
index 031680e18..1730663c5 100644
--- a/src/modules/m_delaymsg.cpp
+++ b/src/modules/m_delaymsg.cpp
@@ -19,11 +19,12 @@
#include "inspircd.h"
-class DelayMsgMode : public ModeHandler
+class DelayMsgMode : public ParamMode<DelayMsgMode, LocalIntExt>
{
public:
LocalIntExt jointime;
- DelayMsgMode(Module* Parent) : ModeHandler(Parent, "delaymsg", 'd', PARAM_SETONLY, MODETYPE_CHANNEL)
+ DelayMsgMode(Module* Parent)
+ : ParamMode<DelayMsgMode, LocalIntExt>(Parent, "delaymsg", 'd')
, jointime("delaymsg", Parent)
{
levelrequired = OP_VALUE;
@@ -34,7 +35,13 @@ class DelayMsgMode : public ModeHandler
return (atoi(their_param.c_str()) < atoi(our_param.c_str()));
}
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
+ ModeAction OnSet(User* source, Channel* chan, std::string& parameter);
+ void OnUnset(User* source, Channel* chan);
+
+ void SerializeParam(Channel* chan, int n, std::string& out)
+ {
+ out += ConvToStr(n);
+ }
};
class ModuleDelayMsg : public Module
@@ -50,37 +57,27 @@ class ModuleDelayMsg : public Module
ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE;
};
-ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ModeAction DelayMsgMode::OnSet(User* source, Channel* chan, std::string& parameter)
{
- if (adding)
- {
- if ((channel->IsModeSet(this)) && (channel->GetModeParameter(this) == parameter))
- return MODEACTION_DENY;
+ // Setting a new limit, sanity check
+ unsigned int limit = ConvToInt(parameter);
+ if (limit == 0)
+ limit = 1;
- /* Setting a new limit, sanity check */
- long limit = atoi(parameter.c_str());
-
- /* Wrap low values at 32768 */
- if (limit < 0)
- limit = 0x7FFF;
-
- parameter = ConvToStr(limit);
- }
- else
- {
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
-
- /*
- * Clean up metadata
- */
- const UserMembList* names = channel->GetUsers();
- for (UserMembCIter n = names->begin(); n != names->end(); ++n)
- jointime.set(n->second, 0);
- }
+ ext.set(chan, limit);
return MODEACTION_ALLOW;
}
+void DelayMsgMode::OnUnset(User* source, Channel* chan)
+{
+ /*
+ * Clean up metadata
+ */
+ const UserMembList* names = chan->GetUsers();
+ for (UserMembCIter n = names->begin(); n != names->end(); ++n)
+ jointime.set(n->second, 0);
+}
+
Version ModuleDelayMsg::GetVersion()
{
return Version("Provides channelmode +d <int>, to deny messages to a channel until <int> seconds.", VF_VENDOR);
@@ -114,14 +111,14 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty
if (ts == 0)
return MOD_RES_PASSTHRU;
- std::string len = channel->GetModeParameter(&djm);
+ int len = djm.ext.get(channel);
- if (ts + atoi(len.c_str()) > ServerInstance->Time())
+ if ((ts + len) > ServerInstance->Time())
{
if (channel->GetPrefixValue(user) < VOICE_VALUE)
{
- user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :You must wait %s seconds after joining to send to channel (+d)",
- channel->name.c_str(), len.c_str());
+ user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :You must wait %d seconds after joining to send to channel (+d)",
+ channel->name.c_str(), len);
return MOD_RES_DENY;
}
}
diff --git a/src/modules/m_joinflood.cpp b/src/modules/m_joinflood.cpp
index edce2b22c..52802f168 100644
--- a/src/modules/m_joinflood.cpp
+++ b/src/modules/m_joinflood.cpp
@@ -82,52 +82,40 @@ class joinfloodsettings
/** Handles channel mode +j
*/
-class JoinFlood : public ModeHandler
+class JoinFlood : public ParamMode<JoinFlood, SimpleExtItem<joinfloodsettings> >
{
public:
- SimpleExtItem<joinfloodsettings> ext;
- JoinFlood(Module* Creator) : ModeHandler(Creator, "joinflood", 'j', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("joinflood", Creator) { }
+ JoinFlood(Module* Creator)
+ : ParamMode<JoinFlood, SimpleExtItem<joinfloodsettings> >(Creator, "joinflood", 'j')
+ {
+ }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
+ std::string::size_type colon = parameter.find(':');
+ if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
{
- std::string::size_type colon = parameter.find(':');
- if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
- return MODEACTION_DENY;
- }
-
- /* Set up the flood parameters for this channel */
- unsigned int njoins = ConvToInt(parameter.substr(0, colon));
- unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
- if ((njoins<1) || (nsecs<1))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
- return MODEACTION_DENY;
- }
-
- joinfloodsettings jfs(nsecs, njoins);
- joinfloodsettings* f = ext.get(channel);
- if ((f) && (*f == jfs))
- // mode params match
- return MODEACTION_DENY;
-
- ext.set(channel, jfs);
- parameter = ConvToStr(njoins) + ":" + ConvToStr(nsecs);
- return MODEACTION_ALLOW;
+ source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
+ return MODEACTION_DENY;
}
- else
- {
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
- ext.unset(channel);
- return MODEACTION_ALLOW;
+ /* Set up the flood parameters for this channel */
+ unsigned int njoins = ConvToInt(parameter.substr(0, colon));
+ unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
+ if ((njoins<1) || (nsecs<1))
+ {
+ source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
+ return MODEACTION_DENY;
}
- return MODEACTION_DENY;
+
+ ext.set(channel, new joinfloodsettings(nsecs, njoins));
+ return MODEACTION_ALLOW;
+ }
+
+ void SerializeParam(Channel* chan, const joinfloodsettings* jfs, std::string& out)
+ {
+ out.append(ConvToStr(jfs->joins)).push_back(':');
+ out.append(ConvToStr(jfs->secs));
}
};
diff --git a/src/modules/m_kicknorejoin.cpp b/src/modules/m_kicknorejoin.cpp
index ce95085d8..fdb7b8f24 100644
--- a/src/modules/m_kicknorejoin.cpp
+++ b/src/modules/m_kicknorejoin.cpp
@@ -27,43 +27,42 @@
typedef std::map<std::string, time_t> delaylist;
+struct KickRejoinData
+{
+ delaylist kicked;
+ unsigned int delay;
+
+ KickRejoinData(unsigned int Delay) : delay(Delay) { }
+};
+
/** Handles channel mode +J
*/
-class KickRejoin : public ModeHandler
+class KickRejoin : public ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >
{
static const unsigned int max = 60;
public:
- SimpleExtItem<delaylist> ext;
KickRejoin(Module* Creator)
- : ModeHandler(Creator, "kicknorejoin", 'J', PARAM_SETONLY, MODETYPE_CHANNEL)
- , ext("norejoinusers", Creator)
+ : ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >(Creator, "kicknorejoin", 'J')
{
}
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
- {
- int v = ConvToInt(parameter);
- if (v <= 0)
- return MODEACTION_DENY;
- if (parameter == channel->GetModeParameter(this))
- return MODEACTION_DENY;
-
- if ((IS_LOCAL(source) && ((unsigned int)v > max)))
- v = max;
+ int v = ConvToInt(parameter);
+ if (v <= 0)
+ return MODEACTION_DENY;
- parameter = ConvToStr(v);
- }
- else
- {
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
+ if ((IS_LOCAL(source) && ((unsigned int)v > max)))
+ v = max;
- ext.unset(channel);
- }
+ ext.set(channel, new KickRejoinData(v));
return MODEACTION_ALLOW;
}
+
+ void SerializeParam(Channel* chan, const KickRejoinData* krd, std::string& out)
+ {
+ out.append(ConvToStr(krd->delay));
+ }
};
class ModuleKickNoRejoin : public Module
@@ -80,18 +79,18 @@ public:
{
if (chan)
{
- delaylist* dl = kr.ext.get(chan);
- if (dl)
+ KickRejoinData* data = kr.ext.get(chan);
+ if (data)
{
- for (delaylist::iterator iter = dl->begin(); iter != dl->end(); )
+ delaylist& kicked = data->kicked;
+ for (delaylist::iterator iter = kicked.begin(); iter != kicked.end(); )
{
if (iter->second > ServerInstance->Time())
{
if (iter->first == user->uuid)
{
- std::string modeparam = chan->GetModeParameter(&kr);
- user->WriteNumeric(ERR_DELAYREJOIN, "%s :You must wait %s seconds after being kicked to rejoin (+J)",
- chan->name.c_str(), modeparam.c_str());
+ user->WriteNumeric(ERR_DELAYREJOIN, "%s :You must wait %u seconds after being kicked to rejoin (+J)",
+ chan->name.c_str(), data->delay);
return MOD_RES_DENY;
}
++iter;
@@ -99,12 +98,9 @@ public:
else
{
// Expired record, remove.
- dl->erase(iter++);
+ kicked.erase(iter++);
}
}
-
- if (dl->empty())
- kr.ext.unset(chan);
}
}
return MOD_RES_PASSTHRU;
@@ -112,15 +108,13 @@ public:
void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) CXX11_OVERRIDE
{
- if (memb->chan->IsModeSet(&kr) && (IS_LOCAL(memb->user)) && (source != memb->user))
+ if ((!IS_LOCAL(memb->user)) || (source == memb->user))
+ return;
+
+ KickRejoinData* data = kr.ext.get(memb->chan);
+ if (data)
{
- delaylist* dl = kr.ext.get(memb->chan);
- if (!dl)
- {
- dl = new delaylist;
- kr.ext.set(memb->chan, dl);
- }
- (*dl)[memb->user->uuid] = ServerInstance->Time() + ConvToInt(memb->chan->GetModeParameter(&kr));
+ data->kicked[memb->user->uuid] = ServerInstance->Time() + data->delay;
}
}
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index e2d752d18..92d67b9ab 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -64,52 +64,44 @@ class floodsettings
/** Handles channel mode +f
*/
-class MsgFlood : public ModeHandler
+class MsgFlood : public ParamMode<MsgFlood, SimpleExtItem<floodsettings> >
{
public:
- SimpleExtItem<floodsettings> ext;
- MsgFlood(Module* Creator) : ModeHandler(Creator, "flood", 'f', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("messageflood", Creator) { }
+ MsgFlood(Module* Creator)
+ : ParamMode<MsgFlood, SimpleExtItem<floodsettings> >(Creator, "flood", 'f')
+ {
+ }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
+ std::string::size_type colon = parameter.find(':');
+ if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
{
- std::string::size_type colon = parameter.find(':');
- if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter", channel->name.c_str());
- return MODEACTION_DENY;
- }
-
- /* Set up the flood parameters for this channel */
- bool ban = (parameter[0] == '*');
- unsigned int nlines = ConvToInt(parameter.substr(ban ? 1 : 0, ban ? colon-1 : colon));
- unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
-
- if ((nlines<2) || (nsecs<1))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter", channel->name.c_str());
- return MODEACTION_DENY;
- }
+ source->WriteNumeric(608, "%s :Invalid flood parameter", channel->name.c_str());
+ return MODEACTION_DENY;
+ }
- floodsettings* f = ext.get(channel);
- if ((f) && (nlines == f->lines) && (nsecs == f->secs) && (ban == f->ban))
- // mode params match
- return MODEACTION_DENY;
+ /* Set up the flood parameters for this channel */
+ bool ban = (parameter[0] == '*');
+ unsigned int nlines = ConvToInt(parameter.substr(ban ? 1 : 0, ban ? colon-1 : colon));
+ unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
- ext.set(channel, new floodsettings(ban, nsecs, nlines));
- parameter = std::string(ban ? "*" : "") + ConvToStr(nlines) + ":" + ConvToStr(nsecs);
- return MODEACTION_ALLOW;
- }
- else
+ if ((nlines<2) || (nsecs<1))
{
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
-
- ext.unset(channel);
- return MODEACTION_ALLOW;
+ source->WriteNumeric(608, "%s :Invalid flood parameter", channel->name.c_str());
+ return MODEACTION_DENY;
}
+
+ ext.set(channel, new floodsettings(ban, nsecs, nlines));
+ return MODEACTION_ALLOW;
+ }
+
+ void SerializeParam(Channel* chan, const floodsettings* fs, std::string& out)
+ {
+ if (fs->ban)
+ out.push_back('*');
+ out.append(ConvToStr(fs->lines)).push_back(':');
+ out.append(ConvToStr(fs->secs));
}
};
diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp
index 93fbbfaaa..f74a18422 100644
--- a/src/modules/m_nickflood.cpp
+++ b/src/modules/m_nickflood.cpp
@@ -78,51 +78,41 @@ class nickfloodsettings
/** Handles channel mode +F
*/
-class NickFlood : public ModeHandler
+class NickFlood : public ParamMode<NickFlood, SimpleExtItem<nickfloodsettings> >
{
public:
- SimpleExtItem<nickfloodsettings> ext;
- NickFlood(Module* Creator) : ModeHandler(Creator, "nickflood", 'F', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("nickflood", Creator) { }
+ NickFlood(Module* Creator)
+ : ParamMode<NickFlood, SimpleExtItem<nickfloodsettings> >(Creator, "nickflood", 'F')
+ {
+ }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
+ std::string::size_type colon = parameter.find(':');
+ if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
{
- std::string::size_type colon = parameter.find(':');
- if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
- return MODEACTION_DENY;
- }
-
- /* Set up the flood parameters for this channel */
- unsigned int nnicks = ConvToInt(parameter.substr(0, colon));
- unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
-
- if ((nnicks<1) || (nsecs<1))
- {
- source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
- return MODEACTION_DENY;
- }
+ source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
+ return MODEACTION_DENY;
+ }
- nickfloodsettings* f = ext.get(channel);
- if ((f) && (nnicks == f->nicks) && (nsecs == f->secs))
- // mode params match
- return MODEACTION_DENY;
+ /* Set up the flood parameters for this channel */
+ unsigned int nnicks = ConvToInt(parameter.substr(0, colon));
+ unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
- ext.set(channel, new nickfloodsettings(nsecs, nnicks));
- parameter = ConvToStr(nnicks) + ":" + ConvToStr(nsecs);
- return MODEACTION_ALLOW;
- }
- else
+ if ((nnicks<1) || (nsecs<1))
{
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
-
- ext.unset(channel);
- return MODEACTION_ALLOW;
+ source->WriteNumeric(608, "%s :Invalid flood parameter",channel->name.c_str());
+ return MODEACTION_DENY;
}
+
+ ext.set(channel, new nickfloodsettings(nsecs, nnicks));
+ return MODEACTION_ALLOW;
+ }
+
+ void SerializeParam(Channel* chan, const nickfloodsettings* nfs, std::string& out)
+ {
+ out.append(ConvToStr(nfs->nicks)).push_back(':');
+ out.append(ConvToStr(nfs->secs));
}
};
diff --git a/src/modules/m_redirect.cpp b/src/modules/m_redirect.cpp
index 5fc97d3c5..e822676bf 100644
--- a/src/modules/m_redirect.cpp
+++ b/src/modules/m_redirect.cpp
@@ -26,57 +26,49 @@
/** Handle channel mode +L
*/
-class Redirect : public ModeHandler
+class Redirect : public ParamMode<Redirect, LocalStringExt>
{
public:
- Redirect(Module* Creator) : ModeHandler(Creator, "redirect", 'L', PARAM_SETONLY, MODETYPE_CHANNEL) { }
+ Redirect(Module* Creator)
+ : ParamMode<Redirect, LocalStringExt>(Creator, "redirect", 'L') { }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
{
- if (adding)
+ if (IS_LOCAL(source))
{
- if (IS_LOCAL(source))
+ if (!ServerInstance->IsChannel(parameter))
{
- if (!ServerInstance->IsChannel(parameter))
- {
- source->WriteNumeric(ERR_NOSUCHCHANNEL, "%s :Invalid channel name", parameter.c_str());
- return MODEACTION_DENY;
- }
+ source->WriteNumeric(ERR_NOSUCHCHANNEL, "%s :Invalid channel name", parameter.c_str());
+ return MODEACTION_DENY;
}
+ }
- if (IS_LOCAL(source) && !source->IsOper())
+ if (IS_LOCAL(source) && !source->IsOper())
+ {
+ Channel* c = ServerInstance->FindChan(parameter);
+ if (!c)
{
- Channel* c = ServerInstance->FindChan(parameter);
- if (!c)
- {
- source->WriteNumeric(690, ":Target channel %s must exist to be set as a redirect.",parameter.c_str());
- return MODEACTION_DENY;
- }
- else if (c->GetPrefixValue(source) < OP_VALUE)
- {
- source->WriteNumeric(690, ":You must be opped on %s to set it as a redirect.",parameter.c_str());
- return MODEACTION_DENY;
- }
- }
-
- if (channel->GetModeParameter(this) == parameter)
+ source->WriteNumeric(690, ":Target channel %s must exist to be set as a redirect.",parameter.c_str());
return MODEACTION_DENY;
- /*
- * We used to do some checking for circular +L here, but there is no real need for this any more especially as we
- * now catch +L looping in PreJoin. Remove it, since O(n) logic makes me sad, and we catch it anyway. :) -- w00t
- */
- return MODEACTION_ALLOW;
- }
- else
- {
- if (channel->IsModeSet(this))
+ }
+ else if (c->GetPrefixValue(source) < OP_VALUE)
{
- return MODEACTION_ALLOW;
+ source->WriteNumeric(690, ":You must be opped on %s to set it as a redirect.",parameter.c_str());
+ return MODEACTION_DENY;
}
}
- return MODEACTION_DENY;
+ /*
+ * We used to do some checking for circular +L here, but there is no real need for this any more especially as we
+ * now catch +L looping in PreJoin. Remove it, since O(n) logic makes me sad, and we catch it anyway. :) -- w00t
+ */
+ ext.set(channel, parameter);
+ return MODEACTION_ALLOW;
+ }
+ void SerializeParam(Channel* chan, const std::string* str, std::string& out)
+ {
+ out += *str;
}
};
@@ -121,7 +113,7 @@ class ModuleRedirect : public Module
{
if (chan->GetUserCounter() >= ConvToInt(chan->GetModeParameter(limitmode)))
{
- std::string channel = chan->GetModeParameter(&re);
+ const std::string& channel = *re.ext.get(chan);
/* sometimes broken ulines can make circular or chained +L, avoid this */
Channel* destchan = ServerInstance->FindChan(channel);
diff --git a/src/modules/m_repeat.cpp b/src/modules/m_repeat.cpp
index d91fe7e8a..d8fccbffc 100644
--- a/src/modules/m_repeat.cpp
+++ b/src/modules/m_repeat.cpp
@@ -19,7 +19,45 @@
#include "inspircd.h"
-class RepeatMode : public ModeHandler
+class ChannelSettings
+{
+ public:
+ enum RepeatAction
+ {
+ ACT_KICK,
+ ACT_BLOCK,
+ ACT_BAN
+ };
+
+ RepeatAction Action;
+ unsigned int Backlog;
+ unsigned int Lines;
+ unsigned int Diff;
+ unsigned int Seconds;
+
+ void serialize(std::string& out) const
+ {
+ if (Action == ACT_BAN)
+ out.push_back('*');
+ else if (Action == ACT_BLOCK)
+ out.push_back('~');
+
+ out.append(ConvToStr(Lines)).push_back(':');
+ out.append(ConvToStr(Seconds));
+ if (Diff)
+ {
+ out.push_back(':');
+ out.append(ConvToStr(Diff));
+ if (Backlog)
+ {
+ out.push_back(':');
+ out.append(ConvToStr(Backlog));
+ }
+ }
+ }
+};
+
+class RepeatMode : public ParamMode<RepeatMode, SimpleExtItem<ChannelSettings> >
{
private:
struct RepeatItem
@@ -80,64 +118,24 @@ class RepeatMode : public ModeHandler
}
public:
- enum RepeatAction
- {
- ACT_KICK,
- ACT_BLOCK,
- ACT_BAN
- };
-
- class ChannelSettings
- {
- public:
- RepeatAction Action;
- unsigned int Backlog;
- unsigned int Lines;
- unsigned int Diff;
- unsigned int Seconds;
-
- std::string serialize()
- {
- std::string ret = ((Action == ACT_BAN) ? "*" : (Action == ACT_BLOCK ? "~" : "")) + ConvToStr(Lines) + ":" + ConvToStr(Seconds);
- if (Diff)
- {
- ret += ":" + ConvToStr(Diff);
- if (Backlog)
- ret += ":" + ConvToStr(Backlog);
- }
- return ret;
- }
- };
-
SimpleExtItem<MemberInfo> MemberInfoExt;
- SimpleExtItem<ChannelSettings> ChanSet;
RepeatMode(Module* Creator)
- : ModeHandler(Creator, "repeat", 'E', PARAM_SETONLY, MODETYPE_CHANNEL)
+ : ParamMode<RepeatMode, SimpleExtItem<ChannelSettings> >(Creator, "repeat", 'E')
, MemberInfoExt("repeat_memb", Creator)
- , ChanSet("repeat", Creator)
{
}
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding)
+ void OnUnset(User* source, Channel* chan)
{
- if (!adding)
- {
- if (!channel->IsModeSet(this))
- return MODEACTION_DENY;
-
- // Unset the per-membership extension when the mode is removed
- const UserMembList* users = channel->GetUsers();
- for (UserMembCIter i = users->begin(); i != users->end(); ++i)
- MemberInfoExt.unset(i->second);
-
- ChanSet.unset(channel);
- return MODEACTION_ALLOW;
- }
-
- if (channel->GetModeParameter(this) == parameter)
- return MODEACTION_DENY;
+ // Unset the per-membership extension when the mode is removed
+ const UserMembList* users = chan->GetUsers();
+ for (UserMembCIter i = users->begin(); i != users->end(); ++i)
+ MemberInfoExt.unset(i->second);
+ }
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
+ {
ChannelSettings settings;
if (!ParseSettings(source, parameter, settings))
{
@@ -155,7 +153,7 @@ class RepeatMode : public ModeHandler
if ((localsource) && (!ValidateSettings(localsource, settings)))
return MODEACTION_DENY;
- ChanSet.set(channel, settings);
+ ext.set(channel, settings);
return MODEACTION_ALLOW;
}
@@ -197,7 +195,7 @@ class RepeatMode : public ModeHandler
{
if (++matches >= rs->Lines)
{
- if (rs->Action != ACT_BLOCK)
+ if (rs->Action != ChannelSettings::ACT_BLOCK)
rp->Counter = 0;
return true;
}
@@ -251,6 +249,11 @@ class RepeatMode : public ModeHandler
return ConvToStr(ms.MaxLines) + ":" + ConvToStr(ms.MaxSecs) + ":" + ConvToStr(ms.MaxDiff) + ":" + ConvToStr(ms.MaxBacklog);
}
+ void SerializeParam(Channel* chan, const ChannelSettings* chset, std::string& out)
+ {
+ chset->serialize(out);
+ }
+
private:
bool ParseSettings(User* source, std::string& parameter, ChannelSettings& settings)
{
@@ -262,11 +265,11 @@ class RepeatMode : public ModeHandler
if ((item[0] == '*') || (item[0] == '~'))
{
- settings.Action = ((item[0] == '*') ? ACT_BAN : ACT_BLOCK);
+ settings.Action = ((item[0] == '*') ? ChannelSettings::ACT_BAN : ChannelSettings::ACT_BLOCK);
item.erase(item.begin());
}
else
- settings.Action = ACT_KICK;
+ settings.Action = ChannelSettings::ACT_KICK;
if ((settings.Lines = ConvToInt(item)) == 0)
return false;
@@ -295,7 +298,6 @@ class RepeatMode : public ModeHandler
}
}
- parameter = settings.serialize();
return true;
}
@@ -352,26 +354,27 @@ class RepeatModule : public Module
if (target_type != TYPE_CHANNEL || !IS_LOCAL(user))
return MOD_RES_PASSTHRU;
- Membership* memb = ((Channel*)dest)->GetUser(user);
- if (!memb || !memb->chan->IsModeSet(&rm))
+ Channel* chan = reinterpret_cast<Channel*>(dest);
+ ChannelSettings* settings = rm.ext.get(chan);
+ if (!settings)
return MOD_RES_PASSTHRU;
- if (ServerInstance->OnCheckExemption(user, memb->chan, "repeat") == MOD_RES_ALLOW)
+ Membership* memb = chan->GetUser(user);
+ if (!memb)
return MOD_RES_PASSTHRU;
- RepeatMode::ChannelSettings* settings = rm.ChanSet.get(memb->chan);
- if (!settings)
+ if (ServerInstance->OnCheckExemption(user, chan, "repeat") == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
if (rm.MatchLine(memb, settings, text))
{
- if (settings->Action == RepeatMode::ACT_BLOCK)
+ if (settings->Action == ChannelSettings::ACT_BLOCK)
{
user->WriteNotice("*** This line is too similiar to one of your last lines.");
return MOD_RES_DENY;
}
- if (settings->Action == RepeatMode::ACT_BAN)
+ if (settings->Action == ChannelSettings::ACT_BAN)
{
std::vector<std::string> parameters;
parameters.push_back(memb->chan->name);