evennia/docs/1.0-dev/_modules/evennia/commands/default/system.html
Evennia docbuilder action ecb368ddb6 Updated HTML docs
2022-02-05 15:09:22 +00:00

1261 lines
No EOL
159 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.commands.default.system &#8212; Evennia 1.0-dev 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 1.0-dev</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.commands.default.system</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.commands.default.system</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">System commands</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">code</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">django</span>
<span class="kn">import</span> <span class="nn">twisted</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.server.sessionhandler</span> <span class="kn">import</span> <span class="n">SESSIONS</span>
<span class="kn">from</span> <span class="nn">evennia.accounts.models</span> <span class="kn">import</span> <span class="n">AccountDB</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span><span class="p">,</span> <span class="n">utils</span><span class="p">,</span> <span class="n">gametime</span><span class="p">,</span> <span class="n">search</span>
<span class="kn">from</span> <span class="nn">evennia.utils.eveditor</span> <span class="kn">import</span> <span class="n">EvEditor</span>
<span class="kn">from</span> <span class="nn">evennia.utils.evtable</span> <span class="kn">import</span> <span class="n">EvTable</span>
<span class="kn">from</span> <span class="nn">evennia.utils.evmenu</span> <span class="kn">import</span> <span class="n">ask_yes_no</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">class_from_module</span><span class="p">,</span> <span class="n">iter_to_str</span>
<span class="kn">from</span> <span class="nn">evennia.scripts.taskhandler</span> <span class="kn">import</span> <span class="n">TaskHandlerTask</span>
<span class="n">COMMAND_DEFAULT_CLASS</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">)</span>
<span class="n">_TASK_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BROADCAST_SERVER_RESTART_MESSAGES</span>
<span class="c1"># delayed imports</span>
<span class="n">_RESOURCE</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_IDMAPPER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># limit symbol import for API</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;CmdAccounts&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdReload&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdReset&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdShutdown&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdPy&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdService&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdAbout&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdTime&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdServerLoad&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdTasks&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdTickers&quot;</span><span class="p">,</span>
<span class="p">)</span>
<div class="viewcode-block" id="CmdReload"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdReload">[docs]</a><span class="k">class</span> <span class="nc">CmdReload</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> reload the server</span>
<span class="sd"> Usage:</span>
<span class="sd"> reload [reason]</span>
<span class="sd"> This restarts the server. The Portal is not</span>
<span class="sd"> affected. Non-persistent scripts will survive a reload (use</span>
<span class="sd"> reset to purge) and at_reload() hooks will be called.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@reload&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@restart&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(reload) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdReload.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdReload.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Reload the system.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;(Reason: </span><span class="si">%s</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span><span class="p">:</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="s2">&quot; Server restart initiated </span><span class="si">%s</span><span class="s2">...&quot;</span> <span class="o">%</span> <span class="n">reason</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">portal_restart_server</span><span class="p">()</span></div></div>
<div class="viewcode-block" id="CmdReset"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdReset">[docs]</a><span class="k">class</span> <span class="nc">CmdReset</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> reset and reboot the server</span>
<span class="sd"> Usage:</span>
<span class="sd"> reset</span>
<span class="sd"> Notes:</span>
<span class="sd"> For normal updating you are recommended to use reload rather</span>
<span class="sd"> than this command. Use shutdown for a complete stop of</span>
<span class="sd"> everything.</span>
<span class="sd"> This emulates a cold reboot of the Server component of Evennia.</span>
<span class="sd"> The difference to shutdown is that the Server will auto-reboot</span>
<span class="sd"> and that it does not affect the Portal, so no users will be</span>
<span class="sd"> disconnected. Contrary to reload however, all shutdown hooks will</span>
<span class="sd"> be called and any non-database saved scripts, ndb-attributes,</span>
<span class="sd"> cmdsets etc will be wiped.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@reset&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@reboot&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(reload) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdReset.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdReset.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Reload the system.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="s2">&quot; Server resetting/restarting ...&quot;</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">portal_reset_server</span><span class="p">()</span></div></div>
<div class="viewcode-block" id="CmdShutdown"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdShutdown">[docs]</a><span class="k">class</span> <span class="nc">CmdShutdown</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> stop the server completely</span>
<span class="sd"> Usage:</span>
<span class="sd"> shutdown [announcement]</span>
<span class="sd"> Gracefully shut down both Server and Portal.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@shutdown&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(shutdown) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdShutdown.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdShutdown.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Define function&quot;&quot;&quot;</span>
<span class="c1"># Only allow shutdown if caller has session</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">sessions</span><span class="o">.</span><span class="n">get</span><span class="p">():</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Shutting down server ...&quot;</span><span class="p">)</span>
<span class="n">announcement</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Server is being SHUT DOWN!</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="n">announcement</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="s2">&quot;Server shutdown by </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="n">announcement</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">portal_shutdown</span><span class="p">()</span></div></div>
<span class="k">def</span> <span class="nf">_py_load</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_py_code</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">buf</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Execute the buffer.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">measure_time</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_py_measure_time</span>
<span class="n">client_raw</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_py_clientraw</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Executing code</span><span class="si">%s</span><span class="s2"> ...&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="s2">&quot; (measure timing)&quot;</span> <span class="k">if</span> <span class="n">measure_time</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="n">_run_code_snippet</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;exec&quot;</span><span class="p">,</span> <span class="n">measure_time</span><span class="o">=</span><span class="n">measure_time</span><span class="p">,</span> <span class="n">client_raw</span><span class="o">=</span><span class="n">client_raw</span><span class="p">,</span> <span class="n">show_input</span><span class="o">=</span><span class="kc">False</span>
<span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">_py_quit</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="k">del</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_py_measure_time</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Exited the code editor.&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_run_code_snippet</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span> <span class="n">pycode</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;eval&quot;</span><span class="p">,</span> <span class="n">measure_time</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">client_raw</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">show_input</span><span class="o">=</span><span class="kc">True</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run code and try to display information to the caller.</span>
<span class="sd"> Args:</span>
<span class="sd"> caller (Object): The caller.</span>
<span class="sd"> pycode (str): The Python code to run.</span>
<span class="sd"> measure_time (bool, optional): Should we measure the time of execution?</span>
<span class="sd"> client_raw (bool, optional): Should we turn off all client-specific escaping?</span>
<span class="sd"> show_input (bookl, optional): Should we display the input?</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Try to retrieve the session</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">caller</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;sessions&quot;</span><span class="p">):</span>
<span class="n">sessions</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">sessions</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">available_vars</span> <span class="o">=</span> <span class="n">evennia_local_vars</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">if</span> <span class="n">show_input</span><span class="p">:</span>
<span class="k">for</span> <span class="n">session</span> <span class="ow">in</span> <span class="n">sessions</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;&gt;&gt;&gt; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pycode</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;raw&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">})</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;&gt;&gt;&gt; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pycode</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;raw&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">})</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># reroute standard output to game client console</span>
<span class="n">old_stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span>
<span class="n">old_stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>
<span class="k">class</span> <span class="nc">FakeStd</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">fake_std</span> <span class="o">=</span> <span class="n">FakeStd</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">fake_std</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">fake_std</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">pycode_compiled</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="n">pycode</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">mode</span> <span class="o">=</span> <span class="s2">&quot;exec&quot;</span>
<span class="n">pycode_compiled</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="n">pycode</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
<span class="n">duration</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">measure_time</span><span class="p">:</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">ret</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">pycode_compiled</span><span class="p">,</span> <span class="p">{},</span> <span class="n">available_vars</span><span class="p">)</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">duration</span> <span class="o">=</span> <span class="s2">&quot; (runtime ~ </span><span class="si">%.4f</span><span class="s2"> ms)&quot;</span> <span class="o">%</span> <span class="p">((</span><span class="n">t1</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">duration</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ret</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">pycode_compiled</span><span class="p">,</span> <span class="p">{},</span> <span class="n">available_vars</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">errlist</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">errlist</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">4</span><span class="p">:</span>
<span class="n">errlist</span> <span class="o">=</span> <span class="n">errlist</span><span class="p">[</span><span class="mi">4</span><span class="p">:]</span>
<span class="n">ret</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">line</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">errlist</span> <span class="k">if</span> <span class="n">line</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c1"># return to old stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">old_stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">old_stderr</span>
<span class="k">if</span> <span class="n">ret</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="c1"># we must convert here to allow msg to pass it (a tuple is confused</span>
<span class="c1"># with a outputfunc structure)</span>
<span class="n">ret</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span>
<span class="k">for</span> <span class="n">session</span> <span class="ow">in</span> <span class="n">sessions</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;raw&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;client_raw&quot;</span><span class="p">:</span> <span class="n">client_raw</span><span class="p">})</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;raw&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;client_raw&quot;</span><span class="p">:</span> <span class="n">client_raw</span><span class="p">})</span>
<span class="k">def</span> <span class="nf">evennia_local_vars</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return Evennia local variables usable in the py command as a dictionary.&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">evennia</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">&quot;self&quot;</span><span class="p">:</span> <span class="n">caller</span><span class="p">,</span>
<span class="s2">&quot;me&quot;</span><span class="p">:</span> <span class="n">caller</span><span class="p">,</span>
<span class="s2">&quot;here&quot;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;location&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
<span class="s2">&quot;evennia&quot;</span><span class="p">:</span> <span class="n">evennia</span><span class="p">,</span>
<span class="s2">&quot;ev&quot;</span><span class="p">:</span> <span class="n">evennia</span><span class="p">,</span>
<span class="s2">&quot;inherits_from&quot;</span><span class="p">:</span> <span class="n">utils</span><span class="o">.</span><span class="n">inherits_from</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">class</span> <span class="nc">EvenniaPythonConsole</span><span class="p">(</span><span class="n">code</span><span class="o">.</span><span class="n">InteractiveConsole</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Evennia wrapper around a Python interactive console.&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">evennia_local_vars</span><span class="p">(</span><span class="n">caller</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Don&#39;t send to stderr, send to self.caller.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">push</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Push some code, whether complete or not.&quot;&quot;&quot;</span>
<span class="n">old_stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span>
<span class="n">old_stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>
<span class="k">class</span> <span class="nc">FakeStd</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">fake_std</span> <span class="o">=</span> <span class="n">FakeStd</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">fake_std</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">fake_std</span>
<span class="n">result</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">old_stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">old_stderr</span>
<span class="k">return</span> <span class="n">result</span>
<div class="viewcode-block" id="CmdPy"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdPy">[docs]</a><span class="k">class</span> <span class="nc">CmdPy</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> execute a snippet of python code</span>
<span class="sd"> Usage:</span>
<span class="sd"> py [cmd]</span>
<span class="sd"> py/edit</span>
<span class="sd"> py/time &lt;cmd&gt;</span>
<span class="sd"> py/clientraw &lt;cmd&gt;</span>
<span class="sd"> py/noecho</span>
<span class="sd"> Switches:</span>
<span class="sd"> time - output an approximate execution time for &lt;cmd&gt;</span>
<span class="sd"> edit - open a code editor for multi-line code experimentation</span>
<span class="sd"> clientraw - turn off all client-specific escaping. Note that this may</span>
<span class="sd"> lead to different output depending on prototocol (such as angular brackets</span>
<span class="sd"> being parsed as HTML in the webclient but not in telnet clients)</span>
<span class="sd"> noecho - in Python console mode, turn off the input echo (e.g. if your client</span>
<span class="sd"> does this for you already)</span>
<span class="sd"> Without argument, open a Python console in-game. This is a full console,</span>
<span class="sd"> accepting multi-line Python code for testing and debugging. Type `exit()` to</span>
<span class="sd"> return to the game. If Evennia is reloaded, the console will be closed.</span>
<span class="sd"> Enter a line of instruction after the &#39;py&#39; command to execute it</span>
<span class="sd"> immediately. Separate multiple commands by &#39;;&#39; or open the code editor</span>
<span class="sd"> using the /edit switch (all lines added in editor will be executed</span>
<span class="sd"> immediately when closing or using the execute command in the editor).</span>
<span class="sd"> A few variables are made available for convenience in order to offer access</span>
<span class="sd"> to the system (you can import more at execution time).</span>
<span class="sd"> Available variables in py environment:</span>
<span class="sd"> self, me : caller</span>
<span class="sd"> here : caller.location</span>
<span class="sd"> evennia : the evennia API</span>
<span class="sd"> inherits_from(obj, parent) : check object inheritance</span>
<span class="sd"> You can explore The evennia API from inside the game by calling</span>
<span class="sd"> the `__doc__` property on entities:</span>
<span class="sd"> py evennia.__doc__</span>
<span class="sd"> py evennia.managers.__doc__</span>
<span class="sd"> |rNote: In the wrong hands this command is a severe security risk. It</span>
<span class="sd"> should only be accessible by trusted server admins/superusers.|n</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@py&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@!&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;time&quot;</span><span class="p">,</span> <span class="s2">&quot;edit&quot;</span><span class="p">,</span> <span class="s2">&quot;clientraw&quot;</span><span class="p">,</span> <span class="s2">&quot;noecho&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(py) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<span class="n">arg_regex</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<div class="viewcode-block" id="CmdPy.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdPy.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;hook function&quot;&quot;&quot;</span>
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">pycode</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
<span class="n">noecho</span> <span class="o">=</span> <span class="s2">&quot;noecho&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="k">if</span> <span class="s2">&quot;edit&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_py_measure_time</span> <span class="o">=</span> <span class="s2">&quot;time&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_py_clientraw</span> <span class="o">=</span> <span class="s2">&quot;clientraw&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="n">EvEditor</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span>
<span class="n">loadfunc</span><span class="o">=</span><span class="n">_py_load</span><span class="p">,</span>
<span class="n">savefunc</span><span class="o">=</span><span class="n">_py_code</span><span class="p">,</span>
<span class="n">quitfunc</span><span class="o">=</span><span class="n">_py_quit</span><span class="p">,</span>
<span class="n">key</span><span class="o">=</span><span class="s2">&quot;Python exec: :w or :!&quot;</span><span class="p">,</span>
<span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">codefunc</span><span class="o">=</span><span class="n">_py_code</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pycode</span><span class="p">:</span>
<span class="c1"># Run in interactive mode</span>
<span class="n">console</span> <span class="o">=</span> <span class="n">EvenniaPythonConsole</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="n">banner</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;|gEvennia Interactive Python mode</span><span class="si">{echomode}</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Python </span><span class="si">{version}</span><span class="s2"> on </span><span class="si">{platform}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">echomode</span><span class="o">=</span><span class="s2">&quot; (no echoing of prompts)&quot;</span> <span class="k">if</span> <span class="n">noecho</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">version</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="n">platform</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">platform</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">banner</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">main_prompt</span> <span class="o">=</span> <span class="s2">&quot;|x[py mode - quit() to exit]|n&quot;</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="n">main_prompt</span>
<span class="k">while</span> <span class="n">line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;exit&quot;</span><span class="p">,</span> <span class="s2">&quot;exit()&quot;</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="k">yield</span> <span class="p">(</span><span class="n">prompt</span><span class="p">)</span>
<span class="k">if</span> <span class="n">noecho</span><span class="p">:</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="s2">&quot;...&quot;</span> <span class="k">if</span> <span class="n">console</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">else</span> <span class="n">main_prompt</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">line</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;&gt;&gt;&gt; </span><span class="si">{</span><span class="n">line</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="n">line</span> <span class="k">if</span> <span class="n">console</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">else</span> <span class="n">main_prompt</span>
<span class="k">except</span> <span class="ne">SystemExit</span><span class="p">:</span>
<span class="k">break</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|gClosing the Python console.|n&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">_run_code_snippet</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">,</span>
<span class="n">measure_time</span><span class="o">=</span><span class="s2">&quot;time&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">,</span>
<span class="n">client_raw</span><span class="o">=</span><span class="s2">&quot;clientraw&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">,</span>
<span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdAccounts"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdAccounts">[docs]</a><span class="k">class</span> <span class="nc">CmdAccounts</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manage registered accounts</span>
<span class="sd"> Usage:</span>
<span class="sd"> accounts [nr]</span>
<span class="sd"> accounts/delete &lt;name or #id&gt; [: reason]</span>
<span class="sd"> Switches:</span>
<span class="sd"> delete - delete an account from the server</span>
<span class="sd"> By default, lists statistics about the Accounts registered with the game.</span>
<span class="sd"> It will list the &lt;nr&gt; amount of latest registered accounts</span>
<span class="sd"> If not given, &lt;nr&gt; defaults to 10.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@accounts&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@account&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;delete&quot;</span><span class="p">,)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(listaccounts) or perm(Admin)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdAccounts.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdAccounts.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;List the accounts&quot;&quot;&quot;</span>
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
<span class="k">if</span> <span class="s2">&quot;delete&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">account</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;account&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">account</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">account</span><span class="o">.</span><span class="n">check_permstring</span><span class="p">(</span><span class="s2">&quot;Developer&quot;</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You are not allowed to delete accounts.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: accounts/delete &lt;name or #id&gt; [: reason]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
<span class="n">args</span><span class="p">,</span> <span class="n">reason</span> <span class="o">=</span> <span class="p">[</span><span class="n">arg</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)]</span>
<span class="c1"># We use account_search since we want to be sure to find also accounts</span>
<span class="c1"># that lack characters.</span>
<span class="n">accounts</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">account_search</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">accounts</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Could not find an account by that name.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">accounts</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;There were multiple matches:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot; </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">account</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">account</span><span class="o">.</span><span class="n">key</span><span class="p">)</span> <span class="k">for</span> <span class="n">account</span> <span class="ow">in</span> <span class="n">accounts</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">account</span> <span class="o">=</span> <span class="n">accounts</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">account</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have the permissions to delete that account.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">username</span> <span class="o">=</span> <span class="n">account</span><span class="o">.</span><span class="n">username</span>
<span class="c1"># ask for confirmation</span>
<span class="n">confirm</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;It is often better to block access to an account rather than to delete it. &quot;</span>
<span class="s2">&quot;|yAre you sure you want to permanently delete &quot;</span>
<span class="s2">&quot;account &#39;|n</span><span class="si">{}</span><span class="s2">|y&#39;|n yes/[no]?&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">answer</span> <span class="o">=</span> <span class="k">yield</span> <span class="p">(</span><span class="n">confirm</span><span class="p">)</span>
<span class="k">if</span> <span class="n">answer</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;y&quot;</span><span class="p">,</span> <span class="s2">&quot;yes&quot;</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Canceled deletion.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># Boot the account then delete it.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Informing and disconnecting account ...&quot;</span><span class="p">)</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Your account &#39;</span><span class="si">%s</span><span class="s2">&#39; is being *permanently* deleted.</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">username</span>
<span class="k">if</span> <span class="n">reason</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; Reason given:</span><span class="se">\n</span><span class="s2"> &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">reason</span>
<span class="n">account</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_sec</span><span class="p">(</span>
<span class="s2">&quot;Account Deleted: </span><span class="si">%s</span><span class="s2"> (Reason: </span><span class="si">%s</span><span class="s2">, Caller: </span><span class="si">%s</span><span class="s2">, IP: </span><span class="si">%s</span><span class="s2">).&quot;</span>
<span class="o">%</span> <span class="p">(</span><span class="n">account</span><span class="p">,</span> <span class="n">reason</span><span class="p">,</span> <span class="n">caller</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">address</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">account</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Account </span><span class="si">%s</span><span class="s2"> was successfully deleted.&quot;</span> <span class="o">%</span> <span class="n">username</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># No switches, default to displaying a list of accounts.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
<span class="n">nlim</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">nlim</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">naccounts</span> <span class="o">=</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
<span class="c1"># typeclass table</span>
<span class="n">dbtotals</span> <span class="o">=</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">object_totals</span><span class="p">()</span>
<span class="n">typetable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wtypeclass|n&quot;</span><span class="p">,</span> <span class="s2">&quot;|wcount|n&quot;</span><span class="p">,</span> <span class="s2">&quot;|w</span><span class="si">%%</span><span class="s2">|n&quot;</span><span class="p">,</span> <span class="n">border</span><span class="o">=</span><span class="s2">&quot;cells&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">count</span> <span class="ow">in</span> <span class="n">dbtotals</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">typetable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%.2f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">((</span><span class="nb">float</span><span class="p">(</span><span class="n">count</span><span class="p">)</span> <span class="o">/</span> <span class="n">naccounts</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">))</span>
<span class="c1"># last N table</span>
<span class="n">plyrs</span> <span class="o">=</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s2">&quot;db_date_created&quot;</span><span class="p">)[</span><span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">naccounts</span> <span class="o">-</span> <span class="n">nlim</span><span class="p">)</span> <span class="p">:]</span>
<span class="n">latesttable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wcreated|n&quot;</span><span class="p">,</span> <span class="s2">&quot;|wdbref|n&quot;</span><span class="p">,</span> <span class="s2">&quot;|wname|n&quot;</span><span class="p">,</span> <span class="s2">&quot;|wtypeclass|n&quot;</span><span class="p">,</span> <span class="n">border</span><span class="o">=</span><span class="s2">&quot;cells&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">ply</span> <span class="ow">in</span> <span class="n">plyrs</span><span class="p">:</span>
<span class="n">latesttable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="n">utils</span><span class="o">.</span><span class="n">datetime_format</span><span class="p">(</span><span class="n">ply</span><span class="o">.</span><span class="n">date_created</span><span class="p">),</span> <span class="n">ply</span><span class="o">.</span><span class="n">dbref</span><span class="p">,</span> <span class="n">ply</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">ply</span><span class="o">.</span><span class="n">path</span>
<span class="p">)</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|wAccount typeclass distribution:|n</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">typetable</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|wLast </span><span class="si">%s</span><span class="s2"> Accounts created:|n</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">min</span><span class="p">(</span><span class="n">naccounts</span><span class="p">,</span> <span class="n">nlim</span><span class="p">),</span> <span class="n">latesttable</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdService"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdService">[docs]</a><span class="k">class</span> <span class="nc">CmdService</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> manage system services</span>
<span class="sd"> Usage:</span>
<span class="sd"> service[/switch] &lt;service&gt;</span>
<span class="sd"> Switches:</span>
<span class="sd"> list - shows all available services (default)</span>
<span class="sd"> start - activates or reactivate a service</span>
<span class="sd"> stop - stops/inactivate a service (can often be restarted)</span>
<span class="sd"> delete - tries to permanently remove a service</span>
<span class="sd"> Service management system. Allows for the listing,</span>
<span class="sd"> starting, and stopping of services. If no switches</span>
<span class="sd"> are given, services will be listed. Note that to operate on the</span>
<span class="sd"> service you have to supply the full (green or red) name as given</span>
<span class="sd"> in the list.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@service&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@services&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;list&quot;</span><span class="p">,</span> <span class="s2">&quot;start&quot;</span><span class="p">,</span> <span class="s2">&quot;stop&quot;</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(service) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdService.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdService.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Implement command&quot;&quot;&quot;</span>
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">switches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="k">if</span> <span class="n">switches</span> <span class="ow">and</span> <span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;list&quot;</span><span class="p">,</span> <span class="s2">&quot;start&quot;</span><span class="p">,</span> <span class="s2">&quot;stop&quot;</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: service/&lt;list|start|stop|delete&gt; [servicename]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># get all services</span>
<span class="n">service_collection</span> <span class="o">=</span> <span class="n">SESSIONS</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">services</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">switches</span> <span class="ow">or</span> <span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;list&quot;</span><span class="p">:</span>
<span class="c1"># Just display the list of installed services and their</span>
<span class="c1"># status, then exit.</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wService|n (use services/start|stop|delete)&quot;</span><span class="p">,</span> <span class="s2">&quot;|wstatus&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">service</span> <span class="ow">in</span> <span class="n">service_collection</span><span class="o">.</span><span class="n">services</span><span class="p">:</span>
<span class="n">table</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="n">service</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">service</span><span class="o">.</span><span class="n">running</span> <span class="ow">and</span> <span class="s2">&quot;|gRunning&quot;</span> <span class="ow">or</span> <span class="s2">&quot;|rNot Running&quot;</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">table</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># Get the service to start / stop</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">service</span> <span class="o">=</span> <span class="n">service_collection</span><span class="o">.</span><span class="n">getServiceNamed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Invalid service name. This command is case-sensitive. &quot;</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;See service/list for valid service name (enter the full name exactly).&quot;</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;stop&quot;</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">):</span>
<span class="c1"># Stopping/killing a service gracefully closes it and disconnects</span>
<span class="c1"># any connections (if applicable).</span>
<span class="n">delmode</span> <span class="o">=</span> <span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;delete&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">service</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;That service is not currently running.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">service</span><span class="o">.</span><span class="n">name</span><span class="p">[:</span><span class="mi">7</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;Evennia&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="n">delmode</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You cannot remove a core Evennia service (named &#39;Evennia*&#39;).&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;|RYou seem to be shutting down a core Evennia &quot;</span>
<span class="s2">&quot;service (named &#39;Evennia*&#39;).</span><span class="se">\n</span><span class="s2">Note that stopping &quot;</span>
<span class="s2">&quot;some TCP port services will *not* disconnect users &quot;</span>
<span class="s2">&quot;*already* connected on those ports, but *may* &quot;</span>
<span class="s2">&quot;instead cause spurious errors for them.</span><span class="se">\n</span><span class="s2">To safely &quot;</span>
<span class="s2">&quot;and permanently remove ports, change settings file &quot;</span>
<span class="s2">&quot;and restart the server.|n</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">if</span> <span class="n">delmode</span><span class="p">:</span>
<span class="n">service</span><span class="o">.</span><span class="n">stopService</span><span class="p">()</span>
<span class="n">service_collection</span><span class="o">.</span><span class="n">removeService</span><span class="p">(</span><span class="n">service</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|gStopped and removed service &#39;</span><span class="si">%s</span><span class="s2">&#39;.|n&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Stopping service &#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="si">}</span><span class="s2">&#39;...&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">service</span><span class="o">.</span><span class="n">stopService</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|rErrors were reported when stopping this service</span><span class="si">{</span><span class="n">err</span><span class="si">}</span><span class="s2">.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;If there are remaining problems, try reloading &quot;</span>
<span class="s2">&quot;or rebooting the server.&quot;</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|g... Stopped service &#39;</span><span class="si">%s</span><span class="s2">&#39;.|n&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;start&quot;</span><span class="p">:</span>
<span class="c1"># Attempt to start a service.</span>
<span class="k">if</span> <span class="n">service</span><span class="o">.</span><span class="n">running</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;That service is already running.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Starting service &#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="si">}</span><span class="s2">&#39; ...&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">service</span><span class="o">.</span><span class="n">startService</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|rErrors were reported when starting this service</span><span class="si">{</span><span class="n">err</span><span class="si">}</span><span class="s2">.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;If there are remaining problems, try reloading the server, changing the &quot;</span>
<span class="s2">&quot;settings if it&#39;s a non-standard service.|n&quot;</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|gService started.|n&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdAbout"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdAbout">[docs]</a><span class="k">class</span> <span class="nc">CmdAbout</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> show Evennia info</span>
<span class="sd"> Usage:</span>
<span class="sd"> about</span>
<span class="sd"> Display info about the game engine.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@about&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s2">&quot;@version&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdAbout.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdAbout.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Display information about server or target&quot;&quot;&quot;</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> |cEvennia|n MU* development system</span>
<span class="s2"> |wEvennia version|n: </span><span class="si">{version}</span><span class="s2"></span>
<span class="s2"> |wOS|n: </span><span class="si">{os}</span><span class="s2"></span>
<span class="s2"> |wPython|n: </span><span class="si">{python}</span><span class="s2"></span>
<span class="s2"> |wTwisted|n: </span><span class="si">{twisted}</span><span class="s2"></span>
<span class="s2"> |wDjango|n: </span><span class="si">{django}</span><span class="s2"></span>
<span class="s2"> |wHomepage|n https://evennia.com</span>
<span class="s2"> |wCode|n https://github.com/evennia/evennia</span>
<span class="s2"> |wDemo|n https://demo.evennia.com</span>
<span class="s2"> |wGame listing|n https://games.evennia.com</span>
<span class="s2"> |wChat|n https://discord.gg/AJJpcRUhtF</span>
<span class="s2"> |wForum|n https://github.com/evennia/evennia/discussions</span>
<span class="s2"> |wLicence|n https://opensource.org/licenses/BSD-3-Clause</span>
<span class="s2"> |wMaintainer|n (2010-) Griatch (griatch AT gmail DOT com)</span>
<span class="s2"> |wMaintainer|n (2006-10) Greg Taylor</span>
<span class="s2"> &quot;&quot;&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">version</span><span class="o">=</span><span class="n">utils</span><span class="o">.</span><span class="n">get_evennia_version</span><span class="p">(),</span>
<span class="n">os</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="n">python</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">twisted</span><span class="o">=</span><span class="n">twisted</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">short</span><span class="p">(),</span>
<span class="n">django</span><span class="o">=</span><span class="n">django</span><span class="o">.</span><span class="n">get_version</span><span class="p">(),</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdTime"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTime">[docs]</a><span class="k">class</span> <span class="nc">CmdTime</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> show server time statistics</span>
<span class="sd"> Usage:</span>
<span class="sd"> time</span>
<span class="sd"> List Server time statistics such as uptime</span>
<span class="sd"> and the current time stamp.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@time&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s2">&quot;@uptime&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(time) or perm(Player)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdTime.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTime.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Show server time data in a table.&quot;&quot;&quot;</span>
<span class="n">table1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span><span class="s2">&quot;|wServer time&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">78</span><span class="p">)</span>
<span class="n">table1</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Current uptime&quot;</span><span class="p">,</span> <span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">uptime</span><span class="p">(),</span> <span class="mi">3</span><span class="p">))</span>
<span class="n">table1</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Portal uptime&quot;</span><span class="p">,</span> <span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">portal_uptime</span><span class="p">(),</span> <span class="mi">3</span><span class="p">))</span>
<span class="n">table1</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Total runtime&quot;</span><span class="p">,</span> <span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">runtime</span><span class="p">(),</span> <span class="mi">2</span><span class="p">))</span>
<span class="n">table1</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;First start&quot;</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">server_epoch</span><span class="p">()))</span>
<span class="n">table1</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Current time&quot;</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
<span class="n">table1</span><span class="o">.</span><span class="n">reformat_column</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
<span class="n">table2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wIn-Game time&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wReal time x </span><span class="si">%g</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">gametime</span><span class="o">.</span><span class="n">TIMEFACTOR</span><span class="p">,</span>
<span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">,</span>
<span class="n">width</span><span class="o">=</span><span class="mi">78</span><span class="p">,</span>
<span class="n">border_top</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">epochtxt</span> <span class="o">=</span> <span class="s2">&quot;Epoch (</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="s2">&quot;from settings&quot;</span> <span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">TIME_GAME_EPOCH</span> <span class="k">else</span> <span class="s2">&quot;server start&quot;</span><span class="p">)</span>
<span class="n">table2</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="n">epochtxt</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">game_epoch</span><span class="p">()))</span>
<span class="n">table2</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Total time passed:&quot;</span><span class="p">,</span> <span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">gametime</span><span class="p">(),</span> <span class="mi">2</span><span class="p">))</span>
<span class="n">table2</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;Current time &quot;</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">gametime</span><span class="o">.</span><span class="n">gametime</span><span class="p">(</span><span class="n">absolute</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">table2</span><span class="o">.</span><span class="n">reformat_column</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">table1</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">table2</span><span class="p">))</span></div></div>
<div class="viewcode-block" id="CmdServerLoad"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdServerLoad">[docs]</a><span class="k">class</span> <span class="nc">CmdServerLoad</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> show server load and memory statistics</span>
<span class="sd"> Usage:</span>
<span class="sd"> server[/mem]</span>
<span class="sd"> Switches:</span>
<span class="sd"> mem - return only a string of the current memory usage</span>
<span class="sd"> flushmem - flush the idmapper cache</span>
<span class="sd"> This command shows server load statistics and dynamic memory</span>
<span class="sd"> usage. It also allows to flush the cache of accessed database</span>
<span class="sd"> objects.</span>
<span class="sd"> Some Important statistics in the table:</span>
<span class="sd"> |wServer load|n is an average of processor usage. It&#39;s usually</span>
<span class="sd"> between 0 (no usage) and 1 (100% usage), but may also be</span>
<span class="sd"> temporarily higher if your computer has multiple CPU cores.</span>
<span class="sd"> The |wResident/Virtual memory|n displays the total memory used by</span>
<span class="sd"> the server process.</span>
<span class="sd"> Evennia |wcaches|n all retrieved database entities when they are</span>
<span class="sd"> loaded by use of the idmapper functionality. This allows Evennia</span>
<span class="sd"> to maintain the same instances of an entity and allowing</span>
<span class="sd"> non-persistent storage schemes. The total amount of cached objects</span>
<span class="sd"> are displayed plus a breakdown of database object types.</span>
<span class="sd"> The |wflushmem|n switch allows to flush the object cache. Please</span>
<span class="sd"> note that due to how Python&#39;s memory management works, releasing</span>
<span class="sd"> caches may not show you a lower Residual/Virtual memory footprint,</span>
<span class="sd"> the released memory will instead be re-used by the program.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@server&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@serverload&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;mem&quot;</span><span class="p">,</span> <span class="s2">&quot;flushmem&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(list) or perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdServerLoad.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdServerLoad.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Show list.&quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_IDMAPPER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IDMAPPER</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.utils.idmapper</span> <span class="kn">import</span> <span class="n">models</span> <span class="k">as</span> <span class="n">_IDMAPPER</span>
<span class="k">if</span> <span class="s2">&quot;flushmem&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="c1"># flush the cache</span>
<span class="n">prev</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">_IDMAPPER</span><span class="o">.</span><span class="n">cache_size</span><span class="p">()</span>
<span class="n">nflushed</span> <span class="o">=</span> <span class="n">_IDMAPPER</span><span class="o">.</span><span class="n">flush_cache</span><span class="p">()</span>
<span class="n">now</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">_IDMAPPER</span><span class="o">.</span><span class="n">cache_size</span><span class="p">()</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;The Idmapper cache freed |w</span><span class="si">{idmapper}</span><span class="s2">|n database objects.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;The Python garbage collector freed |w</span><span class="si">{gc}</span><span class="s2">|n Python instances total.&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">idmapper</span><span class="o">=</span><span class="p">(</span><span class="n">prev</span> <span class="o">-</span> <span class="n">now</span><span class="p">),</span> <span class="n">gc</span><span class="o">=</span><span class="n">nflushed</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># display active processes</span>
<span class="n">os_windows</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;nt&quot;</span>
<span class="n">pid</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>
<span class="k">if</span> <span class="n">os_windows</span><span class="p">:</span>
<span class="c1"># Windows requires the psutil module to even get paltry</span>
<span class="c1"># statistics like this (it&#39;s pretty much worthless,</span>
<span class="c1"># unfortunately, since it&#39;s not specific to the process) /rant</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">psutil</span>
<span class="n">has_psutil</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">has_psutil</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">has_psutil</span><span class="p">:</span>
<span class="n">loadavg</span> <span class="o">=</span> <span class="n">psutil</span><span class="o">.</span><span class="n">cpu_percent</span><span class="p">()</span>
<span class="n">_mem</span> <span class="o">=</span> <span class="n">psutil</span><span class="o">.</span><span class="n">virtual_memory</span><span class="p">()</span>
<span class="n">rmem</span> <span class="o">=</span> <span class="n">_mem</span><span class="o">.</span><span class="n">used</span> <span class="o">/</span> <span class="p">(</span><span class="mf">1000.0</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">)</span>
<span class="n">pmem</span> <span class="o">=</span> <span class="n">_mem</span><span class="o">.</span><span class="n">percent</span>
<span class="k">if</span> <span class="s2">&quot;mem&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Total computer memory usage: |w</span><span class="si">%g</span><span class="s2">|n MB (</span><span class="si">%g%%</span><span class="s2">)&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span> <span class="o">%</span> <span class="p">(</span><span class="n">rmem</span><span class="p">,</span> <span class="n">pmem</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># Display table</span>
<span class="n">loadtable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span><span class="s2">&quot;property&quot;</span><span class="p">,</span> <span class="s2">&quot;statistic&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Total CPU load&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> </span><span class="si">%%</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">loadavg</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Total computer memory usage&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> MB (</span><span class="si">%g%%</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rmem</span><span class="p">,</span> <span class="n">pmem</span><span class="p">))</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Process ID&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pid</span><span class="p">),</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">loadtable</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;Not available on Windows without &#39;psutil&#39; library &quot;</span>
<span class="s2">&quot;(install with |wpip install psutil|n).&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Linux / BSD (OSX) - proper pid-based statistics</span>
<span class="k">global</span> <span class="n">_RESOURCE</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_RESOURCE</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">resource</span> <span class="k">as</span> <span class="nn">_RESOURCE</span>
<span class="n">loadavg</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getloadavg</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">rmem</span> <span class="o">=</span> <span class="p">(</span>
<span class="nb">float</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s2">&quot;ps -p </span><span class="si">%d</span><span class="s2"> -o </span><span class="si">%s</span><span class="s2"> | tail -1&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="s2">&quot;rss&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <span class="o">/</span> <span class="mf">1000.0</span>
<span class="p">)</span> <span class="c1"># resident memory</span>
<span class="n">vmem</span> <span class="o">=</span> <span class="p">(</span>
<span class="nb">float</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s2">&quot;ps -p </span><span class="si">%d</span><span class="s2"> -o </span><span class="si">%s</span><span class="s2"> | tail -1&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="s2">&quot;vsz&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <span class="o">/</span> <span class="mf">1000.0</span>
<span class="p">)</span> <span class="c1"># virtual memory</span>
<span class="n">pmem</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span>
<span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s2">&quot;ps -p </span><span class="si">%d</span><span class="s2"> -o </span><span class="si">%s</span><span class="s2"> | tail -1&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="s2">&quot;%mem&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="p">)</span> <span class="c1"># % of resident memory to total</span>
<span class="n">rusage</span> <span class="o">=</span> <span class="n">_RESOURCE</span><span class="o">.</span><span class="n">getrusage</span><span class="p">(</span><span class="n">_RESOURCE</span><span class="o">.</span><span class="n">RUSAGE_SELF</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;mem&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Memory usage: RMEM: |w</span><span class="si">%g</span><span class="s2">|n MB (</span><span class="si">%g%%</span><span class="s2">), VMEM (res+swap+cache): |w</span><span class="si">%g</span><span class="s2">|n MB.&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span> <span class="o">%</span> <span class="p">(</span><span class="n">rmem</span><span class="p">,</span> <span class="n">pmem</span><span class="p">,</span> <span class="n">vmem</span><span class="p">))</span>
<span class="k">return</span>
<span class="n">loadtable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span><span class="s2">&quot;property&quot;</span><span class="p">,</span> <span class="s2">&quot;statistic&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Server load (1 min)&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">loadavg</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Process ID&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pid</span><span class="p">),</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Memory usage&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> MB (</span><span class="si">%g%%</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rmem</span><span class="p">,</span> <span class="n">pmem</span><span class="p">))</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Virtual address space&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;|x(resident+swap+caching)|n&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> MB&quot;</span> <span class="o">%</span> <span class="n">vmem</span><span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;CPU time used (total)&quot;</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> (</span><span class="si">%g</span><span class="s2">s)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_utime</span><span class="p">),</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_utime</span><span class="p">),</span>
<span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;CPU time used (user)&quot;</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> (</span><span class="si">%g</span><span class="s2">s)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">utils</span><span class="o">.</span><span class="n">time_format</span><span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_stime</span><span class="p">),</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_stime</span><span class="p">),</span>
<span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;Page faults&quot;</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> hard, </span><span class="si">%g</span><span class="s2"> soft, </span><span class="si">%g</span><span class="s2"> swapouts&quot;</span>
<span class="o">%</span> <span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_majflt</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_minflt</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_nswap</span><span class="p">),</span>
<span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;Disk I/O&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> reads, </span><span class="si">%g</span><span class="s2"> writes&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_inblock</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_oublock</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="s2">&quot;Network I/O&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> in, </span><span class="si">%g</span><span class="s2"> out&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_msgrcv</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_msgsnd</span><span class="p">))</span>
<span class="n">loadtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;Context switching&quot;</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">%g</span><span class="s2"> vol, </span><span class="si">%g</span><span class="s2"> forced, </span><span class="si">%g</span><span class="s2"> signals&quot;</span>
<span class="o">%</span> <span class="p">(</span><span class="n">rusage</span><span class="o">.</span><span class="n">ru_nvcsw</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_nivcsw</span><span class="p">,</span> <span class="n">rusage</span><span class="o">.</span><span class="n">ru_nsignals</span><span class="p">),</span>
<span class="p">)</span>
<span class="c1"># os-generic</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;|wServer CPU and Memory load:|n</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">loadtable</span>
<span class="c1"># object cache count (note that sys.getsiseof is not called so this works for pypy too.</span>
<span class="n">total_num</span><span class="p">,</span> <span class="n">cachedict</span> <span class="o">=</span> <span class="n">_IDMAPPER</span><span class="o">.</span><span class="n">cache_size</span><span class="p">()</span>
<span class="n">sorted_cache</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span>
<span class="p">[(</span><span class="n">key</span><span class="p">,</span> <span class="n">num</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">num</span> <span class="ow">in</span> <span class="n">cachedict</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">],</span>
<span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">tup</span><span class="p">:</span> <span class="n">tup</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
<span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">memtable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span><span class="s2">&quot;entity name&quot;</span><span class="p">,</span> <span class="s2">&quot;number&quot;</span><span class="p">,</span> <span class="s2">&quot;idmapper %&quot;</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">sorted_cache</span><span class="p">:</span>
<span class="n">memtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="n">tup</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">&quot;</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tup</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s2">&quot;</span><span class="si">%.2f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">tup</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">/</span> <span class="n">total_num</span> <span class="o">*</span> <span class="mi">100</span><span class="p">))</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|w Entity idmapper cache:|n </span><span class="si">%i</span><span class="s2"> items</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">total_num</span><span class="p">,</span> <span class="n">memtable</span><span class="p">)</span>
<span class="c1"># return to caller</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdTickers"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTickers">[docs]</a><span class="k">class</span> <span class="nc">CmdTickers</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> View running tickers</span>
<span class="sd"> Usage:</span>
<span class="sd"> tickers</span>
<span class="sd"> Note: Tickers are created, stopped and manipulated in Python code</span>
<span class="sd"> using the TickerHandler. This is merely a convenience function for</span>
<span class="sd"> inspecting the current status.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@tickers&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(tickers) or perm(Builder)&quot;</span>
<div class="viewcode-block" id="CmdTickers.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTickers.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">TICKER_HANDLER</span>
<span class="n">all_subs</span> <span class="o">=</span> <span class="n">TICKER_HANDLER</span><span class="o">.</span><span class="n">all_display</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">all_subs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;No tickers are currently active.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span><span class="s2">&quot;interval (s)&quot;</span><span class="p">,</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span> <span class="s2">&quot;path/methodname&quot;</span><span class="p">,</span> <span class="s2">&quot;idstring&quot;</span><span class="p">,</span> <span class="s2">&quot;db&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">sub</span> <span class="ow">in</span> <span class="n">all_subs</span><span class="p">:</span>
<span class="n">table</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="n">sub</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
<span class="s2">&quot;</span><span class="si">%s%s</span><span class="s2">&quot;</span>
<span class="o">%</span> <span class="p">(</span>
<span class="n">sub</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">or</span> <span class="s2">&quot;[None]&quot;</span><span class="p">,</span>
<span class="n">sub</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">and</span> <span class="s2">&quot; (#</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sub</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">id</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">sub</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">&quot;id&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="n">sub</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">sub</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="n">sub</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
<span class="n">sub</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="ow">or</span> <span class="s2">&quot;[Unset]&quot;</span><span class="p">,</span>
<span class="s2">&quot;*&quot;</span> <span class="k">if</span> <span class="n">sub</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="k">else</span> <span class="s2">&quot;-&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|wActive tickers|n:</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">table</span><span class="p">))</span></div></div>
<div class="viewcode-block" id="CmdTasks"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTasks">[docs]</a><span class="k">class</span> <span class="nc">CmdTasks</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Display or terminate active tasks (delays).</span>
<span class="sd"> Usage:</span>
<span class="sd"> tasks[/switch] [task_id or function_name]</span>
<span class="sd"> Switches:</span>
<span class="sd"> pause - Pause the callback of a task.</span>
<span class="sd"> unpause - Process all callbacks made since pause() was called.</span>
<span class="sd"> do_task - Execute the task (call its callback).</span>
<span class="sd"> call - Call the callback of this task.</span>
<span class="sd"> remove - Remove a task without executing it.</span>
<span class="sd"> cancel - Stop a task from automatically executing.</span>
<span class="sd"> Notes:</span>
<span class="sd"> A task is a single use method of delaying the call of a function. Calls are created</span>
<span class="sd"> in code, using `evennia.utils.delay`.</span>
<span class="sd"> See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.</span>
<span class="sd"> By default, tasks that are canceled and never called are cleaned up after one minute.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.</span>
<span class="sd"> In this example slow exits creates it&#39;s tasks with</span>
<span class="sd"> `utils.delay(move_delay, move_callback)`</span>
<span class="sd"> - `tasks/cancel 2` - Cancel task id 2.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;@tasks&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;@delays&quot;</span><span class="p">,</span> <span class="s2">&quot;@task&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;pause&quot;</span><span class="p">,</span> <span class="s2">&quot;unpause&quot;</span><span class="p">,</span> <span class="s2">&quot;do_task&quot;</span><span class="p">,</span> <span class="s2">&quot;call&quot;</span><span class="p">,</span> <span class="s2">&quot;remove&quot;</span><span class="p">,</span> <span class="s2">&quot;cancel&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;perm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;System&quot;</span>
<div class="viewcode-block" id="CmdTasks.coll_date_func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTasks.coll_date_func">[docs]</a> <span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">coll_date_func</span><span class="p">(</span><span class="n">task</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Replace regex characters in date string and collect deferred function name.&quot;&quot;&quot;</span>
<span class="n">t_comp_date</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">t_func_mem_ref</span> <span class="o">=</span> <span class="n">t_func_name</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t_func_name</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">4</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">t_comp_date</span><span class="p">,</span> <span class="n">t_func_mem_ref</span></div>
<div class="viewcode-block" id="CmdTasks.do_task_action"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTasks.do_task_action">[docs]</a> <span class="k">def</span> <span class="nf">do_task_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</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"> Process the action of a tasks command.</span>
<span class="sd"> This exists to gain support with yes or no function from EvMenu.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">task_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">task_id</span>
<span class="c1"># get a reference of the global task handler</span>
<span class="k">global</span> <span class="n">_TASK_HANDLER</span>
<span class="k">if</span> <span class="n">_TASK_HANDLER</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.scripts.taskhandler</span> <span class="kn">import</span> <span class="n">TASK_HANDLER</span> <span class="k">as</span> <span class="n">_TASK_HANDLER</span>
<span class="c1"># verify manipulating the correct task</span>
<span class="n">task_args</span> <span class="o">=</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">task_args</span><span class="p">:</span> <span class="c1"># check if the task is still active</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;Task completed while waiting for input.&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># make certain a task with matching IDs has not been created</span>
<span class="n">t_comp_date</span><span class="p">,</span> <span class="n">t_func_mem_ref</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">coll_date_func</span><span class="p">(</span><span class="n">task_args</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">t_comp_date</span> <span class="o">!=</span> <span class="n">t_comp_date</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">t_func_mem_ref</span> <span class="o">!=</span> <span class="n">t_func_mem_ref</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;Task completed while waiting for input.&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># Do the action requested by command caller</span>
<span class="n">action_return</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">task_action</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">action_request</span><span class="si">}</span><span class="s1"> request completed.&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;The task function </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">action_request</span><span class="si">}</span><span class="s1"> returned: </span><span class="si">{</span><span class="n">action_return</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdTasks.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.system.html#evennia.commands.default.system.CmdTasks.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># get a reference of the global task handler</span>
<span class="k">global</span> <span class="n">_TASK_HANDLER</span>
<span class="k">if</span> <span class="n">_TASK_HANDLER</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.scripts.taskhandler</span> <span class="kn">import</span> <span class="n">TASK_HANDLER</span> <span class="k">as</span> <span class="n">_TASK_HANDLER</span>
<span class="c1"># handle no tasks active.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;There are no active tasks.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;Likely the task has completed and been removed.&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># handle caller&#39;s request to manipulate a task(s)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">:</span>
<span class="c1"># find if the argument is a task id or function name</span>
<span class="n">action_request</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">arg_is_id</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhslist</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="n">arg_is_id</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># if the argument is a task id, proccess the action on a single task</span>
<span class="k">if</span> <span class="n">arg_is_id</span><span class="p">:</span>
<span class="n">err_arg_msg</span> <span class="o">=</span> <span class="s1">&#39;Switch and task ID are required when manipulating a task.&#39;</span>
<span class="n">task_comp_msg</span> <span class="o">=</span> <span class="s1">&#39;Task completed while processing request.&#39;</span>
<span class="c1"># handle missing arguments or switches</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err_arg_msg</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># create a handle for the task</span>
<span class="n">task_id</span> <span class="o">=</span> <span class="n">arg_is_id</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">TaskHandlerTask</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="c1"># handle task no longer existing</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">task</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Task </span><span class="si">{</span><span class="n">task_id</span><span class="si">}</span><span class="s1"> does not exist.&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># get a reference of the function caller requested</span>
<span class="n">switch_action</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">task</span><span class="p">,</span> <span class="n">action_request</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">switch_action</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s1">, is not an acceptable task action or &#39;</span> \
<span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">task_comp_msg</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="c1"># verify manipulating the correct task</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="n">task_args</span> <span class="o">=</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">task_args</span><span class="p">:</span> <span class="c1"># check if the task is still active</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">task_comp_msg</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">t_comp_date</span><span class="p">,</span> <span class="n">t_func_mem_ref</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">coll_date_func</span><span class="p">(</span><span class="n">task_args</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task_args</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="n">t_func_name</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t_func_name</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">task</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span> <span class="c1"># make certain the task has not been called yet.</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">action_request</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span><span class="si">}</span><span class="s1"> task </span><span class="si">{</span><span class="n">task_id</span><span class="si">}</span><span class="s1"> with completion date &#39;</span>
<span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">t_comp_date</span><span class="si">}</span><span class="s1"> (</span><span class="si">{</span><span class="n">t_func_name</span><span class="si">}</span><span class="s1">) </span><span class="se">{{</span><span class="s1">options</span><span class="se">}}</span><span class="s1">?&#39;</span><span class="p">)</span>
<span class="n">no_msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;No </span><span class="si">{</span><span class="n">action_request</span><span class="si">}</span><span class="s1"> processed.&#39;</span>
<span class="c1"># record variables for use in do_task_action method</span>
<span class="bp">self</span><span class="o">.</span><span class="n">task_id</span> <span class="o">=</span> <span class="n">task_id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">t_comp_date</span> <span class="o">=</span> <span class="n">t_comp_date</span>
<span class="bp">self</span><span class="o">.</span><span class="n">t_func_mem_ref</span> <span class="o">=</span> <span class="n">t_func_mem_ref</span>
<span class="bp">self</span><span class="o">.</span><span class="n">task_action</span> <span class="o">=</span> <span class="n">switch_action</span>
<span class="bp">self</span><span class="o">.</span><span class="n">action_request</span> <span class="o">=</span> <span class="n">action_request</span>
<span class="n">ask_yes_no</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prompt</span><span class="o">=</span><span class="n">prompt</span><span class="p">,</span>
<span class="n">yes_action</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">do_task_action</span><span class="p">,</span>
<span class="n">no_action</span><span class="o">=</span><span class="n">no_msg</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="s2">&quot;Y&quot;</span><span class="p">,</span>
<span class="n">allow_abort</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">task_comp_msg</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># the argument is not a task id, process the action on all task deferring the function</span>
<span class="c1"># specified as an argument</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">name_match_found</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">arg_func_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhslist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="c1"># repack tasks into a new dictionary</span>
<span class="n">current_tasks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="n">task_args</span> <span class="ow">in</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">current_tasks</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">task_id</span><span class="p">:</span> <span class="n">task_args</span><span class="p">})</span>
<span class="c1"># call requested action on all tasks with the function name</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="n">task_args</span> <span class="ow">in</span> <span class="n">current_tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task_args</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="n">t_func_name</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t_func_name</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span> <span class="k">else</span> <span class="kc">None</span>
<span class="c1"># skip this task if it is not for the function desired</span>
<span class="k">if</span> <span class="n">arg_func_name</span> <span class="o">!=</span> <span class="n">t_func_name</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">name_match_found</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">TaskHandlerTask</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="n">switch_action</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">task</span><span class="p">,</span> <span class="n">action_request</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="n">switch_action</span><span class="p">:</span>
<span class="n">action_return</span> <span class="o">=</span> <span class="n">switch_action</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Task action </span><span class="si">{</span><span class="n">action_request</span><span class="si">}</span><span class="s1"> completed on task ID </span><span class="si">{</span><span class="n">task_id</span><span class="si">}</span><span class="s1">.&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;The task function </span><span class="si">{</span><span class="n">action_request</span><span class="si">}</span><span class="s1"> returned: </span><span class="si">{</span><span class="n">action_return</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="c1"># provide a message if not tasks of the function name was found</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">name_match_found</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;No tasks deferring function name </span><span class="si">{</span><span class="n">arg_func_name</span><span class="si">}</span><span class="s1"> found.&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># check if an maleformed request was created</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;Task command misformed.&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">&#39;Proper format tasks[/switch] [function name or task id]&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># No task manupilation requested, build a table of tasks and display it</span>
<span class="c1"># get the width of screen in characters</span>
<span class="n">width</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_width</span><span class="p">()</span>
<span class="c1"># create table header and list to hold tasks data and actions</span>
<span class="n">tasks_header</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;Task ID&#39;</span><span class="p">,</span> <span class="s1">&#39;Completion Date&#39;</span><span class="p">,</span> <span class="s1">&#39;Function&#39;</span><span class="p">,</span> <span class="s1">&#39;Arguments&#39;</span><span class="p">,</span> <span class="s1">&#39;KWARGS&#39;</span><span class="p">,</span>
<span class="s1">&#39;persistent&#39;</span><span class="p">)</span>
<span class="c1"># empty list of lists, the size of the header</span>
<span class="n">tasks_list</span> <span class="o">=</span> <span class="p">[</span><span class="nb">list</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">tasks_header</span><span class="p">))]</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="n">task</span> <span class="ow">in</span> <span class="n">_TASK_HANDLER</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="c1"># collect data from the task</span>
<span class="n">t_comp_date</span><span class="p">,</span> <span class="n">t_func_mem_ref</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">coll_date_func</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">t_func_name</span> <span class="o">=</span> <span class="n">t_func_name</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t_func_name</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">t_args</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="n">t_kwargs</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
<span class="n">t_pers</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">task</span><span class="p">[</span><span class="mi">4</span><span class="p">])</span>
<span class="c1"># add task data to the tasks list</span>
<span class="n">task_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">task_id</span><span class="p">,</span> <span class="n">t_comp_date</span><span class="p">,</span> <span class="n">t_func_name</span><span class="p">,</span> <span class="n">t_args</span><span class="p">,</span> <span class="n">t_kwargs</span><span class="p">,</span> <span class="n">t_pers</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">tasks_header</span><span class="p">)):</span>
<span class="n">tasks_list</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">task_data</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="c1"># create and display the table</span>
<span class="n">tasks_table</span> <span class="o">=</span> <span class="n">EvTable</span><span class="p">(</span><span class="o">*</span><span class="n">tasks_header</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="n">tasks_list</span><span class="p">,</span> <span class="n">maxwidth</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">border</span><span class="o">=</span><span class="s1">&#39;cells&#39;</span><span class="p">,</span>
<span class="n">align</span><span class="o">=</span><span class="s1">&#39;center&#39;</span><span class="p">)</span>
<span class="n">actions</span> <span class="o">=</span> <span class="p">(</span><span class="sa">f</span><span class="s1">&#39;/</span><span class="si">{</span><span class="n">switch</span><span class="si">}</span><span class="s1">&#39;</span> <span class="k">for</span> <span class="n">switch</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switch_options</span><span class="p">)</span>
<span class="n">helptxt</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Actions: </span><span class="si">{</span><span class="n">iter_to_str</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">tasks_table</span><span class="p">)</span> <span class="o">+</span> <span class="n">helptxt</span><span class="p">)</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="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="system.html">1.0-dev (develop 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 1.0-dev</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.commands.default.system</a></li>
</ul>
<div class="develop">develop branch</div>
</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>