From f7e947901fcc116dcbcff765aeb2c0056bd7c444 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 7 Aug 2021 23:33:34 +0200 Subject: [PATCH] Fix bug in $protkey protfunc. Resolve #2329. --- evennia/prototypes/prototypes.py | 8 +++++--- evennia/prototypes/spawner.py | 29 +++++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/evennia/prototypes/prototypes.py b/evennia/prototypes/prototypes.py index c81ffe7363..361c3c9e65 100644 --- a/evennia/prototypes/prototypes.py +++ b/evennia/prototypes/prototypes.py @@ -829,7 +829,8 @@ def validate_prototype( prototype["prototype_locks"] = prototype_locks -def protfunc_parser(value, available_functions=None, testing=False, stacktrace=False, caller=None, **kwargs): +def protfunc_parser(value, available_functions=None, testing=False, stacktrace=False, + caller=None, **kwargs): """ Parse a prototype value string for a protfunc and process it. @@ -1003,7 +1004,7 @@ def check_permission(prototype_key, action, default=True): return default -def init_spawn_value(value, validator=None, caller=None): +def init_spawn_value(value, validator=None, caller=None, prototype=None): """ Analyze the prototype value and produce a value useful at the point of spawning. @@ -1016,6 +1017,7 @@ def init_spawn_value(value, validator=None, caller=None): check and guarantee the outcome is of a given type. caller (Object or Account): This is necessary for certain protfuncs that perform object searches and have to check permissions. + prototype (dict): Prototype this is to be used for. Necessary for certain protfuncs. Returns: any (any): The (potentially pre-processed value to use for this prototype key) @@ -1030,7 +1032,7 @@ def init_spawn_value(value, validator=None, caller=None): value = validator(value[0](*make_iter(args))) else: value = validator(value) - result = protfunc_parser(value, caller=caller) + result = protfunc_parser(value, caller=caller, prototype=prototype) if result != value: return validator(result) return result diff --git a/evennia/prototypes/spawner.py b/evennia/prototypes/spawner.py index d025f75f02..eb01b9eae0 100644 --- a/evennia/prototypes/spawner.py +++ b/evennia/prototypes/spawner.py @@ -678,36 +678,37 @@ def batch_update_objects_with_prototype(prototype, diff=None, objects=None, val = new_prototype[key] do_save = True + def _init(val, typ): + return init_spawn_value(val, str, caller=caller, prototype=new_prototype) + if key == "key": - obj.db_key = init_spawn_value(val, str, caller=caller) + obj.db_key = _init(val, str) elif key == "typeclass": - obj.db_typeclass_path = init_spawn_value(val, str, caller=caller) + obj.db_typeclass_path = _init(val, str) elif key == "location": - obj.db_location = init_spawn_value(val, value_to_obj, caller=caller) + obj.db_location = _init(val, value_to_obj) elif key == "home": - obj.db_home = init_spawn_value(val, value_to_obj, caller=caller) + obj.db_home = _init(val, value_to_obj) elif key == "destination": - obj.db_destination = init_spawn_value(val, value_to_obj, caller=caller) + obj.db_destination = _init(val, value_to_obj) elif key == "locks": if directive == "REPLACE": obj.locks.clear() - obj.locks.add(init_spawn_value(val, str, caller=caller)) + obj.locks.add(_init(val, str)) elif key == "permissions": if directive == "REPLACE": obj.permissions.clear() - obj.permissions.batch_add(*(init_spawn_value(perm, str, caller=caller) - for perm in val)) + obj.permissions.batch_add(*(_init(perm, str) for perm in val)) elif key == "aliases": if directive == "REPLACE": obj.aliases.clear() - obj.aliases.batch_add(*(init_spawn_value(alias, str, caller=caller) - for alias in val)) + obj.aliases.batch_add(*(_init(alias, str) for alias in val)) elif key == "tags": if directive == "REPLACE": obj.tags.clear() obj.tags.batch_add( *( - (init_spawn_value(ttag, str, caller=caller), tcategory, tdata) + (_init(ttag, str), tcategory, tdata) for ttag, tcategory, tdata in val ) ) @@ -717,8 +718,8 @@ def batch_update_objects_with_prototype(prototype, diff=None, objects=None, obj.attributes.batch_add( *( ( - init_spawn_value(akey, str, caller=caller), - init_spawn_value(aval, value_to_obj, caller=caller), + _init(akey, str), + _init(aval, value_to_obj), acategory, alocks, ) @@ -729,7 +730,7 @@ def batch_update_objects_with_prototype(prototype, diff=None, objects=None, # we don't auto-rerun exec statements, it would be huge security risk! pass else: - obj.attributes.add(key, init_spawn_value(val, value_to_obj, caller=caller)) + obj.attributes.add(key, _init(val, value_to_obj)) elif directive == "REMOVE": do_save = True if key == "key":