From 1691906401f26a7a64dab7687509b96599543480 Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Tue, 26 Jul 2022 21:07:24 -0400 Subject: [PATCH] Improved CmdParser to invert control of matching largely to Command class. Streamlined related code. --- evennia/commands/cmdparser.py | 40 +++++++---------------------------- evennia/commands/command.py | 24 ++++++++++++++++++--- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/evennia/commands/cmdparser.py b/evennia/commands/cmdparser.py index e2c470b456..5bcbd6651f 100644 --- a/evennia/commands/cmdparser.py +++ b/evennia/commands/cmdparser.py @@ -61,38 +61,14 @@ def build_matches(raw_string, cmdset, include_prefixes=False): """ matches = [] try: - if include_prefixes: - # use the cmdname as-is - l_raw_string = raw_string.lower() - for cmd in cmdset: - matches.extend( - [ - create_match(cmdname, raw_string, cmd, cmdname) - for cmdname in [cmd.key] + cmd.aliases - if cmdname - and l_raw_string.startswith(cmdname.lower()) - and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :])) - ] - ) - else: - # strip prefixes set in settings - raw_string = ( - raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string - ) - l_raw_string = raw_string.lower() - for cmd in cmdset: - for raw_cmdname in [cmd.key] + cmd.aliases: - cmdname = ( - raw_cmdname.lstrip(_CMD_IGNORE_PREFIXES) - if len(raw_cmdname) > 1 - else raw_cmdname - ) - if ( - cmdname - and l_raw_string.startswith(cmdname.lower()) - and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :])) - ): - matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname)) + orig_string = raw_string + if not include_prefixes and len(raw_string) > 1: + raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES) + search_string = raw_string.lower() + for cmd in cmdset: + cmdname, raw_cmdname = cmd.match(search_string, include_prefixes=include_prefixes) + if cmdname: + matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname)) except Exception: log_trace("cmdhandler error. raw_input:%s" % raw_string) return matches diff --git a/evennia/commands/command.py b/evennia/commands/command.py index 4c9c24d403..b1522d6210 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -221,6 +221,7 @@ class Command(metaclass=CommandMeta): """ if kwargs: _init_command(self, **kwargs) + self._optimize() @lazy_property def lockhandler(self): @@ -297,10 +298,15 @@ class Command(metaclass=CommandMeta): Optimize the key and aliases for lookups. """ # optimization - a set is much faster to match against than a list - self._matchset = set([self.key] + self.aliases) + matches = [self.key.lower()] + matches.extend(x.lower() for x in self.aliases) + + self._matchset = set(matches) # optimization for looping over keys+aliases self._keyaliases = tuple(self._matchset) + self._noprefix_aliases = {x.lstrip(CMD_IGNORE_PREFIXES): x for x in matches} + def set_key(self, new_key): """ Update key. @@ -336,7 +342,7 @@ class Command(metaclass=CommandMeta): self.aliases = list(set(alias for alias in aliases if alias != self.key)) self._optimize() - def match(self, cmdname): + def match(self, cmdname, include_prefixes=True): """ This is called by the system when searching the available commands, in order to determine if this is the one we wanted. cmdname was @@ -345,11 +351,23 @@ class Command(metaclass=CommandMeta): Args: cmdname (str): Always lowercase when reaching this point. + Kwargs: + include_prefixes (bool): If false, will compare against the _noprefix + variants of commandnames. + Returns: result (bool): Match result. """ - return cmdname in self._matchset + if include_prefixes: + for cmd_key in self._keyaliases: + if cmdname.startswith(cmd_key) and (not self.arg_regex or self.arg_regex.match(cmdname[len(cmd_key) :])): + return cmd_key, cmd_key + else: + for k, v in self._noprefix_aliases.items(): + if cmdname.startswith(k) and (not self.arg_regex or self.arg_regex.match(cmdname[len(k) :])): + return k, v + return None, None def access(self, srcobj, access_type="cmd", default=False): """