evennia/docs/0.x/_modules/evennia/scripts/scripts.html
2023-12-20 19:10:09 +01:00

822 lines
No EOL
84 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.scripts.scripts &#8212; Evennia 0.9.5 documentation</title>
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<script src="../../../_static/language_data.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
<link rel="shortcut icon" href="../../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.scripts.scripts</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.scripts.scripts</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">This module defines Scripts, out-of-character entities that can store</span>
<span class="sd">data both on themselves and on other objects while also having the</span>
<span class="sd">ability to run timers.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">twisted.internet.defer</span> <span class="kn">import</span> <span class="n">Deferred</span><span class="p">,</span> <span class="n">maybeDeferred</span>
<span class="kn">from</span> <span class="nn">twisted.internet.task</span> <span class="kn">import</span> <span class="n">LoopingCall</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ObjectDoesNotExist</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">from</span> <span class="nn">evennia.typeclasses.models</span> <span class="kn">import</span> <span class="n">TypeclassBase</span>
<span class="kn">from</span> <span class="nn">evennia.scripts.models</span> <span class="kn">import</span> <span class="n">ScriptDB</span>
<span class="kn">from</span> <span class="nn">evennia.scripts.manager</span> <span class="kn">import</span> <span class="n">ScriptManager</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span><span class="p">,</span> <span class="n">logger</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;DefaultScript&quot;</span><span class="p">,</span> <span class="s2">&quot;DoNothing&quot;</span><span class="p">,</span> <span class="s2">&quot;Store&quot;</span><span class="p">]</span>
<span class="n">FLUSHING_INSTANCES</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># whether we&#39;re in the process of flushing scripts from the cache</span>
<span class="n">SCRIPT_FLUSH_TIMERS</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># stores timers for scripts that are currently being flushed</span>
<span class="k">def</span> <span class="nf">restart_scripts_after_flush</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;After instances are flushed, validate scripts so they&#39;re not dead for a long period of time&quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">FLUSHING_INSTANCES</span>
<span class="n">ScriptDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">validate</span><span class="p">()</span>
<span class="n">FLUSHING_INSTANCES</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">class</span> <span class="nc">ExtendedLoopingCall</span><span class="p">(</span><span class="n">LoopingCall</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> LoopingCall that can start at a delay different</span>
<span class="sd"> than `self.interval`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">start_delay</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">callcount</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interval</span><span class="p">,</span> <span class="n">now</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">start_delay</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">count_start</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Start running function every interval seconds.</span>
<span class="sd"> This overloads the LoopingCall default by offering the</span>
<span class="sd"> start_delay keyword and ability to repeat.</span>
<span class="sd"> Args:</span>
<span class="sd"> interval (int): Repeat interval in seconds.</span>
<span class="sd"> now (bool, optional): Whether to start immediately or after</span>
<span class="sd"> `start_delay` seconds.</span>
<span class="sd"> start_delay (int): The number of seconds before starting.</span>
<span class="sd"> If None, wait interval seconds. Only valid if `now` is `False`.</span>
<span class="sd"> It is used as a way to start with a variable start time</span>
<span class="sd"> after a pause.</span>
<span class="sd"> count_start (int): Number of repeats to start at. The count</span>
<span class="sd"> goes up every time the system repeats. This is used to</span>
<span class="sd"> implement something repeating `N` number of times etc.</span>
<span class="sd"> Raises:</span>
<span class="sd"> AssertError: if trying to start a task which is already running.</span>
<span class="sd"> ValueError: If interval is set to an invalid value &lt; 0.</span>
<span class="sd"> Notes:</span>
<span class="sd"> As opposed to Twisted&#39;s inbuilt count mechanism, this</span>
<span class="sd"> system will count also if force_repeat() was called rather</span>
<span class="sd"> than just the number of `interval` seconds since the start.</span>
<span class="sd"> This allows us to force-step through a limited number of</span>
<span class="sd"> steps if we want.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">running</span><span class="p">,</span> <span class="s2">&quot;Tried to start an already running ExtendedLoopingCall.&quot;</span>
<span class="k">if</span> <span class="n">interval</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;interval must be &gt;= 0&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">deferred</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_deferred</span> <span class="o">=</span> <span class="n">Deferred</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">starttime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="o">.</span><span class="n">seconds</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="n">interval</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_runAtStart</span> <span class="o">=</span> <span class="n">now</span>
<span class="bp">self</span><span class="o">.</span><span class="n">callcount</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">count_start</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span> <span class="o">=</span> <span class="n">start_delay</span> <span class="k">if</span> <span class="n">start_delay</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">start_delay</span><span class="p">)</span>
<span class="k">if</span> <span class="n">now</span><span class="p">:</span>
<span class="c1"># run immediately</span>
<span class="bp">self</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">start_delay</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">start_delay</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># start after some time: for this to work we need to</span>
<span class="c1"># trick _scheduleFrom by temporarily setting a different</span>
<span class="c1"># self.interval for it to check.</span>
<span class="n">real_interval</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span><span class="p">,</span> <span class="n">start_delay</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_scheduleFrom</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">starttime</span><span class="p">)</span>
<span class="c1"># re-set the actual interval (this will be picked up</span>
<span class="c1"># next time it runs</span>
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="n">real_interval</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_scheduleFrom</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">starttime</span><span class="p">)</span>
<span class="k">return</span> <span class="n">deferred</span>
<span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Tick one step. We update callcount (tracks number of calls) as</span>
<span class="sd"> well as null start_delay (needed in order to correctly</span>
<span class="sd"> estimate next_call_time at all times).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">callcount</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">starttime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="o">.</span><span class="n">seconds</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_deferred</span><span class="p">:</span>
<span class="n">LoopingCall</span><span class="o">.</span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">force_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Force-fire the callback</span>
<span class="sd"> Raises:</span>
<span class="sd"> AssertionError: When trying to force a task that is not</span>
<span class="sd"> running.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">running</span><span class="p">,</span> <span class="s2">&quot;Tried to fire an ExtendedLoopingCall that was not running.&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">starttime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="o">.</span><span class="n">seconds</span><span class="p">()</span>
<span class="bp">self</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">next_call_time</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the next call time. This also takes the eventual effect</span>
<span class="sd"> of start_delay into account.</span>
<span class="sd"> Returns:</span>
<span class="sd"> next (int or None): The time in seconds until the next call. This</span>
<span class="sd"> takes `start_delay` into account. Returns `None` if</span>
<span class="sd"> the task is not running.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">running</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">total_runtime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="o">.</span><span class="n">seconds</span><span class="p">()</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">starttime</span>
<span class="n">interval</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span>
<span class="k">return</span> <span class="n">interval</span> <span class="o">-</span> <span class="p">(</span><span class="n">total_runtime</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">ScriptBase</span><span class="p">(</span><span class="n">ScriptDB</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">TypeclassBase</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Base class for scripts. Don&#39;t inherit from this, inherit from the</span>
<span class="sd"> class `DefaultScript` below instead.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">objects</span> <span class="o">=</span> <span class="n">ScriptManager</span><span class="p">()</span>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;&lt;</span><span class="si">{cls}</span><span class="s2"> </span><span class="si">{key}</span><span class="s2">&gt;&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_start_task</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Start task runner.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span> <span class="o">=</span> <span class="n">ExtendedLoopingCall</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_step_task</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span><span class="p">:</span>
<span class="c1"># the script was paused; restarting</span>
<span class="n">callcount</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_callcount</span> <span class="ow">or</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">start</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span><span class="p">,</span> <span class="n">now</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">start_delay</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span><span class="p">,</span> <span class="n">count_start</span><span class="o">=</span><span class="n">callcount</span>
<span class="p">)</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_repeats</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="c1"># starting script anew</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span><span class="p">,</span> <span class="n">now</span><span class="o">=</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_start_delay</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_stop_task</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Stop task runner</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span> <span class="ow">and</span> <span class="n">task</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="n">task</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">_step_errback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Callback for runner errors</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span>
<span class="n">estring</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Script </span><span class="si">%(key)s</span><span class="s2">(#</span><span class="si">%(dbid)s</span><span class="s2">) of type &#39;</span><span class="si">%(cname)s</span><span class="s2">&#39;: at_repeat() error &#39;</span><span class="si">%(err)s</span><span class="s2">&#39;.&quot;</span>
<span class="p">)</span> <span class="o">%</span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="s2">&quot;dbid&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbid</span><span class="p">,</span> <span class="s2">&quot;cname&quot;</span><span class="p">:</span> <span class="n">cname</span><span class="p">,</span> <span class="s2">&quot;err&quot;</span><span class="p">:</span> <span class="n">e</span><span class="o">.</span><span class="n">getErrorMessage</span><span class="p">()}</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">estring</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="c1"># we must not crash inside the errback, even if db_obj is None.</span>
<span class="k">pass</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="n">estring</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_step_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Step task runner. No try..except needed due to defer wrap.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="p">:</span>
<span class="c1"># if there is no task, we have no business using this method</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
<span class="k">return</span>
<span class="c1"># call hook</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_repeat</span><span class="p">()</span>
<span class="c1"># check repeats</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="p">:</span>
<span class="c1"># we need to check for the task in case stop() was called</span>
<span class="c1"># inside at_repeat() and it already went away.</span>
<span class="n">callcount</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">callcount</span>
<span class="n">maxcount</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_repeats</span>
<span class="k">if</span> <span class="n">maxcount</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">maxcount</span> <span class="o">&lt;=</span> <span class="n">callcount</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_step_task</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Step task. This groups error handling.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">maybeDeferred</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_step_callback</span><span class="p">)</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_step_errback</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Should be overridden in child.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">at_first_save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is called after very first time this object is saved.</span>
<span class="sd"> Generally, you don&#39;t need to overload this, but only the hooks</span>
<span class="sd"> called by this method.</span>
<span class="sd"> Args:</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_script_creation</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;_createdict&quot;</span><span class="p">):</span>
<span class="c1"># this will only be set if the utils.create_script</span>
<span class="c1"># function was used to create the object. We want</span>
<span class="c1"># the create call&#39;s kwargs to override the values</span>
<span class="c1"># set by hooks.</span>
<span class="n">cdict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_createdict</span>
<span class="n">updates</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_key</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_key</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbid</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_key&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_key</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_key</span> <span class="o">=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_key&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;interval&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;interval&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;interval&quot;</span><span class="p">])</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_interval&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;start_delay&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;start_delay&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_start_delay</span> <span class="o">=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;start_delay&quot;</span><span class="p">]</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_start_delay&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;repeats&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">repeats</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;repeats&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_repeats</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;repeats&quot;</span><span class="p">])</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_repeats&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;persistent&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">persistent</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;persistent&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_persistent</span> <span class="o">=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;persistent&quot;</span><span class="p">]</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_persistent&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">!=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;desc&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_desc</span> <span class="o">=</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;desc&quot;</span><span class="p">]</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;db_desc&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">updates</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">update_fields</span><span class="o">=</span><span class="n">updates</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;permissions&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">batch_add</span><span class="p">(</span><span class="o">*</span><span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;permissions&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;locks&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;locks&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;tags&quot;</span><span class="p">):</span>
<span class="c1"># this should be a list of tags, tuples (key, category) or (key, category, data)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">batch_add</span><span class="p">(</span><span class="o">*</span><span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;tags&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;attributes&quot;</span><span class="p">):</span>
<span class="c1"># this should be tuples (key, val, ...)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">batch_add</span><span class="p">(</span><span class="o">*</span><span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;attributes&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;nattributes&quot;</span><span class="p">):</span>
<span class="c1"># this should be a dict of nattrname:value</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;nattributes&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nattributes</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">cdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;autostart&quot;</span><span class="p">):</span>
<span class="c1"># don&#39;t auto-start the script</span>
<span class="k">return</span>
<span class="c1"># auto-start script (default)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<div class="viewcode-block" id="DefaultScript"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript">[docs]</a><span class="k">class</span> <span class="nc">DefaultScript</span><span class="p">(</span><span class="n">ScriptBase</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is the base TypeClass for all Scripts. Scripts describe</span>
<span class="sd"> events, timers and states in game, they can have a time component</span>
<span class="sd"> or describe a state that changes under certain conditions.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="DefaultScript.create"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.create">[docs]</a> <span class="nd">@classmethod</span>
<span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Provides a passthrough interface to the utils.create_script() function.</span>
<span class="sd"> Args:</span>
<span class="sd"> key (str): Name of the new object.</span>
<span class="sd"> Returns:</span>
<span class="sd"> object (Object): A newly created object of the given typeclass.</span>
<span class="sd"> errors (list): A list of errors in string form, if any.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">obj</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">key</span>
<span class="c1"># If no typeclass supplied, use this class</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;typeclass&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;typeclass&quot;</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_script</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;The script &#39;</span><span class="si">%s</span><span class="s2">&#39; encountered errors and could not be created.&quot;</span> <span class="o">%</span> <span class="n">key</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">,</span> <span class="n">errors</span></div>
<div class="viewcode-block" id="DefaultScript.at_script_creation"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_script_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Only called once, when script is first created.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultScript.time_until_next_repeat"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.time_until_next_repeat">[docs]</a> <span class="k">def</span> <span class="nf">time_until_next_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get time until the script fires it `at_repeat` hook again.</span>
<span class="sd"> Returns:</span>
<span class="sd"> next (int): Time in seconds until the script runs again.</span>
<span class="sd"> If not a timed script, return `None`.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This hook is not used in any way by the script&#39;s stepping</span>
<span class="sd"> system; it&#39;s only here for the user to be able to check in</span>
<span class="sd"> on their scripts and when they will next be run.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="n">task</span><span class="o">.</span><span class="n">next_call_time</span><span class="p">()))</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="DefaultScript.remaining_repeats"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.remaining_repeats">[docs]</a> <span class="k">def</span> <span class="nf">remaining_repeats</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the number of returning repeats for limited Scripts.</span>
<span class="sd"> Returns:</span>
<span class="sd"> remaining (int or `None`): The number of repeats</span>
<span class="sd"> remaining until the Script stops. Returns `None`</span>
<span class="sd"> if it has unlimited repeats.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_repeats</span> <span class="o">-</span> <span class="n">task</span><span class="o">.</span><span class="n">callcount</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="DefaultScript.at_idmapper_flush"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_idmapper_flush">[docs]</a> <span class="k">def</span> <span class="nf">at_idmapper_flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;If we&#39;re flushing this object, make sure the LoopingCall is gone too&quot;&quot;&quot;</span>
<span class="n">ret</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">at_idmapper_flush</span><span class="p">()</span>
<span class="k">if</span> <span class="n">ret</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="k">global</span> <span class="n">FLUSHING_INSTANCES</span>
<span class="c1"># store the current timers for the _task and stop it to avoid duplicates after cache flush</span>
<span class="n">paused_time</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">next_call_time</span><span class="p">()</span>
<span class="n">callcount</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">callcount</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_task</span><span class="p">()</span>
<span class="n">SCRIPT_FLUSH_TIMERS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">paused_time</span><span class="p">,</span> <span class="n">callcount</span><span class="p">)</span>
<span class="c1"># here we ensure that the restart call only happens once, not once per script</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">FLUSHING_INSTANCES</span><span class="p">:</span>
<span class="n">FLUSHING_INSTANCES</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">restart_scripts_after_flush</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
<span class="k">return</span> <span class="n">ret</span></div>
<div class="viewcode-block" id="DefaultScript.start"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force_restart</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called every time the script is started (for persistent</span>
<span class="sd"> scripts, this is usually once every server start)</span>
<span class="sd"> Args:</span>
<span class="sd"> force_restart (bool, optional): Normally an already</span>
<span class="sd"> started script will not be started again. if</span>
<span class="sd"> `force_restart=True`, the script will always restart</span>
<span class="sd"> the script, regardless of if it has started before.</span>
<span class="sd"> Returns:</span>
<span class="sd"> result (int): 0 or 1 depending on if the script successfully</span>
<span class="sd"> started or not. Used in counting.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">force_restart</span><span class="p">:</span>
<span class="c1"># The script is already running, but make sure we have a _task if</span>
<span class="c1"># this is after a cache flush</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span> <span class="o">=</span> <span class="n">ExtendedLoopingCall</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_step_task</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">start_delay</span><span class="p">,</span> <span class="n">callcount</span> <span class="o">=</span> <span class="n">SCRIPT_FLUSH_TIMERS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">]</span>
<span class="k">del</span> <span class="n">SCRIPT_FLUSH_TIMERS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">]</span>
<span class="n">now</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">KeyError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
<span class="n">now</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_start_delay</span>
<span class="n">start_delay</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">callcount</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span><span class="o">.</span><span class="n">start</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span><span class="p">,</span> <span class="n">now</span><span class="o">=</span><span class="n">now</span><span class="p">,</span> <span class="n">start_delay</span><span class="o">=</span><span class="n">start_delay</span><span class="p">,</span> <span class="n">count_start</span><span class="o">=</span><span class="n">callcount</span>
<span class="p">)</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span>
<span class="k">if</span> <span class="n">obj</span><span class="p">:</span>
<span class="c1"># check so the scripted object is valid and initalized</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">cmdset</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="c1"># this means the object is not initialized.</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="c1"># try to restart a paused script</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">unpause</span><span class="p">(</span><span class="n">manual_unpause</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
<span class="c1"># manually paused.</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="c1"># start the script from scratch</span>
<span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_start</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_interval</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_start_task</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">1</span></div>
<div class="viewcode-block" id="DefaultScript.stop"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.stop">[docs]</a> <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">kill</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called to stop the script from running. This also deletes the</span>
<span class="sd"> script.</span>
<span class="sd"> Args:</span>
<span class="sd"> kill (bool, optional): - Stop the script without</span>
<span class="sd"> calling any relevant script hooks.</span>
<span class="sd"> Returns:</span>
<span class="sd"> result (int): 0 if the script failed to stop, 1 otherwise.</span>
<span class="sd"> Used in counting.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kill</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_stop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_task</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">AssertionError</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">except</span> <span class="n">ObjectDoesNotExist</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span></div>
<div class="viewcode-block" id="DefaultScript.pause"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.pause">[docs]</a> <span class="k">def</span> <span class="nf">pause</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">manual_pause</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This stops a running script and stores its active state.</span>
<span class="sd"> It WILL NOT call the `at_stop()` hook.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_manual_pause</span> <span class="o">=</span> <span class="n">manual_pause</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span><span class="p">:</span>
<span class="c1"># only allow pause if not already paused</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span> <span class="o">=</span> <span class="n">task</span><span class="o">.</span><span class="n">next_call_time</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_callcount</span> <span class="o">=</span> <span class="n">task</span><span class="o">.</span><span class="n">callcount</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_task</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="o">=</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="DefaultScript.unpause"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.unpause">[docs]</a> <span class="k">def</span> <span class="nf">unpause</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">manual_unpause</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Restart a paused script. This WILL call the `at_start()` hook.</span>
<span class="sd"> Args:</span>
<span class="sd"> manual_unpause (bool, optional): This is False if unpause is</span>
<span class="sd"> called by the server reload/reset mechanism.</span>
<span class="sd"> Returns:</span>
<span class="sd"> result (bool): True if unpause was triggered, False otherwise.</span>
<span class="sd"> Raises:</span>
<span class="sd"> RuntimeError: If trying to automatically resart this script</span>
<span class="sd"> (usually after a reset/reload), but it was manually paused,</span>
<span class="sd"> and so should not the auto-unpaused.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">manual_unpause</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_manual_pause</span><span class="p">:</span>
<span class="c1"># if this script was paused manually (by a direct call of pause),</span>
<span class="c1"># it cannot be automatically unpaused (e.g. by a @reload)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span>
<span class="c1"># Ensure that the script is fully unpaused, so that future calls</span>
<span class="c1"># to unpause do not raise a RuntimeError</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_manual_pause</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span><span class="p">:</span>
<span class="c1"># only unpause if previously paused</span>
<span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_start</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_start_task</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="DefaultScript.restart"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.restart">[docs]</a> <span class="k">def</span> <span class="nf">restart</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">repeats</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">start_delay</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Restarts an already existing/running Script from the</span>
<span class="sd"> beginning, optionally using different settings. This will</span>
<span class="sd"> first call the stop hooks, and then the start hooks again.</span>
<span class="sd"> Args:</span>
<span class="sd"> interval (int, optional): Allows for changing the interval</span>
<span class="sd"> of the Script. Given in seconds. if `None`, will use the already stored interval.</span>
<span class="sd"> repeats (int, optional): The number of repeats. If unset, will</span>
<span class="sd"> use the previous setting.</span>
<span class="sd"> start_delay (bool, optional): If we should wait `interval` seconds</span>
<span class="sd"> before starting or not. If `None`, re-use the previous setting.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_stop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_task</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">is_active</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># remove all pause flags</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_time</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_manual_pause</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_paused_callcount</span>
<span class="c1"># set new flags and start over</span>
<span class="k">if</span> <span class="n">interval</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">interval</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">interval</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="n">interval</span>
<span class="k">if</span> <span class="n">repeats</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">repeats</span> <span class="o">=</span> <span class="n">repeats</span>
<span class="k">if</span> <span class="n">start_delay</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_delay</span> <span class="o">=</span> <span class="n">start_delay</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></div>
<div class="viewcode-block" id="DefaultScript.reset_callcount"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.reset_callcount">[docs]</a> <span class="k">def</span> <span class="nf">reset_callcount</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Reset the count of the number of calls done.</span>
<span class="sd"> Args:</span>
<span class="sd"> value (int, optional): The repeat value to reset to. Default</span>
<span class="sd"> is to set it all the way back to 0.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This is only useful if repeats != 0.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span><span class="p">:</span>
<span class="n">task</span><span class="o">.</span><span class="n">callcount</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">))</span></div>
<div class="viewcode-block" id="DefaultScript.force_repeat"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.force_repeat">[docs]</a> <span class="k">def</span> <span class="nf">force_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Fire a premature triggering of the script callback. This</span>
<span class="sd"> will reset the timer and count down repeats as if the script</span>
<span class="sd"> had fired normally.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_task</span>
<span class="k">if</span> <span class="n">task</span><span class="p">:</span>
<span class="n">task</span><span class="o">.</span><span class="n">force_repeat</span><span class="p">()</span></div>
<div class="viewcode-block" id="DefaultScript.is_valid"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.is_valid">[docs]</a> <span class="k">def</span> <span class="nf">is_valid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Is called to check if the script is valid to run at this time.</span>
<span class="sd"> Should return a boolean. The method is assumed to collect all</span>
<span class="sd"> needed information from its related self.obj.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_deleted</span></div>
<div class="viewcode-block" id="DefaultScript.at_start"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_start">[docs]</a> <span class="k">def</span> <span class="nf">at_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called whenever the script is started, which for persistent</span>
<span class="sd"> scripts is at least once every server start. It will also be</span>
<span class="sd"> called when starting again after a pause (such as after a</span>
<span class="sd"> server reload)</span>
<span class="sd"> Args:</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultScript.at_repeat"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_repeat">[docs]</a> <span class="k">def</span> <span class="nf">at_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called repeatedly if this Script is set to repeat regularly.</span>
<span class="sd"> Args:</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultScript.at_stop"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_stop">[docs]</a> <span class="k">def</span> <span class="nf">at_stop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called whenever when it&#39;s time for this script to stop (either</span>
<span class="sd"> because is_valid returned False or it runs out of iterations)</span>
<span class="sd"> Args</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultScript.at_server_reload"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_server_reload">[docs]</a> <span class="k">def</span> <span class="nf">at_server_reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This hook is called whenever the server is shutting down for</span>
<span class="sd"> restart/reboot. If you want to, for example, save</span>
<span class="sd"> non-persistent properties across a restart, this is the place</span>
<span class="sd"> to do it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultScript.at_server_shutdown"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript.at_server_shutdown">[docs]</a> <span class="k">def</span> <span class="nf">at_server_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This hook is called whenever the server is shutting down fully</span>
<span class="sd"> (i.e. not for a restart).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div></div>
<span class="c1"># Some useful default Script types used by Evennia.</span>
<div class="viewcode-block" id="DoNothing"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DoNothing">[docs]</a><span class="k">class</span> <span class="nc">DoNothing</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A script that does nothing. Used as default fallback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="DoNothing.at_script_creation"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DoNothing.at_script_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Setup the script</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;sys_do_nothing&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="s2">&quot;This is an empty placeholder script.&quot;</span></div></div>
<div class="viewcode-block" id="Store"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.Store">[docs]</a><span class="k">class</span> <span class="nc">Store</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Simple storage script</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="Store.at_script_creation"><a class="viewcode-back" href="../../../api/evennia.scripts.scripts.html#evennia.scripts.scripts.Store.at_script_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Setup the script</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;sys_storage&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="s2">&quot;This is a generic storage container.&quot;</span></div></div>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../../index.html">
<img class="logo" src="../../../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="../../../../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
<li><a href="scripts.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.scripts.scripts</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>