From c2a3c789d37461907beec6a77063de9123b1e2a5 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 31 Oct 2021 23:08:33 +0100 Subject: [PATCH] Change settings.COMMAND_ARG_REGEX default to require a space or '/' between cmdname and argument. This better matches common expectations. Resolves #1541. --- CHANGELOG.md | 2 ++ evennia/commands/default/admin.py | 26 ++++++++++++++++++-------- evennia/commands/default/general.py | 7 +++++++ evennia/commands/default/tests.py | 2 +- evennia/commands/tests.py | 4 ++++ evennia/settings_default.py | 6 +++--- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98587c304c..ff1307d033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,8 @@ Up requirements to Django 3.2+, Twisted 21+ `SERVER_HOSTNAME` setting for use in the server:port stanza. - Changed all `at_before/after_*` hooks to `at_pre/post_*` for consistency across Evennia (the old names still work but are deprecated) +- Change `settings.COMMAND_DEFAULT_ARG_REGEX` default from `None` to a regex meaning that + a space or `/` must separate the cmdname and args. This better fits common expectations. ### Evennia 0.9.5 (2019-2020) diff --git a/evennia/commands/default/admin.py b/evennia/commands/default/admin.py index 62f5cdef54..ee892fd3df 100644 --- a/evennia/commands/default/admin.py +++ b/evennia/commands/default/admin.py @@ -216,13 +216,18 @@ class CmdBan(COMMAND_DEFAULT_CLASS): ipregex = ipregex.replace("*", "[0-9]{1,3}") ipregex = re.compile(r"%s" % ipregex) bantup = ("", ban, ipregex, now, reason) + + ret = yield(f"Are you sure you want to {typ}-ban '|w{ban}|n' [Y]/N?") + if str(ret).lower() in ("no", "n"): + self.caller.msg("Aborted.") + return + # save updated banlist banlist.append(bantup) ServerConfig.objects.conf("server_bans", banlist) - self.caller.msg("%s-Ban |w%s|n was added." % (typ, ban)) + self.caller.msg(f"{typ}-ban '|w{ban}|n' was added. Use |wunban|n to reinstate.") logger.log_sec( - "Banned %s: %s (Caller: %s, IP: %s)." - % (typ, ban.strip(), self.caller, self.session.address) + "Banned {typ}: {ban.strip()} (Caller: {self.caller}, IP: {self.session.address})." ) @@ -264,15 +269,20 @@ class CmdUnban(COMMAND_DEFAULT_CLASS): elif not (0 < num < len(banlist) + 1): self.caller.msg("Ban id |w%s|x was not found." % self.args) else: - # all is ok, clear ban + # all is ok, ask, then clear ban ban = banlist[num - 1] + value = " ".join([s for s in ban[:2]]) + + ret = yield(f"Are you sure you want to unban {num}: '{value}' [Y]/N?") + if str(ret).lower() in ("n", "no"): + self.caller.msg("Aborted.") + return + del banlist[num - 1] ServerConfig.objects.conf("server_bans", banlist) - value = " ".join([s for s in ban[:2]]) - self.caller.msg("Cleared ban %s: %s" % (num, value)) + self.caller.msg(f"Cleared ban {num}: '{value}'" % (num, value)) logger.log_sec( - "Unbanned: %s (Caller: %s, IP: %s)." - % (value.strip(), self.caller, self.session.address) + "Unbanned: {value.strip()} (Caller: {self.caller}, IP: {self.session.address})." ) diff --git a/evennia/commands/default/general.py b/evennia/commands/default/general.py index 7994d14b49..e0f7d84526 100644 --- a/evennia/commands/default/general.py +++ b/evennia/commands/default/general.py @@ -586,6 +586,9 @@ class CmdSay(COMMAND_DEFAULT_CLASS): aliases = ['"', "'"] locks = "cmd:all()" + # don't require a space after `say/'/"` + arg_regex = None + def func(self): """Run the say command""" @@ -671,6 +674,10 @@ class CmdPose(COMMAND_DEFAULT_CLASS): aliases = [":", "emote"] locks = "cmd:all()" + # we want to be able to pose without whitespace between + # the command/alias and the pose (e.g. :pose) + arg_regex = None + def parse(self): """ Custom parse the cases where the emote diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 6f2fbdeaf1..4290063d22 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -761,7 +761,7 @@ class TestAdmin(CommandTest): self.call(admin.CmdWall(), "Test", "Announcing to all connected sessions ...") def test_ban(self): - self.call(admin.CmdBan(), "Char", "Name-Ban char was added.") + self.call(admin.CmdBan(), "Char", "Name-ban 'char' was added. Use unban to reinstate.") def test_force(self): cid = self.char2.id diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index 0e224c5602..a5608d92c1 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -1092,18 +1092,22 @@ class AccessableCommand(Command): class _CmdTest1(AccessableCommand): key = "test1" + arg_regex = None class _CmdTest2(AccessableCommand): key = "another command" + arg_regex = None class _CmdTest3(AccessableCommand): key = "&the third command" + arg_regex = None class _CmdTest4(AccessableCommand): key = "test2" + arg_regex = None class _CmdSetTest(CmdSet): diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 3dbfd3131d..b94a29927a 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -476,9 +476,9 @@ CMDSET_FALLBACKS = { COMMAND_DEFAULT_CLASS = "evennia.commands.default.muxcommand.MuxCommand" # Command.arg_regex is a regular expression desribing how the arguments # to the command must be structured for the command to match a given user -# input. By default there is no restriction as long as the input string -# starts with the command name. -COMMAND_DEFAULT_ARG_REGEX = None +# input. By default the command-name should end with a space or / (since the +# default commands uses MuxCommand and /switches). +COMMAND_DEFAULT_ARG_REGEX = r'^[ /]+.*$|$' # By default, Command.msg will only send data to the Session calling # the Command in the first place. If set, Command.msg will instead return # data to all Sessions connected to the Account/Character associated with