Working on cleaning some strange behavior when trying to submitting faulty typeclasses to script system. Also fixing bugs here and there.

This commit is contained in:
Griatch 2011-07-03 21:01:06 +00:00
parent dae375d1c4
commit 6cb2b8b745
12 changed files with 301 additions and 141 deletions

View file

@ -99,16 +99,18 @@ class AttackTimer(Script):
"Called every self.interval seconds." "Called every self.interval seconds."
if self.obj.db.inactive: if self.obj.db.inactive:
return return
#print "attack timer: at_repeat", self.dbobj.id, self.ndb.twisted_task, id(self.ndb.twisted_task)
if self.obj.db.roam_mode: if self.obj.db.roam_mode:
self.obj.roam() self.obj.roam()
return #return
elif self.obj.db.battle_mode: elif self.obj.db.battle_mode:
#print "attack"
self.obj.attack() self.obj.attack()
return return
elif self.obj.db.pursue_mode: elif self.obj.db.pursue_mode:
#print "pursue"
self.obj.pursue() self.obj.pursue()
return #return
else: else:
#dead mode. Wait for respawn. #dead mode. Wait for respawn.
dead_at = self.db.dead_at dead_at = self.db.dead_at
@ -250,14 +252,13 @@ class Enemy(Mob):
those that previously attacked it. those that previously attacked it.
""" """
last_attacker = self.db.last_attacker last_attacker = self.db.last_attacker
players = [obj for obj in self.location.contents if utils.inherits_from(obj, BASE_CHARACTER_TYPECLASS)] players = [obj for obj in self.location.contents if utils.inherits_from(obj, BASE_CHARACTER_TYPECLASS) and not obj.is_superuser]
if players: if players:
# we found players in the room. Maybe we caught up with some, or some walked in on us # we found players in the room. Maybe we caught up with some, or some walked in on us
# before we had time to pursue them. Switch to battle mode. # before we had time to pursue them. Switch to battle mode.
self.battle_mode = True self.battle_mode = True
self.roam_mode = False self.roam_mode = False
self.pursue_mode = False self.pursue_mode = False
#self.attack()
else: else:
# find all possible destinations. # find all possible destinations.
destinations = [ex.destination for ex in self.location.exits if ex.access(self, "traverse")] destinations = [ex.destination for ex in self.location.exits if ex.access(self, "traverse")]

View file

@ -242,7 +242,12 @@ class StateLightSourceOn(Script):
prematurely, this hook will also be called in that case. prematurely, this hook will also be called in that case.
""" """
# calculate remaining burntime # calculate remaining burntime
time_burnt = time.time() - self.db.script_started try:
time_burnt = time.time() - self.db.script_started
except TypeError:
# can happen if script_started is not defined
time_burnt = self.interval
burntime = self.interval - time_burnt burntime = self.interval - time_burnt
self.obj.db.burntime = burntime self.obj.db.burntime = burntime
if burntime <= 0: if burntime <= 0:
@ -732,12 +737,7 @@ class CmdAttack(Command):
# should return True if target is defeated, False otherwise. # should return True if target is defeated, False otherwise.
return target.at_hit(self.obj, self.caller, damage) return target.at_hit(self.obj, self.caller, damage)
elif target.db.health: elif target.db.health:
target.db.health -= damage target.db.health -= damage
if target.db.health <= 0:
# enemy is down!
return True
else:
return False
else: else:
# sorry, impossible to fight this enemy ... # sorry, impossible to fight this enemy ...
self.caller.msg("The enemy seems unaffacted.") self.caller.msg("The enemy seems unaffacted.")

View file

@ -466,7 +466,7 @@ class CmdLookBridge(Command):
def func(self): def func(self):
"Looking around, including a chance to fall." "Looking around, including a chance to fall."
bridge_position = self.caller.db.tutorial_bridge_position bridge_position = self.caller.db.tutorial_bridge_position
messages =("You are standing {wvery close to the the bridge's western foundation{n. If you go west you will be back on solid ground ...", messages =("You are standing {wvery close to the the bridge's western foundation{n. If you go west you will be back on solid ground ...",
"The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.", "The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.",
@ -486,8 +486,8 @@ class CmdLookBridge(Command):
self.caller.msg(message) self.caller.msg(message)
# there is a chance that we fall if we are on the western or central part of the bridge. # there is a chance that we fall if we are on the western or central part of the bridge.
if bridge_position < 3 and random.random() < 0.2 and not self.caller.is_superuser: if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
# we fall on 20% of the times. # we fall on 5% of the times.
fexit = ObjectDB.objects.object_search(self.obj.db.fall_exit) fexit = ObjectDB.objects.object_search(self.obj.db.fall_exit)
if fexit: if fexit:
string = "\n Suddenly the plank you stand on gives way under your feet! You fall!" string = "\n Suddenly the plank you stand on gives way under your feet! You fall!"
@ -500,7 +500,8 @@ class CmdLookBridge(Command):
# at_object_leave hook manually (otherwise this is done by move_to()). # at_object_leave hook manually (otherwise this is done by move_to()).
self.caller.msg("{r%s{n" % string) self.caller.msg("{r%s{n" % string)
self.obj.at_object_leave(self.caller, fexit) self.obj.at_object_leave(self.caller, fexit)
self.caller.location = fexit[0] # stealth move, without any other hook calls. self.caller.location = fexit[0] # stealth move, without any other hook calls.
self.obj.msg_contents("A plank gives way under %s's feet and they fall from the bridge!" % self.caller.key)
# custom help command # custom help command
class CmdBridgeHelp(Command): class CmdBridgeHelp(Command):

View file

@ -42,6 +42,7 @@ class IrregularEvent(Script):
rand = random.random() rand = random.random()
if rand <= self.db.random_chance: if rand <= self.db.random_chance:
try: try:
#self.obj.msg_contents("irregular event for %s(#%i)" % (self.obj, self.obj.id))
self.obj.update_irregular() self.obj.update_irregular()
except Exception: except Exception:
pass pass

View file

@ -23,15 +23,17 @@ class BodyFunctions(Script):
self.key = "bodyfunction" self.key = "bodyfunction"
self.desc = "Adds various timed events to a character." self.desc = "Adds various timed events to a character."
self.interval = 20 # seconds self.interval = 20 # seconds
#self.repeats = 5 # repeat only a certain number of times
self.start_delay = True # wait self.interval until first call self.start_delay = True # wait self.interval until first call
self.persistent = False self.persistent = False
def at_repeat(self): def at_repeat(self):
""" """
This gets called every self.interval seconds. We make This gets called every self.interval seconds. We make
a random check here so as to only return 30% of the time. a random check here so as to only return 33% of the time.
""" """
if random.random() > 0.66: #)
if random.random() < 0.33:
# no message this time # no message this time
return return
rand = random.random() rand = random.random()

View file

@ -1861,7 +1861,7 @@ class CmdScript(MuxCommand):
# adding a new script, and starting it # adding a new script, and starting it
ok = obj.scripts.add(self.rhs, autostart=True) ok = obj.scripts.add(self.rhs, autostart=True)
if not ok: if not ok:
string += "\nScript %s could not be added." % self.rhs string += "\nScript %s could not be added and/or started." % self.rhs
else: else:
string = "Script successfully added and started." string = "Script successfully added and started."

View file

@ -165,7 +165,7 @@ class CmdScripts(MuxCommand):
if not hasattr(script, 'repeats') or not script.repeats: if not hasattr(script, 'repeats') or not script.repeats:
table[5].append("--") table[5].append("--")
else: else:
table[5].append("%ss" % script.repeats) table[5].append("%s" % script.repeats)
if script.persistent: if script.persistent:
table[6].append("*") table[6].append("*")
else: else:

View file

@ -53,18 +53,22 @@ class ScriptManager(TypedObjectManager):
for script in scripts: for script in scripts:
script.stop() script.stop()
def remove_non_persistent(self): def remove_non_persistent(self, obj=None):
""" """
This cleans up the script database of all non-persistent This cleans up the script database of all non-persistent
scripts. It is called every time the server restarts. scripts, or only those on obj. It is called every time the server restarts
and
""" """
nr_deleted = 0 if obj:
for script in [script for script in self.get_all_scripts() to_stop = self.filter(db_persistent=False, db_obj=obj)
if not script.persistent]: else:
to_stop = self.filter(db_persistent=False)
nr_deleted = to_stop.count()
for script in to_stop.filter(db_is_active=True):
script.stop() script.stop()
nr_deleted += 1 for script in to_stop.filter(db_is_active=False):
return nr_deleted script.delete()
return nr_deleted
def validate(self, scripts=None, obj=None, key=None, dbref=None, def validate(self, scripts=None, obj=None, key=None, dbref=None,
init_mode=False): init_mode=False):
@ -111,7 +115,7 @@ class ScriptManager(TypedObjectManager):
if init_mode: if init_mode:
# special mode when server starts or object logs in. # special mode when server starts or object logs in.
# This deletes all non-persistent scripts from database # This deletes all non-persistent scripts from database
nr_stopped += self.remove_non_persistent() nr_stopped += self.remove_non_persistent(obj=obj)
if dbref and self.dbref(dbref): if dbref and self.dbref(dbref):
scripts = self.get_id(dbref) scripts = self.get_id(dbref)

View file

@ -6,6 +6,8 @@ It also defines a few common scripts.
""" """
from time import time from time import time
from twisted.internet.defer import maybeDeferred
from twisted.internet.task import LoopingCall
from twisted.internet import task from twisted.internet import task
from src.server.sessionhandler import SESSIONS from src.server.sessionhandler import SESSIONS
from src.typeclasses.typeclass import TypeClass from src.typeclasses.typeclass import TypeClass
@ -18,54 +20,67 @@ from src.utils import logger
# #
class ScriptClass(TypeClass): class ScriptClass(TypeClass):
""" """
Base class for all Scripts. Base class for scripts
""" """
# private methods for handling timers. # private methods
def __eq__(self, other): def __eq__(self, other):
""" """
This has to be located at this level, having it in the This has to be located at this level, having it in the
parent doesn't work. parent doesn't work.
""" """
if other: try:
return other.id == self.id return other.id == self.id
return False except Exception:
return False
def _start_task(self): def _start_task(self):
"start the task runner." "start task runner"
if self.interval > 0: #print "_start_task: self.interval:", self.key, self.interval, self.dbobj.db_interval
#print "Starting task runner" self.ndb.twisted_task = LoopingCall(self._step_task)
start_now = not self.start_delay self.ndb.twisted_task.start(self.interval, now=not self.start_delay)
self.ndb.twisted_task = task.LoopingCall(self._step_task) self.ndb.time_last_called = int(time())
self.ndb.twisted_task.start(self.interval, now=start_now)
self.ndb.time_last_called = int(time())
#self.save()
def _stop_task(self): def _stop_task(self):
"stop the task runner" "stop task runner"
if hasattr(self.ndb, "twisted_task"): try:
self.ndb.twisted_task.stop() self.ndb.twisted_task.stop()
def _step_task(self): except Exception:
"perform one repeat step of the script" pass
#print "Stepping task runner (obj %s)" % id(self) def _step_err_callback(self, e):
#print "Has dbobj: %s" % hasattr(self, 'dbobj') "callback for runner errors"
cname = self.__class__.__name__
estring = "Script %s(#%i) of type '%s': at_repeat() error '%s'." % (self.key, self.id, cname, e.getErrorMessage())
try:
self.dbobj.db_obj.msg(estring)
except Exception:
pass
logger.log_errmsg(estring)
def _step_succ_callback(self):
"step task runner. No try..except needed due to defer wrap."
if not self.is_valid(): if not self.is_valid():
#the script is not valid anymore. Abort.
self.stop() self.stop()
return return
try: self.at_repeat()
self.at_repeat() repeats = self.dbobj.db_repeats
if self.repeats: if repeats <= 0:
if self.repeats <= 1: pass # infinite repeat
self.stop() elif repeats == 1:
return self.stop()
else: return
self.repeats -= 1 else:
self.ndb.time_last_called = int(time()) self.dbobj.db_repeats -= 1
self.save() self.ndb.time_last_called = int(time())
self.save()
def _step_task(self):
"step task"
try:
d = maybeDeferred(self._step_succ_callback)
d.addErrback(self._step_err_callback)
return d
except Exception: except Exception:
logger.log_trace() logger.log_trace()
self._stop_task()
def time_until_next_repeat(self): def time_until_next_repeat(self):
""" """
@ -75,9 +90,9 @@ class ScriptClass(TypeClass):
system; it's only here for the user to be able to system; it's only here for the user to be able to
check in on their scripts and when they will next be run. check in on their scripts and when they will next be run.
""" """
if self.interval and hasattr(self.ndb, 'time_last_called'): try:
return max(0, (self.ndb.time_last_called + self.interval) - int(time())) return max(0, (self.ndb.time_last_called + self.dbobj.db_interval) - int(time()))
else: except Exception:
return None return None
def start(self, force_restart=False): def start(self, force_restart=False):
@ -87,42 +102,37 @@ class ScriptClass(TypeClass):
force_restart - if True, will always restart the script, regardless force_restart - if True, will always restart the script, regardless
of if it has started before. of if it has started before.
returns 0 or 1 to indicated the script has been started or not. Used in counting.
""" """
#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 force_restart: if self.dbobj.db_is_active and not force_restart:
self.is_active = False # script already runs.
return 0
should_start = True
if self.obj: if self.obj:
# check so the scripted object is valid and initalized
try: try:
#print "checking cmdset ... for obj", self.obj
dummy = object.__getattribute__(self.obj, 'cmdset') dummy = object.__getattribute__(self.obj, 'cmdset')
#print "... checked cmdset"
except AttributeError: except AttributeError:
#print "self.obj.cmdset not found. Setting is_active=False." # this means the object is not initialized.
self.is_active = False self.dbobj.db_is_active = False
should_start = False return 0
if self.is_active and not force_restart: # try to start the script
should_start = False try:
self.dbobj.db_is_active = True
if should_start: self.dbobj.save()
#print "... starting." self.at_start()
try: if self.dbobj.db_interval > 0:
self.is_active = True
self.at_start()
self._start_task() self._start_task()
return 1 return 1
except Exception: except Exception:
#print ".. error when starting" logger.log_trace()
logger.log_trace() self.dbobj.db_is_active = False
self.is_active = False self.dbobj.save()
return 0 return 0
else:
# avoid starting over.
#print "... Start cancelled (invalid start or already running)."
return 0 # this is used by validate() for counting started scripts
def stop(self, kill=False): def stop(self, kill=False):
""" """
Called to stop the script from running. Called to stop the script from running.
@ -136,18 +146,21 @@ class ScriptClass(TypeClass):
self.at_stop() self.at_stop()
except Exception: except Exception:
logger.log_trace() logger.log_trace()
if self.interval: if self.dbobj.db_interval > 0:
try: try:
self._stop_task() self._stop_task()
except Exception: except Exception:
pass pass
self.is_running = False
try: try:
self.delete() self.dbobj.delete()
except AssertionError: except AssertionError:
return 0 return 0
return 1 return 1
# hooks
def at_script_creation(self):
"placeholder"
pass
def is_valid(self): def is_valid(self):
"placeholder" "placeholder"
pass pass
@ -162,6 +175,153 @@ class ScriptClass(TypeClass):
pass pass
# class ScriptClassOld(TypeClass):
# """
# Base class for all Scripts.
# """
# # private methods for handling timers.
# def __eq__(self, other):
# """
# This has to be located at this level, having it in the
# parent doesn't work.
# """
# if other:
# return other.id == self.id
# return False
# def _start_task(self):
# "start the task runner."
# print "self_interval:", self.interval
# if self.interval > 0:
# #print "Starting task runner"
# start_now = not self.start_delay
# self.ndb.twisted_task = task.LoopingCall(self._step_task)
# self.ndb.twisted_task.start(self.interval, now=start_now)
# self.ndb.time_last_called = int(time())
# #self.save()
# def _stop_task(self):
# "stop the task runner"
# if hasattr(self.ndb, "twisted_task"):
# self.ndb.twisted_task.stop()
# def _step_task(self):
# "perform one repeat step of the script"
# #print "Stepping task runner (obj %s)" % id(self)
# #print "Has dbobj: %s" % hasattr(self, 'dbobj')
# if not self.is_valid():
# #the script is not valid anymore. Abort.
# self.stop()
# return
# try:
# self.at_repeat()
# if self.repeats:
# if self.repeats <= 1:
# self.stop()
# return
# else:
# self.repeats -= 1
# self.ndb.time_last_called = int(time())
# self.save()
# except Exception:
# logger.log_trace()
# self._stop_task()
# def time_until_next_repeat(self):
# """
# Returns the time in seconds until the script will be
# run again. If this is not a stepping script, returns None.
# This is not used in any way by the script's stepping
# system; it's only here for the user to be able to
# check in on their scripts and when they will next be run.
# """
# if self.interval and hasattr(self.ndb, 'time_last_called'):
# return max(0, (self.ndb.time_last_called + self.interval) - int(time()))
# else:
# return None
# def start(self, force_restart=False):
# """
# Called every time the script is started (for
# persistent scripts, this is usually once every server start)
# force_restart - if True, will always restart the script, regardless
# of if it has started before.
# """
# #print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
# # self.is_active, force_restart)
# if force_restart:
# self.is_active = False
# should_start = True
# if self.obj:
# try:
# #print "checking cmdset ... for obj", self.obj
# dummy = object.__getattribute__(self.obj, 'cmdset')
# #print "... checked cmdset"
# except AttributeError:
# #print "self.obj.cmdset not found. Setting is_active=False."
# self.is_active = False
# should_start = False
# if self.is_active and not force_restart:
# should_start = False
# if should_start:
# #print "... starting."
# try:
# self.is_active = True
# self.at_start()
# self._start_task()
# return 1
# except Exception:
# #print ".. error when starting"
# logger.log_trace()
# self.is_active = False
# return 0
# else:
# # avoid starting over.
# #print "... Start cancelled (invalid start or already running)."
# return 0 # this is used by validate() for counting started scripts
# def stop(self, kill=False):
# """
# Called to stop the script from running.
# This also deletes the script.
# kill - don't call finishing hooks.
# """
# #print "stopping script %s" % self.key
# if not kill:
# try:
# self.at_stop()
# except Exception:
# logger.log_trace()
# if self.interval:
# try:
# self._stop_task()
# except Exception:
# pass
# self.is_running = False
# try:
# self.delete()
# except AssertionError:
# return 0
# return 1
# def is_valid(self):
# "placeholder"
# pass
# def at_start(self):
# "placeholder."
# pass
# def at_stop(self):
# "placeholder"
# pass
# def at_repeat(self):
# "placeholder"
# pass
# #
# Base Script - inherit from this # Base Script - inherit from this
# #
@ -178,9 +338,9 @@ class Script(ScriptClass):
""" """
self.key = "<unnamed>" self.key = "<unnamed>"
self.desc = "" self.desc = ""
self.interval = 0 self.interval = 0 # infinite
self.start_delay = False self.start_delay = False
self.repeats = 0 self.repeats = 0 # infinite
self.persistent = False self.persistent = False
def is_valid(self): def is_valid(self):
@ -212,18 +372,17 @@ class Script(ScriptClass):
""" """
pass pass
# Some useful default Script types
# Some useful default Script types used by Evennia.
class DoNothing(Script): class DoNothing(Script):
"An script that does nothing. Used as default." "An script that does nothing. Used as default."
def at_script_creation(self): def at_script_creation(self):
"Setup the script" "Setup the script"
self.key = "sys_do_nothing" self.key = "sys_do_nothing"
self.desc = "This does nothing." self.desc = "This does nothing."
self.persistent = False
def is_valid(self):
"This script disables itself as soon as possible"
return False
class CheckSessions(Script): class CheckSessions(Script):
"Check sessions regularly." "Check sessions regularly."
@ -272,17 +431,9 @@ class ValidateChannelHandler(Script):
class AddCmdSet(Script): class AddCmdSet(Script):
""" """
This script permanently assigns a command set This script permanently assigns a command set
to an object. This is called automatically by the cmdhandler to an object whenever it is started. This is not
when an object is assigned a persistent cmdset. used by the core system anymore, it's here mostly
as an example.
To use, create this script, then assign to the two attributes
'cmdset' and 'add_default' as appropriate:
> from src.utils import create
> script = create.create_script('src.scripts.scripts.AddCmdSet')
> script.db.cmdset = 'game.gamesrc.commands.mycmdset.MyCmdSet'
> script.db.add_default = False
> obj.scripts.add(script)
""" """
def at_script_creation(self): def at_script_creation(self):
"Setup the script" "Setup the script"

View file

@ -291,6 +291,9 @@ class SessionBase(object):
if character: if character:
# normal operation. # normal operation.
character.execute_cmd(command_string) character.execute_cmd(command_string)
#import cProfile
#cProfile.runctx("character.execute_cmd(command_string)",
# {"command_string":command_string,"character":character}, {}, "execute_cmd.profile")
else: else:
if self.logged_in: if self.logged_in:
# there is no character, but we are logged in. Use player instead. # there is no character, but we are logged in. Use player instead.

View file

@ -629,6 +629,7 @@ class TypedObject(SharedMemoryModel):
cname = infochan.key cname = infochan.key
cmessage = "\n".join(["[%s]: %s" % (cname, line) for line in message.split('\n')]) cmessage = "\n".join(["[%s]: %s" % (cname, line) for line in message.split('\n')])
infochan.msg(message) infochan.msg(message)
logger.log_errmsg(cmessage)
else: else:
# no mudinfo channel is found. Log instead. # no mudinfo channel is found. Log instead.
cmessage = "\n".join(["[NO MUDINFO CHANNEL]: %s" % line for line in message.split('\n')]) cmessage = "\n".join(["[NO MUDINFO CHANNEL]: %s" % line for line in message.split('\n')])
@ -639,8 +640,8 @@ class TypedObject(SharedMemoryModel):
else: else:
logger.log_trace(cmessage) logger.log_trace(cmessage)
#path = self.db_typeclass_path
path = object.__getattribute__(self, 'db_typeclass_path') path = object.__getattribute__(self, 'db_typeclass_path')
#print "typeclass_loading:", id(self), path
errstring = "" errstring = ""
if not path: if not path:
@ -666,7 +667,7 @@ class TypedObject(SharedMemoryModel):
if callable(typeclass): if callable(typeclass):
# don't return yet, we must cache this further down. # don't return yet, we must cache this further down.
errstring = "" errstring = ""
break break # leave test loop
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
errstring += " to specify the actual typeclass name inside the module too." errstring += " to specify the actual typeclass name inside the module too."
@ -674,34 +675,32 @@ class TypedObject(SharedMemoryModel):
errstring += "\n%s" % typeclass # this will hold an error message. errstring += "\n%s" % typeclass # this will hold an error message.
if not callable(typeclass): if not callable(typeclass):
# Still not a valid import. Fallback to default. # Still not a valid import. Fallback to default.
# Note that we don't save to this changed path! Fix the typeclass
# definition instead.
defpath = object.__getattribute__(self, "default_typeclass_path") defpath = object.__getattribute__(self, "default_typeclass_path")
errstring += "\n\nUsing Default class '%s'." % defpath errstring += "\n\nUsing Default class '%s'." % defpath
self.db_typeclass_path = defpath
self.save()
logger.log_errmsg(errstring)
typeclass = object.__getattribute__(self, "_path_import")(defpath) typeclass = object.__getattribute__(self, "_path_import")(defpath)
errmsg(errstring) errmsg(errstring)
if not callable(typeclass): if not callable(typeclass):
# if typeclass still doesn't exist at this point, we're in trouble. # if typeclass still doesn't exist at this point, we're in trouble.
# fall back to hardcoded core class. # fall back to hardcoded core class which is wrong for e.g. scripts/players etc.
errstring = " %s\n%s" % (typeclass, errstring) errstring = " %s\n%s" % (typeclass, errstring)
errstring += " Default class '%s' failed to load." % defpath errstring += " Default class '%s' failed to load." % defpath
defpath = "src.objects.objects.Object" defpath = "src.objects.objects.Object"
errstring += "\n Using Evennia's default class '%s'." % defpath errstring += "\n Using Evennia's default class '%s'." % defpath
self.db_typeclass_path = defpath
self.save()
logger.log_errmsg(errstring)
typeclass = object.__getattribute__(self, "_path_import")(defpath) typeclass = object.__getattribute__(self, "_path_import")(defpath)
errmsg(errstring) errmsg(errstring)
else: else:
TYPECLASS_CACHE[path] = typeclass TYPECLASS_CACHE[path] = typeclass
return typeclass return typeclass
#@typeclass.deleter #@typeclass.deleter
def typeclass_del(self): def typeclass_del(self):
"Deleter. Allows for del self.typeclass (don't allow deletion)" "Deleter. Allows for del self.typeclass (don't allow deletion)"
raise Exception("The typeclass property should never be deleted!") raise Exception("The typeclass property should never be deleted!")
# typeclass property
typeclass = property(typeclass_get, fdel=typeclass_del) typeclass = property(typeclass_get, fdel=typeclass_del)

View file

@ -47,7 +47,7 @@ def create_object(typeclass, key=None, location=None,
from src.objects.models import ObjectDB from src.objects.models import ObjectDB
#print "in create_object", typeclass #print "in create_object", typeclass
if isinstance(typeclass, ObjectDB): if isinstance(typeclass, ObjectDB):
# this is already an object instance! # this is already an objectdb instance!
new_db_object = typeclass new_db_object = typeclass
typeclass = new_db_object.typeclass typeclass = new_db_object.typeclass
elif isinstance(typeclass, Object): elif isinstance(typeclass, Object):
@ -147,11 +147,11 @@ 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 isinstance(typeclass, ScriptDB):
#print "this is already a script instance!", typeclass, typeclass.__class__ #print "this is already a scriptdb instance!"
new_db_object = typeclass new_db_object = typeclass
typeclass = new_db_object.typeclass typeclass = new_db_object.typeclass
elif isinstance(typeclass, Script): elif isinstance(typeclass, Script):
#print "this is already an object typeclass!" #print "this is already an object typeclass!", typeclass, typeclass.__class__
new_db_object = typeclass.dbobj new_db_object = typeclass.dbobj
typeclass = typeclass.__class__ typeclass = typeclass.__class__
else: else:
@ -159,19 +159,18 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
new_db_object = ScriptDB() new_db_object = ScriptDB()
#new_db_object = ScriptDB() #new_db_object = ScriptDB()
if not callable(typeclass): if not callable(typeclass):
# try to load this in case it's a path # try to load this in case it's a path
if typeclass: if typeclass:
typeclass = utils.to_unicode(typeclass) typeclass = utils.to_unicode(typeclass)
new_db_object.typeclass_path = typeclass new_db_object.db_typeclass_path = typeclass
new_db_object.save() new_db_object.save()
# this will load either the typeclass or the default one # this will load either the typeclass or the default one
typeclass = new_db_object.typeclass typeclass = new_db_object.typeclass
new_db_object.save() new_db_object.save()
# the typeclass is initialized # the typeclass is initialized
new_script = typeclass(new_db_object) new_script = typeclass(new_db_object)
# store variables on the typeclass (which means # store variables on the typeclass (which means
# it's actually transparently stored on the db object) # it's actually transparently stored on the db object)
if not key: if not key:
if typeclass and hasattr(typeclass, '__name__'): if typeclass and hasattr(typeclass, '__name__'):
@ -200,7 +199,6 @@ 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()
return new_script return new_script
# #