mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 07:27:17 +02:00
Scripts and Exits updated. Fixed some deep issues with Scripts that caused object-based scripts to not properly shut down in some situations, as well as spawn multiple instances of themselves. I think this should resolve all "at_repeat doubling" issues reported. Due to optimizations in the typeclass cache loader in a previous update, the Exit cmdsets were not properly loaded (they were loaded at cache time, which now doesn't happen as often). So Exits instead rely on the new "at_cmdset_get" hook called by the cmdhandler. It allows dynamic modification of cmdsets just before they are accessed. Resolves issue173 (I hope). Resolves issue180. Resolves issue 181.
This commit is contained in:
parent
16affc284b
commit
2b4e008d18
13 changed files with 135 additions and 68 deletions
|
|
@ -84,6 +84,10 @@ def get_and_merge_cmdsets(caller):
|
||||||
that this is only relevant for logged-in callers.
|
that this is only relevant for logged-in callers.
|
||||||
"""
|
"""
|
||||||
# The calling object's cmdset
|
# The calling object's cmdset
|
||||||
|
try:
|
||||||
|
caller.at_cmdset_get()
|
||||||
|
except Exception:
|
||||||
|
logger.log_trace()
|
||||||
try:
|
try:
|
||||||
caller_cmdset = caller.cmdset.current
|
caller_cmdset = caller.cmdset.current
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
@ -103,6 +107,12 @@ def get_and_merge_cmdsets(caller):
|
||||||
# Gather all cmdsets stored on objects in the room and
|
# Gather all cmdsets stored on objects in the room and
|
||||||
# also in the caller's inventory and the location itself
|
# also in the caller's inventory and the location itself
|
||||||
local_objlist = location.contents_get(exclude=caller.dbobj) + caller.contents + [location]
|
local_objlist = location.contents_get(exclude=caller.dbobj) + caller.contents + [location]
|
||||||
|
for obj in local_objlist:
|
||||||
|
try:
|
||||||
|
# call hook in case we need to do dynamic changing to cmdset
|
||||||
|
obj.at_cmdset_get()
|
||||||
|
except Exception:
|
||||||
|
logger.log_trace()
|
||||||
local_objects_cmdsets = [obj.cmdset.current for obj in local_objlist
|
local_objects_cmdsets = [obj.cmdset.current for obj in local_objlist
|
||||||
if (obj.cmdset.current and obj.locks.check(caller, 'call', no_superuser_bypass=True))]
|
if (obj.cmdset.current and obj.locks.check(caller, 'call', no_superuser_bypass=True))]
|
||||||
for cset in local_objects_cmdsets:
|
for cset in local_objects_cmdsets:
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,17 @@ class CmdSetHandler(object):
|
||||||
self.obj.cmdset_storage = storage
|
self.obj.cmdset_storage = storage
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def has_cmdset(self, cmdset_key, must_be_default=False):
|
||||||
|
"""
|
||||||
|
checks so the cmdsethandler contains a cmdset with the given key.
|
||||||
|
must_be_default - only match against the default cmdset.
|
||||||
|
"""
|
||||||
|
if must_be_default:
|
||||||
|
return self.cmdset_stack and self.cmdset_stack[0].key == cmdset_key
|
||||||
|
else:
|
||||||
|
return any([cmdset.key == cmdset_key for cmdset in self.cmdset_stack])
|
||||||
|
|
||||||
|
|
||||||
def all(self):
|
def all(self):
|
||||||
"""
|
"""
|
||||||
Returns all cmdsets.
|
Returns all cmdsets.
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,8 @@ class CmdScripts(MuxCommand):
|
||||||
else:
|
else:
|
||||||
string = "Stopping script '%s'." % scripts[0].key
|
string = "Stopping script '%s'." % scripts[0].key
|
||||||
scripts[0].stop()
|
scripts[0].stop()
|
||||||
|
#import pdb
|
||||||
|
#pdb.set_trace()
|
||||||
ScriptDB.objects.validate() #just to be sure all is synced
|
ScriptDB.objects.validate() #just to be sure all is synced
|
||||||
else:
|
else:
|
||||||
# multiple matches.
|
# multiple matches.
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,6 @@ class ObjectDB(TypedObject):
|
||||||
self.cmdset = CmdSetHandler(self)
|
self.cmdset = CmdSetHandler(self)
|
||||||
self.cmdset.update(init_mode=True)
|
self.cmdset.update(init_mode=True)
|
||||||
self.scripts = ScriptHandler(self)
|
self.scripts = ScriptHandler(self)
|
||||||
self.scripts.validate(init_mode=True)
|
|
||||||
self.nicks = ObjectNickHandler(self)
|
self.nicks = ObjectNickHandler(self)
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# Wrapper properties to easily set database fields. These are
|
||||||
|
|
@ -804,6 +803,9 @@ class ObjectDB(TypedObject):
|
||||||
if object.__getattribute__(self, 'player') and self.player:
|
if object.__getattribute__(self, 'player') and self.player:
|
||||||
self.player.character = None
|
self.player.character = None
|
||||||
self.player = None
|
self.player = None
|
||||||
|
|
||||||
|
for script in self.scripts.all():
|
||||||
|
script.stop()
|
||||||
|
|
||||||
# if self.player:
|
# if self.player:
|
||||||
# self.player.user.is_active = False
|
# self.player.user.is_active = False
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,30 @@ class Object(TypeClass):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def basetype_posthook_setup(self):
|
||||||
|
"""
|
||||||
|
Called once, after basetype_setup and at_object_creation. This should generally not be overloaded unless
|
||||||
|
you are redefining how a room/exit/object works. It allows for basetype-like setup
|
||||||
|
after the object is created. An example of this is EXITs, who need to know keys, aliases, locks
|
||||||
|
etc to set up their exit-cmdsets.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def at_cache(self):
|
def at_cache(self):
|
||||||
"""
|
"""
|
||||||
Called whenever this object is cached or reloaded.
|
Called whenever this object is cached to the idmapper backend.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def at_cmdset_get(self):
|
||||||
|
"""
|
||||||
|
Called just before cmdsets on this object are requested by the
|
||||||
|
command handler. If changes need to be done on the fly to the cmdset
|
||||||
|
before passing them on to the cmdhandler, this is the place to do it.
|
||||||
|
This is called also if the object currently have no cmdsets.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def at_first_login(self):
|
def at_first_login(self):
|
||||||
"""
|
"""
|
||||||
Only called once, the very first
|
Only called once, the very first
|
||||||
|
|
@ -423,11 +441,15 @@ class Exit(Object):
|
||||||
"""
|
"""
|
||||||
Helper function for creating an exit command set + command.
|
Helper function for creating an exit command set + command.
|
||||||
|
|
||||||
Note that exitdbobj is an ObjectDB instance. This is necessary for
|
The command of this cmdset has the same name as the Exit object
|
||||||
handling reloads and avoid tracebacks while the typeclass system
|
and allows the exit to react when the player enter the exit's name,
|
||||||
is rebooting.
|
triggering the movement between rooms.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Note that exitdbobj is an ObjectDB instance. This is necessary
|
||||||
|
for handling reloads and avoid tracebacks if this is called while
|
||||||
|
the typeclass system is rebooting.
|
||||||
|
"""
|
||||||
|
#print "Exit:create_exit_cmdset "
|
||||||
class ExitCommand(command.Command):
|
class ExitCommand(command.Command):
|
||||||
"""
|
"""
|
||||||
This is a command that simply cause the caller
|
This is a command that simply cause the caller
|
||||||
|
|
@ -476,7 +498,6 @@ class Exit(Object):
|
||||||
return exit_cmdset
|
return exit_cmdset
|
||||||
|
|
||||||
# Command hooks
|
# Command hooks
|
||||||
|
|
||||||
def basetype_setup(self):
|
def basetype_setup(self):
|
||||||
"""
|
"""
|
||||||
Setup exit-security
|
Setup exit-security
|
||||||
|
|
@ -485,21 +506,26 @@ class Exit(Object):
|
||||||
overload the default locks (it is called after this one).
|
overload the default locks (it is called after this one).
|
||||||
"""
|
"""
|
||||||
super(Exit, self).basetype_setup()
|
super(Exit, self).basetype_setup()
|
||||||
|
|
||||||
# this is the fundamental thing for making the Exit work:
|
|
||||||
self.cmdset.add_default(self.create_exit_cmdset(self.dbobj), permanent=False)
|
|
||||||
# an exit should have a destination (this is replaced at creation time)
|
|
||||||
if self.dbobj.location:
|
|
||||||
self.destination = self.dbobj.location
|
|
||||||
|
|
||||||
# setting default locks (overload these in at_object_creation()
|
# setting default locks (overload these in at_object_creation()
|
||||||
self.locks.add("puppet:false()") # would be weird to puppet an exit ...
|
self.locks.add("puppet:false()") # would be weird to puppet an exit ...
|
||||||
self.locks.add("traverse:all()") # who can pass through exit by default
|
self.locks.add("traverse:all()") # who can pass through exit by default
|
||||||
self.locks.add("get:false()") # noone can pick up the exit
|
self.locks.add("get:false()") # noone can pick up the exit
|
||||||
|
|
||||||
def at_cache(self):
|
# an exit should have a destination (this is replaced at creation time)
|
||||||
"Called when the typeclass is re-cached or reloaded. Should usually not be edited."
|
if self.dbobj.location:
|
||||||
self.cmdset.add_default(self.create_exit_cmdset(self.dbobj), permanent=False)
|
self.destination = self.dbobj.location
|
||||||
|
|
||||||
|
def at_cmdset_get(self):
|
||||||
|
"""
|
||||||
|
Called when the cmdset is requested from this object, just before the cmdset is
|
||||||
|
actually extracted. If no Exit-cmdset is cached, create it now.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.ndb.exit_reset or not self.cmdset.has_cmdset("_exitset", must_be_default=True):
|
||||||
|
# we are resetting, or no exit-cmdset was set. Create one dynamically.
|
||||||
|
self.cmdset.add_default(self.create_exit_cmdset(self.dbobj), permanent=False)
|
||||||
|
self.ndb.exit_reset = False
|
||||||
|
|
||||||
# this and other hooks are what usually can be modified safely.
|
# this and other hooks are what usually can be modified safely.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,8 @@ class ScriptManager(TypedObjectManager):
|
||||||
key = validate only scripts with a particular key
|
key = validate only scripts with a particular key
|
||||||
dbref = validate only the single script with this particular id.
|
dbref = validate only the single script with this particular id.
|
||||||
|
|
||||||
init_mode - When this mode is active, non-persistent scripts
|
init_mode - This is used during server upstart. It causes non-persistent
|
||||||
will be removed and persistent scripts will be
|
scripts to be removed and persistent scripts to be
|
||||||
force-restarted.
|
force-restarted.
|
||||||
|
|
||||||
This method also makes sure start any scripts it validates,
|
This method also makes sure start any scripts it validates,
|
||||||
|
|
@ -117,26 +117,30 @@ class ScriptManager(TypedObjectManager):
|
||||||
# This deletes all non-persistent scripts from database
|
# This deletes all non-persistent scripts from database
|
||||||
nr_stopped += self.remove_non_persistent(obj=obj)
|
nr_stopped += self.remove_non_persistent(obj=obj)
|
||||||
# turn off the activity flag for all remaining scripts
|
# turn off the activity flag for all remaining scripts
|
||||||
for script in self.all():
|
scripts = self.get_all_scripts()
|
||||||
script.is_active = False
|
for script in scripts:
|
||||||
|
script.dbobj.is_active = False
|
||||||
|
|
||||||
|
elif not scripts:
|
||||||
|
# normal operation
|
||||||
|
if dbref and self.dbref(dbref):
|
||||||
|
scripts = self.get_id(dbref)
|
||||||
|
elif obj:
|
||||||
|
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
||||||
|
else:
|
||||||
|
scripts = self.get_all_scripts(key=key) #self.model.get_all_cached_instances()
|
||||||
|
|
||||||
if dbref and self.dbref(dbref):
|
|
||||||
scripts = self.get_id(dbref)
|
|
||||||
elif scripts:
|
|
||||||
pass
|
|
||||||
elif obj:
|
|
||||||
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
|
||||||
else:
|
|
||||||
scripts = self.model.get_all_cached_instances()#get_all_scripts(key=key)
|
|
||||||
if not scripts:
|
if not scripts:
|
||||||
|
# no scripts available to validate
|
||||||
VALIDATE_ITERATION -= 1
|
VALIDATE_ITERATION -= 1
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
#print "scripts to validate: [%s]" % (", ".join(script.key for script in scripts))
|
#print "scripts to validate: [%s]" % (", ".join(script.key for script in scripts))
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
if script.is_valid():
|
if script.is_valid():
|
||||||
#print "validating %s (%i)" % (script.key, id(script.dbobj))
|
#print "validating %s (%i) (init_mode=%s)" % (script.key, id(script.dbobj), init_mode)
|
||||||
nr_started += script.start(force_restart=init_mode)
|
nr_started += script.start(force_restart=init_mode)
|
||||||
#print "back from start."
|
#print "back from start. nr_started=", nr_started
|
||||||
else:
|
else:
|
||||||
script.stop()
|
script.stop()
|
||||||
nr_stopped += 1
|
nr_stopped += 1
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,10 @@ class ScriptClass(TypeClass):
|
||||||
def _stop_task(self):
|
def _stop_task(self):
|
||||||
"stop task runner"
|
"stop task runner"
|
||||||
try:
|
try:
|
||||||
self.ndb.twisted_task.stop()
|
#print "stopping twisted task:", id(self.ndb.twisted_task), self.obj
|
||||||
|
self.ndb.twisted_task.stop()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
logger.log_trace()
|
||||||
def _step_err_callback(self, e):
|
def _step_err_callback(self, e):
|
||||||
"callback for runner errors"
|
"callback for runner errors"
|
||||||
cname = self.__class__.__name__
|
cname = self.__class__.__name__
|
||||||
|
|
@ -74,7 +75,7 @@ class ScriptClass(TypeClass):
|
||||||
self.save()
|
self.save()
|
||||||
def _step_task(self):
|
def _step_task(self):
|
||||||
"step task"
|
"step task"
|
||||||
try:
|
try:
|
||||||
d = maybeDeferred(self._step_succ_callback)
|
d = maybeDeferred(self._step_succ_callback)
|
||||||
d.addErrback(self._step_err_callback)
|
d.addErrback(self._step_err_callback)
|
||||||
return d
|
return d
|
||||||
|
|
@ -107,30 +108,30 @@ class ScriptClass(TypeClass):
|
||||||
"""
|
"""
|
||||||
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
||||||
# self.is_active, force_restart)
|
# self.is_active, force_restart)
|
||||||
if self.dbobj.db_is_active and not force_restart:
|
|
||||||
# script already runs.
|
if self.dbobj.is_active and not force_restart:
|
||||||
|
# script already runs and should not be restarted.
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if self.obj:
|
obj = self.obj
|
||||||
|
if obj:
|
||||||
# check so the scripted object is valid and initalized
|
# check so the scripted object is valid and initalized
|
||||||
try:
|
try:
|
||||||
dummy = object.__getattribute__(self.obj, 'cmdset')
|
dummy = object.__getattribute__(obj, 'cmdset')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# this means the object is not initialized.
|
# this means the object is not initialized.
|
||||||
self.dbobj.db_is_active = False
|
self.dbobj.is_active = False
|
||||||
return 0
|
return 0
|
||||||
# try to start the script
|
# try to start the script
|
||||||
try:
|
try:
|
||||||
self.dbobj.db_is_active = True
|
self.dbobj.is_active = True
|
||||||
self.dbobj.save()
|
|
||||||
self.at_start()
|
self.at_start()
|
||||||
if self.dbobj.db_interval > 0:
|
if self.dbobj.db_interval > 0:
|
||||||
self._start_task()
|
self._start_task()
|
||||||
return 1
|
return 1
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
self.dbobj.db_is_active = False
|
self.dbobj.is_active = False
|
||||||
self.dbobj.save()
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def stop(self, kill=False):
|
def stop(self, kill=False):
|
||||||
|
|
@ -141,6 +142,8 @@ class ScriptClass(TypeClass):
|
||||||
kill - don't call finishing hooks.
|
kill - don't call finishing hooks.
|
||||||
"""
|
"""
|
||||||
#print "stopping script %s" % self.key
|
#print "stopping script %s" % self.key
|
||||||
|
#import pdb
|
||||||
|
#pdb.set_trace()
|
||||||
if not kill:
|
if not kill:
|
||||||
try:
|
try:
|
||||||
self.at_stop()
|
self.at_stop()
|
||||||
|
|
@ -149,11 +152,13 @@ class ScriptClass(TypeClass):
|
||||||
if self.dbobj.db_interval > 0:
|
if self.dbobj.db_interval > 0:
|
||||||
try:
|
try:
|
||||||
self._stop_task()
|
self._stop_task()
|
||||||
except Exception:
|
except Exception, e:
|
||||||
|
logger.log_trace("Stopping script %s(%s)" % (self.key, self.id))
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self.dbobj.delete()
|
self.dbobj.delete()
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
|
logger.log_trace()
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
@ -175,7 +180,7 @@ class ScriptClass(TypeClass):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# class ScriptClassOld(TypeClass):
|
# class ScriptClass(TypeClass):
|
||||||
# """
|
# """
|
||||||
# Base class for all Scripts.
|
# Base class for all Scripts.
|
||||||
# """
|
# """
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ from twisted.internet import protocol, reactor, defer
|
||||||
from twisted.web import server, static
|
from twisted.web import server, static
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.utils import reloads
|
from src.scripts.models import ScriptDB
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
from src.server import initial_setup
|
from src.server import initial_setup
|
||||||
|
|
@ -99,7 +99,7 @@ class Evennia(object):
|
||||||
channelhandler.CHANNELHANDLER.update()
|
channelhandler.CHANNELHANDLER.update()
|
||||||
|
|
||||||
# init all global scripts
|
# init all global scripts
|
||||||
reloads.reload_scripts(init_mode=True)
|
ScriptDB.objects.validate(init_mode=True)
|
||||||
|
|
||||||
# Make info output to the terminal.
|
# Make info output to the terminal.
|
||||||
self.terminal_output()
|
self.terminal_output()
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ class SessionBase(object):
|
||||||
self.log('Logged in: %s' % self)
|
self.log('Logged in: %s' % self)
|
||||||
|
|
||||||
# start (persistent) scripts on this object
|
# start (persistent) scripts on this object
|
||||||
reloads.reload_scripts(obj=self.player.character, init_mode=True)
|
reloads.reload_scripts(obj=self.player.character)
|
||||||
|
|
||||||
#add session to connected list
|
#add session to connected list
|
||||||
SESSIONS.add_loggedin_session(self)
|
SESSIONS.add_loggedin_session(self)
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ class Attribute(SharedMemoryModel):
|
||||||
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
||||||
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
||||||
lock_storage = property(lock_storage_get, lock_storage_set, lock_storage_del)
|
lock_storage = property(lock_storage_get, lock_storage_set, lock_storage_del)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
@ -747,8 +747,8 @@ class TypedObject(SharedMemoryModel):
|
||||||
defpath = "src.objects.objects.Object"
|
defpath = "src.objects.objects.Object"
|
||||||
typeclass = object.__getattribute__(self, "_path_import")(defpath)
|
typeclass = object.__getattribute__(self, "_path_import")(defpath)
|
||||||
if not silent:
|
if not silent:
|
||||||
errstring += " %s\n%s" % (typeclass, errstring)
|
#errstring = " %s\n%s" % (typeclass, errstring)
|
||||||
errstring += " Default class '%s' failed to load." % failpath
|
errstring = " Default class '%s' failed to load." % failpath
|
||||||
errstring += "\n Using Evennia's default class '%s'." % defpath
|
errstring += "\n Using Evennia's default class '%s'." % defpath
|
||||||
object.__getattribute__(self, "_display_errmsg")(errstring)
|
object.__getattribute__(self, "_display_errmsg")(errstring)
|
||||||
if not callable(typeclass):
|
if not callable(typeclass):
|
||||||
|
|
@ -1083,7 +1083,12 @@ class TypedObject(SharedMemoryModel):
|
||||||
def all(self):
|
def all(self):
|
||||||
return [val for val in self.__dict__.keys()
|
return [val for val in self.__dict__.keys()
|
||||||
if not val.startswith['_']]
|
if not val.startswith['_']]
|
||||||
pass
|
def __getattribute__(self, key):
|
||||||
|
# return None if no matching attribute was found.
|
||||||
|
try:
|
||||||
|
return object.__getattribute__(self, key)
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
self._ndb_holder = NdbHolder()
|
self._ndb_holder = NdbHolder()
|
||||||
return self._ndb_holder
|
return self._ndb_holder
|
||||||
#@ndb.setter
|
#@ndb.setter
|
||||||
|
|
|
||||||
|
|
@ -91,20 +91,20 @@ def create_object(typeclass, key=None, location=None,
|
||||||
player.obj = new_object
|
player.obj = new_object
|
||||||
|
|
||||||
new_object.destination = destination
|
new_object.destination = destination
|
||||||
|
|
||||||
# call the hook method. This is where all at_creation
|
# call the hook method. This is where all at_creation
|
||||||
# customization happens as the typeclass stores custom
|
# customization happens as the typeclass stores custom
|
||||||
# things on its database object.
|
# things on its database object.
|
||||||
new_object.basetype_setup() # setup the basics of Exits, Characters etc.
|
new_object.basetype_setup() # setup the basics of Exits, Characters etc.
|
||||||
new_object.at_object_creation()
|
new_object.at_object_creation()
|
||||||
|
|
||||||
# custom-given variables override the hook
|
# custom-given perms/locks overwrite hooks
|
||||||
if permissions:
|
if permissions:
|
||||||
new_object.permissions = permissions
|
new_object.permissions = permissions
|
||||||
if aliases:
|
|
||||||
new_object.aliases = aliases
|
|
||||||
if locks:
|
if locks:
|
||||||
new_object.locks.add(locks)
|
new_object.locks.add(locks)
|
||||||
|
if aliases:
|
||||||
|
new_object.aliases = aliases
|
||||||
|
|
||||||
# perform a move_to in order to display eventual messages.
|
# perform a move_to in order to display eventual messages.
|
||||||
if home:
|
if home:
|
||||||
|
|
@ -114,6 +114,10 @@ def create_object(typeclass, key=None, location=None,
|
||||||
else:
|
else:
|
||||||
# rooms would have location=None.
|
# rooms would have location=None.
|
||||||
new_object.location = None
|
new_object.location = None
|
||||||
|
|
||||||
|
# post-hook setup (mainly used by Exits)
|
||||||
|
new_object.basetype_posthook_setup()
|
||||||
|
|
||||||
new_object.save()
|
new_object.save()
|
||||||
return new_object
|
return new_object
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,9 @@ class SharedMemoryModel(Model):
|
||||||
if instance._get_pk_val() is not None:
|
if instance._get_pk_val() is not None:
|
||||||
cls.__instance_cache__[instance._get_pk_val()] = instance
|
cls.__instance_cache__[instance._get_pk_val()] = instance
|
||||||
try:
|
try:
|
||||||
object.__getattribute__(instance, "at_cache")()
|
object.__getattribute__(instance, "at_cache")()
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError), e:
|
||||||
|
#print e, instance._get_pk_val()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#key = "%s-%s" % (cls, instance.pk)
|
#key = "%s-%s" % (cls, instance.pk)
|
||||||
|
|
@ -118,7 +119,7 @@ class SharedMemoryModel(Model):
|
||||||
|
|
||||||
|
|
||||||
def _flush_cached_by_key(cls, key):
|
def _flush_cached_by_key(cls, key):
|
||||||
del cls.__instance_cache__[key]
|
del cls.__instance_cache__[key]
|
||||||
_flush_cached_by_key = classmethod(_flush_cached_by_key)
|
_flush_cached_by_key = classmethod(_flush_cached_by_key)
|
||||||
|
|
||||||
def flush_cached_instance(cls, instance):
|
def flush_cached_instance(cls, instance):
|
||||||
|
|
|
||||||
|
|
@ -128,23 +128,20 @@ def reload_modules():
|
||||||
# run through all objects in database, forcing re-caching.
|
# run through all objects in database, forcing re-caching.
|
||||||
|
|
||||||
|
|
||||||
def reload_scripts(scripts=None, obj=None, key=None,
|
def reload_scripts(scripts=None, obj=None, key=None, dbref=None):
|
||||||
dbref=None, init_mode=False):
|
|
||||||
"""
|
"""
|
||||||
Run a validation of the script database.
|
Run a validation of the script database.
|
||||||
obj - only validate scripts on this object
|
obj - only validate scripts on this object
|
||||||
key - only validate scripts with this key
|
key - only validate scripts with this key
|
||||||
dbref - only validate the script with this unique idref
|
dbref - only validate the script with this unique idref
|
||||||
emit_to_obj - which object to receive error message
|
emit_to_obj - which object to receive error message
|
||||||
init_mode - during init-mode, non-persistent scripts are
|
|
||||||
cleaned out. All persistent scripts are force-started.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nr_started, nr_stopped = ScriptDB.objects.validate(scripts=scripts,
|
nr_started, nr_stopped = ScriptDB.objects.validate(scripts=scripts,
|
||||||
obj=obj, key=key,
|
obj=obj, key=key,
|
||||||
dbref=dbref,
|
dbref=dbref,
|
||||||
init_mode=init_mode)
|
init_mode=False)
|
||||||
if nr_started or nr_stopped:
|
if nr_started or nr_stopped:
|
||||||
string = " Started %s script(s). Stopped %s invalid script(s)." % \
|
string = " Started %s script(s). Stopped %s invalid script(s)." % \
|
||||||
(nr_started, nr_stopped)
|
(nr_started, nr_stopped)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue