Remove FPART, force REMOVE to always use the new syntax.

FPART was deprecated in v3 when the parameters for REMOVE were
switched.

This does not need any compat layer changes as v3 always forwarded
FPART as REMOVE.
This commit is contained in:
Sadie Powell 2022-04-13 00:17:36 +01:00
parent 2b3f3b2797
commit a810c07ccf
3 changed files with 30 additions and 92 deletions

View File

@ -30,14 +30,14 @@ parameter for this command.
<helpop key="cuser" title="User Commands" value=" <helpop key="cuser" title="User Commands" value="
ACCEPT ADMIN AWAY COMMANDS CYCLE DCCALLOW ACCEPT ADMIN AWAY COMMANDS CYCLE DCCALLOW
FPART HEXIP INFO INVITE ISON JOIN HEXIP INFO INVITE ISON JOIN KICK
KICK KNOCK LINKS LIST LUSERS MAP KNOCK LINKS LIST LUSERS MAP MKPASSWD
MKPASSWD MODE MODULES MONITOR MOTD NAMES MODE MODULES MONITOR MOTD NAMES NICK
NICK NOTICE OPER PART PASS PING NOTICE OPER PART PASS PING PONG
PONG PRIVMSG QUIT REMOVE SERVLIST SETNAME PRIVMSG QUIT REMOVE SERVLIST SETNAME SILENCE
SILENCE SQUERY SSLINFO STATS TBAN TIME SQUERY SSLINFO STATS TBAN TIME TITLE
TITLE TOPIC UNINVITE USER USERHOST VERSION TOPIC UNINVITE USER USERHOST VERSION VHOST
VHOST WATCH WHO WHOIS WHOWAS WATCH WHO WHOIS WHOWAS
"> ">
<helpop key="squery" title="/SQUERY <target> :<message>" value=" <helpop key="squery" title="/SQUERY <target> :<message>" value="
@ -149,11 +149,6 @@ Removes listmodes from a channel, optionally matching a glob-based pattern.
E.g. '/RMODE #channel b m:*' will remove all mute extbans on the channel. E.g. '/RMODE #channel b m:*' will remove all mute extbans on the channel.
"> ">
<helpop key="fpart" title="/FPART <channel> <nick> [:<reason>]" value="
This behaves identically to /REMOVE. /REMOVE is a built-in mIRC command
which caused trouble for some users.
">
<helpop key="hexip" title="/HEXIP <hex-ip|raw-ip>" value=" <helpop key="hexip" title="/HEXIP <hex-ip|raw-ip>" value="
If the specified argument is a raw IP address then respond with the If the specified argument is a raw IP address then respond with the
hex encoded equivalent as if sent by an ident gateway. Otherwise, if hex encoded equivalent as if sent by an ident gateway. Otherwise, if

View File

@ -1774,8 +1774,7 @@
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Remove module: Adds the /REMOVE command which is a peaceful # Remove module: Adds the /REMOVE command which is a peaceful
# alternative to /KICK. It also provides the /FPART command which works # alternative to /KICK.
# in the same way as /REMOVE.
#<module name="remove"> #<module name="remove">
# #
# supportnokicks: If yes, /REMOVE is not allowed on channels where the # supportnokicks: If yes, /REMOVE is not allowed on channels where the

View File

