OBS: You need to resync your database! Moved cmdsets into the database rather than being dependent on scripts. Moved the creation of the cmdset- and cmdset-handlers into ObjectDB.__init__ rather than bootstrapping it from the typeclass. Added some more script functionality for testing, includong the @script command for assigning a script to an object.
This commit is contained in:
parent
e965830735
commit
126e2ea61f
17 changed files with 370 additions and 216 deletions
62
game/gamesrc/scripts/examples/bodyfunctions.py
Normal file
62
game/gamesrc/scripts/examples/bodyfunctions.py
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
"""
|
||||||
|
Example script for testing. This adds a simple timer that
|
||||||
|
has your character make observations and noices at irregular
|
||||||
|
intervals.
|
||||||
|
|
||||||
|
To test, use
|
||||||
|
@script me = examples.bodyfunctions.BodyFunctions
|
||||||
|
|
||||||
|
The script will only send messages to the object it
|
||||||
|
is stored on, so make sure to put it on yourself
|
||||||
|
or you won't see any messages!
|
||||||
|
|
||||||
|
"""
|
||||||
|
import random
|
||||||
|
from game.gamesrc.scripts.basescript import Script
|
||||||
|
|
||||||
|
|
||||||
|
class BodyFunctions(Script):
|
||||||
|
"""
|
||||||
|
This class defines the script itself
|
||||||
|
"""
|
||||||
|
|
||||||
|
def at_script_creation(self):
|
||||||
|
self.key = "bodyfunction"
|
||||||
|
self.desc = "Adds various timed events to a character."
|
||||||
|
self.interval = 20 # seconds
|
||||||
|
self.start_delay # wait self.interval until first call
|
||||||
|
self.persistent = False
|
||||||
|
|
||||||
|
def at_repeat(self):
|
||||||
|
"""
|
||||||
|
This gets called every self.interval seconds. We make
|
||||||
|
a random check here so as to only return 30% of the time.
|
||||||
|
"""
|
||||||
|
if random.random() > 0.66:
|
||||||
|
# no message this time
|
||||||
|
return
|
||||||
|
rand = random.random()
|
||||||
|
# return a random message
|
||||||
|
if rand < 0.1:
|
||||||
|
string = "You tap your foot, looking around."
|
||||||
|
elif rand < 0.2:
|
||||||
|
string = "You have an itch. Hard to reach too."
|
||||||
|
elif rand < 0.3:
|
||||||
|
string = "You think you hear someone behind you. ... but when you look there's noone there."
|
||||||
|
elif rand < 0.4:
|
||||||
|
string = "You inspect your fingernails. Nothing to report."
|
||||||
|
elif rand < 0.5:
|
||||||
|
string = "You cough discreetly into your hand."
|
||||||
|
elif rand < 0.6:
|
||||||
|
string = "You scratch your head, looking around."
|
||||||
|
elif rand < 0.7:
|
||||||
|
string = "You blink, forgetting what it was you were going to do."
|
||||||
|
elif rand < 0.8:
|
||||||
|
string = "You feel lonely all of a sudden."
|
||||||
|
elif rand < 0.9:
|
||||||
|
string = "You get a great idea. Of course you won't tell anyone."
|
||||||
|
else:
|
||||||
|
string = "You suddenly realize how much you love Evennia!"
|
||||||
|
|
||||||
|
# echo the message to the object
|
||||||
|
self.obj.msg(string)
|
||||||
|
|
@ -114,10 +114,7 @@ def get_and_merge_cmdsets(caller):
|
||||||
local_objlist = location.contents + caller.contents
|
local_objlist = location.contents + caller.contents
|
||||||
local_objects_cmdsets = [obj.cmdset.current
|
local_objects_cmdsets = [obj.cmdset.current
|
||||||
for obj in local_objlist
|
for obj in local_objlist
|
||||||
if obj.cmdset.outside_access]
|
if obj.locks.check(caller, 'call', no_superuser_bypass=True)]
|
||||||
# print "used objs: %s" % ([obj.name
|
|
||||||
# for obj in local_objlist
|
|
||||||
# if obj.cmdset.outside_access])
|
|
||||||
|
|
||||||
# Merge all command sets into one
|
# Merge all command sets into one
|
||||||
# (the order matters, the higher-prio cmdsets are merged last)
|
# (the order matters, the higher-prio cmdsets are merged last)
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,7 @@ the 'Fishing' set. Fishing from a boat? No problem!
|
||||||
"""
|
"""
|
||||||
import traceback
|
import traceback
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils import create
|
|
||||||
from src.commands.cmdset import CmdSet
|
from src.commands.cmdset import CmdSet
|
||||||
from src.scripts.scripts import AddCmdSet
|
|
||||||
|
|
||||||
CACHED_CMDSETS = {}
|
CACHED_CMDSETS = {}
|
||||||
|
|
||||||
|
|
@ -128,7 +126,7 @@ def import_cmdset(python_path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||||
|
|
||||||
class CmdSetHandler(object):
|
class CmdSetHandler(object):
|
||||||
"""
|
"""
|
||||||
The CmdSetHandler is always stored on an object, supplied as the argument.
|
The CmdSetHandler is always stored on an object, this object is supplied as an argument.
|
||||||
|
|
||||||
The 'current' cmdset is the merged set currently active for this object.
|
The 'current' cmdset is the merged set currently active for this object.
|
||||||
This is the set the game engine will retrieve when determining which
|
This is the set the game engine will retrieve when determining which
|
||||||
|
|
@ -137,35 +135,29 @@ class CmdSetHandler(object):
|
||||||
the 'current' cmdset.
|
the 'current' cmdset.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, obj, outside_access=True):
|
def __init__(self, obj):
|
||||||
"""
|
"""
|
||||||
This method is called whenever an object is recreated.
|
This method is called whenever an object is recreated.
|
||||||
|
|
||||||
obj - this is a reference to the game object this handler
|
obj - this is a reference to the game object this handler
|
||||||
belongs to.
|
belongs to.
|
||||||
outside_access - if false, the cmdparser will only retrieve
|
|
||||||
this cmdset when it is its obj itself that is calling for it.
|
|
||||||
(this is is good to use for player objects, since they
|
|
||||||
should not have access to the cmdsets of other player
|
|
||||||
objects).
|
|
||||||
"""
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
# if false, only the object itself may use this handler
|
|
||||||
# (this should be set especially by character objects)
|
|
||||||
self.outside_access = outside_access
|
|
||||||
|
|
||||||
# the id of the "merged" current cmdset for easy access.
|
# the id of the "merged" current cmdset for easy access.
|
||||||
self.key = None
|
self.key = None
|
||||||
# this holds the "merged" current command set
|
# this holds the "merged" current command set
|
||||||
self.current = None
|
self.current = None
|
||||||
# this holds a history of CommandSets
|
# this holds a history of CommandSets
|
||||||
self.cmdset_stack = [CmdSet(cmdsetobj=self.obj, key="Empty")]
|
self.cmdset_stack = [CmdSet(cmdsetobj=self.obj, key="Empty")]
|
||||||
# this tracks which mergetypes are actually in play in the stack
|
# this tracks which mergetypes are actually in play in the stack
|
||||||
self.mergetype_stack = ["Union"]
|
self.mergetype_stack = ["Union"]
|
||||||
self.update()
|
|
||||||
|
|
||||||
#print "cmdsethandler init. id:%s, obj:%s, cmdsetstack:%s " % (id(self), self.obj.key, [cmdset.key for cmdset in self.cmdset_stack])
|
# the subset of the cmdset_paths that are to be stored in the database
|
||||||
|
self.permanent_paths = [""]
|
||||||
|
|
||||||
|
# self.update(init_mode=True) is then called from the object __init__.
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Display current commands"
|
"Display current commands"
|
||||||
|
|
||||||
|
|
@ -180,8 +172,8 @@ class CmdSetHandler(object):
|
||||||
if mergetype != cmdset.mergetype:
|
if mergetype != cmdset.mergetype:
|
||||||
mergetype = "%s^" % (mergetype)
|
mergetype = "%s^" % (mergetype)
|
||||||
string += "\n %i: <%s (%s, prio %i)>: %s" % \
|
string += "\n %i: <%s (%s, prio %i)>: %s" % \
|
||||||
(snum, cmdset.key, mergetype,
|
(snum, cmdset.key, mergetype,
|
||||||
cmdset.priority, cmdset)
|
cmdset.priority, cmdset)
|
||||||
string += "\n (combining %i cmdsets):" % (num+1)
|
string += "\n (combining %i cmdsets):" % (num+1)
|
||||||
else:
|
else:
|
||||||
string += "\n "
|
string += "\n "
|
||||||
|
|
@ -195,22 +187,40 @@ class CmdSetHandler(object):
|
||||||
mergetype, self.current)
|
mergetype, self.current)
|
||||||
return string.strip()
|
return string.strip()
|
||||||
|
|
||||||
def update(self):
|
def update(self, init_mode=False):
|
||||||
"""
|
"""
|
||||||
Re-adds all sets in the handler to have an updated
|
Re-adds all sets in the handler to have an updated
|
||||||
current set.
|
current set.
|
||||||
|
|
||||||
|
init_mode is used right after this handler was
|
||||||
|
created; it imports all permanent cmdsets from db.
|
||||||
"""
|
"""
|
||||||
updated = None
|
if init_mode:
|
||||||
|
self.cmdset_stack = []
|
||||||
|
# reimport all permanent cmdsets
|
||||||
|
self.permanent_paths = self.obj.cmdset_storage
|
||||||
|
new_permanent_paths = []
|
||||||
|
|
||||||
|
for pos, path in enumerate(self.permanent_paths):
|
||||||
|
if pos == 0 and not path:
|
||||||
|
self.cmdset_stack = [CmdSet(cmdsetobj=self.obj, key="Empty")]
|
||||||
|
else:
|
||||||
|
cmdset = self.import_cmdset(path)
|
||||||
|
if cmdset:
|
||||||
|
self.cmdset_stack.append(cmdset)
|
||||||
|
|
||||||
|
# merge the stack into a new merged cmdset
|
||||||
|
new_current = None
|
||||||
self.mergetype_stack = []
|
self.mergetype_stack = []
|
||||||
for cmdset in self.cmdset_stack:
|
for cmdset in self.cmdset_stack:
|
||||||
try:
|
try:
|
||||||
# for cmdset's '+' operator, order matters.
|
# for cmdset's '+' operator, order matters.
|
||||||
updated = cmdset + updated
|
new_current = cmdset + new_current
|
||||||
except TypeError:
|
except TypeError:
|
||||||
continue
|
continue
|
||||||
self.mergetype_stack.append(updated.actual_mergetype)
|
self.mergetype_stack.append(new_current.actual_mergetype)
|
||||||
self.current = updated
|
self.current = new_current
|
||||||
|
|
||||||
def import_cmdset(self, cmdset_path, emit_to_obj=None):
|
def import_cmdset(self, cmdset_path, emit_to_obj=None):
|
||||||
"""
|
"""
|
||||||
load a cmdset from a module.
|
load a cmdset from a module.
|
||||||
|
|
@ -247,23 +257,17 @@ class CmdSetHandler(object):
|
||||||
cmdset = cmdset(self.obj)
|
cmdset = cmdset(self.obj)
|
||||||
elif isinstance(cmdset, basestring):
|
elif isinstance(cmdset, basestring):
|
||||||
# this is (maybe) a python path. Try to import from cache.
|
# this is (maybe) a python path. Try to import from cache.
|
||||||
cmdset = self.import_cmdset(cmdset, emit_to_obj)
|
cmdset = self.import_cmdset(cmdset)#, emit_to_obj)
|
||||||
if cmdset:
|
if cmdset:
|
||||||
self.cmdset_stack.append(cmdset)
|
self.cmdset_stack.append(cmdset)
|
||||||
|
if permanent:
|
||||||
|
# store the path permanently
|
||||||
|
self.permanent_paths.append(cmdset.path)
|
||||||
|
self.obj.cmdset_storage = self.permanent_paths
|
||||||
|
else:
|
||||||
|
# store an empty entry and don't save (this makes it easy to delete).
|
||||||
|
self.permanent_paths.append("")
|
||||||
self.update()
|
self.update()
|
||||||
if permanent:
|
|
||||||
# create a script to automatically add this cmdset at
|
|
||||||
# startup. We don't start it here since the cmdset was
|
|
||||||
# already added above.
|
|
||||||
try:
|
|
||||||
cmdset = "%s.%s" % (cmdset.__module__, cmdset.__name__)
|
|
||||||
except Exception:
|
|
||||||
logger.log_trace()
|
|
||||||
return
|
|
||||||
script = create.create_script(AddCmdSet)
|
|
||||||
script.db.cmdset = cmdset
|
|
||||||
script.db.add_default = False
|
|
||||||
self.obj.scripts.add(script, autostart=False)
|
|
||||||
|
|
||||||
def add_default(self, cmdset, emit_to_obj=None, permanent=False):
|
def add_default(self, cmdset, emit_to_obj=None, permanent=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -281,70 +285,74 @@ class CmdSetHandler(object):
|
||||||
cmdset = cmdset(self.obj)
|
cmdset = cmdset(self.obj)
|
||||||
elif isinstance(cmdset, basestring):
|
elif isinstance(cmdset, basestring):
|
||||||
# this is (maybe) a python path. Try to import from cache.
|
# this is (maybe) a python path. Try to import from cache.
|
||||||
cmdset = self.import_cmdset(cmdset, emit_to_obj)
|
cmdset = self.import_cmdset(cmdset)
|
||||||
if cmdset:
|
if cmdset:
|
||||||
self.cmdset_stack[0] = cmdset
|
if self.cmdset_stack:
|
||||||
self.mergetype_stack[0] = cmdset.mergetype
|
self.cmdset_stack[0] = cmdset
|
||||||
self.update()
|
self.mergetype_stack.insert[0] = cmdset.mergetype
|
||||||
#print "add_default:", permanent
|
else:
|
||||||
if permanent:
|
self.cmdset_stack = [cmdset]
|
||||||
# create a script to automatically add this cmdset at
|
self.mergetype_stack = cmdset.mergetype
|
||||||
# startup. We don't start it here since the cmdset was
|
|
||||||
# already added above.
|
if permanent:
|
||||||
try:
|
if self.permanent_paths:
|
||||||
cmdset = "%s.%s" % (cmdset.__module__, cmdset.__class__.__name__)
|
self.permanent_paths[0] = cmdset.path
|
||||||
except Exception:
|
else:
|
||||||
#print traceback.format_exc()
|
self.permanent_paths = [cmdset.path]
|
||||||
logger.log_trace()
|
self.obj.cmdset_storage = self.permanent_paths
|
||||||
return
|
else:
|
||||||
#print "cmdset to add:", cmdset
|
if self.permanent_paths:
|
||||||
script = create.create_script(AddCmdSet)
|
self.permanent_paths[0] = ""
|
||||||
script.db.cmdset = cmdset
|
else:
|
||||||
script.db.add_default = True
|
self.permanent_paths = [""]
|
||||||
self.obj.scripts.add(script, key="add_default_cmdset", autostart=False)
|
self.update()
|
||||||
|
|
||||||
def delete(self, key_or_class=None):
|
def delete(self, cmdset=None):
|
||||||
"""
|
"""
|
||||||
Remove a cmdset from the handler. If a key is supplied,
|
Remove a cmdset from the handler.
|
||||||
it attempts to remove this. If no key is given,
|
|
||||||
|
cmdset can be supplied either as a cmdset-key,
|
||||||
|
an instance of the CmdSet or a python path
|
||||||
|
to the cmdset. If no key is given,
|
||||||
the last cmdset in the stack is removed. Whenever
|
the last cmdset in the stack is removed. Whenever
|
||||||
the cmdset_stack changes, the cmdset is updated.
|
the cmdset_stack changes, the cmdset is updated.
|
||||||
The default cmdset (first entry in stack) is never
|
The default cmdset (first entry in stack) is never
|
||||||
removed - remove it explicitly with delete_default.
|
removed - remove it explicitly with delete_default.
|
||||||
|
|
||||||
key_or_class - a specific cmdset key or a cmdset class (in
|
|
||||||
the latter case, *all* cmdsets of this class
|
|
||||||
will be removed from handler!)
|
|
||||||
"""
|
"""
|
||||||
if len(self.cmdset_stack) < 2:
|
if len(self.cmdset_stack) < 2:
|
||||||
# don't allow deleting default cmdsets here.
|
# don't allow deleting default cmdsets here.
|
||||||
return
|
return
|
||||||
|
|
||||||
if not key_or_class:
|
if not cmdset:
|
||||||
# remove the last one in the stack (except the default position)
|
# remove the last one in the stack (except the default position)
|
||||||
self.cmdset_stack.pop()
|
self.cmdset_stack.pop()
|
||||||
else:
|
self.permanent_paths.pop()
|
||||||
# argument key is given, is it a key or a class?
|
else:
|
||||||
|
# try it as a callable
|
||||||
default_cmdset = self.cmdset_stack[0]
|
if callable(cmdset) and hasattr(cmdset, 'path'):
|
||||||
|
indices = [i+1 for i, cset in enumerate(self.cmdset_stack[1:]) if cset.path == cmdset.path]
|
||||||
if callable(key_or_class) and hasattr(key_or_class, '__name__'):
|
|
||||||
# this is a callable with __name__ - we assume it's a class
|
|
||||||
self.cmdset_stack = [cmdset for cmdset in self.cmdset_stack[1:]
|
|
||||||
if cmdset.__class__.__name__ != key_or_class.__name__]
|
|
||||||
else:
|
else:
|
||||||
# try it as a string
|
# try it as a path or key
|
||||||
self.cmdset_stack = [cmdset for cmdset in self.cmdset_stack[1:]
|
indices = [i+1 for i, cset in enumerate(self.cmdset_stack[1:]) if cset.path == cmdset or cset.key == cmdset]
|
||||||
if cmdset.key != key_or_class]
|
|
||||||
|
for i in indices:
|
||||||
self.cmdset_stack.insert(0, default_cmdset)
|
del self.cmdset_stack[i]
|
||||||
|
del self.permanent_paths[i]
|
||||||
|
self.obj.cmdset_storage = self.permanent_paths
|
||||||
|
|
||||||
# re-sync the cmdsethandler.
|
# re-sync the cmdsethandler.
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def delete_default(self):
|
def delete_default(self):
|
||||||
"This explicitly deletes the default cmdset. It's the only command that can."
|
"This explicitly deletes the default cmdset. It's the only command that can."
|
||||||
self.cmdset_stack[0] = CmdSet(cmdsetobj=self.obj, key="Empty")
|
if self.cmdset_stack:
|
||||||
|
self.cmdset_stack[0] = CmdSet(cmdsetobj=self.obj, key="Empty")
|
||||||
|
self.permanent_paths[0] = ""
|
||||||
|
else:
|
||||||
|
self.cmdset_stack = [CmdSet(cmdsetobj=self.obj, key="Empty")]
|
||||||
|
self.permanent_paths = [""]
|
||||||
|
self.obj.cmdset_storage = self.permanent_paths
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def all(self):
|
def all(self):
|
||||||
|
|
@ -360,6 +368,8 @@ class CmdSetHandler(object):
|
||||||
"""
|
"""
|
||||||
self.cmdset_stack = [self.cmdset_stack[0]]
|
self.cmdset_stack = [self.cmdset_stack[0]]
|
||||||
self.mergetype_stack = [self.cmdset_stack[0].mergetype]
|
self.mergetype_stack = [self.cmdset_stack[0].mergetype]
|
||||||
|
self.permanent_paths[0] = [self.permanent_paths[0]]
|
||||||
|
self.obj.cmdset_storage = self.permanent_paths
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
|
|
||||||
|
|
@ -750,6 +750,40 @@ class CmdLink(MuxCommand):
|
||||||
# give feedback
|
# give feedback
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
class CmdUnLink(CmdLink):
|
||||||
|
"""
|
||||||
|
@unlink - unconnect objects
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
@unlink <Object>
|
||||||
|
|
||||||
|
Unlinks an object, for example an exit, disconnecting
|
||||||
|
it from whatever it was connected to.
|
||||||
|
"""
|
||||||
|
# this is just a child of CmdLink
|
||||||
|
|
||||||
|
key = "@unlink"
|
||||||
|
locks = "cmd:perm(unlink) or perm(Builders)"
|
||||||
|
help_key = "Building"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""
|
||||||
|
All we need to do here is to set the right command
|
||||||
|
and call func in CmdLink
|
||||||
|
"""
|
||||||
|
|
||||||
|
caller = self.caller
|
||||||
|
|
||||||
|
if not self.args:
|
||||||
|
caller.msg("Usage: @unlink <object>")
|
||||||
|
return
|
||||||
|
|
||||||
|
# This mimics '@link <obj> = ' which is the same as @unlink
|
||||||
|
self.rhs = ""
|
||||||
|
|
||||||
|
# call the @link functionality
|
||||||
|
super(CmdUnLink, self).func()
|
||||||
|
|
||||||
|
|
||||||
class CmdListCmdSets(MuxCommand):
|
class CmdListCmdSets(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1585,36 +1619,67 @@ class CmdTeleport(MuxCommand):
|
||||||
caller.msg("Teleported.")
|
caller.msg("Teleported.")
|
||||||
|
|
||||||
|
|
||||||
class CmdUnLink(CmdLink):
|
class CmdScript(MuxCommand):
|
||||||
"""
|
"""
|
||||||
@unlink - unconnect objects
|
attach scripts
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@unlink <Object>
|
@script[/switch] <obj> = <script.path or scriptkey>
|
||||||
|
|
||||||
|
Switches:
|
||||||
|
start - start a previously added script
|
||||||
|
stop - stop a previously added script
|
||||||
|
|
||||||
Unlinks an object, for example an exit, disconnecting
|
Attaches the given script to the object and starts it. Script path can be given
|
||||||
it from whatever it was connected to.
|
from the base location for scripts as given in settings.
|
||||||
|
If stopping/starting an already existing script, the script's key
|
||||||
|
can be given instead (if giving a path, *all* scripts with this path
|
||||||
|
on <obj> will be affected).
|
||||||
"""
|
"""
|
||||||
# this is just a child of CmdLink
|
|
||||||
|
key = "@script"
|
||||||
|
aliases = "@addscript"
|
||||||
|
|
||||||
key = "@unlink"
|
locks = "cmd:perm(script) or perm(Wizards)"
|
||||||
locks = "cmd:perm(unlink) or perm(Builders)"
|
|
||||||
help_key = "Building"
|
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"""
|
"Do stuff"
|
||||||
All we need to do here is to set the right command
|
|
||||||
and call func in CmdLink
|
|
||||||
"""
|
|
||||||
|
|
||||||
caller = self.caller
|
|
||||||
|
|
||||||
if not self.args:
|
|
||||||
caller.msg("Usage: @unlink <object>")
|
|
||||||
return
|
|
||||||
|
|
||||||
# This mimics '@link <obj> = ' which is the same as @unlink
|
caller = self.caller
|
||||||
self.rhs = ""
|
|
||||||
|
if not self.rhs:
|
||||||
|
string = "Usage: @script[/switch] <obj> = <script.path or script key>"
|
||||||
|
caller.msg(string)
|
||||||
|
return
|
||||||
|
|
||||||
# call the @link functionality
|
inp = self.rhs
|
||||||
super(CmdUnLink, self).func()
|
if not inp.startswith('src.') and not inp.startswith('game.'):
|
||||||
|
# append the default path.
|
||||||
|
inp = "%s.%s" % (settings.BASE_SCRIPT_PATH, inp)
|
||||||
|
|
||||||
|
obj = caller.search(self.lhs)
|
||||||
|
if not obj:
|
||||||
|
return
|
||||||
|
string = ""
|
||||||
|
if "stop" in self.switches:
|
||||||
|
# we are stopping an already existing script
|
||||||
|
ok = obj.scripts.stop(inp)
|
||||||
|
if not ok:
|
||||||
|
string = "Script %s could not be stopped. Does it exist?" % inp
|
||||||
|
else:
|
||||||
|
string = "Script stopped and removed from object."
|
||||||
|
if "start" in self.switches:
|
||||||
|
# we are starting an already existing script
|
||||||
|
ok = obj.scripts.start(inp)
|
||||||
|
if not ok:
|
||||||
|
string = "Script %s could not be (re)started." % inp
|
||||||
|
else:
|
||||||
|
string = "Script started successfully."
|
||||||
|
if not self.switches:
|
||||||
|
# adding a new script, and starting it
|
||||||
|
ok = obj.scripts.add(inp, autostart=True)
|
||||||
|
if not ok:
|
||||||
|
string = "Script %s could not be added." % inp
|
||||||
|
else:
|
||||||
|
string = "Script successfully added and started."
|
||||||
|
caller.msg(string)
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ class DefaultCmdSet(CmdSet):
|
||||||
self.add(building.CmdExamine())
|
self.add(building.CmdExamine())
|
||||||
self.add(building.CmdTypeclass())
|
self.add(building.CmdTypeclass())
|
||||||
self.add(building.CmdLock())
|
self.add(building.CmdLock())
|
||||||
|
self.add(building.CmdScript())
|
||||||
|
|
||||||
# Comm commands
|
# Comm commands
|
||||||
self.add(comms.CmdAddCom())
|
self.add(comms.CmdAddCom())
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ class CmdPy(MuxCommand):
|
||||||
Usage:
|
Usage:
|
||||||
@py <cmd>
|
@py <cmd>
|
||||||
|
|
||||||
In this limited python environment.
|
In this limited python environment, there are a
|
||||||
|
few variables made available to give access to
|
||||||
|
the system.
|
||||||
|
|
||||||
available_vars: 'self','me' : caller
|
available_vars: 'self','me' : caller
|
||||||
'here' : caller.location
|
'here' : caller.location
|
||||||
|
|
@ -82,7 +84,7 @@ class CmdPy(MuxCommand):
|
||||||
'ConfigValue' ConfigValue class
|
'ConfigValue' ConfigValue class
|
||||||
only two
|
only two
|
||||||
variables are defined: 'self'/'me' which refers to one's
|
variables are defined: 'self'/'me' which refers to one's
|
||||||
own object, and 'here' which refers to the current
|
own object, and 'here' which refers to self's current
|
||||||
location.
|
location.
|
||||||
"""
|
"""
|
||||||
key = "@py"
|
key = "@py"
|
||||||
|
|
@ -102,10 +104,11 @@ class CmdPy(MuxCommand):
|
||||||
return
|
return
|
||||||
# create temporary test objects for playing with
|
# create temporary test objects for playing with
|
||||||
script = create.create_script("src.scripts.scripts.DoNothing",
|
script = create.create_script("src.scripts.scripts.DoNothing",
|
||||||
'testscript')
|
key = 'testscript')
|
||||||
obj = create.create_object("src.objects.objects.Object",
|
obj = create.create_object("src.objects.objects.Object",
|
||||||
'testobject')
|
key='testobject')
|
||||||
conf = ConfigValue() # used to access conf values
|
conf = ConfigValue() # used to access conf values
|
||||||
|
|
||||||
available_vars = {'self':caller,
|
available_vars = {'self':caller,
|
||||||
'me':caller,
|
'me':caller,
|
||||||
'here':caller.location,
|
'here':caller.location,
|
||||||
|
|
@ -131,7 +134,10 @@ class CmdPy(MuxCommand):
|
||||||
ret = "\n".join("<<< %s" % line for line in errlist if line)
|
ret = "\n".join("<<< %s" % line for line in errlist if line)
|
||||||
caller.msg(ret)
|
caller.msg(ret)
|
||||||
obj.delete()
|
obj.delete()
|
||||||
script.delete()
|
try:
|
||||||
|
script.delete()
|
||||||
|
except AssertionError: # this is a strange thing; the script looses its id somehow..?
|
||||||
|
pass
|
||||||
|
|
||||||
class CmdScripts(MuxCommand):
|
class CmdScripts(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ class LockHandler(object):
|
||||||
"""
|
"""
|
||||||
self.reset_flag = True
|
self.reset_flag = True
|
||||||
|
|
||||||
def check(self, accessing_obj, access_type, default=False):
|
def check(self, accessing_obj, access_type, default=False, no_superuser_bypass=False):
|
||||||
"""
|
"""
|
||||||
Checks a lock of the correct type by passing execution
|
Checks a lock of the correct type by passing execution
|
||||||
off to the lock function(s).
|
off to the lock function(s).
|
||||||
|
|
@ -295,14 +295,17 @@ class LockHandler(object):
|
||||||
accessing_obj - the object seeking access
|
accessing_obj - the object seeking access
|
||||||
access_type - the type of access wanted
|
access_type - the type of access wanted
|
||||||
default - if no suitable lock type is found, use this
|
default - if no suitable lock type is found, use this
|
||||||
|
no_superuser_bypass - don't use this unless you really, really need to
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.reset_flag:
|
if self.reset_flag:
|
||||||
# rebuild cache
|
# rebuild cache
|
||||||
self._cache_locks(self.obj.lock_storage)
|
self._cache_locks(self.obj.lock_storage)
|
||||||
self.reset_flag = False
|
self.reset_flag = False
|
||||||
|
|
||||||
if (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) \
|
if (not no_superuser_bypass and (hasattr(accessing_obj, 'player')
|
||||||
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser)):
|
and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
||||||
|
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))):
|
||||||
# we grant access to superusers and also to protocol instances that not yet has any player assigned to them (the
|
# we grant access to superusers and also to protocol instances that not yet has any player assigned to them (the
|
||||||
# latter is a safety feature since superuser cannot be authenticated at some point during the connection).
|
# latter is a safety feature since superuser cannot be authenticated at some point during the connection).
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ from src.typeclasses.models import Attribute, TypedObject
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.objects.manager import ObjectManager
|
from src.objects.manager import ObjectManager
|
||||||
from src.config.models import ConfigValue
|
from src.config.models import ConfigValue
|
||||||
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
|
from src.scripts.scripthandler import ScriptHandler
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils.utils import is_iter
|
from src.utils.utils import is_iter
|
||||||
|
|
||||||
|
|
@ -216,18 +217,24 @@ class ObjectDB(TypedObject):
|
||||||
# a safety location, this usually don't change much.
|
# a safety location, this usually don't change much.
|
||||||
db_home = models.ForeignKey('self', related_name="homes_set",
|
db_home = models.ForeignKey('self', related_name="homes_set",
|
||||||
blank=True, null=True)
|
blank=True, null=True)
|
||||||
|
# database storage of persistant cmdsets.
|
||||||
|
db_cmdset_storage = models.TextField(null=True)
|
||||||
|
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = ObjectManager()
|
objects = ObjectManager()
|
||||||
|
|
||||||
# Add the object-specific handlers
|
# Add the object-specific handlers
|
||||||
# (scripts and cmdset must be added from
|
|
||||||
# typeclass, so not added here)
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"Parent must be initialized first."
|
"Parent must be initialized first."
|
||||||
TypedObject.__init__(self, *args, **kwargs)
|
TypedObject.__init__(self, *args, **kwargs)
|
||||||
|
# handlers
|
||||||
|
self.cmdset = CmdSetHandler(self)
|
||||||
|
self.cmdset.update(init_mode=True)
|
||||||
|
self.scripts = ScriptHandler(self)
|
||||||
|
self.scripts.validate(init_mode=True)
|
||||||
self.nicks = NickHandler(self)
|
self.nicks = NickHandler(self)
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# Wrapper properties to easily set database fields. These are
|
||||||
# @property decorators that allows to access these fields using
|
# @property decorators that allows to access these fields using
|
||||||
# normal python operations (without having to remember to save()
|
# normal python operations (without having to remember to save()
|
||||||
|
|
@ -381,6 +388,28 @@ class ObjectDB(TypedObject):
|
||||||
query.delete()
|
query.delete()
|
||||||
aliases = property(aliases_get, aliases_set, aliases_del)
|
aliases = property(aliases_get, aliases_set, aliases_del)
|
||||||
|
|
||||||
|
# cmdset_storage property
|
||||||
|
#@property
|
||||||
|
def cmdset_storage_get(self):
|
||||||
|
"Getter. Allows for value = self.name. Returns a list of cmdset_storage."
|
||||||
|
if self.db_cmdset_storage:
|
||||||
|
return [path.strip() for path in self.db_cmdset_storage.split(',')]
|
||||||
|
return []
|
||||||
|
#@cmdset_storage.setter
|
||||||
|
def cmdset_storage_set(self, value):
|
||||||
|
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
||||||
|
if is_iter(value):
|
||||||
|
value = ",".join([str(val).strip() for val in value])
|
||||||
|
self.db_cmdset_storage = value
|
||||||
|
self.save()
|
||||||
|
#@cmdset_storage.deleter
|
||||||
|
def cmdset_storage_del(self):
|
||||||
|
"Deleter. Allows for del self.name"
|
||||||
|
self.db_cmdset_storage = ""
|
||||||
|
self.save()
|
||||||
|
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
verbose_name = "Object"
|
verbose_name = "Object"
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,9 @@ That an object is controlled by a player/user is just defined by its
|
||||||
they control by simply linking to a new object's user property.
|
they control by simply linking to a new object's user property.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
|
||||||
from src.scripts.scripthandler import ScriptHandler
|
|
||||||
from src.objects.exithandler import EXITHANDLER
|
from src.objects.exithandler import EXITHANDLER
|
||||||
from src.utils import utils
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base class to inherit from.
|
# Base class to inherit from.
|
||||||
|
|
@ -33,33 +30,6 @@ class Object(TypeClass):
|
||||||
objects in the game.
|
objects in the game.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, dbobj):
|
|
||||||
"""
|
|
||||||
Set up the Object-specific handlers. Note that we must
|
|
||||||
be careful to run the parent's init function too
|
|
||||||
or typeclasses won't work!
|
|
||||||
"""
|
|
||||||
# initialize typeclass system. This sets up self.dbobj.
|
|
||||||
super(Object, self).__init__(dbobj)
|
|
||||||
# create the command- and scripthandlers as needed
|
|
||||||
try:
|
|
||||||
dummy = object.__getattribute__(dbobj, 'cmdset')
|
|
||||||
create_cmdset = type(dbobj.cmdset) != CmdSetHandler
|
|
||||||
except AttributeError:
|
|
||||||
create_cmdset = True
|
|
||||||
try:
|
|
||||||
dummy = object.__getattribute__(dbobj, 'scripts')
|
|
||||||
create_scripts = type(dbobj.scripts) != ScriptHandler
|
|
||||||
except AttributeError:
|
|
||||||
create_scripts = True
|
|
||||||
|
|
||||||
if create_cmdset:
|
|
||||||
dbobj.cmdset = CmdSetHandler(dbobj)
|
|
||||||
if utils.inherits_from(self, settings.BASE_CHARACTER_TYPECLASS) or utils.inherits_from(self, Character):
|
|
||||||
dbobj.cmdset.outside_access = False
|
|
||||||
if create_scripts:
|
|
||||||
dbobj.scripts = ScriptHandler(dbobj)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
This has be located at this level, having it in the
|
This has be located at this level, having it in the
|
||||||
|
|
@ -87,11 +57,12 @@ class Object(TypeClass):
|
||||||
|
|
||||||
dbref = self.dbobj.dbref
|
dbref = self.dbobj.dbref
|
||||||
|
|
||||||
self.locks.add("control:id(%s) or perm(Immortals)" % dbref)
|
self.locks.add("control:id(%s) or perm(Immortals)" % dbref) # edit locks/permissions, delete
|
||||||
self.locks.add("examine:perm(Builders)")
|
self.locks.add("examine:perm(Builders)") # examine properties
|
||||||
self.locks.add("edit:perm(Wizards)")
|
self.locks.add("edit:perm(Wizards)") # edit properties/attributes
|
||||||
self.locks.add("delete:perm(Wizards)")
|
self.locks.add("delete:perm(Wizards)") # delete object
|
||||||
self.locks.add("get:all()")
|
self.locks.add("get:all()") # pick up object
|
||||||
|
self.locks.add("call:true()") # allow to call commands on this object
|
||||||
|
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -341,11 +312,15 @@ class Character(Object):
|
||||||
Setup character-specific security
|
Setup character-specific security
|
||||||
"""
|
"""
|
||||||
super(Character, self).basetype_setup()
|
super(Character, self).basetype_setup()
|
||||||
self.locks.add("puppet:id(%s) or perm(Immortals); get:false()" % self.dbobj.dbref)
|
self.locks.add("puppet:id(%s) or perm(Immortals)" % self.dbobj.dbref) # who may become this object's player
|
||||||
|
self.locks.add("get:false()") # noone can pick up the character
|
||||||
|
self.locks.add("call:false()") # no commands can be called on character
|
||||||
|
|
||||||
# add the default cmdset
|
# add the default cmdset
|
||||||
from settings import CMDSET_DEFAULT
|
from settings import CMDSET_DEFAULT
|
||||||
self.cmdset.add_default(CMDSET_DEFAULT, permanent=True)
|
self.cmdset.add_default(CMDSET_DEFAULT, permanent=True)
|
||||||
|
# no other character should be able to call commands on the Character.
|
||||||
|
self.cmdset.outside_access = False
|
||||||
|
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -399,11 +374,12 @@ class Exit(Object):
|
||||||
"""
|
"""
|
||||||
# the lock is open to all by default
|
# the lock is open to all by default
|
||||||
super(Exit, self).basetype_setup()
|
super(Exit, self).basetype_setup()
|
||||||
self.locks.add("traverse:all(); get:false()")
|
self.locks.add("traverse:all()") # who can pass through exit
|
||||||
|
self.locks.add("get:false()") # noone can pick up the exit
|
||||||
|
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"""
|
"""
|
||||||
Another example just for show; the _destination attribute
|
An example just for show; the _destination attribute
|
||||||
is usually set at creation time, not as part of the class
|
is usually set at creation time, not as part of the class
|
||||||
definition (unless you want an entire class of exits
|
definition (unless you want an entire class of exits
|
||||||
all leadning to the same hard-coded place ...)
|
all leadning to the same hard-coded place ...)
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@ class ScriptManager(TypedObjectManager):
|
||||||
return []
|
return []
|
||||||
scripts = self.filter(db_obj=obj)
|
scripts = self.filter(db_obj=obj)
|
||||||
if key:
|
if key:
|
||||||
return [script for script in scripts if script.key == key]
|
return scripts.filter(db_key=key)
|
||||||
return scripts
|
return scripts
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_all_scripts(self, key=None):
|
def get_all_scripts(self, key=None):
|
||||||
"""
|
"""
|
||||||
Return all scripts, alternative only
|
Return all scripts, alternative only
|
||||||
scripts with a certain key/dbref.
|
scripts with a certain key/dbref or path.
|
||||||
"""
|
"""
|
||||||
if key:
|
if key:
|
||||||
dbref = self.dbref(key)
|
dbref = self.dbref(key)
|
||||||
|
|
@ -39,7 +39,7 @@ class ScriptManager(TypedObjectManager):
|
||||||
# not a dbref. Normal key search
|
# not a dbref. Normal key search
|
||||||
scripts = self.filter(db_key=key)
|
scripts = self.filter(db_key=key)
|
||||||
else:
|
else:
|
||||||
scripts = self.all()
|
scripts = list(self.all())
|
||||||
return scripts
|
return scripts
|
||||||
|
|
||||||
def delete_script(self, dbref):
|
def delete_script(self, dbref):
|
||||||
|
|
@ -120,7 +120,7 @@ class ScriptManager(TypedObjectManager):
|
||||||
elif obj:
|
elif obj:
|
||||||
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
scripts = self.get_all_scripts_on_obj(obj, key=key)
|
||||||
else:
|
else:
|
||||||
scripts = self.get_all_scripts(key=key)
|
scripts = self.model.get_all_cached_instances()#get_all_scripts(key=key)
|
||||||
if not scripts:
|
if not scripts:
|
||||||
VALIDATE_ITERATION -= 1
|
VALIDATE_ITERATION -= 1
|
||||||
return None, None
|
return None, None
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from src.typeclasses.models import Attribute, TypedObject
|
from src.typeclasses.models import Attribute, TypedObject
|
||||||
from src.scripts.manager import ScriptManager
|
from src.scripts.manager import ScriptManager
|
||||||
#from src.locks.lockhandler import LockHandler
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -24,22 +24,6 @@ class ScriptHandler(object):
|
||||||
"""
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|
||||||
# this is required to stop a nasty loop in some situations that
|
|
||||||
# has the handler infinitely recursively re-added to its object.
|
|
||||||
self.obj.scripts = self
|
|
||||||
|
|
||||||
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
|
||||||
#print "starting scripthandler. %s has scripts %s" % (self.obj, scripts)
|
|
||||||
if scripts:
|
|
||||||
okscripts = [script for script in scripts if script.persistent == True]
|
|
||||||
delscripts = [script for script in scripts if script not in okscripts]
|
|
||||||
for script in delscripts:
|
|
||||||
#print "stopping script %s" % script
|
|
||||||
script.stop()
|
|
||||||
for script in okscripts:
|
|
||||||
#print "starting script %s" % script
|
|
||||||
script.start()
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"List the scripts tied to this object"
|
"List the scripts tied to this object"
|
||||||
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
||||||
|
|
@ -72,39 +56,51 @@ class ScriptHandler(object):
|
||||||
script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=autostart)
|
script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=autostart)
|
||||||
if not script:
|
if not script:
|
||||||
logger.log_errmsg("Script %s failed to be created/start." % scriptclass)
|
logger.log_errmsg("Script %s failed to be created/start." % scriptclass)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def start(self, scriptkey):
|
def start(self, scriptid):
|
||||||
"""
|
"""
|
||||||
Find an already added script and force-start it
|
Find an already added script and force-start it
|
||||||
"""
|
"""
|
||||||
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptkey)
|
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
||||||
|
num = 0
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
script.start()
|
num += script.start()
|
||||||
|
return num
|
||||||
|
|
||||||
def delete(self, scriptkey):
|
def delete(self, scriptid):
|
||||||
"""
|
"""
|
||||||
Forcibly delete a script from this object.
|
Forcibly delete a script from this object.
|
||||||
|
|
||||||
|
scriptid can be a script key or the path to a script (in the
|
||||||
|
latter case all scripts with this path will be deleted!)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptkey)
|
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
||||||
|
if not delscripts:
|
||||||
|
delscripts = [script for script in ScriptDB.objects.get_all_scripts_on_obj(self.obj) if script.path == scriptid]
|
||||||
|
num = 0
|
||||||
for script in delscripts:
|
for script in delscripts:
|
||||||
script.stop()
|
num += script.stop()
|
||||||
|
return num
|
||||||
|
|
||||||
def stop(self, scriptkey):
|
def stop(self, scriptid):
|
||||||
"""
|
"""
|
||||||
Alias for delete.
|
Alias for delete. scriptid can be a script key or a script path string.
|
||||||
"""
|
"""
|
||||||
self.delete(scriptkey)
|
return self.delete(scriptid)
|
||||||
|
|
||||||
def all(self, scriptkey=None):
|
def all(self, scriptid=None):
|
||||||
"""
|
"""
|
||||||
Get all scripts stored in the handler, alternatively all matching a key.
|
Get all scripts stored in the handler, alternatively all matching a key.
|
||||||
"""
|
"""
|
||||||
return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptkey)
|
return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self, init_mode=False):
|
||||||
"""
|
"""
|
||||||
Runs a validation on this object's scripts only.
|
Runs a validation on this object's scripts only.
|
||||||
This should be called regularly to crank the wheels.
|
This should be called regularly to crank the wheels.
|
||||||
"""
|
"""
|
||||||
ScriptDB.objects.validate(obj=self.obj)
|
ScriptDB.objects.validate(obj=self.obj, init_mode=init_mode)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,8 @@ class ScriptClass(TypeClass):
|
||||||
try:
|
try:
|
||||||
self.delete()
|
self.delete()
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
pass
|
return 0
|
||||||
|
return 1
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
"placeholder"
|
"placeholder"
|
||||||
|
|
|
||||||
|
|
@ -753,7 +753,8 @@ class TypedObject(SharedMemoryModel):
|
||||||
for nattr in self.ndb.all():
|
for nattr in self.ndb.all():
|
||||||
del nattr
|
del nattr
|
||||||
|
|
||||||
# run hook for this new typeclass
|
# run hooks for this new typeclass
|
||||||
|
new_typeclass.basetype_setup()
|
||||||
new_typeclass.at_object_creation()
|
new_typeclass.at_object_creation()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,13 @@ class MetaTypeClass(type):
|
||||||
printed in a nicer way (it might end up having no name at all
|
printed in a nicer way (it might end up having no name at all
|
||||||
otherwise due to the magics being done with get/setattribute).
|
otherwise due to the magics being done with get/setattribute).
|
||||||
"""
|
"""
|
||||||
|
def __init__(mcs, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Adds some features to typeclassed objects
|
||||||
|
"""
|
||||||
|
super(MetaTypeClass, mcs).__init__(*args, **kwargs)
|
||||||
|
mcs.path = "%s.%s" % (mcs.__module__, mcs.__name__)
|
||||||
|
|
||||||
def __str__(cls):
|
def __str__(cls):
|
||||||
return "%s" % cls.__name__
|
return "%s" % cls.__name__
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,13 +170,13 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
|
||||||
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 key:
|
|
||||||
new_db_object.name = key
|
|
||||||
else:
|
if not key:
|
||||||
if typeclass and hasattr(typeclass, '__name__'):
|
if typeclass and hasattr(typeclass, '__name__'):
|
||||||
new_db_object.name = "%s" % typeclass.__name__
|
new_script.key = "%s" % typeclass.__name__
|
||||||
else:
|
else:
|
||||||
new_db_object.name = "#%i" % new_db_object.id
|
new_script.key = "#%i" % new_db_object.id
|
||||||
|
|
||||||
# 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
|
||||||
|
|
@ -184,6 +184,9 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
|
||||||
new_script.at_script_creation()
|
new_script.at_script_creation()
|
||||||
|
|
||||||
# custom-given variables override the hook
|
# custom-given variables override the hook
|
||||||
|
if key:
|
||||||
|
new_script.key = key
|
||||||
|
|
||||||
if locks:
|
if locks:
|
||||||
new_script.locks.add(locks)
|
new_script.locks.add(locks)
|
||||||
|
|
||||||
|
|
@ -191,12 +194,9 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
|
||||||
try:
|
try:
|
||||||
new_script.obj = obj
|
new_script.obj = obj
|
||||||
except ValueError:
|
except ValueError:
|
||||||
new_script.obj = obj.dbobj
|
new_script.obj = obj.dbobj
|
||||||
|
|
||||||
new_script.save()
|
|
||||||
|
|
||||||
# a new created script should always be started, so
|
# a new created script should usually be started.
|
||||||
# we do this now.
|
|
||||||
if autostart:
|
if autostart:
|
||||||
new_script.start()
|
new_script.start()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ def start_reload_loop():
|
||||||
def run_loop():
|
def run_loop():
|
||||||
""
|
""
|
||||||
cemit_info('-'*50)
|
cemit_info('-'*50)
|
||||||
cemit_info(" Starting asynchronous server reload ...")
|
cemit_info(" Starting asynchronous server reload.")
|
||||||
reload_modules() # this must be given time to finish
|
reload_modules() # this must be given time to finish
|
||||||
|
|
||||||
wait_time = 5
|
wait_time = 5
|
||||||
cemit_info(" Wait for %ss to give modules time to fully re-cache ..." % wait_time)
|
cemit_info(" Waiting %ss to give modules time to fully re-cache ..." % wait_time)
|
||||||
time.sleep(wait_time)
|
time.sleep(wait_time)
|
||||||
|
|
||||||
reload_scripts()
|
reload_scripts()
|
||||||
|
|
@ -90,7 +90,7 @@ def reload_modules():
|
||||||
"Check so modpath is not in an unsafe module"
|
"Check so modpath is not in an unsafe module"
|
||||||
return not any(mpath.startswith(modpath) for mpath in unsafe_modules)
|
return not any(mpath.startswith(modpath) for mpath in unsafe_modules)
|
||||||
|
|
||||||
cemit_info("\n Cleaning module caches ...")
|
cemit_info(" Cleaning module caches ...")
|
||||||
|
|
||||||
# clean as much of the caches as we can
|
# clean as much of the caches as we can
|
||||||
cache = AppCache()
|
cache = AppCache()
|
||||||
|
|
@ -149,15 +149,15 @@ def reload_scripts(scripts=None, obj=None, key=None,
|
||||||
cleaned out. All persistent scripts are force-started.
|
cleaned out. All persistent scripts are force-started.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
cemit_info(" Validating scripts ...")
|
|
||||||
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=init_mode)
|
||||||
|
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)
|
||||||
cemit_info(string)
|
cemit_info(string)
|
||||||
|
|
||||||
def reload_commands():
|
def reload_commands():
|
||||||
from src.commands import cmdsethandler
|
from src.commands import cmdsethandler
|
||||||
|
|
@ -170,12 +170,13 @@ def reset_loop():
|
||||||
cemit_info(" Running resets on database entities ...")
|
cemit_info(" Running resets on database entities ...")
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
|
|
||||||
[s.locks.reset() for s in ScriptDB.objects.all()]
|
|
||||||
[p.locks.reset() for p in PlayerDB.objects.all()]
|
|
||||||
[h.locks.reset() for h in HelpEntry.objects.all()]
|
[h.locks.reset() for h in HelpEntry.objects.all()]
|
||||||
[m.locks.reset() for m in Msg.objects.all()]
|
[m.locks.reset() for m in Msg.objects.all()]
|
||||||
[c.locks.reset() for c in Channel.objects.all()]
|
[c.locks.reset() for c in Channel.objects.all()]
|
||||||
|
[s.locks.reset() for s in ScriptDB.objects.all()]
|
||||||
|
[p.locks.reset() for p in PlayerDB.objects.all()]
|
||||||
[(o.typeclass(o), o.cmdset.reset(), o.locks.reset()) for o in ObjectDB.get_all_cached_instances()]
|
[(o.typeclass(o), o.cmdset.reset(), o.locks.reset()) for o in ObjectDB.get_all_cached_instances()]
|
||||||
|
|
||||||
t2 = time.time()
|
t2 = time.time()
|
||||||
cemit_info(" ... Loop finished in %g seconds." % (t2-t1))
|
cemit_info(" ... Loop finished in %g seconds." % (t2-t1))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue