Update scripts command, Scripts documentation

This commit is contained in:
Griatch 2021-03-07 17:41:48 +01:00
parent b5195a6e96
commit e1762c8b2f
9 changed files with 386 additions and 318 deletions

View file

@ -3059,7 +3059,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
attach a script to an object
Usage:
script[/switch] <obj> [= script_path or <scriptkey>]
addscript[/switch] <obj> [= script_path or <scriptkey>]
Switches:
start - start all non-running scripts on object, or a given script only
@ -3074,8 +3074,8 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
the object.
"""
key = "script"
aliases = "addscript"
key = "addscript"
aliases = ["attachscript"]
switch_options = ("start", "stop")
locks = "cmd:perm(script) or perm(Builder)"
help_category = "Building"

View file

@ -460,7 +460,7 @@ class ScriptEvMore(EvMore):
rept = "-/-"
table.add_row(
script.id,
f"#{script.id}",
f"{script.obj.key}({script.obj.dbref})"
if (hasattr(script, "obj") and script.obj)
else "<Global>",
@ -477,15 +477,19 @@ class ScriptEvMore(EvMore):
class CmdScripts(COMMAND_DEFAULT_CLASS):
"""
list and manage all running scripts
List and manage all running scripts. Allows for creating new global
scripts.
Usage:
scripts[/switches] [#dbref, key, script.path or <obj>]
script[/switches] [#dbref, key, script.path or <obj>]
Switches:
start - start a script (must supply a script path)
stop - stops an existing script
kill - kills a script - without running its cleanup hooks
create - create a new global script of given typeclass path. This will
auto-start the script's timer if it has one.
start - start/unpause an existing script's timer.
stop - stops an existing script's timer
pause - pause a script's timer
delete - deletes script. This will also stop the timer as needed
If no switches are given, this command just views all active
scripts. The argument can be either an object, at which point it
@ -493,76 +497,100 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
or #dbref. For using the /stop switch, a unique script #dbref is
required since whole classes of scripts often have the same name.
Use script for managing commands on objects.
Use the `script` build-level command for managing scripts attached to
objects.
"""
key = "scripts"
aliases = ["globalscript", "listscripts"]
switch_options = ("start", "stop", "kill")
aliases = ["scripts"]
switch_options = ("create", "start", "stop", "pause", "delete")
locks = "cmd:perm(listscripts) or perm(Admin)"
help_category = "System"
excluded_typeclass_paths = ["evennia.prototypes.prototypes.DbPrototype"]
switch_mapping = {
"create": "|gCreated|n",
"start": "|gStarted|n",
"stop": "|RStopped|n",
"pause": "|Paused|n",
"delete": "|rDeleted|n"
}
def _search_script(self, args):
# test first if this is a script match
scripts = ScriptDB.objects.get_all_scripts(key=args)
if scripts:
return scripts
# try typeclass path
scripts = ScriptDB.objects.filter(db_typeclass_path__iendswith=args)
if scripts:
return scripts
# try to find an object instead.
objects = ObjectDB.objects.object_search(args)
if objects:
scripts = ScriptDB.objects.filter(db_obj__in=objects)
return scripts
def func(self):
"""implement method"""
caller = self.caller
args = self.args
if args:
if "start" in self.switches:
# global script-start mode
new_script = create.create_script(args)
if new_script:
caller.msg("Global script %s was started successfully." % args)
else:
caller.msg("Global script %s could not start correctly. See logs." % args)
if "create" in self.switches:
# global script-start mode
verb = self.switch_mapping['create']
if not args:
caller.msg("Usage script/create <key or typeclass>")
return
# test first if this is a script match
scripts = ScriptDB.objects.get_all_scripts(key=args)
if not scripts:
# try to find an object instead.
objects = ObjectDB.objects.object_search(args)
if objects:
scripts = []
for obj in objects:
# get all scripts on the object(s)
scripts.extend(ScriptDB.objects.get_all_scripts_on_obj(obj))
else:
# we want all scripts.
scripts = ScriptDB.objects.get_all_scripts()
if not scripts:
caller.msg("No scripts are running.")
return
# filter any found scripts by tag category.
scripts = scripts.exclude(db_typeclass_path__in=self.excluded_typeclass_paths)
if not scripts:
string = "No scripts found with a key '%s', or on an object named '%s'." % (args, args)
caller.msg(string)
new_script = create.create_script(args)
if new_script:
caller.msg(f"Global Script {verb} - {new_script.key} ({new_script.typeclass_path})")
ScriptEvMore(caller, [new_script], session=self.session)
else:
caller.msg(f"Global Script |rNOT|n {verb} |r(see log)|n - arguments: {args}")
return
if self.switches and self.switches[0] in ("stop", "del", "delete", "kill"):
# we want to delete something
if len(scripts) == 1:
# we have a unique match!
if "kill" in self.switches:
string = "Killing script '%s'" % scripts[0].key
scripts[0].stop(kill=True)
else:
string = "Stopping script '%s'." % scripts[0].key
scripts[0].stop()
# import pdb # DEBUG
# pdb.set_trace() # DEBUG
caller.msg(string)
else:
# multiple matches.
ScriptEvMore(caller, scripts, session=self.session)
caller.msg("Multiple script matches. Please refine your search")
# all other switches require existing scripts
if args:
scripts = self._search_script(args)
if not scripts:
caller.msg(f"No scripts found matching '{args}'.")
return
else:
# No stopping or validation. We just want to view things.
scripts = ScriptDB.objects.all()
if not scripts:
caller.msg("No scripts found.")
return
if args and self.switches:
# global script-modifying mode
if scripts.count() > 1:
caller.msg("Multiple script matches. Please refine your search.")
return
script = scripts[0]
script_key = script.key
script_typeclass_path = script.typeclass_path
for switch in self.switches:
verb = self.switch_mapping[switch]
msgs = []
try:
getattr(script, switch)()
except Exception:
logger.log_trace()
msgs.append(f"Global Script |rNOT|n {verb} |r(see log)|n - "
f"{script_key} ({script_typeclass_path})|n")
else:
msgs.append(f"Global Script {verb} - "
f"{script_key} ({script_typeclass_path})")
caller.msg("\n".join(msgs))
if "delete" not in self.switches:
ScriptEvMore(caller, [script], session=self.session)
return
else:
# simply show the found scripts
ScriptEvMore(caller, scripts.order_by("id"), session=self.session)

View file

@ -515,19 +515,8 @@ class ScriptBase(ScriptDB, metaclass=TypeclassBase):
"""
self._start_task(interval=interval, start_delay=start_delay, repeats=repeats, **kwargs)
def update(self, interval=None, start_delay=None, repeats=None, **kwargs):
"""
Update the Script's timer component with new settings.
Keyword Args:
interval (int): How often to fire `at_repeat` in seconds.
start_delay (int): If the start of ticking should be delayed.
repeats (int): How many repeats. 0 for infinite repeats.
**kwargs: Optional (default unused) kwargs passed on into the `at_start` hook.
"""
self._start_task(interval=interval, start_delay=start_delay,
repeats=repeats, force_restart=True, **kwargs)
# legacy alias
update = start
def stop(self, **kwargs):
"""

View file

@ -1083,9 +1083,8 @@ def repeat(interval, callback, persistent=True, idstring="", stop=False,
Returns:
tuple or None: This is the `store_key` - the identifier for the created ticker.
Store this and pass into unrepat() in order to to stop this ticker
later. It this lost you need to stop the ticker via TICKER_HANDLER.remove
by supplying all the same arguments
directly. No return if `stop=True`
later. It this lost you need to stop the ticker via `TICKER_HANDLER.remove`
by supplying all the same arguments directly. No return if `stop=True`
Raises:
KeyError: If trying to stop a ticker that was not found.