Changed/fixed some issues with the command priorities that caused a lower-prio dynamically-created command to not properly be accounted for. Also changed the prio order for which of the cmdsets are used for checking the "duplicates" flag - it is now the new set being merged onto the new one (i.e. the priorotized) cmdset that must have this flag set in order for the result to have duplicates.
This commit is contained in:
parent
1e6384e40c
commit
92339362ec
4 changed files with 90 additions and 78 deletions
|
|
@ -152,21 +152,21 @@ class CmdSet(object):
|
||||||
|
|
||||||
# Priority-sensitive merge operations for cmdsets
|
# Priority-sensitive merge operations for cmdsets
|
||||||
|
|
||||||
def _union(self, cmdset_a, cmdset_b, duplicates=False):
|
def _union(self, cmdset_a, cmdset_b):
|
||||||
"C = A U B. CmdSet A is assumed to have higher priority"
|
"C = A U B. CmdSet A is assumed to have higher priority"
|
||||||
cmdset_c = cmdset_a._duplicate()
|
cmdset_c = cmdset_a._duplicate()
|
||||||
# we make copies, not refs by use of [:]
|
# we make copies, not refs by use of [:]
|
||||||
cmdset_c.commands = cmdset_a.commands[:]
|
cmdset_c.commands = cmdset_a.commands[:]
|
||||||
if duplicates and cmdset_a.priority == cmdset_b.priority:
|
if cmdset_a.duplicates and cmdset_a.priority == cmdset_b.priority:
|
||||||
cmdset_c.commands.extend(cmdset_b.commands)
|
cmdset_c.commands.extend(cmdset_b.commands)
|
||||||
else:
|
else:
|
||||||
cmdset_c.commands.extend([cmd for cmd in cmdset_b if not cmd in cmdset_a])
|
cmdset_c.commands.extend([cmd for cmd in cmdset_b if not cmd in cmdset_a])
|
||||||
return cmdset_c
|
return cmdset_c
|
||||||
|
|
||||||
def _intersect(self, cmdset_a, cmdset_b, duplicates=False):
|
def _intersect(self, cmdset_a, cmdset_b):
|
||||||
"C = A (intersect) B. A is assumed higher priority"
|
"C = A (intersect) B. A is assumed higher priority"
|
||||||
cmdset_c = cmdset_a._duplicate()
|
cmdset_c = cmdset_a._duplicate()
|
||||||
if duplicates and cmdset_a.priority == cmdset_b.priority:
|
if cmdset_a.duplicates and cmdset_a.priority == cmdset_b.priority:
|
||||||
for cmd in [cmd for cmd in cmdset_a if cmd in cmdset_b]:
|
for cmd in [cmd for cmd in cmdset_a if cmd in cmdset_b]:
|
||||||
cmdset_c.add(cmd)
|
cmdset_c.add(cmd)
|
||||||
cmdset_c.add(cmdset_b.get(cmd))
|
cmdset_c.add(cmdset_b.get(cmd))
|
||||||
|
|
@ -174,13 +174,13 @@ class CmdSet(object):
|
||||||
cmdset_c.commands = [cmd for cmd in cmdset_a if cmd in cmdset_b]
|
cmdset_c.commands = [cmd for cmd in cmdset_a if cmd in cmdset_b]
|
||||||
return cmdset_c
|
return cmdset_c
|
||||||
|
|
||||||
def _replace(self, cmdset_a, cmdset_b, cmdset_c):
|
def _replace(self, cmdset_a, cmdset_b):
|
||||||
"C = A + B where the result is A."
|
"C = A + B where the result is A."
|
||||||
cmdset_c = cmdset_a._duplicate()
|
cmdset_c = cmdset_a._duplicate()
|
||||||
cmdset_c.commands = cmdset_a.commands[:]
|
cmdset_c.commands = cmdset_a.commands[:]
|
||||||
return cmdset_c
|
return cmdset_c
|
||||||
|
|
||||||
def _remove(self, cmdset_a, cmdset_b, cmdset_c):
|
def _remove(self, cmdset_a, cmdset_b):
|
||||||
"C = A + B, where B is filtered by A"
|
"C = A + B, where B is filtered by A"
|
||||||
cmdset_c = cmdset_a._duplicate()
|
cmdset_c = cmdset_a._duplicate()
|
||||||
cmdset_c.commands = [cmd for cmd in cmdset_b if not cmd in cmdset_a]
|
cmdset_c.commands = [cmd for cmd in cmdset_b if not cmd in cmdset_a]
|
||||||
|
|
@ -267,13 +267,13 @@ class CmdSet(object):
|
||||||
|
|
||||||
mergetype = self.key_mergetypes.get(cmdset_b.key, self.mergetype)
|
mergetype = self.key_mergetypes.get(cmdset_b.key, self.mergetype)
|
||||||
if mergetype == "Intersect":
|
if mergetype == "Intersect":
|
||||||
cmdset_c = self._intersect(self, cmdset_b, cmdset_b.duplicates)
|
cmdset_c = self._intersect(self, cmdset_b)
|
||||||
elif mergetype == "Replace":
|
elif mergetype == "Replace":
|
||||||
cmdset_c = self._replace(self, cmdset_b, cmdset_b.duplicates)
|
cmdset_c = self._replace(self, cmdset_b)
|
||||||
elif mergetype == "Remove":
|
elif mergetype == "Remove":
|
||||||
cmdset_c = self._remove(self, cmdset_b, cmdset_b.duplicates)
|
cmdset_c = self._remove(self, cmdset_b)
|
||||||
else: # Union
|
else: # Union
|
||||||
cmdset_c = self._union(self, cmdset_b, cmdset_b.duplicates)
|
cmdset_c = self._union(self, cmdset_b)
|
||||||
cmdset_c.no_channels = self.no_channels
|
cmdset_c.no_channels = self.no_channels
|
||||||
cmdset_c.no_exits = self.no_exits
|
cmdset_c.no_exits = self.no_exits
|
||||||
cmdset_c.no_objs = self.no_objs
|
cmdset_c.no_objs = self.no_objs
|
||||||
|
|
@ -286,13 +286,13 @@ class CmdSet(object):
|
||||||
|
|
||||||
mergetype = cmdset_b.key_mergetypes.get(self.key, cmdset_b.mergetype)
|
mergetype = cmdset_b.key_mergetypes.get(self.key, cmdset_b.mergetype)
|
||||||
if mergetype == "Intersect":
|
if mergetype == "Intersect":
|
||||||
cmdset_c = self._intersect(cmdset_b, self, self.duplicates)
|
cmdset_c = self._intersect(cmdset_b, self)
|
||||||
elif mergetype == "Replace":
|
elif mergetype == "Replace":
|
||||||
cmdset_c = self._replace(cmdset_b, self, self.duplicates)
|
cmdset_c = self._replace(cmdset_b, self)
|
||||||
elif mergetype == "Remove":
|
elif mergetype == "Remove":
|
||||||
cmdset_c = self._remove(self, cmdset_b, self.duplicates)
|
cmdset_c = self._remove(self, cmdset_b)
|
||||||
else: # Union
|
else: # Union
|
||||||
cmdset_c = self._union(cmdset_b, self, self.duplicates)
|
cmdset_c = self._union(cmdset_b, self)
|
||||||
cmdset_c.no_channels = cmdset_b.no_channels
|
cmdset_c.no_channels = cmdset_b.no_channels
|
||||||
cmdset_c.no_exits = cmdset_b.no_exits
|
cmdset_c.no_exits = cmdset_b.no_exits
|
||||||
cmdset_c.no_objs = cmdset_b.no_objs
|
cmdset_c.no_objs = cmdset_b.no_objs
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,21 @@ import re
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils.utils import is_iter, fill
|
from src.utils.utils import is_iter, fill
|
||||||
|
|
||||||
class CommandMeta(type):
|
def _init_command(mcs, **kwargs):
|
||||||
"""
|
"""
|
||||||
This metaclass makes some minor on-the-fly convenience fixes to the command
|
Helper command.
|
||||||
class in case the admin forgets to put things in lowercase etc.
|
Makes sure all data are stored as lowercase and
|
||||||
"""
|
|
||||||
def __init__(mcs, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Simply make sure all data are stored as lowercase and
|
|
||||||
do checking on all properties that should be in list form.
|
do checking on all properties that should be in list form.
|
||||||
Sets up locks to be more forgiving.
|
Sets up locks to be more forgiving. This is used both by the metaclass
|
||||||
|
and (optionally) at instantiation time.
|
||||||
|
|
||||||
|
If kwargs are given, these are set as instance-specific properties on the command.
|
||||||
"""
|
"""
|
||||||
|
for i in range(len(kwargs)):
|
||||||
|
# used for dynamic creation of commands
|
||||||
|
key, value = kwargs.popitem()
|
||||||
|
setattr(mcs, key, value)
|
||||||
|
|
||||||
mcs.key = mcs.key.lower()
|
mcs.key = mcs.key.lower()
|
||||||
if mcs.aliases and not is_iter(mcs.aliases):
|
if mcs.aliases and not is_iter(mcs.aliases):
|
||||||
try:
|
try:
|
||||||
|
|
@ -61,6 +65,14 @@ class CommandMeta(type):
|
||||||
if not hasattr(mcs, "help_category"):
|
if not hasattr(mcs, "help_category"):
|
||||||
mcs.help_category = "general"
|
mcs.help_category = "general"
|
||||||
mcs.help_category = mcs.help_category.lower()
|
mcs.help_category = mcs.help_category.lower()
|
||||||
|
|
||||||
|
|
||||||
|
class CommandMeta(type):
|
||||||
|
"""
|
||||||
|
The metaclass cleans up all properties on the class
|
||||||
|
"""
|
||||||
|
def __init__(mcs, *args, **kwargs):
|
||||||
|
_init_command(mcs, **kwargs)
|
||||||
super(CommandMeta, mcs).__init__(*args, **kwargs)
|
super(CommandMeta, mcs).__init__(*args, **kwargs)
|
||||||
|
|
||||||
# The Command class is the basic unit of an Evennia command; when
|
# The Command class is the basic unit of an Evennia command; when
|
||||||
|
|
@ -125,8 +137,12 @@ class Command(object):
|
||||||
# sessid - which session-id (if any) is responsible for triggering this command
|
# sessid - which session-id (if any) is responsible for triggering this command
|
||||||
#
|
#
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, **kwargs):
|
||||||
"the lockhandler works the same as for objects."
|
"""the lockhandler works the same as for objects.
|
||||||
|
optional kwargs will be set as properties on the Command at runtime,
|
||||||
|
overloading evential same-named class properties."""
|
||||||
|
if kwargs:
|
||||||
|
_init_command(self, **kwargs)
|
||||||
self.lockhandler = LockHandler(self)
|
self.lockhandler = LockHandler(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
||||||
|
|
@ -136,14 +136,11 @@ class ChannelHandler(object):
|
||||||
and run self.update on the handler.
|
and run self.update on the handler.
|
||||||
"""
|
"""
|
||||||
# map the channel to a searchable command
|
# map the channel to a searchable command
|
||||||
cmd = ChannelCommand()
|
cmd = ChannelCommand(key=channel.key.strip().lower(),
|
||||||
cmd.key = channel.key.strip().lower()
|
aliases=channel.aliases if channel.aliases else [],
|
||||||
cmd.obj = channel
|
locks="cmd:all();%s" % channel.locks,
|
||||||
|
obj=channel)
|
||||||
cmd.__doc__= self._format_help(channel)
|
cmd.__doc__= self._format_help(channel)
|
||||||
if channel.aliases:
|
|
||||||
cmd.aliases = channel.aliases
|
|
||||||
cmd.lock_storage = "cmd:all();%s" % channel.locks
|
|
||||||
cmd.lockhandler.reset()
|
|
||||||
self.cached_channel_cmds.append(cmd)
|
self.cached_channel_cmds.append(cmd)
|
||||||
self.cached_cmdsets = {}
|
self.cached_cmdsets = {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -907,13 +907,12 @@ class Exit(Object):
|
||||||
self.obj.at_failed_traverse(self.caller)
|
self.obj.at_failed_traverse(self.caller)
|
||||||
|
|
||||||
# create an exit command.
|
# create an exit command.
|
||||||
cmd = ExitCommand()
|
cmd = ExitCommand(key=exidbobj.db_key.strip().lower(),
|
||||||
cmd.key = exidbobj.db_key.strip().lower()
|
aliases=exidbobj.aliases,
|
||||||
cmd.obj = exidbobj
|
locks=str(exidbobj.locks),
|
||||||
cmd.aliases = exidbobj.aliases
|
auto_help=False,
|
||||||
cmd.locks = str(exidbobj.locks)
|
destination=exidbobj.db_destination,
|
||||||
cmd.destination = exidbobj.db_destination
|
obj=exidbobj)
|
||||||
cmd.auto_help = False
|
|
||||||
# create a cmdset
|
# create a cmdset
|
||||||
exit_cmdset = cmdset.CmdSet(None)
|
exit_cmdset = cmdset.CmdSet(None)
|
||||||
exit_cmdset.key = '_exitset'
|
exit_cmdset.key = '_exitset'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue