def __init__(self, player): if locks.authority() is not locks.SYSTEM: raise locks.LockFailedError( "PythonMode requires system authority.") self.console = code.InteractiveConsole() player.send(">>>")
def go(self, player): if not self.locks.go(player): raise locks.LockFailedError( "You can't go through {}.".format(self)) player.location = self.destination params = { "player": player.name, "exit": self.name, "source": self.location.name, "destination": self.destination.name } try: self.location.emit(self.depart_message.format(**params)) except AttributeError: pass try: self.destination.emit(self.arrive_message.format(**params), exceptions=[player]) except AttributeError: pass try: player.send(self.go_message.format(**params)) except AttributeError: pass
def destroy(self): """ Destroy this object, if current authority passes its destroy lock. """ if not self.locks.destroy(): raise locks.LockFailedError("You cannot destroy {}.".format( self.name, self.owner)) delete(self)
def location(self, destination): origin = self.location if not destination.locks.insert(): raise locks.LockFailedError("You can't put that in {}.".format( destination.name)) if origin and not origin.locks.remove(): raise locks.LockFailedError( "You can't remove that from {}.".format(origin.name)) player = locks.authority() if destination == player: if not self.locks.take(): raise locks.LockFailedError("You cannot take {}.".format( self.name)) elif origin == player: if not self.locks.drop(): raise locks.LockFailedError("You cannot drop {}.".format( self.name)) # Locks passed or non-applicable. Proceed with the move. with locks.authority_of(locks.SYSTEM): self._location = destination with locks.authority_of(self): # this gets to use self authority because it should always happen, # regardless of the reason location is being changed. # it does NOT get to use system authority because it's sometimes # (always, for players) how position gets initialized, which locks # the object out of its own position attribute. if destination is not origin: # whatever we were doing there, we're not doing it any more self.position = None # Trigger a "look" command so we see our new surroundings from muss.commands.world import Look try: Look().execute(self, {"obj": destination}) except AttributeError: pass
def __getattribute__(self, attr): if attr == "__dict__" and locks.authority() is locks.SYSTEM: # This comes up when we're unpickling the db, and attr_locks # doesn't exist yet return super(Object, self).__getattribute__(attr) attr_locks = super(Object, self).__getattribute__("attr_locks") if attr in attr_locks: if attr_locks[attr].get_lock(): # Lock passes; grant access return super(Object, self).__getattribute__(attr) else: # Lock fails; deny access raise locks.LockFailedError("You don't have permission to get " "{} from {}.".format(attr, self)) else: # No lock is defined; grant access return super(Object, self).__getattribute__(attr)
def name(self, name): if name.startswith("#"): raise ValueError("Names can't begin with a #.") if hasattr(self, "name"): with locks.authority_of(locks.SYSTEM): lock = self.attr_locks["name"].set_lock if lock(): with locks.authority_of(locks.SYSTEM): self._name = name else: raise locks.LockFailedError("You don't have permission to set " "name on {}.".format(self)) else: lock = locks.OwnsAttribute(self, "name") attr_lock = locks.AttributeLock(set_lock=lock) with locks.authority_of(locks.SYSTEM): self.attr_locks["name"] = attr_lock self._name = name
def __delattr__(self, attr): try: with locks.authority_of(locks.SYSTEM): owner_lock = locks.Owns(self.attr_locks[attr]) except KeyError as e: if hasattr(self, attr): # Attribute exists, lock doesn't. This is a code error. raise e else: # The attribute doesn't exist. raise AttributeError if owner_lock(): super(Object, self).__delattr__(attr) with locks.authority_of(locks.SYSTEM): del self.attr_locks[attr] else: raise locks.LockFailedError( "You don't have permission to unset {} " "on {}.".format(attr, self))
def lock_attr(self, attr, owner=None, get_lock=None, set_lock=None): if not hasattr(self, attr): raise KeyError("{} has no attribute {}.".format(self, attr)) with locks.authority_of(locks.SYSTEM): lock = self.attr_locks[attr] if (locks.authority() is not lock.owner and locks.authority() is not locks.SYSTEM): raise locks.LockFailedError("You don't own that attribute.") if owner is None and get_lock is None and set_lock is None: raise TypeError( "Specify at least one of owner, get_lock, set_lock") if owner is not None: lock.owner = owner if get_lock is not None: lock.get_lock = get_lock if set_lock is not None: lock.set_lock = set_lock
def __setattr__(self, attr, value): # Does the attribute already exist? if attr not in super(Object, self).__getattribute__("__dict__"): # No, it's a new one; allow the write and also create a default lock super(Object, self).__setattr__(attr, value) lock = locks.AttributeLock( set_lock=locks.OwnsAttribute(self, attr)) with locks.authority_of(locks.SYSTEM): self.attr_locks[attr] = lock else: # Yes, so check the lock with locks.authority_of(locks.SYSTEM): if attr not in self.attr_locks: # No lock is defined; allow the write return super(Object, self).__setattr__(attr, value) else: set_lock = self.attr_locks[attr].set_lock if set_lock(): return super(Object, self).__setattr__(attr, value) else: # Lock fails; deny the write raise locks.LockFailedError("You don't have permission to set " "{} on {}.".format(attr, self))
def location(self): # Everything has a location. If feel the need to delete it, consider # setting it to None instead. raise locks.LockFailedError("You don't have permission to unset " "location on {}.".format(self))