1
0
mirror of https://github.com/anope/anope.git synced 2026-07-09 20:03:13 +02:00

Use m_rewrite to rewrite op, deop, halfop, ... etc

This commit is contained in:
Adam
2013-01-08 20:25:01 -05:00
parent 5f3dfc2960
commit 9931ec2994
15 changed files with 313 additions and 544 deletions
+21 -5
View File
@@ -272,7 +272,6 @@ command { service = "BotServ"; name = "SET PRIVATE"; command = "botserv/set/priv
fantasy { name = "ACCESS"; command = "chanserv/access"; }
fantasy { name = "AKICK"; command = "chanserv/akick"; }
fantasy { name = "AOP"; command = "chanserv/aop"; }
fantasy { name = "APPENDTOPIC"; command = "chanserv/appendtopic"; }
fantasy { name = "BAN"; command = "chanserv/ban"; }
fantasy { name = "CLONE"; command = "chanserv/clone"; }
fantasy { name = "DEHALFOP"; command = "chanserv/dehalfop"; }
@@ -285,22 +284,22 @@ fantasy { name = "ENFORCE"; command = "chanserv/enforce"; }
fantasy { name = "ENTRYMSG"; command = "chanserv/entrymsg"; }
fantasy { name = "FLAGS"; command = "chanserv/flags"; }
fantasy { name = "HALFOP"; command = "chanserv/halfop"; }
fantasy { name = "HELP"; command = "generic/help"; }
fantasy { name = "HELP"; command = "generic/help"; prepend_channel = false }
fantasy { name = "HOP"; command = "chanserv/hop"; }
fantasy { name = "INFO"; command = "chanserv/info"; }
fantasy { name = "INFO"; command = "chanserv/info"; prepend_channel = false }
fantasy { name = "INVITE"; command = "chanserv/invite"; }
fantasy { name = "K"; command = "chanserv/kick"; }
fantasy { name = "KB"; command = "chanserv/ban"; }
fantasy { name = "KICK"; command = "chanserv/kick"; }
fantasy { name = "LEVELS"; command = "chanserv/levels"; }
fantasy { name = "LIST"; command = "chanserv/list"; }
fantasy { name = "LIST"; command = "chanserv/list"; prepend_channel = false }
fantasy { name = "LOG"; command = "chanserv/log"; }
fantasy { name = "MODE"; command = "chanserv/mode"; }
fantasy { name = "OP"; command = "chanserv/op"; }
fantasy { name = "OWNER"; command = "chanserv/owner"; }
fantasy { name = "PROTECT"; command = "chanserv/protect"; }
fantasy { name = "QOP"; command = "chanserv/qop"; }
fantasy { name = "SEEN"; command = "chanserv/seen"; }
fantasy { name = "SEEN"; command = "chanserv/seen"; prepend_channel = false }
fantasy { name = "SOP"; command = "chanserv/sop"; }
fantasy { name = "STATUS"; command = "chanserv/status"; }
fantasy { name = "SUSPEND"; command = "chanserv/suspend"; permission = "chanserv/suspend"; }
@@ -312,3 +311,20 @@ fantasy { name = "UP"; command = "chanserv/up"; }
fantasy { name = "VOICE"; command = "chanserv/voice"; }
fantasy { name = "VOP"; command = "chanserv/vop"; }
/* Use m_rewrite to rewrite the op, deop, etc. fantasy commands (see chanserv.conf). */
fantasy { name = "OWNER"; command = "rewrite"; }
fantasy { name = "DEOWNER"; command = "rewrite"; }
fantasy { name = "PROTECT"; command = "rewrite"; }
fantasy { name = "DEPROTECT"; command = "rewrite"; }
fantasy { name = "OP"; command = "rewrite"; }
fantasy { name = "DEOP"; command = "rewrite"; }
fantasy { name = "HALFOP"; command = "rewrite"; }
fantasy { name = "DEHALFOP"; command = "rewrite"; }
fantasy { name = "VOICE"; command = "rewrite"; }
fantasy { name = "DEVOICE"; command = "rewrite"; }
+113 -21
View File
@@ -1005,27 +1005,6 @@ command { service = "ChanServ"; name = "LOG"; command = "chanserv/log"; }
module { name = "cs_mode" }
command { service = "ChanServ"; name = "MODE"; command = "chanserv/mode"; }
/*
* cs_mode
*
* Provides the commands chanserv/op, chanserv/deop, chanserv/halfop, chanserv/dehalfop
* chanserv/voice, chanserv/devoice, chanserv/protect, chanserv/deprotect,
* chanserv/owner, and chanserv/deowner.
*
* Used for setting and removing modes on users.
*/
module { name = "cs_modes" }
command { service = "ChanServ"; name = "OP"; command = "chanserv/op"; }
command { service = "ChanServ"; name = "DEOP"; command = "chanserv/deop"; }
command { service = "ChanServ"; name = "HALFOP"; command = "chanserv/halfop"; }
command { service = "ChanServ"; name = "DEHALFOP"; command = "chanserv/dehalfop"; }
command { service = "ChanServ"; name = "VOICE"; command = "chanserv/voice"; }
command { service = "ChanServ"; name = "DEVOICE"; command = "chanserv/devoice"; }
command { service = "ChanServ"; name = "PROTECT"; command = "chanserv/protect"; }
command { service = "ChanServ"; name = "DEPROTECT"; command = "chanserv/deprotect"; }
command { service = "ChanServ"; name = "OWNER"; command = "chanserv/owner"; }
command { service = "ChanServ"; name = "DEOWNER"; command = "chanserv/deowner"; }
/*
* cs_register
*
@@ -1220,6 +1199,119 @@ command { service = "ChanServ"; name = "AOP"; command = "chanserv/aop"; }
command { service = "ChanServ"; name = "HOP"; command = "chanserv/hop"; }
command { service = "ChanServ"; name = "VOP"; command = "chanserv/vop"; }
/* Use m_rewrite to rewrite the op, deop, etc. commands (see modules.conf). */
command
{
service = "ChanServ"; name = "OWNER"; command = "rewrite"
rewrite = true
rewrite_souce = "OWNER $"
rewrite_target = "MODE $1 SET +q $2"
rewrite_description = "Gives you owner status on channel"
}
command
{
service = "ChanServ"; name = "DEOWNER"; command = "rewrite"
rewrite = true
rewrite_source = "DEOWNER $"
rewrite_target = "MODE $1 SET -q $2"
rewrite_description = "Removes your owner status on a channel"
}
command
{
service = "ChanServ"; name = "PROTECT"; command = "rewrite";
rewrite = true
rewrite_source = "PROTECT $"
rewrite_target = "MODE $1 SET +a $2"
rewrite_description = "Protects a selected nick on a channel"
}
command
{
service = "ChanServ"; name = "DEPROTECT"; command = "rewrite";
rewrite = true
rewrite_source = "DEPROTECT $"
rewrite_target = "MODE $1 SET -a $2"
rewrite_description = "Deprotects a selected nick on a channel"
}
command
{
service = "ChanServ"; name = "OP"; command = "rewrite";
rewrite = true
rewrite_source = "OP $"
rewrite_target = "MODE $1 SET +o $2"
rewrite_description = "Gives Op status to a selected nick on a channel"
}
command
{
service = "ChanServ"; name = "DEOP"; command = "rewrite";
rewrite = true
rewrite_source = "DEOP $"
rewrite_target = "MODE $1 SET -o $2";
rewrite_description = "Deops a selected nick on a channel"
}
/* HALFOP and DEHALFOP commands */
command
{
service = "ChanServ"; name = "HALFOP"; command = "rewrite";
rewrite = true
rewrite_source = "HALFOP $"
rewrite_target = "MODE $1 SET +h $2"
rewrite_description = "Halfops a selected nick on a channel"
}
command
{
service = "ChanServ"; name = "DEHALFOP"; command = "rewrite"
rewrite = true
rewrite_source = "DEHALFOP $"
rewrite_target = "MODE $1 SET -h $2"
rewrite_description = "Dehalfops a selected nick on a channel"
}
/* VOICE and DEVOICE commands */
command
{
service = "ChanServ"; name = "VOICE"; command = "rewrite";
rewrite = true
rewrite_source = "VOICE $"
rewrite_target = "MODE $1 SET +v $2"
rewrite_description = "Voices a selected nick on a channel"
}
command
{
service = "ChanServ"; name = "DEVOICE"; command = "rewrite";
rewrite = true
rewrite_source = "DEVOICE $"
rewrite_target = "MODE $1 SET -v $2"
rewrite_description = "Devoices a selected nick on a channel"
}
/*
* Extra ChanServ related modules.
*/
+26 -15
View File
@@ -500,23 +500,34 @@ module { name = "m_regex_pcre" }
/*
* m_rewrite
*
* Provides the command rewrite.
*
* Allows rewriting commands sent to clients.
*/
#module { name = "m_rewrite" }
rewrite
{
/* The client to apply this rewrite to. */
client = "ChanServ"
/* Source message to match. A $ can be used to match anything. */
source_message = "CLEAR $ USERS"
/*
* Message to rewrite the source message to. A $ followed by a number, eg $0, gets
* replaced by the number-th word from the source_message, starting from 0.
*/
target_message = "KICK $1 *"
}
module { name = "m_rewrite" }
#command
#{
# service = "ChanServ"; name = "CLEAR"; command = "rewrite"
#
# /* Enable m_rewrite */
# rewrite = true
#
# /* Source message to match. A $ can be used to match anything. */
# rewrite_source = "CLEAR $ USERS"
#
# /*
# * Message to rewrite the source message to. A $ followed by a number, eg $0, gets
# * replaced by the number-th word from the source_message, starting from 0.
# */
# rewrite_target = "KICK $1 *"
#
# /*
# * The command description. This only shows up in HELP's output.
# * Comment this option to prevent the command from showing in the
# * HELP command.
# */
# rewrite_description = "Clears all users from a channel"
#}
/*
* m_ssl
+4 -3
View File
@@ -21,9 +21,6 @@ enum CommandFlag
/* Command allow unidentified users to use it */
CFLAG_ALLOW_UNREGISTERED,
/* Command's first parameter is a channel name */
CFLAG_STRIP_CHANNEL,
/* Command requires a user to execute */
CFLAG_REQUIRE_USER
};
@@ -33,10 +30,14 @@ struct CommandInfo
{
typedef Anope::map<CommandInfo> map;
CommandInfo() : prepend_channel(false) { }
/* Service name of the command */
Anope::string name;
/* Permission required to execute the command */
Anope::string permission;
/* Only used with fantasy */
bool prepend_channel;
};
/* Where the replies from commands go to. User inheits from this and is the normal
-2
View File
@@ -38,7 +38,6 @@ class CommandCSStats : public Command
public:
CommandCSStats(Module *creator) : Command (creator, "chanserv/stats", 0, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays your Channel Stats"));
this->SetSyntax(_("\037nick\037"));
}
@@ -51,7 +50,6 @@ class CommandCSGStats : public Command
public:
CommandCSGStats(Module *creator) : Command (creator, "chanserv/gstats", 0, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays your Global Stats"));
this->SetSyntax(_("\037nick\037"));
}
-4
View File
@@ -37,7 +37,6 @@ class CommandCSTop : public Command
public:
CommandCSTop(Module *creator) : Command (creator, "chanserv/top", 0, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays the top 3 users of a channel"));
this->SetSyntax(_("\037channel\037"));
}
@@ -50,7 +49,6 @@ class CommandCSTop10 : public Command
public:
CommandCSTop10(Module *creator) : Command (creator, "chanserv/top10", 0, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays the top 10 users of a channel"));
this->SetSyntax(_("\037channel\037"));
}
@@ -63,7 +61,6 @@ class CommandCSGTop : public Command
public:
CommandCSGTop(Module *creator) : Command (creator, "chanserv/gtop", 0, 1)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays the top 3 users of the network"));
this->SetSyntax("");
}
@@ -76,7 +73,6 @@ class CommandCSGTop10 : public Command
public:
CommandCSGTop10(Module *creator) : Command (creator, "chanserv/gtop10", 0, 1)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Displays the top 10 users of the network"));
this->SetSyntax("");
}
-1
View File
@@ -29,7 +29,6 @@ class CommandCSInfo : public Command
public:
CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
this->SetDesc(_("Lists information about the named registered channel"));
this->SetSyntax(_("\037channel\037"));
}
-1
View File
@@ -18,7 +18,6 @@ class CommandCSList : public Command
public:
CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Lists all registered channels matching the given pattern"));
this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
}
+45 -21
View File
@@ -15,19 +15,20 @@
class CommandCSMode : public Command
{
bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm)
bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm, bool self)
{
if (!ci || !cm || cm->type != MODE_STATUS)
return false;
const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" };
const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" },
accesses_self[] = { "VOICEME", "HALFOPME", "OPDEOPME", "PROTECTME", "OWNERME", "" };
const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER };
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
AccessGroup access = source.AccessFor(ci);
unsigned short u_level = 0;
for (int i = 0; !accesses[i].empty(); ++i)
if (access.HasPriv(accesses[i]))
if (access.HasPriv(self ? accesses_self[i] : accesses[i]))
{
ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]);
if (cm2 == NULL || cm2->type != MODE_STATUS)
@@ -193,10 +194,12 @@ class CommandCSMode : public Command
{
User *u = source.GetUser();
bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/set");
spacesepstream sep(params.size() > 3 ? params[3] : "");
Anope::string modes = params[2], param;
bool override = !source.AccessFor(ci).HasPriv("MODE");
bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/set");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2];
int adding = -1;
@@ -211,7 +214,7 @@ class CommandCSMode : public Command
adding = 0;
break;
case '*':
if (adding == -1)
if (adding == -1 || !has_access)
break;
for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j)
{
@@ -237,12 +240,16 @@ class CommandCSMode : public Command
switch (cm->type)
{
case MODE_REGULAR:
if (!has_access)
break;
if (adding)
ci->c->SetMode(NULL, cm);
else
ci->c->RemoveMode(NULL, cm);
break;
case MODE_PARAM:
if (!has_access)
break;
if (adding && !sep.GetToken(param))
break;
if (adding)
@@ -253,25 +260,25 @@ class CommandCSMode : public Command
case MODE_STATUS:
{
if (!sep.GetToken(param))
break;
if (!this->CanSet(source, ci, cm))
{
source.Reply(_("You do not have access to set mode %c."), cm->mchar);
break;
}
param = source.GetNick();
AccessGroup u_access = source.AccessFor(ci);
if (param.find_first_of("*?") != Anope::string::npos)
{
if (!this->CanSet(source, ci, cm, false))
{
source.Reply(_("You do not have access to set mode %c."), cm->mchar);
break;
}
for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
ChanUserContainer *uc = *it;
AccessGroup targ_access = ci->AccessFor(uc->user);
if (targ_access > u_access)
if (uc->user->IsProtected() || targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
continue;
@@ -295,13 +302,27 @@ class CommandCSMode : public Command
break;
}
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
if (!this->CanSet(source, ci, cm, source.GetUser() == target))
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
source.Reply(_("You do not have access to set mode %c."), cm->mchar);
break;
}
if (source.GetUser() != target)
{
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
else if (target->IsProtected())
{
source.Reply(ACCESS_DENIED);
break;
}
}
if (adding)
ci->c->SetMode(NULL, cm, target->GetUID());
else
@@ -310,6 +331,8 @@ class CommandCSMode : public Command
break;
}
case MODE_LIST:
if (!has_access)
break;
if (!sep.GetToken(param))
break;
if (adding)
@@ -347,16 +370,17 @@ class CommandCSMode : public Command
if (!ci || !ci->c)
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set"))
source.Reply(ACCESS_DENIED);
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, ci, params);
{
if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set"))
source.Reply(ACCESS_DENIED);
else
this->DoLock(source, ci, params);
}
else if (subcommand.equals_ci("SET"))
this->DoSet(source, ci, params);
else
this->OnSyntaxError(source, "");
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
-430
View File
@@ -1,430 +0,0 @@
/* ChanServ core functions
*
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandModeBase : public Command
{
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.GetUser();
User *u2 = User::Find(nick, true);
Channel *c = Channel::Find(chan);
if (!c)
{
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
if (!u2)
{
source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
return;
}
ChannelInfo *ci = c->ci;
if (!ci)
{
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
return;
}
bool is_same = u == u2;
AccessGroup u_access = source.AccessFor(ci), u2_access = ci->AccessFor(u2);
if (is_same ? !source.AccessFor(ci).HasPriv(levelself) : !source.AccessFor(ci).HasPriv(level))
source.Reply(ACCESS_DENIED);
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
else if (!set && u2->IsProtected() && !is_same)
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else
{
if (set)
c->SetMode(NULL, cm, u2->GetUID());
else
c->RemoveMode(NULL, cm, u2->GetUID());
Log(LOG_COMMAND, source, com, ci) << "for " << u2->nick;
}
}
protected:
/** do_util: not a command, but does the job of others
* @param source The source of the command
* @param com The command calling this function
* @param cm A channel mode class
* @param chan The channel its being set on
* @param nick The nick the modes being set on
* @param set Is the mode being set or removed
* @param level The access level required to set this mode on someone else
* @param levelself The access level required to set this mode on yourself
*/
void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.GetUser();
if (chan.empty() && u)
for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end(); ++it)
do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself);
else if (!chan.empty())
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself);
}
public:
CommandModeBase(Module *creator, const Anope::string &cname) : Command(creator, cname, 0, 2)
{
this->SetSyntax(_("[\037channel\037] [\037nick\037]"));
}
};
class CommandCSOp : public CommandModeBase
{
public:
CommandCSOp(Module *creator) : CommandModeBase(creator, "chanserv/op")
{
this->SetDesc(_("Gives Op status to a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Ops a selected nick on a channel. If nick is not given,\n"
"it will op you. If channel is not given, it will op you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel."));
return true;
}
};
class CommandCSDeOp : public CommandModeBase
{
public:
CommandCSDeOp(Module *creator) : CommandModeBase(creator, "chanserv/deop")
{
this->SetDesc(_("Deops a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply("Deops a selected nick on a channel. If nick is not given,\n"
"it will deop you. If channel is not given, it will deop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel.");
return true;
}
};
class CommandCSVoice : public CommandModeBase
{
public:
CommandCSVoice(Module *creator) : CommandModeBase(creator, "chanserv/voice")
{
this->SetDesc(_("Voices a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Voices a selected nick on a channel. If nick is not given,\n"
"it will voice you. If channel is not given, it will voice you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel, or to VOPs or those with level 3\n"
"and above for self voicing."));
return true;
}
};
class CommandCSDeVoice : public CommandModeBase
{
public:
CommandCSDeVoice(Module *creator) : CommandModeBase(creator, "chanserv/devoice")
{
this->SetDesc(_("Devoices a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Devoices a selected nick on a channel. If nick is not given,\n"
"it will devoice you. If channel is not given, it will devoice\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel, or to VOPs or those with level 3\n"
"and above for self devoicing."));
return true;
}
};
class CommandCSHalfOp : public CommandModeBase
{
public:
CommandCSHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/halfop")
{
this->SetDesc(_("Halfops a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Halfops a selected nick on a channel. If nick is not given,\n"
"it will halfop you. If channel is not given, it will halfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access\n"
"and above on the channel, or to HOPs or those with level 4\n"
"and above for self halfopping."));
return true;
}
};
class CommandCSDeHalfOp : public CommandModeBase
{
public:
CommandCSDeHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/dehalfop")
{
this->SetDesc(_("Dehalfops a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Dehalfops a selected nick on a channel. If nick is not given,\n"
"it will dehalfop you. If channel is not given, it will dehalfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access\n"
"and above on the channel, or to HOPs or those with level 4\n"
"and above for self dehalfopping."));
return true;
}
};
class CommandCSProtect : public CommandModeBase
{
public:
CommandCSProtect(Module *creator) : CommandModeBase(creator, "chanserv/protect")
{
this->SetDesc(_("Protects a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Protects a selected nick on a channel. If nick is not given,\n"
"it will protect you. If channel is not given, it will protect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with\n"
"level 10 and above on the channel for self protecting."));
return true;
}
};
class CommandCSDeProtect : public CommandModeBase
{
public:
CommandCSDeProtect(Module *creator) : CommandModeBase(creator, "chanserv/deprotect")
{
this->SetDesc(_("Deprotects a selected nick on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Deprotects a selected nick on a channel. If nick is not given,\n"
"it will deprotect you. If channel is not given, it will deprotect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with\n"
"level 10 and above on the channel for self deprotecting."));
return true;
}
};
class CommandCSOwner : public CommandModeBase
{
public:
CommandCSOwner(Module *creator) : CommandModeBase(module, "chanserv/owner")
{
this->SetDesc(_("Gives you owner status on channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Gives the selected nick owner status on \002channel\002. If nick is not\n"
"given, it will give you owner. If channel is not given, it will\n"
"give you owner on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
};
class CommandCSDeOwner : public CommandModeBase
{
public:
CommandCSDeOwner(Module *creator) : CommandModeBase(creator, "chanserv/deowner")
{
this->SetDesc(_("Removes your owner status on a channel"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Removes owner status from the selected nick on \002channel\002. If nick\n"
"is not given, it will deowner you. If channel is not given, it will\n"
"deowner you on every channel.\n"
" \n"
"Limited to those with founder access on the channel."));
return true;
}
};
class CSModes : public Module
{
CommandCSOwner commandcsowner;
CommandCSDeOwner commandcsdeowner;
CommandCSProtect commandcsprotect;
CommandCSDeProtect commandcsdeprotect;
CommandCSOp commandcsop;
CommandCSDeOp commandcsdeop;
CommandCSHalfOp commandcshalfop;
CommandCSDeHalfOp commandcsdehalfop;
CommandCSVoice commandcsvoice;
CommandCSDeVoice commandcsdevoice;
public:
CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsowner(this), commandcsdeowner(this), commandcsprotect(this), commandcsdeprotect(this),
commandcsop(this), commandcsdeop(this), commandcshalfop(this), commandcsdehalfop(this),
commandcsvoice(this), commandcsdevoice(this)
{
this->SetAuthor("Anope");
}
};
MODULE_INIT(CSModes)
-1
View File
@@ -184,7 +184,6 @@ class CommandSeen : public Command
public:
CommandSeen(Module *creator) : Command(creator, "chanserv/seen", 1, 2)
{
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetDesc(_("Tells you about the last time a user was seen"));
this->SetSyntax(_("\037nick\037"));
}
-1
View File
@@ -19,7 +19,6 @@ class CommandHelp : public Command
CommandHelp(Module *creator) : Command(creator, "generic/help", 0)
{
this->SetDesc(_("Displays this list and give information about commands"));
this->SetFlag(CFLAG_STRIP_CHANNEL);
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
}
+96 -33
View File
@@ -9,7 +9,7 @@
struct Rewrite
{
Anope::string client, source_message, target_message;
Anope::string client, source_message, target_message, desc;
bool Matches(const std::vector<Anope::string> &message)
{
@@ -17,13 +17,13 @@ struct Rewrite
spacesepstream(this->source_message).GetTokens(sm);
for (unsigned i = 0; i < sm.size(); ++i)
if (sm[i] != "$" && !sm[i].equals_ci(message[i]))
if (i >= message.size() || (sm[i] != "$" && !sm[i].equals_ci(message[i])))
return false;
return true;
}
Anope::string Process(const std::vector<Anope::string> &params)
Anope::string Process(CommandSource &source, const std::vector<Anope::string> &params)
{
spacesepstream sep(this->target_message);
Anope::string token, message;
@@ -32,6 +32,8 @@ struct Rewrite
{
if (token[0] != '$')
message += " " + token;
else if (token == "$me")
message += " " + source.GetNick();
else
{
int num = -1, end = -1;
@@ -66,20 +68,97 @@ struct Rewrite
message.trim();
return message;
}
static std::vector<Rewrite> rewrites;
static Rewrite *Find(const Anope::string &client, const Anope::string &cmd)
{
for (unsigned i = 0; i < rewrites.size(); ++i)
{
Rewrite &r = rewrites[i];
if ((client.empty() || r.client.equals_ci(client)) && (r.source_message.equals_ci(cmd) || r.source_message.find_ci(cmd + " ") == 0))
return &r;
}
return NULL;
}
static Rewrite *Match(const Anope::string &client, const std::vector<Anope::string> &params)
{
for (unsigned i = 0; i < rewrites.size(); ++i)
{
Rewrite &r = rewrites[i];
if ((client.empty() || r.client.equals_ci(client)) && r.Matches(params))
return &r;
}
return NULL;
}
};
std::vector<Rewrite> Rewrite::rewrites;
class RewriteCommand : public Command
{
public:
RewriteCommand(Module *creator) : Command(creator, "rewrite", 0, 0) { }
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
std::vector<Anope::string> full_params = params;
full_params.insert(full_params.begin(), source.command);
Rewrite *r = Rewrite::Match(!source.c ? source.service->nick : "", full_params);
if (r != NULL)
{
Anope::string new_message = r->Process(source, full_params);
Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'";
source.service = BotInfo::Find(r->client);
if (!source.service)
return;
RunCommand(source, new_message);
}
else
Log() << "m_rewrite: Unable to rewrite '" << source.command << (!params.empty() ? " " + params[0] : "") << "'";
}
void OnServHelp(CommandSource &source) anope_override
{
Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
if (r != NULL && !r->desc.empty())
{
this->SetDesc(r->desc);
Command::OnServHelp(source);
}
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
if (r != NULL && !r->desc.empty())
{
source.Reply(r->desc);
size_t sz = r->target_message.find(' ');
source.Reply(_("This command is an alias to the command %s."), sz != Anope::string::npos ? r->target_message.substr(0, sz).c_str() : r->target_message.c_str());
return true;
}
return false;
}
};
class ModuleRewrite : public Module
{
std::vector<Rewrite> rewrites;
RewriteCommand cmdrewrite;
public:
ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED)
ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), cmdrewrite(this)
{
this->SetAuthor("Anope");
Implementation i[] = { I_OnReload, I_OnBotPrivmsg };
Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::SetPriority(this, PRIORITY_FIRST);
this->OnReload();
}
@@ -88,42 +167,26 @@ class ModuleRewrite : public Module
{
ConfigReader config;
this->rewrites.clear();
Rewrite::rewrites.clear();
for (int i = 0; i < config.Enumerate("rewrite"); ++i)
for (int i = 0; i < config.Enumerate("command"); ++i)
{
if (!config.ReadFlag("command", "rewrite", "no", i))
continue;
Rewrite rw;
rw.client = config.ReadValue("rewrite", "client", "", i);
rw.source_message = config.ReadValue("rewrite", "source_message", "", i),
rw.target_message = config.ReadValue("rewrite", "target_message", "", i);
rw.client = config.ReadValue("command", "service", "", i);
rw.source_message = config.ReadValue("command", "rewrite_source", "", i),
rw.target_message = config.ReadValue("command", "rewrite_target", "", i);
rw.desc = config.ReadValue("command", "rewrite_description", "", i);
if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty())
continue;
this->rewrites.push_back(rw);
Rewrite::rewrites.push_back(rw);
}
}
EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
{
std::vector<Anope::string> tokens;
spacesepstream(message).GetTokens(tokens);
for (unsigned i = 0; i < this->rewrites.size(); ++i)
{
Rewrite &rw = this->rewrites[i];
if (rw.client == bi->nick && rw.Matches(tokens))
{
Anope::string new_message = rw.Process(tokens);
Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << message << "' to '" << new_message << "'";
message = new_message;
break;
}
}
return EVENT_CONTINUE;
}
};
MODULE_INIT(ModuleRewrite)
+3 -3
View File
@@ -108,9 +108,9 @@ class BotServCore : public Module
for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i)
params.erase(params.begin());
/* All ChanServ commands take the channel as a first parameter */
if (cmd->name.find("chanserv/") == 0 && !cmd->HasFlag(CFLAG_STRIP_CHANNEL))
params.insert(params.begin(), c->ci->name);
/* Some commands take the channel as a first parameter */
if (info.prepend_channel)
params.insert(params.begin(), c->name);
while (cmd->max_params > 0 && params.size() > cmd->max_params)
{
+5 -3
View File
@@ -1011,9 +1011,11 @@ static bool DoFantasy(ServerConfig *config, const Anope::string &, const Anope::
Anope::string name = values[0].GetValue();
Anope::string service = values[1].GetValue();
Anope::string permission = values[2].GetValue();
bool prepend_channel = values[3].GetBool();
config->Fantasy[name].name = service;
config->Fantasy[name].permission = permission;
config->Fantasy[name].prepend_channel = prepend_channel;
return true;
}
@@ -1348,9 +1350,9 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{DT_STRING, DT_STRING, DT_INTEGER, DT_STRING},
InitPrivileges, DoPrivileges, DonePrivileges},
{"fantasy",
{"name", "command", "permission", ""},
{"", "", "", ""},
{DT_STRING, DT_STRING, DT_STRING},
{"name", "command", "permission", "prepend_channel", ""},
{"", "", "", "yes", ""},
{DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN},
InitFantasy, DoFantasy, DoneFantasy},
{"",
{""},