Restructured the way typeclasses are loaded. This makes it possible to run at_init() hooks at initiation also for objects without any custom cases for character/players. at_init() hooks are called only when an object is initiated. This means that a room's at_init() hook is only called when someone looks or enters it or a script operates on it, for example, rest of the time these objects are dormant, most efficiently.

This commit is contained in:
Griatch 2011-10-01 22:00:22 +02:00
parent 0a1bcd36c2
commit 23cd9e31b1
14 changed files with 142 additions and 109 deletions

View file

@ -123,7 +123,7 @@ class CommandTest(TestCase):
self.room1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1") self.room1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1")
self.room2 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room2") self.room2 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room2")
# create a faux player/character for testing. # create a faux player/character for testing.
self.char1 = create.create_player("TestChar", "testplayer@test.com", "testpassword", location=self.room1) self.char1 = create.create_player("TestChar", "testplayer@test.com", "testpassword", character_location=self.room1)
self.char1.player.user.is_superuser = True self.char1.player.user.is_superuser = True
self.char1.lock_storage = "" self.char1.lock_storage = ""
self.char1.locks = LockHandler(self.char1) self.char1.locks = LockHandler(self.char1)
@ -132,7 +132,7 @@ class CommandTest(TestCase):
sess.connectionMade() sess.connectionMade()
sess.session_login(self.char1.player) sess.session_login(self.char1.player)
# create second player # create second player
self.char2 = create.create_player("TestChar2", "testplayer2@test.com", "testpassword2", location=self.room1) self.char2 = create.create_player("TestChar2", "testplayer2@test.com", "testpassword2", character_location=self.room1)
self.char2.player.user.is_superuser = False self.char2.player.user.is_superuser = False
self.char2.lock_storage = "" self.char2.lock_storage = ""
self.char2.locks = LockHandler(self.char2) self.char2.locks = LockHandler(self.char2)

View file

@ -161,9 +161,9 @@ class CmdCreate(MuxCommand):
new_character = create.create_player(playername, email, password, new_character = create.create_player(playername, email, password,
permissions=permissions, permissions=permissions,
location=default_home, character_typeclass=typeclass,
typeclass=typeclass, character_location=default_home,
home=default_home) character_home=default_home)
new_player = new_character.player new_player = new_character.player
# character safety features # character safety features

View file

@ -252,7 +252,7 @@ class ObjectDB(TypedObject):
"Getter. Allows for value = self.location." "Getter. Allows for value = self.location."
loc = self.db_location loc = self.db_location
if loc: if loc:
return loc.typeclass(loc) return loc.typeclass
return None return None
#@location.setter #@location.setter
def location_set(self, location): def location_set(self, location):
@ -291,7 +291,7 @@ class ObjectDB(TypedObject):
"Getter. Allows for value = self.home" "Getter. Allows for value = self.home"
home = self.db_home home = self.db_home
if home: if home:
return home.typeclass(home) return home.typeclass
return None return None
#@home.setter #@home.setter
def home_set(self, home): def home_set(self, home):
@ -329,7 +329,7 @@ class ObjectDB(TypedObject):
"Getter. Allows for value = self.destination." "Getter. Allows for value = self.destination."
dest = self.db_destination dest = self.db_destination
if dest: if dest:
return dest.typeclass(dest) return dest.typeclass
return None return None
#@destination.setter #@destination.setter
def destination_set(self, destination): def destination_set(self, destination):
@ -565,7 +565,7 @@ class ObjectDB(TypedObject):
if nick.db_nick in raw_list: if nick.db_nick in raw_list:
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1) raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
break break
cmdhandler.cmdhandler(self.typeclass(self), raw_string) cmdhandler.cmdhandler(self.typeclass, raw_string)
def msg(self, message, from_obj=None, data=None): def msg(self, message, from_obj=None, data=None):
""" """

View file

@ -76,9 +76,7 @@ class Object(TypeClass):
pass pass
def at_init(self): def at_init(self):
""" """
OBS: CURRENTLY NOT CALLED!
This is always called whenever this This is always called whenever this
object initiated -- both when the object object initiated -- both when the object
is first created as well as after each restart. is first created as well as after each restart.
@ -86,8 +84,7 @@ class Object(TypeClass):
if something should survive a warm-reboot (rebooting if something should survive a warm-reboot (rebooting
the server without the players logging out), put it here. the server without the players logging out), put it here.
""" """
pass pass
def basetype_posthook_setup(self): def basetype_posthook_setup(self):
""" """

View file

@ -358,7 +358,7 @@ class PlayerDB(TypedObject):
if nick.db_nick in raw_list: if nick.db_nick in raw_list:
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1) raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
break break
cmdhandler.cmdhandler(self.typeclass(self), raw_string) cmdhandler.cmdhandler(self.typeclass, raw_string)
def search(self, ostring, global_search=False, attribute_name=None, use_nicks=False, def search(self, ostring, global_search=False, attribute_name=None, use_nicks=False,
location=None, ignore_errors=False, player=False): location=None, ignore_errors=False, player=False):

View file

@ -243,14 +243,14 @@ class ScriptDB(TypedObject):
# #
# #
# this is required to properly handle attrubutes and typeclass loading # this is required to properly handle attributes and typeclass loading
attribute_model_path = "src.scripts.models" attribute_model_path = "src.scripts.models"
attribute_model_name = "ScriptAttribute" attribute_model_name = "ScriptAttribute"
typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS
# this is used by all typedobjects as a fallback # this is used by all typedobjects as a fallback
try: try:
default_typeclass_path = settings.DEFAULT_SCRIPT_TYPECLASS default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS
except: except:
default_typeclass_path = "src.scripts.scripts.DoNothing" default_typeclass_path = "src.scripts.scripts.DoNothing"

View file

@ -221,6 +221,9 @@ class ScriptClass(TypeClass):
return True return True
# hooks # hooks
def at_init(self):
"called every typeclass initiation (reloads/restarts). not much use for scripts."
pass
def at_script_creation(self): def at_script_creation(self):
"placeholder" "placeholder"
pass pass

View file

@ -54,9 +54,10 @@ def create_objects():
# is inherited from the user so we don't specify it again here. # is inherited from the user so we don't specify it again here.
god_character = create.create_player(god_user.username, None, None, god_character = create.create_player(god_user.username, None, None,
user=god_user,
create_character=True, create_character=True,
typeclass=character_typeclass, character_typeclass=character_typeclass)
user=god_user)
god_character.id = 1 god_character.id = 1
god_character.db.desc = _('This is User #1.') god_character.db.desc = _('This is User #1.')
god_character.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all();puppet:false()") god_character.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all();puppet:false()")

View file

@ -150,8 +150,8 @@ class Evennia(object):
from src.players.models import PlayerDB from src.players.models import PlayerDB
#print "run_init_hooks:", ObjectDB.get_all_cached_instances() #print "run_init_hooks:", ObjectDB.get_all_cached_instances()
[(o.typeclass(o), o.at_init()) for o in ObjectDB.get_all_cached_instances()] [(o.typeclass, o.at_init()) for o in ObjectDB.get_all_cached_instances()]
[(p.typeclass(p), p.at_init()) for p in PlayerDB.get_all_cached_instances()] [(p.typeclass, p.at_init()) for p in PlayerDB.get_all_cached_instances()]
def terminal_output(self): def terminal_output(self):
""" """
@ -204,20 +204,20 @@ class Evennia(object):
if mode == 'reload': if mode == 'reload':
# call restart hooks # call restart hooks
[(o.typeclass(o), o.at_server_reload()) for o in ObjectDB.get_all_cached_instances()] [(o.typeclass, o.at_server_reload()) for o in ObjectDB.get_all_cached_instances()]
[(p.typeclass(p), p.at_server_reload()) for p in PlayerDB.get_all_cached_instances()] [(p.typeclass, p.at_server_reload()) for p in PlayerDB.get_all_cached_instances()]
[(s.typeclass(s), s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()] [(s.typeclass, s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()]
ServerConfig.objects.conf("server_restart_mode", "reload") ServerConfig.objects.conf("server_restart_mode", "reload")
else: else:
if mode == 'reset': if mode == 'reset':
# don't call disconnect hooks on reset # don't call disconnect hooks on reset
[(o.typeclass(o), o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()] [(o.typeclass, o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
else: # shutdown else: # shutdown
[(o.typeclass(o), o.at_disconnect(), o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()] [(o.typeclass, o.at_disconnect(), o.at_server_shutdown()) for o in ObjectDB.get_all_cached_instances()]
[(p.typeclass(p), p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()] [(p.typeclass, p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()]
[(s.typeclass(s), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()] [(s.typeclass, s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
ServerConfig.objects.conf("server_restart_mode", "reset") ServerConfig.objects.conf("server_restart_mode", "reset")

View file

@ -48,16 +48,9 @@ class ServerSession(Session):
the session as it was. the session as it was.
""" """
if not self.logged_in: if not self.logged_in:
return return
player = self.get_player()
character = self.get_character() character = self.get_character()
if player:
#print "sync: at_init() - player"
player.at_init()
if character: if character:
#print "sync: at_init() - character"
character.at_init()
# start (persistent) scripts on this object # start (persistent) scripts on this object
ScriptDB.objects.validate(obj=character) ScriptDB.objects.validate(obj=character)

View file

@ -192,6 +192,8 @@ BASE_CHARACTER_TYPECLASS = "game.gamesrc.objects.baseobjects.Character"
BASE_ROOM_TYPECLASS = "game.gamesrc.objects.baseobjects.Room" BASE_ROOM_TYPECLASS = "game.gamesrc.objects.baseobjects.Room"
# Typeclass for Exit objects (fallback) # Typeclass for Exit objects (fallback)
BASE_EXIT_TYPECLASS = "game.gamesrc.objects.baseobjects.Exit" BASE_EXIT_TYPECLASS = "game.gamesrc.objects.baseobjects.Exit"
# Typeclass for Scripts (fallback)
BASE_SCRIPT_TYPECLASS = "src.scripts.scripts.DoNothing"
# The home location for new characters. This must be a unique # The home location for new characters. This must be a unique
# dbref (default is Limbo #2). If you want more advanced control over # dbref (default is Limbo #2). If you want more advanced control over
# start locations, copy the "create" command from # start locations, copy the "create" command from

View file

@ -55,7 +55,7 @@ def returns_typeclass_list(method):
obj_classes = [] obj_classes = []
for dbobj in match: for dbobj in match:
try: try:
obj_classes.append(dbobj.typeclass(dbobj)) obj_classes.append(dbobj.typeclass)
except Exception: except Exception:
obj_classes.append(dbobj) obj_classes.append(dbobj)
#logger.log_trace() #logger.log_trace()

View file

@ -730,7 +730,7 @@ class TypedObject(SharedMemoryModel):
# try to look back to this very database object.) # try to look back to this very database object.)
typeclass = object.__getattribute__(self, 'typeclass') typeclass = object.__getattribute__(self, 'typeclass')
if typeclass: if typeclass:
return object.__getattribute__(typeclass(self), propname) return object.__getattribute__(typeclass, propname)
else: else:
raise AttributeError raise AttributeError
@ -765,9 +765,10 @@ class TypedObject(SharedMemoryModel):
typeclass = object.__getattribute__(self, "cached_typeclass") typeclass = object.__getattribute__(self, "cached_typeclass")
try: try:
if typeclass and object.__getattribute__(typeclass, "path") == path: if typeclass and object.__getattribute__(typeclass, "path") == path:
# don't call at_init() when returning from cache
return typeclass return typeclass
except AttributeError: except AttributeError:
pass pass
errstring = "" errstring = ""
if not path: if not path:
@ -789,7 +790,12 @@ class TypedObject(SharedMemoryModel):
object.__setattr__(self, 'db_typeclass_path', tpath) object.__setattr__(self, 'db_typeclass_path', tpath)
object.__getattribute__(self, 'save')() object.__getattribute__(self, 'save')()
object.__setattr__(self, "cached_typeclass_path", tpath) object.__setattr__(self, "cached_typeclass_path", tpath)
object.__setattr__(self, "cached_typeclass", typeclass) typeclass = typeclass(self)
object.__setattr__(self, "cached_typeclass", typeclass)
try:
typeclass.at_init()
except Exception:
logger.log_trace()
return typeclass return typeclass
elif hasattr(typeclass, '__file__'): elif hasattr(typeclass, '__file__'):
errstring += "\n%s seems to be just the path to a module. You need" % tpath errstring += "\n%s seems to be just the path to a module. You need" % tpath
@ -894,13 +900,19 @@ class TypedObject(SharedMemoryModel):
if not callable(typeclass): if not callable(typeclass):
# if this is still giving an error, Evennia is wrongly configured or buggy # if this is still giving an error, Evennia is wrongly configured or buggy
raise Exception("CRITICAL ERROR: The final fallback typeclass %s cannot load!!" % defpath) raise Exception("CRITICAL ERROR: The final fallback typeclass %s cannot load!!" % defpath)
typeclass = typeclass(self)
if save: if save:
object.__setattr__(self, 'db_typeclass_path', defpath) object.__setattr__(self, 'db_typeclass_path', defpath)
object.__getattribute__(self, 'save')() object.__getattribute__(self, 'save')()
if cache: if cache:
object.__setattr__(self, "cached_typeclass_path", defpath) object.__setattr__(self, "cached_typeclass_path", defpath)
object.__setattr__(self, "cached_typeclass", typeclass) object.__setattr__(self, "cached_typeclass", typeclass)
return typeclass try:
typeclass.at_init()
except Exception:
logger.log_trace()
return typeclass
def is_typeclass(self, typeclass, exact=False): def is_typeclass(self, typeclass, exact=False):
""" """
@ -919,13 +931,14 @@ class TypedObject(SharedMemoryModel):
typeclass = typeclass.path typeclass = typeclass.path
except AttributeError: except AttributeError:
pass pass
typeclasses = [typeclass] + ["%s.%s" % (path, typeclass) for path in self.typeclass_paths]
if exact: if exact:
current_path = object.__getattribute__(self, "cached_typeclass_path") current_path = object.__getattribute__(self, "cached_typeclass_path")
return typeclass and current_path == typeclass return typeclass and any([current_path == typec for typec in typeclasses])
else: else:
# check parent chain # check parent chain
return any([cls for cls in self.typeclass.mro() return any([cls for cls in self.typeclass.mro()
if "%s.%s" % (cls.__module__, cls.__name__) == typeclass]) if any(["%s.%s" % (cls.__module__, cls.__name__) == typec for typec in typeclasses])])
# #
# Object manipulation methods # Object manipulation methods
@ -967,7 +980,7 @@ class TypedObject(SharedMemoryModel):
self.save() self.save()
# this will automatically use a default class if # this will automatically use a default class if
# there is an error with the given typeclass. # there is an error with the given typeclass.
new_typeclass = self.typeclass(self) new_typeclass = self.typeclass
if clean_attributes: if clean_attributes:
# Clean out old attributes # Clean out old attributes

View file

@ -47,9 +47,11 @@ def create_object(typeclass, key=None, location=None,
from src.objects.objects import Object from src.objects.objects import Object
from src.objects.models import ObjectDB from src.objects.models import ObjectDB
if isinstance(typeclass, ObjectDB): if not typeclass:
typeclass = settings.BASE_OBJECT_TYPECLASS
elif isinstance(typeclass, ObjectDB):
# this is already an objectdb instance, extract its typeclass # this is already an objectdb instance, extract its typeclass
typeclass = new_db_object.typeclass.path typeclass = typeclass.typeclass.path
elif isinstance(typeclass, Object) or utils.inherits_from(typeclass, Object): elif isinstance(typeclass, Object) or utils.inherits_from(typeclass, Object):
# this is already an object typeclass, extract its path # this is already an object typeclass, extract its path
typeclass = typeclass.path typeclass = typeclass.path
@ -60,28 +62,22 @@ def create_object(typeclass, key=None, location=None,
# assign the typeclass # assign the typeclass
typeclass = utils.to_unicode(typeclass) typeclass = utils.to_unicode(typeclass)
new_db_object.typeclass_path = typeclass new_db_object.typeclass_path = typeclass
# the name/key is often set later in the typeclass. This
# is set here as a failsafe.
if key:
new_db_object.key = key
else:
new_db_object.key = "#%i" % new_db_object.id
# this will either load the typeclass or the default one # this will either load the typeclass or the default one
typeclass = new_db_object.typeclass new_object = new_db_object.typeclass
if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True): if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True):
# this will fail if we gave a typeclass as input and it still gave us a default # this will fail if we gave a typeclass as input and it still gave us a default
SharedMemoryModel.delete(new_db_object) SharedMemoryModel.delete(new_db_object)
return None return None
# the name/key is often set later in the typeclass. This
# is set here as a failsafe.
if key:
new_db_object.name = key
else:
dbref = new_db_object.id
if typeclass and hasattr(typeclass, '__name__'):
new_db_object.name = "%s%i" % (typeclass.__name__, dbref)
else:
new_db_object.name = "#%i" % dbref
# initialize an object of this typeclass.
new_object = typeclass(new_db_object)
# from now on we can use the typeclass object # from now on we can use the typeclass object
# as if it was the database object. # as if it was the database object.
@ -151,39 +147,37 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
#print "in create_script", typeclass #print "in create_script", typeclass
from src.scripts.models import ScriptDB from src.scripts.models import ScriptDB
if isinstance(typeclass, ScriptDB): if not typeclass:
# this is already an objectdb instance, extract its typeclass typeclass = settings.BASE_SCRIPT_TYPECLASS
elif isinstance(typeclass, ScriptDB):
# this is already an scriptdb instance, extract its typeclass
typeclass = new_db_object.typeclass.path typeclass = new_db_object.typeclass.path
elif isinstance(typeclass, Script) or utils.inherits_from(typeclass, Script): elif isinstance(typeclass, Script) or utils.inherits_from(typeclass, Script):
# this is already an object typeclass, extract its path # this is already an object typeclass, extract its path
typeclass = typeclass.path typeclass = typeclass.path
# create new database object
new_db_object = ScriptDB() # create new database script
new_db_script = ScriptDB()
# assign the typeclass # assign the typeclass
typeclass = utils.to_unicode(typeclass) typeclass = utils.to_unicode(typeclass)
new_db_object.typeclass_path = typeclass new_db_script.typeclass_path = typeclass
# the name/key is often set later in the typeclass. This
# is set here as a failsafe.
if key:
new_db_script.key = key
else:
new_db_script.key = "#%i" % new_db_script.id
# this will either load the typeclass or the default one # this will either load the typeclass or the default one
typeclass = new_db_object.typeclass new_script = new_db_script.typeclass
if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True): if not object.__getattribute__(new_db_script, "is_typeclass")(typeclass, exact=True):
# this can happen if the default was loaded (due to # this will fail if we gave a typeclass as input and it still gave us a default
# inability to load given typeclass), which we print "failure:", new_db_script, typeclass
# don't accept during creation. SharedMemoryModel.delete(new_db_script)
SharedMemoryModel.delete(new_db_object)
return None return None
# the typeclass is initialized
new_script = typeclass(new_db_object)
# store variables on the typeclass (which means
# it's actually transparently stored on the db object)
if not key:
if typeclass and hasattr(typeclass, '__name__'):
new_script.key = "%s" % typeclass.__name__
else:
new_script.key = "#%i" % new_db_object.id
if obj: if obj:
try: try:
@ -206,6 +200,8 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
# a new created script should usually be started. # a new created script should usually be started.
if autostart: if autostart:
new_script.start() new_script.start()
new_db_script.save()
return new_script return new_script
# #
@ -345,22 +341,29 @@ def create_channel(key, aliases=None, desc=None,
# #
def create_player(name, email, password, def create_player(name, email, password,
permissions=None, user=None,
create_character=True, typeclass=None,
location=None, typeclass=None, home=None, is_superuser=False,
is_superuser=False, user=None, locks=None): locks=None, permissions=None,
create_character=True, character_typeclass=None,
character_location=None, character_home=None):
""" """
This creates a new player, handling the creation of the User This creates a new player, handling the creation of the User
object and its associated Player object. If create_character is object and its associated Player object.
If create_character is
True, a game player object with the same name as the User/Player will True, a game player object with the same name as the User/Player will
also be created. Returns the new game character, or the Player obj if no also be created. Its typeclass and base properties can also be given.
Returns the new game character, or the Player obj if no
character is created. For more info about the typeclass argument, character is created. For more info about the typeclass argument,
see create_objects() above. see create_objects() above.
Note: if user is supplied, it will NOT be modified (args name, email, Note: if user is supplied, it will NOT be modified (args name, email,
passw and is_superuser will be ignored). Change those properties passw and is_superuser will be ignored). Change those properties
explicitly instead. directly on the User instead.
If no permissions are given (None), the default permission group If no permissions are given (None), the default permission group
as defined in settings.PERMISSION_PLAYER_DEFAULT will be as defined in settings.PERMISSION_PLAYER_DEFAULT will be
@ -368,16 +371,15 @@ def create_player(name, email, password,
occur. occur.
Concerning is_superuser: Concerning is_superuser:
A superuser should have access to everything A superuser should have access to everything
in the game and on the server/web interface. The very first user in the game and on the server/web interface. The very first user
created in the database is always a superuser (that's using created in the database is always a superuser (that's using
django's own creation, not this one). django's own creation, not this one).
Usually only the server admin should need to be superuser, all Usually only the server admin should need to be superuser, all
other access levels can be handled with more fine-grained other access levels can be handled with more fine-grained
permissions or groups. permissions or groups.
Since superuser overrules all permissions, we don't
Since superuser overrules all permissions, we don't set any in this case.
set any here.
""" """
# The system should already have checked so the name/email # The system should already have checked so the name/email
@ -385,6 +387,7 @@ def create_player(name, email, password,
# getting here. # getting here.
from src.players.models import PlayerDB from src.players.models import PlayerDB
from src.players.player import Player
if user: if user:
new_user = user new_user = user
@ -394,9 +397,30 @@ def create_player(name, email, password,
else: else:
new_user = User.objects.create_user(name, email, password) new_user = User.objects.create_user(name, email, password)
# create the associated Player for this User, and tie them together if not typeclass:
new_player = PlayerDB(db_key=name, user=new_user) typeclass = settings.BASE_PLAYER_TYPECLASS
new_player.save() 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
# this will either load the typeclass or the default one
new_player = new_db_player.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
new_player.basetype_setup() # setup the basic locks and cmdset new_player.basetype_setup() # setup the basic locks and cmdset
# call hook method (may override default permissions) # call hook method (may override default permissions)
@ -413,12 +437,12 @@ def create_player(name, email, password,
# create *in-game* 'player' object # create *in-game* 'player' object
if create_character: if create_character:
if not typeclass: if not character_typeclass:
typeclass = settings.BASE_CHARACTER_TYPECLASS character_typeclass = settings.BASE_CHARACTER_TYPECLASS
# creating the object automatically links the player # creating the object automatically links the player
# and object together by player.obj <-> obj.player # and object together by player.obj <-> obj.player
new_character = create_object(typeclass, name, new_character = create_object(character_typeclass, key=name,
location, home, location=character_location, home=character_location,
permissions=permissions, permissions=permissions,
player=new_player) player=new_player)
return new_character return new_character