Add support for all creation kwargs to GLOBAL_SCRIPT setting. Resolve #2373

This commit is contained in:
Griatch 2021-08-06 20:31:01 +02:00
parent 2c3fd143cc
commit 3f436a5bb2
2 changed files with 110 additions and 101 deletions

View file

@ -366,7 +366,9 @@ There are two ways to make a script appear as a property on `GLOBAL_SCRIPTS`:
1. Manually create a new global script with a `key` using `create_script`. 1. Manually create a new global script with a `key` using `create_script`.
2. Define the script's properties in the `GLOBAL_SCRIPTS` settings variable. This tells Evennia 2. Define the script's properties in the `GLOBAL_SCRIPTS` settings variable. This tells Evennia
that it should check if a script with that `key` exists and if not, create it for you. that it should check if a script with that `key` exists and if not, create it for you.
This is very useful for scripts that must always exist and/or should be auto-created with your server. This is very useful for scripts that must always exist and/or should be auto-created
when your server restarts. If you use this method, you must make sure all
script keys are globally unique.
Here's how to tell Evennia to manage the script in settings: Here's how to tell Evennia to manage the script in settings:
@ -383,6 +385,7 @@ GLOBAL_SCRIPTS = {
"storagescript": {} "storagescript": {}
} }
``` ```
Above we add two scripts with keys `myscript` and `storagescript`respectively. The following dict Above we add two scripts with keys `myscript` and `storagescript`respectively. The following dict
can be empty - the `settings.BASE_SCRIPT_TYPECLASS` will then be used. Under the hood, the provided can be empty - the `settings.BASE_SCRIPT_TYPECLASS` will then be used. Under the hood, the provided
dict (along with the `key`) will be passed into `create_script` automatically, so dict (along with the `key`) will be passed into `create_script` automatically, so

View file

@ -11,6 +11,7 @@ evennia.OPTION_CLASSES
""" """
from pickle import dumps
from django.conf import settings from django.conf import settings
from evennia.utils.utils import class_from_module, callables_from_module from evennia.utils.utils import class_from_module, callables_from_module
from evennia.utils import logger from evennia.utils import logger
@ -132,37 +133,42 @@ class GlobalScriptContainer(Container):
self.load_data() self.load_data()
typeclass = self.typeclass_storage[key] typeclass = self.typeclass_storage[key]
found = typeclass.objects.filter(db_key=key).first() script = typeclass.objects.filter(
interval = self.loaded_data[key].get("interval", None) db_key=key, db_account__isnull=True, db_obj__isnull=True).first()
start_delay = self.loaded_data[key].get("start_delay", None)
repeats = self.loaded_data[key].get("repeats", 0)
desc = self.loaded_data[key].get("desc", "")
if not found: kwargs = {**self.loaded_data[key]}
kwargs['key'] = key
kwargs['persistent'] = kwargs.get('persistent', True)
compare_hash = str(dumps(kwargs, protocol=4))
if script:
script_hash = script.attributes.get("global_script_settings", category="settings_hash")
if script_hash is None:
# legacy - store the hash anew and assume no change
script.attributes.add("global_script_settings", compare_hash,
category="settings_hash")
elif script_hash != compare_hash:
# wipe the old version and create anew
logger.log_info(f"GLOBAL_SCRIPTS: Settings changed for {key} ({typeclass}).")
script.stop()
script.delete()
script = None
if not script:
logger.log_info(f"GLOBAL_SCRIPTS: (Re)creating {key} ({typeclass}).") logger.log_info(f"GLOBAL_SCRIPTS: (Re)creating {key} ({typeclass}).")
new_script, errors = typeclass.create(
key=key, script, errors = typeclass.create(**kwargs)
persistent=True,
interval=interval,
start_delay=start_delay,
repeats=repeats,
desc=desc,
)
if errors: if errors:
logger.log_err("\n".join(errors)) logger.log_err("\n".join(errors))
return None return None
new_script.start() # store a hash representation of the setup
return new_script script.attributes.add("_global_script_settings",
compare_hash, category="settings_hash")
script.start()
if ((found.interval != interval) return script
or (found.start_delay != start_delay)
or (found.repeats != repeats)):
# the setup changed
found.start(interval=interval, start_delay=start_delay, repeats=repeats)
if found.desc != desc:
found.desc = desc
return found
def start(self): def start(self):
""" """