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:
parent
dae375d1c4
commit
6cb2b8b745
12 changed files with 301 additions and 141 deletions
|
|
@ -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")]
|
||||||
|
|
|
||||||
|
|
@ -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.")
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue