From aee147102b90cd7c4f49a7f48ba780cf1d6134ae Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 9 Oct 2011 16:32:55 +0200 Subject: [PATCH] Gave better error messages when a player typeclass has bugs and thus won't load. Also made a better solution for hiding new characters from the start room when first being created (also makes sure that character.location never starts as being None, recovering back to home in that case). --- game/gamesrc/objects/baseobjects.py | 17 +++-- src/commands/default/unloggedin.py | 3 + src/utils/create.py | 107 ++++++++++++++++------------ 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/game/gamesrc/objects/baseobjects.py b/game/gamesrc/objects/baseobjects.py index 66c0c1ad1f..f4b9a9470f 100644 --- a/game/gamesrc/objects/baseobjects.py +++ b/game/gamesrc/objects/baseobjects.py @@ -107,10 +107,10 @@ class Character(BaseCharacter): def at_disconnect(self): """ - We stove away the character when logging off, otherwise they will remain where - they are, 'headless', so to say. + We stove away the character when logging off, otherwise the character object will + remain in the room also after the player logged off ("headless", so to say). """ - if self.location: # have to check, in case of multiple connections + if self.location: # have to check, in case of multiple connections closing self.location.msg_contents("%s has left the game." % self.name) self.db.prelogout_location = self.location self.location = None @@ -120,9 +120,14 @@ class Character(BaseCharacter): This recovers the character again after having been "stoved away" at disconnect. """ if self.db.prelogout_location: - self.location = self.db.prelogout_location - else: - self.db.prelogout_location = self.location + # try to recover + self.location = self.db.prelogout_location + if self.location == None: + # make sure location is never None (home should always exist) + self.location = self.home + # save location again to be sure + self.db.prelogout_location = self.location + self.location.msg_contents("%s has entered the game." % self.name) self.location.at_object_receive(self, self.location) diff --git a/src/commands/default/unloggedin.py b/src/commands/default/unloggedin.py index dc23596969..3da12c66c4 100644 --- a/src/commands/default/unloggedin.py +++ b/src/commands/default/unloggedin.py @@ -165,6 +165,9 @@ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth m character_typeclass=typeclass, character_location=default_home, character_home=default_home) + if not new_character: + session.msg("There was an error creating the default Character/Player. This error was logged. Contact an admin.") + return new_player = new_character.player # character safety features diff --git a/src/utils/create.py b/src/utils/create.py index cd3d020b2a..05e90e8bba 100644 --- a/src/utils/create.py +++ b/src/utils/create.py @@ -397,53 +397,72 @@ def create_player(name, email, password, else: new_user = User.objects.create_user(name, email, password) - if not typeclass: - typeclass = settings.BASE_PLAYER_TYPECLASS - elif isinstance(typeclass, PlayerDB): - # this is already an objectdb instance, extract its typeclass - typeclass = typeclass.typeclass.path - elif isinstance(typeclass, Player) or utils.inherits_from(typeclass, Player): - # this is already an object typeclass, extract its path - typeclass = typeclass.path + try: + if not typeclass: + typeclass = settings.BASE_PLAYER_TYPECLASS + elif isinstance(typeclass, PlayerDB): + # this is already an objectdb instance, extract its typeclass + typeclass = typeclass.typeclass.path + elif isinstance(typeclass, Player) or utils.inherits_from(typeclass, Player): + # this is already an object typeclass, extract its path + typeclass = typeclass.path - # create new database object - new_db_player = PlayerDB(db_key=name, user=new_user) - new_db_player.save() - - # assign the typeclass - typeclass = utils.to_unicode(typeclass) - new_db_player.typeclass_path = typeclass + # create new database object + new_db_player = PlayerDB(db_key=name, user=new_user) + new_db_player.save() - # this will either load the typeclass or the default one - new_player = new_db_player.typeclass + # assign the typeclass + typeclass = utils.to_unicode(typeclass) + new_db_player.typeclass_path = typeclass - if not object.__getattribute__(new_db_player, "is_typeclass")(typeclass, exact=True): - # this will fail if we gave a typeclass as input and it still gave us a default - SharedMemoryModel.delete(new_db_player) - return None + # this will either load the typeclass or the default one + new_player = new_db_player.typeclass - new_player.basetype_setup() # setup the basic locks and cmdset - # call hook method (may override default permissions) - new_player.at_player_creation() + if not object.__getattribute__(new_db_player, "is_typeclass")(typeclass, exact=True): + # this will fail if we gave a typeclass as input and it still gave us a default + SharedMemoryModel.delete(new_db_player) + return None - # custom given arguments potentially overrides the hook - if permissions: - new_player.permissions = permissions - elif not new_player.permissions: - new_player.permissions = settings.PERMISSION_PLAYER_DEFAULT + new_player.basetype_setup() # setup the basic locks and cmdset + # call hook method (may override default permissions) + new_player.at_player_creation() + + # custom given arguments potentially overrides the hook + if permissions: + new_player.permissions = permissions + elif not new_player.permissions: + new_player.permissions = settings.PERMISSION_PLAYER_DEFAULT + + if locks: + new_player.locks.add(locks) + + # create *in-game* 'player' object + if create_character: + if not character_typeclass: + character_typeclass = settings.BASE_CHARACTER_TYPECLASS + # creating the object automatically links the player + # and object together by player.obj <-> obj.player + new_character = create_object(character_typeclass, key=name, + location=None, home=character_location, + permissions=permissions, + player=new_player) + return new_character + return new_player + except Exception: + # a failure in creating the character + if not user: + # in there was a failure we clean up everything we can + logger.log_trace() + try: + new_user.delete() + except Exception: + pass + try: + new_player.delete() + except Exception: + pass + try: + del new_character + except Exception: + pass - if locks: - new_player.locks.add(locks) - - # create *in-game* 'player' object - if create_character: - if not character_typeclass: - character_typeclass = settings.BASE_CHARACTER_TYPECLASS - # creating the object automatically links the player - # and object together by player.obj <-> obj.player - new_character = create_object(character_typeclass, key=name, - location=character_location, home=character_location, - permissions=permissions, - player=new_player) - return new_character - return new_player