From f311ac1ecee20e164666e3d63a349c54c780aabd Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 1 Mar 2026 16:13:53 +0000 Subject: Merge the chg* and set* modules. --- modules/setname.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 12 deletions(-) (limited to 'modules/setname.cpp') diff --git a/modules/setname.cpp b/modules/setname.cpp index a0e1ab572..f7bb4a5d9 100644 --- a/modules/setname.cpp +++ b/modules/setname.cpp @@ -25,35 +25,74 @@ #include "inspircd.h" #include "modules/ircv3.h" #include "modules/monitor.h" +#include "numerichelper.h" class CommandSetName final - : public SplitCommand + : public Command { public: Cap::Capability cap; bool notifyopers; - CommandSetName(Module* Creator) - : SplitCommand(Creator, "SETNAME", 1, 1) - , cap(Creator, "setname") + CommandSetName(Module* mod) + : Command(mod, "SETNAME", 1, 2) + , cap(mod, "setname") { - syntax = { ":" }; + syntax = { "[] :" }; } - CmdResult HandleLocal(LocalUser* user, const Params& parameters) override + CmdResult Handle(User* user, const Params& parameters) override { - if (parameters[0].size() > ServerInstance->Config->Limits.MaxReal) + auto* target = user; + if (parameters.size() > 1) + { + const auto& targetnick = parameters[0]; + if (IS_LOCAL(user)) + { + // For local users we need to check if they can use the command. + target = ServerInstance->Users.FindNick(targetnick, true); + if (user != target && !user->HasPrivPermission("users/setname-others")) + { + user->WriteNumeric(Numerics::NoPrivileges("your server operator account does not have the users/setname-others privilege")); + return CmdResult::FAILURE; + } + } + else + { + // For remote users their server will have checked privs. + target = ServerInstance->Users.Find(targetnick); + } + + if (!target) + { + user->WriteNumeric(Numerics::NoSuchNick(targetnick)); + return CmdResult::FAILURE; + } + } + + if (!IS_LOCAL(target)) + return CmdResult::SUCCESS; // Their server will handle this. + + const auto& newreal = parameters.back(); + if (newreal.size() > ServerInstance->Config->Limits.MaxReal) { IRCv3::WriteReply(Reply::Type::FAIL, user, &cap, this, "INVALID_REALNAME", "Real name is too long"); return CmdResult::FAILURE; } - user->ChangeRealName(parameters[0]); - if (notifyopers) - ServerInstance->SNO.WriteGlobalSno('a', "{} used SETNAME to change their real name to '{}'", - user->nick, parameters[0]); + target->ChangeRealName(newreal); + if (notifyopers || user != target) + { + ServerInstance->SNO.WriteGlobalSno('a', "{} ({}) used {} to change the real name of {} to \"{}\x0F\"", + user->GetRealMask(), user->GetAddress(), this->name, target->nick, newreal); + } return CmdResult::SUCCESS; } + + RouteDescriptor GetRouting(User* user, const Params& parameters) override + { + return parameters.size() > 1 ? ROUTE_OPT_UCAST(parameters[0]) : ROUTE_LOCALONLY; + } }; class ModuleSetName final @@ -66,7 +105,7 @@ private: public: ModuleSetName() - : Module(VF_VENDOR, "Adds the /SETNAME command which allows users to change their real name.") + : Module(VF_VENDOR | VF_OPTCOMMON, "Adds the /SETNAME command which allows users to change their real name.") , cmd(this) , setnameevprov(this, "SETNAME") , monitorapi(this) -- cgit v1.3.1-10-gc9f91