diff --git a/game/gamesrc/objects/examples/object.py b/game/gamesrc/objects/examples/object.py index dca6f88a64..2cc5a0f7eb 100644 --- a/game/gamesrc/objects/examples/object.py +++ b/game/gamesrc/objects/examples/object.py @@ -122,10 +122,9 @@ class Object(DefaultObject): at_server_reload() - called before server is reloaded at_server_shutdown() - called just before server is fully shut down - at_access_success(accessing_obj, access_type) - called if an lock access - check succeeded on this object - at_access_failure(accessing_obj, access_type) - called if an lock access - check failed on this object + at_access(result, accessing_obj, access_type) - called with the result + of a lock access check on this object. Return value + does not affect check result. at_before_move(destination) - called just before moving object to the destination. If returns False, move is cancelled. diff --git a/src/objects/objects.py b/src/objects/objects.py index 9f93a79a17..ca3fbb93bd 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -18,6 +18,7 @@ they control by simply linking to a new object's user property. from django.conf import settings from src.typeclasses.typeclass import TypeClass from src.commands import cmdset, command +from src.utils.logger import log_depmsg __all__ = ("Object", "Character", "Room", "Exit") @@ -155,7 +156,11 @@ class Object(TypeClass): this object in any fashion at_object_receive(obj, source_location) - called when this object receives another object - + at_access(result, **kwargs) - this is called with the result of an + access call, along with any kwargs used + for that call. The return of this + method does not affect the result of the + lock check. at_before_traverse(traversing_object) - (exit-objects only) called just before an object traverses this object @@ -417,7 +422,7 @@ class Object(TypeClass): return self.dbobj.swap_typeclass(new_typeclass, clean_attributes=clean_attributes, no_default=no_default) - def access(self, accessing_obj, access_type='read', default=False): + def access(self, accessing_obj, access_type='read', default=False, **kwargs): """ Determines if another object has permission to access this object in whatever way. @@ -425,15 +430,19 @@ class Object(TypeClass): accessing_obj (Object)- object trying to access this one access_type (string) - type of access sought default (bool) - what to return if no lock of access_type was found - - This function will call at_access_success or at_access_failure - depending on the outcome of the access check. - + **kwargs - passed to at_access hook along with result,accessing_obj and access_type """ - if self.dbobj.access(accessing_obj, access_type=access_type, default=default): + result = self.dbobj.access(accessing_obj, access_type=access_type, default=default) + self.at_access(result, accessing_obj, access_type, **kwargs) + return result + + # OBS: DEPRECATED! + if result: + log_depmsg("at_access_success is deprecated. Use at_access(result,**kwargs) instead.") self.at_access_success(accessing_obj, access_type) return True else: + log_depmsg("at_access_failure is deprecated. Use at_access(result,**kwargs) instead.") self.at_access_failure(accessing_obj, access_type) return False @@ -526,6 +535,7 @@ class Object(TypeClass): """ pass + def at_cmdset_get(self): """ Called just before cmdsets on this object are requested by the @@ -585,8 +595,20 @@ class Object(TypeClass): """ pass + def at_access(self, result, accessing_obj, access_type, **kwargs): + """ + This is called with the result of an access call, along with + any kwargs used for that call. The return of this method does + not affect the result of the lock check. It can be used e.g. to + customize error messages in a central location or other effects + based on the access result. + """ + pass + def at_access_success(self, accessing_obj, access_type): """ + OBS: DEPRECATED. Use at_access instead + This hook is called whenever accessing_obj succeed a lock check of type access_type on this object, for whatever reason. The return value of this hook is not used, the lock will still pass regardless of what @@ -596,6 +618,8 @@ class Object(TypeClass): def at_access_failure(self, accessing_obj, access_type): """ + OBS: DEPRECATED. Use at_access instead + This hook is called whenever accessing_obj fails a lock check of type access_type on this object, for whatever reason. The return value of this hook is not used, the lock will still fail regardless of what diff --git a/src/players/player.py b/src/players/player.py index 6d8042ab5c..f11787b375 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -90,6 +90,7 @@ class Player(TypeClass): usually handled on the character level: at_init() + at_access() at_cmdset_get() at_first_login() at_post_login(sessid=None) @@ -213,12 +214,11 @@ class Player(TypeClass): Returns: boolean True/False depending on if the swap worked or not. - """ self.dbobj.swap_typeclass(new_typeclass, clean_attributes=clean_attributes, no_default=no_default) - def access(self, accessing_obj, access_type='read', default=False): + def access(self, accessing_obj, access_type='read', default=False, **kwargs): """ Determines if another object has permission to access this object in whatever way. @@ -226,8 +226,11 @@ class Player(TypeClass): accessing_obj (Object)- object trying to access this one access_type (string) - type of access sought default (bool) - what to return if no lock of access_type was found + **kwargs - passed to the at_access hook along with the result. """ - return self.dbobj.access(accessing_obj, access_type=access_type, default=default) + result = self.dbobj.access(accessing_obj, access_type=access_type, default=default) + self.at_access(result, accessing_obj, access_type, **kwargs) + return result def check_permstring(self, permstring): """ @@ -236,6 +239,7 @@ class Player(TypeClass): permstring (string) - permission string that need to match a permission on the object. (example: 'Builders') + Note that this method does -not- call the at_access hook. """ return self.dbobj.check_permstring(permstring) @@ -288,6 +292,16 @@ class Player(TypeClass): # and have some things that should be done regardless of which # character is currently connected to this player. + def at_access(self, result, accessing_obj, access_type, **kwargs): + """ + This is called with the result of an access call, along with + any kwargs used for that call. The return of this method does + not affect the result of the lock check. It can be used e.g. to + customize error messages in a central location or other effects + based on the access result. + """ + pass + def at_cmdset_get(self): """ Called just before cmdsets on this player are requested by the diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 56ed41698c..4b51b1d704 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -173,14 +173,17 @@ class Attribute(SharedMemoryModel): def __unicode__(self): return u"%s(%s)" % (_GA(self, "db_key"), _GA(self, "id")) - def access(self, accessing_obj, access_type='read', default=False): + def access(self, accessing_obj, access_type='read', default=False, **kwargs): """ Determines if another object has permission to access. accessing_obj - object trying to access this one access_type - type of access sought default - what to return if no lock of access_type was found + **kwargs - passed to at_access hook along with result. """ - return self.locks.check(accessing_obj, access_type=access_type, default=default) + result = self.locks.check(accessing_obj, access_type=access_type, default=default) + self.at_access(result, **kwargs) + return result def at_set(self, new_value): """ @@ -1060,19 +1063,21 @@ class TypedObject(SharedMemoryModel): # Lock / permission methods # - def access(self, accessing_obj, access_type='read', default=False): + def access(self, accessing_obj, access_type='read', default=False, **kwargs): """ Determines if another object has permission to access. accessing_obj - object trying to access this one access_type - type of access sought default - what to return if no lock of access_type was found + **kwargs - this is ignored, but is there to make the api consistent with the + object-typeclass method access, which use it to feed to its hook methods. """ return self.locks.check(accessing_obj, access_type=access_type, default=default) def check_permstring(self, permstring): """ This explicitly checks if we hold particular permission without - involving any locks. + involving any locks. It does -not- trigger the at_access hook. """ if hasattr(self, "player"): if self.player and self.player.is_superuser: