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:
parent
0a1bcd36c2
commit
23cd9e31b1
14 changed files with 142 additions and 109 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()")
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue