Further stabilizing of spawner storage mechanism and error checking
This commit is contained in:
parent
0967c9f668
commit
641ea746a5
3 changed files with 79 additions and 22 deletions
|
|
@ -2229,11 +2229,14 @@ class CmdExamine(ObjManipCommand):
|
||||||
else:
|
else:
|
||||||
things.append(content)
|
things.append(content)
|
||||||
if exits:
|
if exits:
|
||||||
string += "\n|wExits|n: %s" % ", ".join(["%s(%s)" % (exit.name, exit.dbref) for exit in exits])
|
string += "\n|wExits|n: %s" % ", ".join(
|
||||||
|
["%s(%s)" % (exit.name, exit.dbref) for exit in exits])
|
||||||
if pobjs:
|
if pobjs:
|
||||||
string += "\n|wCharacters|n: %s" % ", ".join(["|c%s|n(%s)" % (pobj.name, pobj.dbref) for pobj in pobjs])
|
string += "\n|wCharacters|n: %s" % ", ".join(
|
||||||
|
["|c%s|n(%s)" % (pobj.name, pobj.dbref) for pobj in pobjs])
|
||||||
if things:
|
if things:
|
||||||
string += "\n|wContents|n: %s" % ", ".join(["%s(%s)" % (cont.name, cont.dbref) for cont in obj.contents
|
string += "\n|wContents|n: %s" % ", ".join(
|
||||||
|
["%s(%s)" % (cont.name, cont.dbref) for cont in obj.contents
|
||||||
if cont not in exits and cont not in pobjs])
|
if cont not in exits and cont not in pobjs])
|
||||||
separator = "-" * _DEFAULT_WIDTH
|
separator = "-" * _DEFAULT_WIDTH
|
||||||
# output info
|
# output info
|
||||||
|
|
@ -2961,9 +2964,6 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# handle lhs
|
# handle lhs
|
||||||
parts = self.lhs.split(";", 3)
|
parts = self.lhs.split(";", 3)
|
||||||
key, desc, tags, lockstring = (
|
|
||||||
"", "User-created prototype", ["user-created"],
|
|
||||||
"edit:id({}) or perm(Admin); use:all()".format(caller.id))
|
|
||||||
nparts = len(parts)
|
nparts = len(parts)
|
||||||
if nparts == 1:
|
if nparts == 1:
|
||||||
key = parts[0].strip()
|
key = parts[0].strip()
|
||||||
|
|
@ -2971,11 +2971,25 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
key, desc = (part.strip() for part in parts)
|
key, desc = (part.strip() for part in parts)
|
||||||
elif nparts == 3:
|
elif nparts == 3:
|
||||||
key, desc, tags = (part.strip() for part in parts)
|
key, desc, tags = (part.strip() for part in parts)
|
||||||
tags = [tag.strip().lower() for tag in tags.split(",")]
|
tags = [tag.strip().lower() for tag in tags.split(",") if tag]
|
||||||
else:
|
else:
|
||||||
# lockstrings can itself contain ;
|
# lockstrings can itself contain ;
|
||||||
key, desc, tags, lockstring = (part.strip() for part in parts)
|
key, desc, tags, lockstring = (part.strip() for part in parts)
|
||||||
tags = [tag.strip().lower() for tag in tags.split(",")]
|
tags = [tag.strip().lower() for tag in tags.split(",") if tag]
|
||||||
|
if not key:
|
||||||
|
caller.msg("The prototype must have a key.")
|
||||||
|
return
|
||||||
|
if not desc:
|
||||||
|
desc = "User-created prototype"
|
||||||
|
if not tags:
|
||||||
|
tags = ["user"]
|
||||||
|
if not lockstring:
|
||||||
|
lockstring = "edit:id({}) or perm(Admin); use:all()".format(caller.id)
|
||||||
|
|
||||||
|
is_valid, err = caller.locks.validate(lockstring)
|
||||||
|
if not is_valid:
|
||||||
|
caller.msg("|rLock error|n: {}".format(err))
|
||||||
|
return
|
||||||
|
|
||||||
# handle rhs:
|
# handle rhs:
|
||||||
prototype = _parse_prototype(self.rhs)
|
prototype = _parse_prototype(self.rhs)
|
||||||
|
|
@ -3002,7 +3016,11 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
# all seems ok. Try to save.
|
# all seems ok. Try to save.
|
||||||
try:
|
try:
|
||||||
prot = save_db_prototype(caller, key, prototype, desc=desc, tags=tags, locks=lockstring)
|
prot = save_db_prototype(
|
||||||
|
caller, key, prototype, desc=desc, tags=tags, locks=lockstring)
|
||||||
|
if not prot:
|
||||||
|
caller.msg("|rError saving:|R {}.|n".format(key))
|
||||||
|
return
|
||||||
prot.locks.append("edit", "perm(Admin)")
|
prot.locks.append("edit", "perm(Admin)")
|
||||||
if not prot.locks.get("use"):
|
if not prot.locks.get("use"):
|
||||||
prot.locks.add("use:all()")
|
prot.locks.add("use:all()")
|
||||||
|
|
@ -3043,7 +3061,6 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
metaproto = metaprotos[0]
|
metaproto = metaprotos[0]
|
||||||
if not caller.locks.check_lockstring(caller, metaproto.locks, access_type='use'):
|
if not caller.locks.check_lockstring(caller, metaproto.locks, access_type='use'):
|
||||||
caller.msg("You don't have access to use this prototype.")
|
caller.msg("You don't have access to use this prototype.")
|
||||||
print("spawning2 {}:{} - {}".format(self.cmdstring, self.args, prototype))
|
|
||||||
return
|
return
|
||||||
prototype = metaproto.prototype
|
prototype = metaproto.prototype
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ class LockHandler(object):
|
||||||
"""
|
"""
|
||||||
self.lock_bypass = hasattr(obj, "is_superuser") and obj.is_superuser
|
self.lock_bypass = hasattr(obj, "is_superuser") and obj.is_superuser
|
||||||
|
|
||||||
def add(self, lockstring):
|
def add(self, lockstring, validate_only=False):
|
||||||
"""
|
"""
|
||||||
Add a new lockstring to handler.
|
Add a new lockstring to handler.
|
||||||
|
|
||||||
|
|
@ -296,10 +296,12 @@ class LockHandler(object):
|
||||||
`"<access_type>:<functions>"`. Multiple access types
|
`"<access_type>:<functions>"`. Multiple access types
|
||||||
should be separated by semicolon (`;`). Alternatively,
|
should be separated by semicolon (`;`). Alternatively,
|
||||||
a list with lockstrings.
|
a list with lockstrings.
|
||||||
|
validate_only (bool, optional): If True, validate the lockstring but
|
||||||
|
don't actually store it.
|
||||||
Returns:
|
Returns:
|
||||||
success (bool): The outcome of the addition, `False` on
|
success (bool): The outcome of the addition, `False` on
|
||||||
error.
|
error. If `validate_only` is True, this will be a tuple
|
||||||
|
(bool, error), for pass/fail and a string error.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(lockstring, basestring):
|
if isinstance(lockstring, basestring):
|
||||||
|
|
@ -308,21 +310,41 @@ class LockHandler(object):
|
||||||
lockdefs = [lockdef for locks in lockstring for lockdef in locks.split(";")]
|
lockdefs = [lockdef for locks in lockstring for lockdef in locks.split(";")]
|
||||||
lockstring = ";".join(lockdefs)
|
lockstring = ";".join(lockdefs)
|
||||||
|
|
||||||
|
err = ""
|
||||||
# sanity checks
|
# sanity checks
|
||||||
for lockdef in lockdefs:
|
for lockdef in lockdefs:
|
||||||
if ':' not in lockdef:
|
if ':' not in lockdef:
|
||||||
self._log_error(_("Lock: '%s' contains no colon (:).") % lockdef)
|
err = _("Lock: '{lockdef}' contains no colon (:).").format(lockdef=lockdef)
|
||||||
|
if validate_only:
|
||||||
|
return False, err
|
||||||
|
else:
|
||||||
|
self._log_error(err)
|
||||||
return False
|
return False
|
||||||
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
|
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
|
||||||
if not access_type:
|
if not access_type:
|
||||||
self._log_error(_("Lock: '%s' has no access_type (left-side of colon is empty).") % lockdef)
|
err = _("Lock: '{lockdef}' has no access_type "
|
||||||
|
"(left-side of colon is empty).").format(lockdef=lockdef)
|
||||||
|
if validate_only:
|
||||||
|
return False, err
|
||||||
|
else:
|
||||||
|
self._log_error(err)
|
||||||
return False
|
return False
|
||||||
if rhs.count('(') != rhs.count(')'):
|
if rhs.count('(') != rhs.count(')'):
|
||||||
self._log_error(_("Lock: '%s' has mismatched parentheses.") % lockdef)
|
err = _("Lock: '{lockdef}' has mismatched parentheses.").format(lockdef=lockdef)
|
||||||
|
if validate_only:
|
||||||
|
return False, err
|
||||||
|
else:
|
||||||
|
self._log_error(err)
|
||||||
return False
|
return False
|
||||||
if not _RE_FUNCS.findall(rhs):
|
if not _RE_FUNCS.findall(rhs):
|
||||||
self._log_error(_("Lock: '%s' has no valid lock functions.") % lockdef)
|
err = _("Lock: '{lockdef}' has no valid lock functions.").format(lockdef=lockdef)
|
||||||
|
if validate_only:
|
||||||
|
return False, err
|
||||||
|
else:
|
||||||
|
self._log_error(err)
|
||||||
return False
|
return False
|
||||||
|
if validate_only:
|
||||||
|
return True, None
|
||||||
# get the lock string
|
# get the lock string
|
||||||
storage_lockstring = self.obj.lock_storage
|
storage_lockstring = self.obj.lock_storage
|
||||||
if storage_lockstring:
|
if storage_lockstring:
|
||||||
|
|
@ -334,6 +356,18 @@ class LockHandler(object):
|
||||||
self._save_locks()
|
self._save_locks()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def validate(self, lockstring):
|
||||||
|
"""
|
||||||
|
Validate lockstring syntactically, without saving it.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lockstring (str): Lockstring to validate.
|
||||||
|
Returns:
|
||||||
|
valid (bool): If validation passed or not.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.add(lockstring, validate_only=True)
|
||||||
|
|
||||||
def replace(self, lockstring):
|
def replace(self, lockstring):
|
||||||
"""
|
"""
|
||||||
Replaces the lockstring entirely.
|
Replaces the lockstring entirely.
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,12 @@ def save_db_prototype(caller, key, prototype, desc="", tags=None, locks="", dele
|
||||||
key_orig = key
|
key_orig = key
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
locks = locks if locks else "use:all();edit:id({}) or perm(Admin)".format(caller.id)
|
locks = locks if locks else "use:all();edit:id({}) or perm(Admin)".format(caller.id)
|
||||||
|
|
||||||
|
is_valid, err = caller.locks.validate(locks)
|
||||||
|
if not is_valid:
|
||||||
|
caller.msg("Lock error: {}".format(err))
|
||||||
|
return False
|
||||||
|
|
||||||
tags = [(tag, "db_prototype") for tag in make_iter(tags)]
|
tags = [(tag, "db_prototype") for tag in make_iter(tags)]
|
||||||
|
|
||||||
if key in _MODULE_PROTOTYPES:
|
if key in _MODULE_PROTOTYPES:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue