Add inside_rec lockfunc. Resolves #1618

This commit is contained in:
Griatch 2020-02-17 01:11:31 +01:00
parent a3c2bb4668
commit a3fe5f4042
4 changed files with 45 additions and 3 deletions

View file

@ -48,6 +48,8 @@ without arguments starts a full interactive Python console.
`.get_command_info()` method for easier overloading and access. (Volund)
- Removed unused `CYCLE_LOGFILES` setting. Added `SERVER_LOG_DAY_ROTATION`
and `SERVER_LOG_MAX_SIZE` (and equivalent for PORTAL) to control log rotation.
- Addded `inside_rec` lockfunc - if room is locked, the normal `inside()` lockfunc will
fail e.g. for your inventory objs (since their loc is you), whereas this will pass.
## Evennia 0.9 (2018-2019)

View file

@ -547,11 +547,39 @@ def inside(accessing_obj, accessed_obj, *args, **kwargs):
Usage:
inside()
Only true if accessing_obj is "inside" accessed_obj
True if accessing_obj is 'inside' accessing_obj. Note that this only checks
one level down. So if if the lock is on a room, you will pass but not your
inventory (since their location is you, not the locked object). If you
want also nested objects to pass the lock, use the `insiderecursive`
lockfunc.
"""
return accessing_obj.location == accessed_obj
def inside_rec(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:
inside_rec()
True if accessing_obj is inside the accessed obj, at up to 10 levels
of recursion (so if this lock is on a room, then an object inside a box
in your inventory will also pass the lock).
"""
def _recursive_inside(obj, accessed_obj, lvl=1):
if obj.location:
if obj.location == accessed_obj:
return True
elif lvl >= 10:
# avoid infinite recursions
return False
else:
return _recursive_inside(obj.location, accessed_obj, lvl + 1)
return False
return _recursive_inside(accessing_obj, accessed_obj)
def holds(accessing_obj, accessed_obj, *args, **kwargs):
"""
Usage:

View file

@ -17,6 +17,7 @@ except ImportError:
from evennia import settings_default
from evennia.locks import lockfuncs
from evennia.utils.create import create_object
# ------------------------------------------------------------
# Lock testing
@ -179,6 +180,13 @@ class TestLockfuncs(EvenniaTest):
self.assertEqual(False, lockfuncs.inside(self.char1, self.room2))
self.assertEqual(True, lockfuncs.holds(self.room1, self.char1))
self.assertEqual(False, lockfuncs.holds(self.room2, self.char1))
# test recursively
self.assertEqual(True, lockfuncs.inside_rec(self.char1, self.room1))
self.assertEqual(False, lockfuncs.inside_rec(self.char1, self.room2))
inventory_item = create_object(key="InsideTester", location=self.char1)
self.assertEqual(True, lockfuncs.inside_rec(inventory_item, self.room1))
self.assertEqual(False, lockfuncs.inside_rec(inventory_item, self.room2))
inventory_item.delete()
def test_has_account(self):
self.assertEqual(True, lockfuncs.has_account(self.char1, None))

View file

@ -314,7 +314,9 @@ class AMPMultiConnectionProtocol(amp.AMP):
try:
super(AMPMultiConnectionProtocol, self).dataReceived(data)
except KeyError:
_get_logger().log_trace("Discarded incoming partial (packed) data (len {})".format(len(data)))
_get_logger().log_trace(
"Discarded incoming partial (packed) data (len {})".format(len(data))
)
elif self.multibatches:
# invalid AMP, but we have a pending multi-batch that is not yet complete
if data[-2:] == NULNUL:
@ -323,7 +325,9 @@ class AMPMultiConnectionProtocol(amp.AMP):
try:
super(AMPMultiConnectionProtocol, self).dataReceived(data)
except KeyError:
_get_logger().log_trace("Discarded incoming multi-batch (packed) data (len {})".format(len(data)))
_get_logger().log_trace(
"Discarded incoming multi-batch (packed) data (len {})".format(len(data))
)
else:
# not an AMP communication, return warning
self.transport.write(_HTTP_WARNING)