diff --git a/src/comms/comms.py b/src/comms/comms.py index 5f5d052d24..303d17ac74 100644 --- a/src/comms/comms.py +++ b/src/comms/comms.py @@ -45,9 +45,74 @@ class Channel(ChannelDB): if cdict["desc"]: self.attributes.add("desc", cdict["desc"]) + def at_channel_creation(self): + """ + Called once, when the channel is first created. + """ + pass # helper methods, for easy overloading + def has_connection(self, player): + """ + Checks so this player is actually listening + to this channel. + """ + if hasattr(player, "player"): + player = player.player + player = player.dbobj + return player in self.db_subscriptions.all() + + def connect(self, player): + "Connect the user to this channel. This checks access." + if hasattr(player, "player"): + player = player.player + # check access + if not self.access(player, 'listen'): + return False + # pre-join hook + connect = self.pre_join_channel(player) + if not connect: + return False + # subscribe + self.db_subscriptions.add(player) + # post-join hook + self.post_join_channel(player) + return True + + def disconnect(self, player): + "Disconnect user from this channel." + if hasattr(player, "player"): + player = player.player + # pre-disconnect hook + disconnect = self.pre_leave_channel(player) + if not disconnect: + return False + # disconnect + self.db_subscriptions.remove(player.dbobj) + # post-disconnect hook + self.post_leave_channel(player.dbobj) + return True + + def access(self, accessing_obj, access_type='listen', default=False): + """ + Determines if another object has permission to access. + accessing_obj - object trying to access this one + access_type - type of access sought + default - what to return if no lock of access_type was found + """ + return self.locks.check(accessing_obj, access_type=access_type, default=default) + + def delete(self): + """ + Deletes channel while also cleaning up channelhandler + """ + self.attributes.clear() + self.aliases.clear() + super(Channel, self).delete() + from src.comms.channelhandler import CHANNELHANDLER + CHANNELHANDLER.update() + def channel_prefix(self, msg=None, emit=False): """ How the channel should prefix itself for users. Return a string. @@ -134,12 +199,6 @@ class Channel(ChannelDB): msg.message = body return msg - def at_channel_create(self): - """ - Run at channel creation. - """ - pass - def pre_join_channel(self, joiner): """ Run right before a channel is joined. If this returns a false value, diff --git a/src/comms/models.py b/src/comms/models.py index 69704ed31e..21d4369b04 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -363,69 +363,5 @@ class ChannelDB(TypedObject): verbose_name = "Channel" verbose_name_plural = "Channels" - # - # Channel class methods - # - def __str__(self): return "Channel '%s' (%s)" % (self.key, self.db.desc) - - def has_connection(self, player): - """ - Checks so this player is actually listening - to this channel. - """ - if hasattr(player, "player"): - player = player.player - player = player.dbobj - return player in self.db_subscriptions.all() - - def connect(self, player): - "Connect the user to this channel. This checks access." - if hasattr(player, "player"): - player = player.player - # check access - if not self.access(player, 'listen'): - return False - # pre-join hook - connect = self.pre_join_channel(player) - if not connect: - return False - # subscribe - self.db_subscriptions.add(player.dbobj) - # post-join hook - self.post_join_channel(player) - return True - - def disconnect(self, player): - "Disconnect user from this channel." - if hasattr(player, "player"): - player = player.player - # pre-disconnect hook - disconnect = self.pre_leave_channel(player) - if not disconnect: - return False - # disconnect - self.db_subscriptions.remove(player.dbobj) - # post-disconnect hook - self.post_leave_channel(player.dbobj) - return True - - def access(self, accessing_obj, access_type='listen', default=False): - """ - Determines if another object has permission to access. - accessing_obj - object trying to access this one - access_type - type of access sought - default - what to return if no lock of access_type was found - """ - return self.locks.check(accessing_obj, access_type=access_type, default=default) - - def delete(self): - """ - Deletes channel while also cleaning up channelhandler - """ - _GA(self, "attributes").clear() - _GA(self, "aliases").clear() - super(ChannelDB, self).delete() - from src.comms.channelhandler import CHANNELHANDLER - CHANNELHANDLER.update() diff --git a/src/scripts/models.py b/src/scripts/models.py index 1d73aa8eb9..f9177c8a81 100644 --- a/src/scripts/models.py +++ b/src/scripts/models.py @@ -73,7 +73,7 @@ class ScriptDB(TypedObject): # # ScriptDB Database Model setup # - # These databse fields are all set using their corresponding properties, + # These database fields are all set using their corresponding properties, # named same as the field, but withtou the db_* prefix. # inherited fields (from TypedObject): @@ -100,10 +100,6 @@ class ScriptDB(TypedObject): # Database manager objects = ScriptDBManager() - # caches for quick lookups - _typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS - _default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS or "src.scripts.scripts.DoNothing" - class Meta: "Define Django meta options" verbose_name = "Script" diff --git a/src/scripts/scripts.py b/src/scripts/scripts.py index cb4e5eefd9..5beefedb4e 100644 --- a/src/scripts/scripts.py +++ b/src/scripts/scripts.py @@ -135,7 +135,7 @@ class ScriptBase(ScriptDB): if self.db._paused_time: # the script was paused; restarting callcount = self.db._paused_callcount or 0 - self.ndb._task.start(self.dbobj.db_interval, + self.ndb._task.start(self.db_interval, now=False, start_delay=self.db._paused_time, count_start=callcount) @@ -143,8 +143,8 @@ class ScriptBase(ScriptDB): del self.db._paused_repeats else: # starting script anew - self.ndb._task.start(self.dbobj.db_interval, - now=not self.dbobj.db_start_delay) + self.ndb._task.start(self.db_interval, + now=not self.db_start_delay) def _stop_task(self): "stop task runner" @@ -159,7 +159,7 @@ class ScriptBase(ScriptDB): {"key": self.key, "dbid": self.dbid, "cname": cname, "err": e.getErrorMessage()} try: - self.dbobj.db_obj.msg(estring) + self.db_obj.msg(estring) except Exception: pass logger.log_errmsg(estring) @@ -176,7 +176,7 @@ class ScriptBase(ScriptDB): # check repeats callcount = self.ndb._task.callcount - maxcount = self.dbobj.db_repeats + maxcount = self.db_repeats if maxcount > 0 and maxcount <= callcount: #print "stopping script!" self.stop() @@ -210,7 +210,7 @@ class ScriptBase(ScriptDB): "Get the number of returning repeats. Returns None if unlimited repeats." task = self.ndb._task if task: - return max(0, self.dbobj.db_repeats - task.callcount) + return max(0, self.db_repeats - task.callcount) def start(self, force_restart=False): """ @@ -224,10 +224,7 @@ class ScriptBase(ScriptDB): Used in counting. """ - #print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj), - # self.is_active, force_restart) - - if self.dbobj.is_active and not force_restart: + if self.is_active and not force_restart: # script already runs and should not be restarted. return 0 @@ -235,11 +232,11 @@ class ScriptBase(ScriptDB): if obj: # check so the scripted object is valid and initalized try: - _GA(obj.dbobj, 'cmdset') + obj.cmdset except AttributeError: # this means the object is not initialized. logger.log_trace() - self.dbobj.is_active = False + self.is_active = False return 0 # try to restart a paused script @@ -247,13 +244,13 @@ class ScriptBase(ScriptDB): return 1 # start the script from scratch - self.dbobj.is_active = True + self.is_active = True try: self.at_start() except Exception: logger.log_trace() - if self.dbobj.db_interval > 0: + if self.db_interval > 0: self._start_task() return 1 @@ -274,7 +271,7 @@ class ScriptBase(ScriptDB): logger.log_trace() self._stop_task() try: - self.dbobj.delete() + self.delete() except AssertionError: logger.log_trace() return 0 @@ -292,7 +289,7 @@ class ScriptBase(ScriptDB): self.db._paused_time = task.next_call_time() self.db._paused_callcount = task.callcount self._stop_task() - self.dbobj.is_active = False + self.is_active = False def unpause(self): """ @@ -300,7 +297,7 @@ class ScriptBase(ScriptDB): """ if self.db._paused_time: # only unpause if previously paused - self.dbobj.is_active = True + self.is_active = True try: self.at_start() @@ -364,10 +361,6 @@ class Script(ScriptBase): aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Object, read-only) - link to database model. dbobj.typeclass - points back to this class - typeclass (Object, read-only) - this links back to this class as an - identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings @@ -441,7 +434,7 @@ class Script(ScriptBase): Generally, you don't need to overload this, but only the hooks called by this method. """ - self.at_script_creation(self) + self.at_script_creation() if hasattr(self, "_createdict"): # this will only be set if the utils.create_script @@ -470,14 +463,6 @@ class Script(ScriptBase): updates.append("db_persistent") if updates: self.save(update_fields=updates) - - if cdict["permissions"]: - self.permissions.add(cdict["permissions"]) - if cdict["locks"]: - self.locks.add(cdict["locks"]) - if cdict["aliases"]: - self.aliases.add(cdict["aliases"]) - if not cdict["autostart"]: # don't auto-start the script return diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py index 8ac302bb84..bc87d5673b 100644 --- a/src/server/initial_setup.py +++ b/src/server/initial_setup.py @@ -69,7 +69,8 @@ def create_objects(): # it to exist in Limbo. character_typeclass = settings.BASE_CHARACTER_TYPECLASS god_character = create.create_object(character_typeclass, - key=god_player.username, nohome=True) + key=god_player.username, + nohome=True) god_character.id = 1 god_character.db.desc = _('This is User #1.') @@ -84,14 +85,13 @@ def create_objects(): room_typeclass = settings.BASE_ROOM_TYPECLASS limbo_obj = create.create_object(room_typeclass, _('Limbo'), nohome=True) limbo_obj.id = 2 - string = " ".join([ - "Welcome to your new {wEvennia{n-based game. From here you are ready", - "to begin development. Visit http://evennia.com if you should need", - "help or would like to participate in community discussions. If you", - "are logged in as User #1 you can create a demo/tutorial area with", - "'@batchcommand contrib.tutorial_world.build'. Log out and create", - "a new non-admin account at the login screen to play the tutorial", - "properly."]) + string = \ + "Welcome to your new {wEvennia{n-based game. From here you are ready " \ + "to begin development. Visit http://evennia.com if you should need " \ + "help or would like to participate in community discussions. If you " \ + "are logged in as user #1 you can create a demo/tutorial area with " \ + "{w@batchcommand contrib.tutorial_world.build{n. Use {w@quell{n or login " \ + "as normal player to play the demo properly." string = _(string) limbo_obj.db.desc = string limbo_obj.save() diff --git a/src/utils/create.py b/src/utils/create.py index 53fd3a2bc0..1e35490518 100644 --- a/src/utils/create.py +++ b/src/utils/create.py @@ -23,8 +23,7 @@ Models covered: """ from django.conf import settings from django.db import IntegrityError -from src.utils.idmapper.models import SharedMemoryModel -from src.utils import utils, logger +from src.utils import logger from src.utils.utils import make_iter, class_from_module, dbid_to_obj # delayed imports @@ -71,6 +70,11 @@ def create_object(typeclass=None, key=None, location=None, nohome - this allows the creation of objects without a default home location; only used when creating the default location itself or during unittests """ + global _ObjectDB + if not _ObjectDB: + from src.objects.models import ObjectDB as _ObjectDB + + typeclass = typeclass if typeclass else settings.BASE_OBJECT_TYPECLASS if isinstance(typeclass, basestring): @@ -141,6 +145,10 @@ def create_script(typeclass, key=None, obj=None, player=None, locks=None, error will be raised. If set, this method will return None upon errors. """ + global _ScriptDB + if not _ScriptDB: + from src.scripts.models import ScriptDB as _ScriptDB + typeclass = typeclass if typeclass else settings.BASE_SCRIPT_TYPECLASS if isinstance(typeclass, basestring): @@ -148,13 +156,18 @@ def create_script(typeclass, key=None, obj=None, player=None, locks=None, typeclass = class_from_module(typeclass, settings.SCRIPT_TYPECLASS_PATHS) # validate input - player = dbid_to_obj(player) - obj = dbid_to_obj(obj) + kwarg = {} + if key: kwarg["db_key"] = key + if player: kwarg["db_player"] = dbid_to_obj(player, _ScriptDB) + if obj: kwarg["db_obj"] = dbid_to_obj(obj, _ScriptDB) + if interval: kwarg["db_interval"] = interval + if start_delay: kwarg["db_start_delay"] = start_delay + if repeats: kwarg["db_repeats"] = repeats + if persistent: kwarg["db_persistent"] = persistent # create new instance - new_script = typeclass(db_key=key, db_obj=obj, db_player=player, - db_interval=interval, db_start_delay=start_delay, - db_repeats=repeats, db_peristent=persistent) + new_script = typeclass(**kwarg) + # store the call signature for the signal new_script._createdict = {"key":key, "obj":obj, "player":player, "locks":locks, "interval":interval, @@ -326,6 +339,10 @@ def create_player(key, email, password, operations and is thus not suitable for play-testing the game. """ + global _PlayerDB + if not _PlayerDB: + from src.players.models import PlayerDB as _PlayerDB + typeclass = typeclass if typeclass else settings.BASE_PLAYER_TYPECLASS if isinstance(typeclass, basestring):