mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-12 12:09:03 -04:00
Add the rest of the <modeletters> support
This commit is contained in:
parent
bc6f9b687f
commit
ecdf81507a
@ -78,6 +78,8 @@ void ModeHandler::AdjustModeChar(char proposed_letter)
|
||||
{
|
||||
if (fixed_letter)
|
||||
return;
|
||||
if (!proposed_letter && GetPrefixRank())
|
||||
return;
|
||||
mode = proposed_letter;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class CensorUser : public SimpleUserModeHandler
|
||||
class CensorChannel : public SimpleChannelModeHandler
|
||||
{
|
||||
public:
|
||||
CensorChannel(Module* Creator) : SimpleChannelModeHandler(Creator, "censor", 'G') { }
|
||||
CensorChannel(Module* Creator) : SimpleChannelModeHandler(Creator, "censor", 'G') { fixed_letter = false; }
|
||||
};
|
||||
|
||||
class ModuleCensor : public Module
|
||||
@ -74,7 +74,7 @@ class ModuleCensor : public Module
|
||||
active = ((User*)dest)->IsModeSet('G');
|
||||
else if (target_type == TYPE_CHANNEL)
|
||||
{
|
||||
active = ((Channel*)dest)->IsModeSet('G');
|
||||
active = ((Channel*)dest)->IsModeSet(&cc);
|
||||
Channel* c = (Channel*)dest;
|
||||
ModResult res;
|
||||
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"censor"));
|
||||
|
@ -29,53 +29,18 @@ struct ChanProtectSettings
|
||||
|
||||
static ChanProtectSettings settings;
|
||||
|
||||
/** Handles basic operation of +qa channel modes
|
||||
*/
|
||||
class FounderProtectBase
|
||||
{
|
||||
private:
|
||||
const std::string type;
|
||||
const char mode;
|
||||
const int list;
|
||||
const int end;
|
||||
public:
|
||||
FounderProtectBase(char Mode, const std::string &mtype, int l, int e) :
|
||||
type(mtype), mode(Mode), list(l), end(e)
|
||||
{
|
||||
}
|
||||
|
||||
void DisplayList(User* user, Channel* channel)
|
||||
{
|
||||
const UserMembList* cl = channel->GetUsers();
|
||||
for (UserMembCIter i = cl->begin(); i != cl->end(); ++i)
|
||||
{
|
||||
if (i->second->hasMode(mode))
|
||||
{
|
||||
user->WriteServ("%d %s %s %s", list, user->nick.c_str(), channel->name.c_str(), i->first->nick.c_str());
|
||||
}
|
||||
}
|
||||
user->WriteServ("%d %s %s :End of channel %s list", end, user->nick.c_str(), channel->name.c_str(), type.c_str());
|
||||
}
|
||||
|
||||
bool CanRemoveOthers(User* u1, Channel* c)
|
||||
{
|
||||
Membership* m1 = c->GetUser(u1);
|
||||
return (settings.DeprivOthers && m1 && m1->hasMode(mode));
|
||||
}
|
||||
};
|
||||
|
||||
/** Abstraction of FounderProtectBase for channel mode +q
|
||||
*/
|
||||
class ChanFounder : public ModeHandler, public FounderProtectBase
|
||||
class ChanFounder : public ModeHandler
|
||||
{
|
||||
public:
|
||||
ChanFounder(Module* Creator)
|
||||
: ModeHandler(Creator, "founder", 'q', PARAM_ALWAYS, MODETYPE_CHANNEL),
|
||||
FounderProtectBase('q', "founder", 386, 387)
|
||||
: ModeHandler(Creator, "founder", 'q', PARAM_ALWAYS, MODETYPE_CHANNEL)
|
||||
{
|
||||
ModeHandler::list = true;
|
||||
levelrequired = FOUNDER_VALUE;
|
||||
m_paramtype = TR_NICK;
|
||||
fixed_letter = false;
|
||||
}
|
||||
|
||||
void setPrefix(int pfx)
|
||||
@ -95,7 +60,7 @@ class ChanFounder : public ModeHandler, public FounderProtectBase
|
||||
if (source == theuser && !adding && settings.DeprivSelf)
|
||||
return MOD_RES_ALLOW;
|
||||
|
||||
if (!adding && FounderProtectBase::CanRemoveOthers(source, channel))
|
||||
if (!adding && CanRemoveOthers(source, channel))
|
||||
{
|
||||
return MOD_RES_PASSTHRU;
|
||||
}
|
||||
@ -113,22 +78,36 @@ class ChanFounder : public ModeHandler, public FounderProtectBase
|
||||
|
||||
void DisplayList(User* user, Channel* channel)
|
||||
{
|
||||
FounderProtectBase::DisplayList(user,channel);
|
||||
const UserMembList* cl = channel->GetUsers();
|
||||
for (UserMembCIter i = cl->begin(); i != cl->end(); ++i)
|
||||
{
|
||||
if (i->second->hasMode(mode))
|
||||
{
|
||||
user->WriteServ("386 %s %s %s", user->nick.c_str(), channel->name.c_str(), i->first->nick.c_str());
|
||||
}
|
||||
}
|
||||
user->WriteServ("387 %s %s :End of channel founder list", user->nick.c_str(), channel->name.c_str());
|
||||
}
|
||||
|
||||
bool CanRemoveOthers(User* u1, Channel* c)
|
||||
{
|
||||
Membership* m1 = c->GetUser(u1);
|
||||
return (settings.DeprivOthers && m1 && m1->hasMode(mode));
|
||||
}
|
||||
};
|
||||
|
||||
/** Abstraction of FounderProtectBase for channel mode +a
|
||||
*/
|
||||
class ChanProtect : public ModeHandler, public FounderProtectBase
|
||||
class ChanProtect : public ModeHandler
|
||||
{
|
||||
public:
|
||||
ChanProtect(Module* Creator)
|
||||
: ModeHandler(Creator, "protected", 'a', PARAM_ALWAYS, MODETYPE_CHANNEL),
|
||||
FounderProtectBase('a',"protected user", 388, 389)
|
||||
: ModeHandler(Creator, "protected", 'a', PARAM_ALWAYS, MODETYPE_CHANNEL)
|
||||
{
|
||||
ModeHandler::list = true;
|
||||
levelrequired = PROTECT_VALUE;
|
||||
m_paramtype = TR_NICK;
|
||||
fixed_letter = false;
|
||||
}
|
||||
|
||||
void setPrefix(int pfx)
|
||||
@ -152,7 +131,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase
|
||||
if (source == theuser && !adding && settings.DeprivSelf)
|
||||
return MOD_RES_ALLOW;
|
||||
|
||||
if (!adding && FounderProtectBase::CanRemoveOthers(source, channel))
|
||||
if (!adding && CanRemoveOthers(source, channel))
|
||||
{
|
||||
return MOD_RES_PASSTHRU;
|
||||
}
|
||||
@ -170,9 +149,22 @@ class ChanProtect : public ModeHandler, public FounderProtectBase
|
||||
|
||||
void DisplayList(User* user, Channel* channel)
|
||||
{
|
||||
FounderProtectBase::DisplayList(user, channel);
|
||||
const UserMembList* cl = channel->GetUsers();
|
||||
for (UserMembCIter i = cl->begin(); i != cl->end(); ++i)
|
||||
{
|
||||
if (i->second->hasMode(mode))
|
||||
{
|
||||
user->WriteServ("388 %s %s %s", user->nick.c_str(), channel->name.c_str(), i->first->nick.c_str());
|
||||
}
|
||||
}
|
||||
user->WriteServ("389 %s %s :End of channel protected user list", user->nick.c_str(), channel->name.c_str());
|
||||
}
|
||||
|
||||
bool CanRemoveOthers(User* u1, Channel* c)
|
||||
{
|
||||
Membership* m1 = c->GetUser(u1);
|
||||
return (settings.DeprivOthers && m1 && m1->hasMode(mode));
|
||||
}
|
||||
};
|
||||
|
||||
class ModuleChanProtect : public Module
|
||||
@ -186,6 +178,7 @@ class ModuleChanProtect : public Module
|
||||
|
||||
void init()
|
||||
{
|
||||
settings.booting = true;
|
||||
/* Load config stuff */
|
||||
LoadSettings();
|
||||
settings.booting = false;
|
||||
@ -233,7 +226,7 @@ class ModuleChanProtect : public Module
|
||||
// the config option for it is set
|
||||
|
||||
if (settings.FirstInGetsFounder && !chan)
|
||||
privs += 'q';
|
||||
privs += cf.GetModeChar();
|
||||
|
||||
return MOD_RES_PASSTHRU;
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ class CommandKnock : public Command
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
|
||||
if (c->IsModeSet('K'))
|
||||
ModeHandler* mh = ServerInstance->Modes->FindMode("noknock");
|
||||
if (c->IsModeSet(mh))
|
||||
{
|
||||
user->WriteNumeric(480, "%s :Can't KNOCK on %s, +K is set.",user->nick.c_str(), c->name.c_str());
|
||||
user->WriteNumeric(480, "%s :Can't KNOCK on %s, noknock mode is set.",user->nick.c_str(), c->name.c_str());
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
|
||||
@ -78,7 +79,7 @@ class CommandKnock : public Command
|
||||
class Knock : public SimpleChannelModeHandler
|
||||
{
|
||||
public:
|
||||
Knock(Module* Creator) : SimpleChannelModeHandler(Creator, "noknock", 'K') { }
|
||||
Knock(Module* Creator) : SimpleChannelModeHandler(Creator, "noknock", 'K') { fixed_letter = false; }
|
||||
};
|
||||
|
||||
class ModuleKnock : public Module
|
||||
@ -88,18 +89,15 @@ class ModuleKnock : public Module
|
||||
public:
|
||||
ModuleKnock() : cmd(this), kn(this)
|
||||
{
|
||||
if (!ServerInstance->Modes->AddMode(&kn))
|
||||
throw ModuleException("Could not add new modes!");
|
||||
ServerInstance->AddCommand(&cmd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual ~ModuleKnock()
|
||||
void init()
|
||||
{
|
||||
ServerInstance->Modules->AddService(kn);
|
||||
ServerInstance->Modules->AddService(cmd);
|
||||
}
|
||||
|
||||
virtual Version GetVersion()
|
||||
Version GetVersion()
|
||||
{
|
||||
return Version("Provides support for /KNOCK and mode +K", VF_OPTCOMMON | VF_VENDOR);
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ class NetworkPrefix : public ModeHandler
|
||||
prefix = NPrefix;
|
||||
levelrequired = INT_MAX;
|
||||
m_paramtype = TR_NICK;
|
||||
fixed_letter = false;
|
||||
}
|
||||
|
||||
unsigned int GetPrefixRank()
|
||||
@ -155,7 +156,7 @@ class ModuleOjoin : public Module
|
||||
{
|
||||
if (mycommand.active)
|
||||
{
|
||||
privs += 'Y';
|
||||
privs += np->GetModeChar();
|
||||
if (op)
|
||||
privs += 'o';
|
||||
return MOD_RES_ALLOW;
|
||||
@ -185,7 +186,7 @@ class ModuleOjoin : public Module
|
||||
ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason)
|
||||
{
|
||||
// Don't do anything if they're not +Y
|
||||
if (!memb->hasMode('Y'))
|
||||
if (!memb->hasMode(np->GetModeChar()))
|
||||
return MOD_RES_PASSTHRU;
|
||||
|
||||
// Let them do whatever they want to themselves.
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
// Not in a class due to circular dependancy hell.
|
||||
static std::string permchannelsconf;
|
||||
static bool WriteDatabase()
|
||||
static bool WriteDatabase(ModeHandler* p)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
@ -46,7 +46,7 @@ static bool WriteDatabase()
|
||||
for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
|
||||
{
|
||||
Channel* chan = i->second;
|
||||
if (!chan->IsModeSet('P'))
|
||||
if (!chan->IsModeSet(p))
|
||||
continue;
|
||||
|
||||
char line[1024];
|
||||
@ -110,21 +110,26 @@ static bool WriteDatabase()
|
||||
class PermChannel : public ModeHandler
|
||||
{
|
||||
public:
|
||||
PermChannel(Module* Creator) : ModeHandler(Creator, "permanent", 'P', PARAM_NONE, MODETYPE_CHANNEL) { oper = true; }
|
||||
PermChannel(Module* Creator) : ModeHandler(Creator, "permanent", 'P', PARAM_NONE, MODETYPE_CHANNEL)
|
||||
{
|
||||
oper = true;
|
||||
fixed_letter = false;
|
||||
}
|
||||
|
||||
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
|
||||
{
|
||||
if (adding)
|
||||
{
|
||||
if (!channel->IsModeSet('P'))
|
||||
if (!channel->IsModeSet(this))
|
||||
{
|
||||
channel->SetMode('P',true);
|
||||
channel->SetMode(this,true);
|
||||
|
||||
return MODEACTION_ALLOW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channel->IsModeSet('P'))
|
||||
if (channel->IsModeSet(this))
|
||||
{
|
||||
channel->SetMode(this,false);
|
||||
if (channel->GetUserCounter() == 0)
|
||||
@ -160,26 +165,6 @@ public:
|
||||
|
||||
CullResult cull()
|
||||
{
|
||||
/*
|
||||
* DelMode can't remove the +P mode on empty channels, or it will break
|
||||
* merging modes with remote servers. Remove the empty channels now as
|
||||
* we know this is not the case.
|
||||
*/
|
||||
chan_hash::iterator iter = ServerInstance->chanlist->begin();
|
||||
while (iter != ServerInstance->chanlist->end())
|
||||
{
|
||||
Channel* c = iter->second;
|
||||
if (c->GetUserCounter() == 0)
|
||||
{
|
||||
chan_hash::iterator at = iter;
|
||||
iter++;
|
||||
FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(c));
|
||||
ServerInstance->chanlist->erase(at);
|
||||
ServerInstance->GlobalCulls.AddItem(c);
|
||||
}
|
||||
else
|
||||
iter++;
|
||||
}
|
||||
ServerInstance->Modes->DelMode(&p);
|
||||
return Module::cull();
|
||||
}
|
||||
@ -230,25 +215,13 @@ public:
|
||||
continue;
|
||||
|
||||
irc::spacesepstream list(modes);
|
||||
std::string modeseq;
|
||||
std::string par;
|
||||
std::vector<std::string> seq;
|
||||
seq.push_back(c->name);
|
||||
std::string token;
|
||||
while (list.GetToken(token))
|
||||
seq.push_back(token);
|
||||
|
||||
list.GetToken(modeseq);
|
||||
|
||||
// XXX bleh, should we pass this to the mode parser instead? ugly. --w00t
|
||||
for (std::string::iterator n = modeseq.begin(); n != modeseq.end(); ++n)
|
||||
{
|
||||
ModeHandler* mode = ServerInstance->Modes->FindMode(*n, MODETYPE_CHANNEL);
|
||||
if (mode)
|
||||
{
|
||||
if (mode->GetNumParams(true))
|
||||
list.GetToken(par);
|
||||
else
|
||||
par.clear();
|
||||
|
||||
mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true);
|
||||
}
|
||||
}
|
||||
ServerInstance->SendMode(seq, ServerInstance->FakeClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,20 +229,20 @@ public:
|
||||
void OnMode(User*, Extensible* dest, const irc::modestacker&)
|
||||
{
|
||||
Channel* chan = dynamic_cast<Channel*>(dest);
|
||||
if (chan && chan->IsModeSet('P'))
|
||||
if (chan && chan->IsModeSet(&p))
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
virtual void OnPostTopicChange(User*, Channel *c, const std::string&)
|
||||
void OnPostTopicChange(User*, Channel *c, const std::string&)
|
||||
{
|
||||
if (c->IsModeSet('P'))
|
||||
if (c->IsModeSet(&p))
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void OnBackgroundTimer(time_t)
|
||||
{
|
||||
if (dirty)
|
||||
WriteDatabase();
|
||||
WriteDatabase(&p);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
@ -280,7 +253,7 @@ public:
|
||||
|
||||
virtual ModResult OnChannelPreDelete(Channel *c)
|
||||
{
|
||||
if (c->IsModeSet('P'))
|
||||
if (c->IsModeSet(&p))
|
||||
return MOD_RES_DENY;
|
||||
|
||||
return MOD_RES_PASSTHRU;
|
||||
|
@ -20,7 +20,7 @@
|
||||
class Redirect : public ModeHandler
|
||||
{
|
||||
public:
|
||||
Redirect(Module* Creator) : ModeHandler(Creator, "redirect", 'L', PARAM_SETONLY, MODETYPE_CHANNEL) { }
|
||||
Redirect(Module* Creator) : ModeHandler(Creator, "redirect", 'L', PARAM_SETONLY, MODETYPE_CHANNEL) { fixed_letter = false; }
|
||||
|
||||
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
|
||||
{
|
||||
@ -57,14 +57,14 @@ class Redirect : public ModeHandler
|
||||
* 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
|
||||
*/
|
||||
channel->SetModeParam('L', parameter);
|
||||
channel->SetModeParam(this, parameter);
|
||||
return MODEACTION_ALLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channel->IsModeSet('L'))
|
||||
if (channel->IsModeSet(this))
|
||||
{
|
||||
channel->SetModeParam('L', "");
|
||||
channel->SetModeParam(this, "");
|
||||
return MODEACTION_ALLOW;
|
||||
}
|
||||
}
|
||||
@ -96,16 +96,16 @@ class ModuleRedirect : public Module
|
||||
{
|
||||
if (chan)
|
||||
{
|
||||
if (chan->IsModeSet('L') && chan->IsModeSet('l'))
|
||||
if (chan->IsModeSet(&re) && chan->IsModeSet('l'))
|
||||
{
|
||||
if (chan->GetUserCounter() >= atoi(chan->GetModeParameter('l').c_str()))
|
||||
{
|
||||
std::string channel = chan->GetModeParameter('L');
|
||||
std::string channel = chan->GetModeParameter(&re);
|
||||
|
||||
/* sometimes broken ulines can make circular or chained +L, avoid this */
|
||||
Channel* destchan = NULL;
|
||||
destchan = ServerInstance->FindChan(channel);
|
||||
if (destchan && destchan->IsModeSet('L'))
|
||||
if (destchan && destchan->IsModeSet(&re))
|
||||
{
|
||||
user->WriteNumeric(470, "%s %s * :You may not join this channel. A redirect is set, but you may not be redirected as it is a circular loop.", user->nick.c_str(), cname);
|
||||
return MOD_RES_DENY;
|
||||
|
@ -21,7 +21,7 @@
|
||||
class Channel_r : public ModeHandler
|
||||
{
|
||||
public:
|
||||
Channel_r(Module* Creator) : ModeHandler(Creator, "c_registered", 'r', PARAM_NONE, MODETYPE_CHANNEL) { }
|
||||
Channel_r(Module* Creator) : ModeHandler(Creator, "c_registered", 'r', PARAM_NONE, MODETYPE_CHANNEL) { fixed_letter = false; }
|
||||
|
||||
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding)
|
||||
{
|
||||
@ -29,9 +29,9 @@ class Channel_r : public ModeHandler
|
||||
if (!IS_LOCAL(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server))
|
||||
{
|
||||
// Only change the mode if it's not redundant
|
||||
if ((adding && !channel->IsModeSet('r')) || (!adding && channel->IsModeSet('r')))
|
||||
if ((adding && !channel->IsModeSet(this)) || (!adding && channel->IsModeSet(this)))
|
||||
{
|
||||
channel->SetMode('r',adding);
|
||||
channel->SetMode(this,adding);
|
||||
return MODEACTION_ALLOW;
|
||||
}
|
||||
|
||||
@ -93,27 +93,27 @@ class AUser_R : public SimpleUserModeHandler
|
||||
class AChannel_M : public SimpleChannelModeHandler
|
||||
{
|
||||
public:
|
||||
AChannel_M(Module* Creator) : SimpleChannelModeHandler(Creator, "regmoderated", 'M') { }
|
||||
AChannel_M(Module* Creator) : SimpleChannelModeHandler(Creator, "regmoderated", 'M') { fixed_letter = false; }
|
||||
};
|
||||
|
||||
class ModuleServicesAccount : public Module
|
||||
{
|
||||
AChannel_R m1;
|
||||
AChannel_M m2;
|
||||
AChannel_R chanR;
|
||||
AChannel_M chanM;
|
||||
AUser_R m3;
|
||||
Channel_r m4;
|
||||
User_r m5;
|
||||
AccountExtItem accountname;
|
||||
public:
|
||||
ModuleServicesAccount() : m1(this), m2(this), m3(this), m4(this), m5(this),
|
||||
ModuleServicesAccount() : chanR(this), chanM(this), m3(this), m4(this), m5(this),
|
||||
accountname("accountname", this)
|
||||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
ServerInstance->Modules->AddService(m1);
|
||||
ServerInstance->Modules->AddService(m2);
|
||||
ServerInstance->Modules->AddService(chanR);
|
||||
ServerInstance->Modules->AddService(chanM);
|
||||
ServerInstance->Modules->AddService(m3);
|
||||
ServerInstance->Modules->AddService(m4);
|
||||
ServerInstance->Modules->AddService(m5);
|
||||
@ -178,7 +178,7 @@ class ModuleServicesAccount : public Module
|
||||
ModResult res;
|
||||
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"regmoderated"));
|
||||
|
||||
if (c->IsModeSet('M') && !is_registered && res != MOD_RES_ALLOW)
|
||||
if (c->IsModeSet(&chanM) && !is_registered && res != MOD_RES_ALLOW)
|
||||
{
|
||||
// user messaging a +M channel and is not registered
|
||||
user->WriteNumeric(477, ""+std::string(user->nick)+" "+std::string(c->name)+" :You need to be identified to a registered account to message this channel");
|
||||
@ -231,7 +231,7 @@ class ModuleServicesAccount : public Module
|
||||
return MOD_RES_PASSTHRU;
|
||||
}
|
||||
|
||||
if (chan->IsModeSet('R'))
|
||||
if (chan->IsModeSet(&chanR))
|
||||
{
|
||||
if (!is_registered)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user