diff --git a/src/commands/cmdhandler.py b/src/commands/cmdhandler.py index 8d2b0e0d5c..9ed4020b63 100644 --- a/src/commands/cmdhandler.py +++ b/src/commands/cmdhandler.py @@ -105,9 +105,10 @@ def get_and_merge_cmdsets(caller): # Gather cmdsets from location, objects in location or carried local_objects_cmdsets = [None] - location = None - if hasattr(caller, "location"): + try: location = caller.location + except Exception: + location = None if location and not caller_cmdset.no_objs: # Gather all cmdsets stored on objects in the room and # also in the caller's inventory and the location itself diff --git a/src/commands/cmdparser.py b/src/commands/cmdparser.py index caf8ef33c2..0d97ce283f 100644 --- a/src/commands/cmdparser.py +++ b/src/commands/cmdparser.py @@ -158,7 +158,7 @@ def at_search_result(msg_obj, ostring, results, global_search=False): if hasattr(result, "location") and result.location == msg_obj: invtext = " (carried)" if show_dbref: - dbreftext = "(#%i)" % result.id + dbreftext = "(#%i)" % result.dbid string += "\n %i-%s%s%s" % (num+1, result.name, dbreftext, invtext) results = None diff --git a/src/locks/lockfuncs.py b/src/locks/lockfuncs.py index 3abb449361..73844aaab5 100644 --- a/src/locks/lockfuncs.py +++ b/src/locks/lockfuncs.py @@ -82,7 +82,6 @@ DefaultLock: Exits: controls who may traverse the exit to """ from django.conf import settings -from src.utils import search from src.utils import utils _PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] @@ -123,7 +122,7 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs): try: perm = args[0].lower() permissions = [p.lower() for p in accessing_obj.permissions] - except AttributeError, IndexError: + except (AttributeError, IndexError): return False if perm in permissions: @@ -193,8 +192,8 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs): dbref = int(args[0].strip().strip('#')) except ValueError: return False - if hasattr(accessing_obj, 'id'): - return dbref == accessing_obj.id + if hasattr(accessing_obj, 'dbid'): + return dbref == accessing_obj.dbid return False def pdbref(accessing_obj, accessed_obj, *args, **kwargs): @@ -255,8 +254,7 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs): "compare based on type" try: return CF_MAPPING.get(typ, 'default')(val1, val2) - except Exception, e: - #print e + except Exception: # this might happen if we try to compare two things that cannot be compared return False @@ -376,7 +374,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs): # helper function. Compares both dbrefs and keys/aliases. objid = str(objid) dbref = utils.dbref(objid) - if dbref and any((True for obj in contents if obj.id == dbref)): + if dbref and any((True for obj in contents if obj.dbid == dbref)): return True objid = objid.lower() return any((True for obj in contents @@ -386,13 +384,13 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs): return check_holds(args[0]) else: try: - if check_holds(accessed_obj.id): + if check_holds(accessed_obj.dbid): #print "holds: accessed_obj.id - True" return True except Exception: pass #print "holds: accessed_obj.obj.id -", hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id) - return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id) + return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.dbid) def superuser(*args, **kwargs): """ diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index 01dc2be53f..3020d86d56 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -346,7 +346,7 @@ class LockHandler(object): if (not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) - or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser)))): + or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser)))): # we grant access to superusers and also to protocol instances that not yet has any player assigned to them (the # latter is a safety feature since superuser cannot be authenticated at some point during the connection). return True diff --git a/src/objects/models.py b/src/objects/models.py index 63c81c67e2..610e4bff23 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -247,14 +247,10 @@ class ObjectDB(TypedObject): "Setter. Allows for self.player = value" if isinstance(player, TypeClass): player = player.dbobj - self.db_player = player - self.save() _set_cache(self, "player", player) #@player.deleter def __player_del(self): "Deleter. Allows for del self.player" - self.db_player = None - self.save() _del_cache(self, "player") player = property(__player_get, __player_set, __player_del) @@ -747,7 +743,7 @@ class ObjectDB(TypedObject): default_home_id = int(settings.CHARACTER_DEFAULT_HOME) try: default_home = ObjectDB.objects.get(id=default_home_id) - if default_home.id == self.id: + if default_home.dbid == self.dbid: # we are deleting default home! default_home = None except Exception: @@ -758,7 +754,7 @@ class ObjectDB(TypedObject): for obj in objs: home = obj.home # Obviously, we can't send it back to here. - if not home or (home and home.id == self.id): + if not home or (home and home.dbid == self.dbid): obj.home = default_home # If for some reason it's still None... @@ -767,14 +763,14 @@ class ObjectDB(TypedObject): string += "now has a null location." obj.location = None obj.msg("Something went wrong! You are dumped into nowhere. Contact an admin.") - logger.log_errmsg(string % (obj.name, obj.id)) + logger.log_errmsg(string % (obj.name, obj.dbid)) return if obj.has_player: if home: string = "Your current location has ceased to exist," string += " moving you to %s(#%d)." - obj.msg(string % (home.name, home.id)) + obj.msg(string % (home.name, home.dbid)) else: # Famous last words: The player should never see this. string = "This place should not exist ... contact an admin." diff --git a/src/objects/objects.py b/src/objects/objects.py index 9da82c02f7..aef06f9034 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -353,16 +353,14 @@ class Object(TypeClass): This has be located at this level, having it in the parent doesn't work. """ - result = self.id == other - if not result and hasattr(other, "id"): - result = self.id == other.id - if not result: + try: + return self.dbref == other or self.dbref == other.dbref + except AttributeError: + # compare players instead try: - result = other and self.user.id == other.user.id + return self.player.uid == other or self.player.uid == other.player.uid except AttributeError: - pass - return result - + return False ## hooks called by the game engine diff --git a/src/players/models.py b/src/players/models.py index 3dca8c617f..b30c20472f 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -257,10 +257,10 @@ class PlayerDB(TypedObject): # def __str__(self): - return smart_str("%s(player %i)" % (self.name, self.id)) + return smart_str("%s(player %i)" % (self.name, self.dbid)) def __unicode__(self): - return u"%s(player#%i)" % (self.name, self.id) + return u"%s(player#%i)" % (self.name, self.dbid) # this is required to properly handle attributes and typeclass loading _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS diff --git a/src/scripts/scripthandler.py b/src/scripts/scripthandler.py index 2d442f1057..750f0cf4ed 100644 --- a/src/scripts/scripthandler.py +++ b/src/scripts/scripthandler.py @@ -2,25 +2,25 @@ The script handler makes sure to check through all stored scripts to make sure they are still relevant. An scripthandler is automatically added to all game objects. You -access it through the property 'scripts' on the game object. +access it through the property 'scripts' on the game object. """ from src.scripts.models import ScriptDB -from src.utils import create +from src.utils import create from src.utils import logger class ScriptHandler(object): """ - Implements the handler. This sits on each game object. + Implements the handler. This sits on each game object. """ def __init__(self, obj): """ Set up internal state. - obj - a reference to the object this handler is attached to. + obj - a reference to the object this handler is attached to. We retrieve all scripts attached to this object and check if they are all peristent. If they are not, they are just - cruft left over from a server shutdown. + cruft left over from a server shutdown. """ self.obj = obj @@ -32,10 +32,10 @@ class ScriptHandler(object): interval = "inf" next_repeat = "inf" repeats = "inf" - if script.interval > 0: + if script.interval > 0: interval = script.interval if script.repeats: - repeats = script.repeats + repeats = script.repeats try: next_repeat = script.time_until_next_repeat() except: next_repeat = "?" string += "\n '%s' (%s/%s, %s repeats): %s" % (script.key, @@ -47,19 +47,19 @@ class ScriptHandler(object): def add(self, scriptclass, key=None, autostart=True): """ - Add an script to this object. - + Add an script to this object. + scriptclass - either a class object inheriting from Script, an instantiated script object or a python path to such a class object. key - optional identifier for the script (often set in script definition) autostart - start the script upon adding it - """ + """ script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=autostart) if not script: logger.log_errmsg("Script %s could not be created and/or started." % scriptclass) - return False - return True + return False + return True def start(self, scriptid): """ @@ -68,14 +68,14 @@ class ScriptHandler(object): scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid) num = 0 for script in scripts: - num += script.start() - return num + num += script.start() + return num def delete(self, scriptid): """ Forcibly delete a script from this object. - - scriptid can be a script key or the path to a script (in the + + scriptid can be a script key or the path to a script (in the latter case all scripts with this path will be deleted!) """ @@ -85,7 +85,7 @@ class ScriptHandler(object): num = 0 for script in delscripts: num += script.stop() - return num + return num def stop(self, scriptid): """ @@ -105,4 +105,4 @@ class ScriptHandler(object): This should be called regularly to crank the wheels. """ ScriptDB.objects.validate(obj=self.obj, init_mode=init_mode) - + diff --git a/src/scripts/scripts.py b/src/scripts/scripts.py index 0934f59b61..120b98f142 100644 --- a/src/scripts/scripts.py +++ b/src/scripts/scripts.py @@ -32,7 +32,7 @@ class ScriptClass(TypeClass): parent doesn't work. """ try: - return other.id == self.id + return other.dbid == self.dbid except Exception: return False @@ -61,7 +61,7 @@ class ScriptClass(TypeClass): def _step_err_callback(self, e): "callback for runner errors" cname = self.__class__.__name__ - estring = "Script %s(#%i) of type '%s': at_repeat() error '%s'." % (self.key, self.id, cname, e.getErrorMessage()) + estring = "Script %s(#%i) of type '%s': at_repeat() error '%s'." % (self.key, self.dbid, cname, e.getErrorMessage()) try: self.dbobj.db_obj.msg(estring) except Exception: @@ -183,7 +183,7 @@ class ScriptClass(TypeClass): try: self._stop_task() except Exception, e: - logger.log_trace("Stopping script %s(%s)" % (self.key, self.id)) + logger.log_trace("Stopping script %s(%s)" % (self.key, self.dbid)) pass try: self.dbobj.delete() diff --git a/src/server/serversession.py b/src/server/serversession.py index c9b09d74cd..73e97bc256 100644 --- a/src/server/serversession.py +++ b/src/server/serversession.py @@ -139,10 +139,7 @@ class ServerSession(Session): """ Get the player associated with this session """ - if self.logged_in: - return self.player - else: - return None + return self.logged_in and self.player def get_character(self): """ diff --git a/src/server/sessionhandler.py b/src/server/sessionhandler.py index bbf6434cf1..38ce8f5c55 100644 --- a/src/server/sessionhandler.py +++ b/src/server/sessionhandler.py @@ -14,7 +14,6 @@ There are two similar but separate stores of sessions: import time from django.conf import settings -from django.contrib.auth.models import User from src.server.models import ServerConfig from src.commands.cmdhandler import CMD_LOGINSTART @@ -259,12 +258,7 @@ class ServerSessionHandler(SessionHandler): """ Given a player, return any matching sessions. """ - username = player.user.username - try: - uobj = User.objects.get(username=username) - except User.DoesNotExist: - return None - uid = uobj.id + uid = player.uid return [session for session in self.sessions.values() if session.logged_in and session.uid == uid] def sessions_from_character(self, character): diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 3b73f1f905..ff362fb33d 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -853,7 +853,7 @@ class TypedObject(SharedMemoryModel): _db_model_name = "typeclass" # used by attributes to safely store objects def __eq__(self, other): - return other and hasattr(other, 'id') and self.id == other.id + return other and hasattr(other, 'dbid') and self.dbid == other.dbid def __str__(self): return smart_str("%s" % self.key) @@ -881,16 +881,35 @@ class TypedObject(SharedMemoryModel): return _GA(typeclass, propname) else: raise AttributeError + #@property + _dbid_cache = None + def __dbid_get(self): + """ + Caches and returns the unique id of the object. + Use this instead of self.id, which is not cached. + """ + dbid = _GA(self, "_dbid_cache") + if not dbid: + dbid = _GA(self, "id") + _SA(self, "_dbid_cache", dbid) + return dbid + def __dbid_set(self, value): + raise Exception("dbid cannot be set!") + def __dbid_del(self): + raise Exception("dbid cannot be deleted!") + dbid = property(__dbid_get, __dbid_set, __dbid_del) #@property def __dbref_get(self): """ - Returns the object's dbref id on the form #NN. - Alternetively, use obj.id directly to get dbref - without any #. + Returns the object's dbref on the form #NN. """ - return "#%s" % str(_GA(self, "id")) - dbref = property(__dbref_get) + return "#%s" % _GA(self, "_TypedObject__dbid_get")() + def __dbref_set(self): + raise Exception("dbref cannot be set!") + def __dbref_del(self): + raise Exception("dbref cannot be deleted!") + dbref = property(__dbref_get, __dbref_set, __dbref_del) # typeclass property #@property diff --git a/src/typeclasses/typeclass.py b/src/typeclasses/typeclass.py index 17643f05dd..3f4c23ea8b 100644 --- a/src/typeclasses/typeclass.py +++ b/src/typeclasses/typeclass.py @@ -91,6 +91,8 @@ class TypeClass(object): transparently include the properties on self.dbobj. Note that dbobj properties have priority, so if you define a same-named + + property on the class, it will NOT be accessible through getattr. """ @@ -115,8 +117,8 @@ class TypeClass(object): try: return _GA(dbobj,"get_attribute_raise")(propname) except AttributeError: - string = "Object: '%s' not found on %s(%s), nor on its typeclass %s." - raise AttributeError(string % (propname, dbobj, dbobj.dbref, dbobj.typeclass_path)) + string = "Object: '%s' not found on %s(#%s), nor on its typeclass %s." + raise AttributeError(string % (propname, dbobj, dbobj.dbid, dbobj.typeclass_path)) def __setattr__(self, propname, value): """ @@ -185,9 +187,9 @@ class TypeClass(object): try: dbobj.del_attribute_raise(propname) except AttributeError: - string = "Object: '%s' not found on %s(%s), nor on its typeclass %s." + string = "Object: '%s' not found on %s(#%s), nor on its typeclass %s." raise AttributeError(string % (propname, dbobj, - dbobj.dbref, + dbobj.dbid, dbobj.typeclass_path,)) def __str__(self):