@ -31,55 +31,40 @@
#include "inspircd.h" #include "inspircd.h"
#include "modules/isupport.h" #include "modules/isupport.h"
/* class CommandRemove final
* This module supports the use of the +q and +a usermodes, but should work without them too.
* Usage of the command is restricted to +hoaq, and you cannot remove a user with a "higher" level than yourself.
* eg: +h can remove +hv and users with no modes. +a can remove +aohv and users with no modes.
*/
/** Base class for /FPART and /REMOVE
*/
class RemoveBase
: public Command : public Command
{ {
bool& supportnokicks; private:
ChanModeReference& nokicksmode; ChanModeReference nokicksmode;
public: public:
unsigned long protectedrank; unsigned long protectedrank;
bool supportnokicks;
RemoveBase(Module* Creator, bool& snk, ChanModeReference& nkm, const char* cmdn) CommandRemove(Module* Creator)
: Command(Creator, cmdn, 2, 3) : Command(Creator, "REMOVE", 2, 3)
, supportnokicks(snk) , nokicksmode(Creator, "nokick")
, nokicksmode(nkm)
{ {
syntax = { "<channel> <nick> [:<reason>]" };
translation = { TR_TEXT, TR_NICK, TR_TEXT };
} }
CmdResult HandleRMB(User* user, const CommandBase::Params& parameters, bool fpart) CmdResult Handle(User* user, const CommandBase::Params& parameters) override
{ {
User* target; // Keep compatibility with v3 servers by allowing them to send removes with the old order.
Channel* channel; bool neworder = !IS_LOCAL(user) && ServerInstance->Channels.IsPrefix(parameters[0][0]);
std::string reason;
// If the command is a /REMOVE then detect the parameter order
bool neworder = (fpart || ServerInstance->Channels.IsPrefix(parameters[0][0]));
/* Set these to the parameters needed, the new version of this module switches it's parameters around
* supplying a new command with the new order while keeping the old /remove with the older order.
* /remove <nick> <channel> [reason ...]
* /fpart <channel> <nick> [reason ...]
*/
const std::string& channame = parameters[neworder ? 0 : 1]; const std::string& channame = parameters[neworder ? 0 : 1];
const std::string& username = parameters[neworder ? 1 : 0]; const std::string& username = parameters[neworder ? 1 : 0];
/* Look up the user we're meant to be removing from the channel */ /* Look up the user we're meant to be removing from the channel */
User* target;
if (IS_LOCAL(user)) if (IS_LOCAL(user))
target = ServerInstance->Users.FindNick(username); target = ServerInstance->Users.FindNick(username);
else else
target = ServerInstance->Users.Find(username); target = ServerInstance->Users.Find(username);
/* And the channel we're meant to be removing them from */ /* And the channel we're meant to be removing them from */
channel = ServerInstance->Channels.Find(channame); Channel* channel = ServerInstance->Channels.Find(channame);
/* Fix by brain - someone needs to learn to validate their input! */ /* Fix by brain - someone needs to learn to validate their input! */
if (!channel) if (!channel)
@ -120,11 +105,9 @@ public:
// REMOVE will be sent to the target's server and it will reply with a PART (or do nothing if it doesn't understand the command) // REMOVE will be sent to the target's server and it will reply with a PART (or do nothing if it doesn't understand the command)
if (!IS_LOCAL(target)) if (!IS_LOCAL(target))
{ {
// Send an ENCAP REMOVE with parameters being in the old <user> <chan> order which is
// compatible with both 2.0 and 3.0. This also turns FPART into REMOVE.
CommandBase::Params p; CommandBase::Params p;
p.push_back(target->uuid);
p.push_back(channel->name); p.push_back(channel->name);
p.push_back(target->uuid);
if (parameters.size() > 2) if (parameters.size() > 2)
p.push_back(":" + parameters[2]); p.push_back(":" + parameters[2]);
ServerInstance->PI->SendEncapsulatedData(target->server->GetName(), "REMOVE", p, user); ServerInstance->PI->SendEncapsulatedData(target->server->GetName(), "REMOVE", p, user);
@ -141,7 +124,7 @@ public:
reasonparam = "No reason given"; reasonparam = "No reason given";
/* Build up the part reason string. */ /* Build up the part reason string. */
reason = "Removed by " + user->nick + ": " + reasonparam; std::string reason = "Removed by " + user->nick + ": " + reasonparam;
channel->WriteRemoteNotice(InspIRCd::Format("%s removed %s from the channel", user->nick.c_str(), target->nick.c_str())); channel->WriteRemoteNotice(InspIRCd::Format("%s removed %s from the channel", user->nick.c_str(), target->nick.c_str()));
target->WriteNotice("*** " + user->nick + " removed you from " + channel->name + " with the message: " + reasonparam); target->WriteNotice("*** " + user->nick + " removed you from " + channel->name + " with the message: " + reasonparam);
@ -165,57 +148,18 @@ public:
} }
}; };
class CommandRemove final
: public RemoveBase
{
public:
CommandRemove(Module* Creator, bool& snk, ChanModeReference& nkm)
: RemoveBase(Creator, snk, nkm, "REMOVE")
{
syntax = { "<channel> <nick> [:<reason>]" };
translation = { TR_NICK, TR_TEXT, TR_TEXT };
}
CmdResult Handle(User* user, const Params& parameters) override
{
return HandleRMB(user, parameters, false);
}
};
class CommandFpart final
: public RemoveBase
{
public:
CommandFpart(Module* Creator, bool& snk, ChanModeReference& nkm)
: RemoveBase(Creator, snk, nkm, "FPART")
{
syntax = { "<channel> <nick> [:<reason>]" };
translation = { TR_TEXT, TR_NICK, TR_TEXT };
}
CmdResult Handle(User* user, const Params& parameters) override
{
return HandleRMB(user, parameters, true);
}
};
class ModuleRemove final class ModuleRemove final
: public Module : public Module
, public ISupport::EventListener , public ISupport::EventListener
{ {
private: private:
ChanModeReference nokicksmode; CommandRemove cmd;
CommandRemove cmd1;
CommandFpart cmd2;
bool supportnokicks;
public: public:
ModuleRemove() ModuleRemove()
: Module(VF_VENDOR | VF_OPTCOMMON, "Adds the /FPART and /REMOVE commands which allows channel operators to force part users from a channel.") : Module(VF_VENDOR | VF_OPTCOMMON, "Adds the /REMOVE command which allows channel operators to force part users from a channel.")
, ISupport::EventListener(this) , ISupport::EventListener(this)
, nokicksmode(this, "nokick") , cmd(this)
, cmd1(this, supportnokicks, nokicksmode)
, cmd2(this, supportnokicks, nokicksmode)
{ {
} }
@ -227,8 +171,8 @@ public:
void ReadConfig(ConfigStatus& status) override void ReadConfig(ConfigStatus& status) override
{ {
auto tag = ServerInstance->Config->ConfValue("remove"); auto tag = ServerInstance->Config->ConfValue("remove");
supportnokicks = tag->getBool("supportnokicks"); cmd.supportnokicks = tag->getBool("supportnokicks");
cmd1.protectedrank = cmd2.protectedrank = tag->getUInt("protectedrank", 50000); cmd.protectedrank = tag->getUInt("protectedrank", 50000);
} }
}; };