Updated HTML docs

This commit is contained in:
Griatch 2021-10-26 21:41:11 +02:00
parent 66d0ad0bc9
commit 7900aad365
2073 changed files with 32986 additions and 41197 deletions

View file

@ -14,6 +14,8 @@
<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" />
@ -38,12 +40,12 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="locks">
<section class="tex2jax_ignore mathjax_ignore" id="locks">
<h1>Locks<a class="headerlink" href="#locks" title="Permalink to this headline"></a></h1>
<p>For most games it is a good idea to restrict what people can do. In Evennia such restrictions are
applied and checked by something called <em>locks</em>. All Evennia entities (<a class="reference internal" href="Commands.html"><span class="doc">Commands</span></a>,
<a class="reference internal" href="Objects.html"><span class="doc">Objects</span></a>, <a class="reference internal" href="Scripts.html"><span class="doc">Scripts</span></a>, <a class="reference internal" href="Accounts.html"><span class="doc">Accounts</span></a>, <a class="reference internal" href="Help-System.html"><span class="doc">Help System</span></a>,
<a class="reference external" href="Components/Communications.html#Msg">messages</a> and <a class="reference external" href="Components/Communications.html#Channels">channels</a>) are accessed through locks.</p>
applied and checked by something called <em>locks</em>. All Evennia entities (<a class="reference internal" href="Commands.html"><span class="doc std std-doc">Commands</span></a>,
<a class="reference internal" href="Objects.html"><span class="doc std std-doc">Objects</span></a>, <a class="reference internal" href="Scripts.html"><span class="doc std std-doc">Scripts</span></a>, <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>, <a class="reference internal" href="Help-System.html"><span class="doc std std-doc">Help System</span></a>,
<a class="reference internal" href="Msg.html"><span class="doc std std-doc">messages</span></a> and <a class="reference internal" href="Channels.html"><span class="doc std std-doc">channels</span></a>) are accessed through locks.</p>
<p>A lock can be thought of as an “access rule” restricting a particular use of an Evennia entity.
Whenever another entity wants that kind of access the lock will analyze that entity in different
ways to determine if access should be granted or not. Evennia implements a “lockdown” philosophy -
@ -57,47 +59,42 @@ to go on with its job.</p>
<section id="setting-and-checking-a-lock">
<h2>Setting and checking a lock<a class="headerlink" href="#setting-and-checking-a-lock" title="Permalink to this headline"></a></h2>
<p>The in-game command for setting locks on objects is <code class="docutils literal notranslate"><span class="pre">lock</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">&gt;</span> <span class="n">lock</span> <span class="n">obj</span> <span class="o">=</span> <span class="o">&lt;</span><span class="n">lockstring</span><span class="o">&gt;</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> &gt; lock obj = &lt;lockstring&gt;
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">&lt;lockstring&gt;</span></code> is a string of a certain form that defines the behaviour of the lock. We will go
into more detail on how <code class="docutils literal notranslate"><span class="pre">&lt;lockstring&gt;</span></code> should look in the next section.</p>
<p>Code-wise, Evennia handles locks through what is usually called <code class="docutils literal notranslate"><span class="pre">locks</span></code> on all relevant entities.
This is a handler that allows you to add, delete and check locks.</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">myobj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="o">&lt;</span><span class="n">lockstring</span><span class="o">&gt;</span><span class="p">)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">myobj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="o">&lt;</span><span class="n">lockstring</span><span class="o">&gt;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>One can call <code class="docutils literal notranslate"><span class="pre">locks.check()</span></code> to perform a lock check, but to hide the underlying implementation all
objects also have a convenience function called <code class="docutils literal notranslate"><span class="pre">access</span></code>. This should preferably be used. In the
example below, <code class="docutils literal notranslate"><span class="pre">accessing_obj</span></code> is the object requesting the delete access whereas <code class="docutils literal notranslate"><span class="pre">obj</span></code> is the
object that might get deleted. This is how it would look (and does look) from inside the <code class="docutils literal notranslate"><span class="pre">delete</span></code>
command:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">):</span>
<span class="n">accessing_obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Sorry, you may not delete that.&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="defining-locks">
<h2>Defining locks<a class="headerlink" href="#defining-locks" title="Permalink to this headline"></a></h2>
<p>Defining a lock (i.e. an access restriction) in Evennia is done by adding simple strings of lock
definitions to the objects <code class="docutils literal notranslate"><span class="pre">locks</span></code> property using <code class="docutils literal notranslate"><span class="pre">obj.locks.add()</span></code>.</p>
<p>Here are some examples of lock strings (not including the quotes):</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">)</span> <span class="c1"># only allow obj #34 to delete</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">)</span> <span class="c1"># only allow obj #34 to delete</span>
<span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">()</span> <span class="c1"># let everyone edit</span>
<span class="c1"># only those who are not &quot;very_weak&quot; or are Admins may pick this up</span>
<span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Formally, a lockstring has the following syntax:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">access_type</span><span class="p">:</span> <span class="p">[</span><span class="n">NOT</span><span class="p">]</span> <span class="n">lockfunc1</span><span class="p">([</span><span class="n">arg1</span><span class="p">,</span><span class="o">..</span><span class="p">])</span> <span class="p">[</span><span class="n">AND</span><span class="o">|</span><span class="n">OR</span><span class="p">]</span> <span class="p">[</span><span class="n">NOT</span><span class="p">]</span> <span class="n">lockfunc2</span><span class="p">([</span><span class="n">arg1</span><span class="p">,</span><span class="o">...</span><span class="p">])</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">access_type</span><span class="p">:</span> <span class="p">[</span><span class="n">NOT</span><span class="p">]</span> <span class="n">lockfunc1</span><span class="p">([</span><span class="n">arg1</span><span class="p">,</span><span class="o">..</span><span class="p">])</span> <span class="p">[</span><span class="n">AND</span><span class="o">|</span><span class="n">OR</span><span class="p">]</span> <span class="p">[</span><span class="n">NOT</span><span class="p">]</span> <span class="n">lockfunc2</span><span class="p">([</span><span class="n">arg1</span><span class="p">,</span><span class="o">...</span><span class="p">])</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
</pre></div>
</td></tr></table></div>
</div>
<p>where <code class="docutils literal notranslate"><span class="pre">[]</span></code> marks optional parts. <code class="docutils literal notranslate"><span class="pre">AND</span></code>, <code class="docutils literal notranslate"><span class="pre">OR</span></code> and <code class="docutils literal notranslate"><span class="pre">NOT</span></code> are not case sensitive and excess spaces are
ignored. <code class="docutils literal notranslate"><span class="pre">lockfunc1,</span> <span class="pre">lockfunc2</span></code> etc are special <em>lock functions</em> available to the lock system.</p>
<p>So, a lockstring consists of the type of restriction (the <code class="docutils literal notranslate"><span class="pre">access_type</span></code>), a colon (<code class="docutils literal notranslate"><span class="pre">:</span></code>) and then an
@ -106,7 +103,7 @@ returns either <code class="docutils literal notranslate"><span class="pre">True
total result is <code class="docutils literal notranslate"><span class="pre">True</span></code>, the lock is passed.</p>
<p>You can create several lock types one after the other by separating them with a semicolon (<code class="docutils literal notranslate"><span class="pre">;</span></code>) in
the lockstring. The string below yields the same result as the previous example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">);</span><span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">();</span><span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>delete:id(34);edit:all();get: not attr(very_weak) or perm(Admin)
</pre></div>
</div>
<section id="valid-access-types">
@ -119,12 +116,12 @@ the default command set) actually checks for, as in the example of <code class="
delete <code class="docutils literal notranslate"><span class="pre">access_type</span></code>.</p>
<p>Below are the access_types checked by the default commandset.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Commands.html"><span class="doc">Commands</span></a></p>
<li><p><a class="reference internal" href="Commands.html"><span class="doc std std-doc">Commands</span></a></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">cmd</span></code> - this defines who may call this command at all.</p></li>
</ul>
</li>
<li><p><a class="reference internal" href="Objects.html"><span class="doc">Objects</span></a>:</p>
<li><p><a class="reference internal" href="Objects.html"><span class="doc std std-doc">Objects</span></a>:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">control</span></code> - who is the “owner” of the object. Can set locks, delete it etc. Defaults to the
creator of the object.</p></li>
@ -142,18 +139,18 @@ something like <code class="docutils literal notranslate"><span class="pre">call
<li><p><code class="docutils literal notranslate"><span class="pre">attrcreate</span></code> - who may create new attributes on the object (default True)</p></li>
</ul>
</li>
<li><p><a class="reference external" href="Components/Objects.html#Characters">Characters</a>:</p>
<li><p><a class="reference internal" href="Objects.html#characters"><span class="std std-doc">Characters</span></a>:</p>
<ul>
<li><p>Same as for Objects</p></li>
</ul>
</li>
<li><p><a class="reference external" href="Components/Objects.html#Exits">Exits</a>:</p>
<li><p><a class="reference internal" href="Objects.html#exits"><span class="std std-doc">Exits</span></a>:</p>
<ul>
<li><p>Same as for Objects</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">traverse</span></code> - who may pass the exit.</p></li>
</ul>
</li>
<li><p><a class="reference internal" href="Accounts.html"><span class="doc">Accounts</span></a>:</p>
<li><p><a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">examine</span></code> - who may examine the accounts properties.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">delete</span></code> - who may delete the account.</p></li>
@ -162,13 +159,13 @@ something like <code class="docutils literal notranslate"><span class="pre">call
<li><p><code class="docutils literal notranslate"><span class="pre">boot</span></code> - who may boot the account.</p></li>
</ul>
</li>
<li><p><a class="reference internal" href="Attributes.html"><span class="doc">Attributes</span></a>: (only checked by <code class="docutils literal notranslate"><span class="pre">obj.secure_attr</span></code>)</p>
<li><p><a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a>: (only checked by <code class="docutils literal notranslate"><span class="pre">obj.secure_attr</span></code>)</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">attrread</span></code> - see/access attribute</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attredit</span></code> - change/delete attribute</p></li>
</ul>
</li>
<li><p><a class="reference external" href="Components/Communications.html#Channels">Channels</a>:</p>
<li><p><a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a>:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">control</span></code> - who is administrating the channel. This means the ability to delete the channel,
boot listeners etc.</p></li>
@ -176,7 +173,7 @@ boot listeners etc.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">listen</span></code> - who may subscribe and listen to the channel.</p></li>
</ul>
</li>
<li><p><a class="reference internal" href="Help-System.html"><span class="doc">HelpEntry</span></a>:</p>
<li><p><a class="reference internal" href="Help-System.html"><span class="doc std std-doc">HelpEntry</span></a>:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">examine</span></code> - who may view this help entry (usually everyone)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">edit</span></code> - who may edit this help entry.</p></li>
@ -193,21 +190,19 @@ text is an arbitrary string that must be unique for an object. If adding a lock
<code class="docutils literal notranslate"><span class="pre">access_type</span></code> as one that already exists on the object, the new one override the old one.</p>
<p>For example, if you wanted to create a bulletin board system and wanted to restrict who can either
read a board or post to a board. You could then define locks such as:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;read:perm(Player);post:perm(Admin)&quot;</span><span class="p">)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;read:perm(Player);post:perm(Admin)&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>This will create a read access type for Characters having the <code class="docutils literal notranslate"><span class="pre">Player</span></code> permission or above and a
post access type for those with <code class="docutils literal notranslate"><span class="pre">Admin</span></code> permissions or above (see below how the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lock
function works). When it comes time to test these permissions, simply check like this (in this
example, the <code class="docutils literal notranslate"><span class="pre">obj</span></code> may be a board on the bulletin board system and <code class="docutils literal notranslate"><span class="pre">accessing_obj</span></code> is the player
trying to read the board):</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">&#39;read&#39;</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">&#39;read&#39;</span><span class="p">):</span>
<span class="n">accessing_obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Sorry, you may not read that.&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="lock-functions">
<h3>Lock functions<a class="headerlink" href="#lock-functions" title="Permalink to this headline"></a></h3>
@ -221,14 +216,7 @@ your own with the same name.</p>
object wanting to get access) and the <em>accessed object</em> (this is the object with the lock). Those
two are fed automatically as the first two arguments to the function when the lock is checked. Any
arguments explicitly given in the lock definition will appear as extra arguments.</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span>
<span class="normal">7</span>
<span class="normal">8</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># A simple example lock function. Called with e.g. `id(34)`. This is</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># A simple example lock function. Called with e.g. `id(34)`. This is</span>
<span class="c1"># defined in, say mygame/server/conf/lockfuncs.py</span>
<span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">accessed_obj</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>
@ -237,23 +225,19 @@ arguments explicitly given in the lock definition will appear as extra arguments
<span class="k">return</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">wanted_id</span>
<span class="k">return</span> <span class="kc">False</span>
</pre></div>
</td></tr></table></div>
</div>
<p>The above could for example be used in a lock function like this:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># we have `obj` and `owner_object` from before</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># we have `obj` and `owner_object` from before</span>
<span class="n">obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;edit: id(</span><span class="si">{</span><span class="n">owner_object</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>We could check if the “edit” lock is passed with something like this:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># as part of a Command&#39;s func() method, for example</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># as part of a Command&#39;s func() method, for example</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">obj</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;edit&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 don&#39;t have access to edit this!&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</td></tr></table></div>
</div>
<p>In this example, everyone except the <code class="docutils literal notranslate"><span class="pre">caller</span></code> with the right <code class="docutils literal notranslate"><span class="pre">id</span></code> will get the error.</p>
<blockquote>
<div><p>(Using the <code class="docutils literal notranslate"><span class="pre">*</span></code> and <code class="docutils literal notranslate"><span class="pre">**</span></code> syntax causes Python to magically put all extra arguments into a list
@ -266,10 +250,10 @@ how <code class="docutils literal notranslate"><span class="pre">*args</span></c
<li><p><code class="docutils literal notranslate"><span class="pre">false()/none()/superuser()</span></code> - give access to none. Superusers bypass the check entirely and are
thus the only ones who will pass this check.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">perm(perm)</span></code> - this tries to match a given <code class="docutils literal notranslate"><span class="pre">permission</span></code> property, on an Account firsthand, on a
Character second. See <a class="reference external" href="Components/Locks.html#permissions">below</a>.</p></li>
Character second. See <a class="reference internal" href="Permissions.html"><span class="doc std std-doc">below</span></a>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">perm_above(perm)</span></code> - like <code class="docutils literal notranslate"><span class="pre">perm</span></code> but requires a “higher” permission level than the one given.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">id(num)/dbref(num)</span></code> - checks so the access_object has a certain dbref/id.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attr(attrname)</span></code> - checks if a certain <a class="reference internal" href="Attributes.html"><span class="doc">Attribute</span></a> exists on accessing_object.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attr(attrname)</span></code> - checks if a certain <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attribute</span></a> exists on accessing_object.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attr(attrname,</span> <span class="pre">value)</span></code> - checks so an attribute exists on accessing_object <em>and</em> has the given
value.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attr_gt(attrname,</span> <span class="pre">value)</span></code> - checks so accessing_object has a value larger (<code class="docutils literal notranslate"><span class="pre">&gt;</span></code>) than the given
@ -290,22 +274,19 @@ setting set to a given value.</p></li>
<p>Sometimes you dont really need to look up a certain lock, you just want to check a lockstring. A
common use is inside Commands, in order to check if a user has a certain permission. The lockhandler
has a method <code class="docutils literal notranslate"><span class="pre">check_lockstring(accessing_obj,</span> <span class="pre">lockstring,</span> <span class="pre">bypass_superuser=False)</span></code> that allows this.</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># inside command definition</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># inside command definition</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">locks</span><span class="o">.</span><span class="n">check_lockstring</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="s2">&quot;dummy:perm(Admin)&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="s2">&quot;You must be an Admin or higher to do this!&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Note here that the <code class="docutils literal notranslate"><span class="pre">access_type</span></code> can be left to a dummy value since this method does not actually do
a Lock lookup.</p>
</section>
<section id="default-locks">
<h2>Default locks<a class="headerlink" href="#default-locks" title="Permalink to this headline"></a></h2>
<p>Evennia sets up a few basic locks on all new objects and accounts (if we didnt, noone would have
any access to anything from the start). This is all defined in the root <a class="reference internal" href="Typeclasses.html"><span class="doc">Typeclasses</span></a>
any access to anything from the start). This is all defined in the root <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a>
of the respective entity, in the hook method <code class="docutils literal notranslate"><span class="pre">basetype_setup()</span></code> (which you usually dont want to
edit unless you want to change how basic stuff like rooms and exits store their internal variables).
This is called once, before <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>, so just put them in the latter method on your
@ -315,78 +296,70 @@ control and delete the object.</p>
</section>
<section id="more-lock-definition-examples">
<h2>More Lock definition examples<a class="headerlink" href="#more-lock-definition-examples" title="Permalink to this headline"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">examine</span><span class="p">:</span> <span class="n">attr</span><span class="p">(</span><span class="n">eyesight</span><span class="p">,</span> <span class="n">excellent</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builders</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>examine: attr(eyesight, excellent) or perm(Builders)
</pre></div>
</div>
<p>You are only allowed to do <em>examine</em> on this object if you have excellent eyesight (that is, has
an Attribute <code class="docutils literal notranslate"><span class="pre">eyesight</span></code> with the value <code class="docutils literal notranslate"><span class="pre">excellent</span></code> defined on yourself) or if you have the
“Builders” permission string assigned to you.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span><span class="p">:</span> <span class="n">holds</span><span class="p">(</span><span class="s1">&#39;the green key&#39;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builder</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open: holds(&#39;the green key&#39;) or perm(Builder)
</pre></div>
</div>
<p>This could be called by the <code class="docutils literal notranslate"><span class="pre">open</span></code> command on a “door” object. The check is passed if you are a
Builder or has the right key in your inventory.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmd</span><span class="p">:</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builders</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cmd: perm(Builders)
</pre></div>
</div>
<p>Evennias command handler looks for a lock of type <code class="docutils literal notranslate"><span class="pre">cmd</span></code> to determine if a user is allowed to even
call upon a particular command or not. When you define a command, this is the kind of lock you must
set. See the default command set for lots of examples. If a character/account dont pass the <code class="docutils literal notranslate"><span class="pre">cmd</span></code>
lock type the command will not even appear in their <code class="docutils literal notranslate"><span class="pre">help</span></code> list.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmd</span><span class="p">:</span> <span class="ow">not</span> <span class="n">perm</span><span class="p">(</span><span class="n">no_tell</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cmd: not perm(no_tell)
</pre></div>
</div>
<p>“Permissions” can also be used to block users or implement highly specific bans. The above example
would be be added as a lock string to the <code class="docutils literal notranslate"><span class="pre">tell</span></code> command. This will allow everyone <em>not</em> having the
“permission” <code class="docutils literal notranslate"><span class="pre">no_tell</span></code> to use the <code class="docutils literal notranslate"><span class="pre">tell</span></code> command. You could easily give an account the “permission”
<code class="docutils literal notranslate"><span class="pre">no_tell</span></code> to disable their use of this particular command henceforth.</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">dbref</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">id</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">dbref</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">id</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;control:id(</span><span class="si">%s</span><span class="s2">);examine:perm(Builders);delete:id(</span><span class="si">%s</span><span class="s2">) or perm(Admin);get:all()&quot;</span> <span class="o">%</span>
<span class="p">(</span><span class="n">dbref</span><span class="p">,</span> <span class="n">dbref</span><span class="p">)</span>
<span class="n">new_obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>This is how the <code class="docutils literal notranslate"><span class="pre">create</span></code> command sets up new objects. In sequence, this permission string sets the
owner of this object be the creator (the one running <code class="docutils literal notranslate"><span class="pre">create</span></code>). Builders may examine the object
whereas only Admins and the creator may delete it. Everyone can pick it up.</p>
</section>
<section id="a-complete-example-of-setting-locks-on-an-object">
<h2>A complete example of setting locks on an object<a class="headerlink" href="#a-complete-example-of-setting-locks-on-an-object" title="Permalink to this headline"></a></h2>
<p>Assume we have two objects - one is ourselves (not superuser) and the other is an <a class="reference internal" href="Objects.html"><span class="doc">Object</span></a>
<p>Assume we have two objects - one is ourselves (not superuser) and the other is an <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a>
called <code class="docutils literal notranslate"><span class="pre">box</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">&gt;</span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">box</span>
<span class="o">&gt;</span> <span class="n">desc</span> <span class="n">box</span> <span class="o">=</span> <span class="s2">&quot;This is a very big and heavy box.&quot;</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> &gt; create/drop box
&gt; desc box = &quot;This is a very big and heavy box.&quot;
</pre></div>
</div>
<p>We want to limit which objects can pick up this heavy box. Lets say that to do that we require the
would-be lifter to to have an attribute <em>strength</em> on themselves, with a value greater than 50. We
assign it to ourselves to begin with.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">&gt;</span> <span class="nb">set</span> <span class="bp">self</span><span class="o">/</span><span class="n">strength</span> <span class="o">=</span> <span class="mi">45</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> &gt; set self/strength = 45
</pre></div>
</div>
<p>Ok, so for testing we made ourselves strong, but not strong enough. Now we need to look at what
happens when someone tries to pick up the the box - they use the <code class="docutils literal notranslate"><span class="pre">get</span></code> command (in the default set).
This is defined in <code class="docutils literal notranslate"><span class="pre">evennia/commands/default/general.py</span></code>. In its code we find this snippet:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</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="s1">&#39;get&#39;</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</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="s1">&#39;get&#39;</span><span class="p">):</span>
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">get_err_msg</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">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">get_err_msg</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="s2">&quot;You can&#39;t get that.&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</td></tr></table></div>
</div>
<p>So the <code class="docutils literal notranslate"><span class="pre">get</span></code> command looks for a lock with the type <em>get</em> (not so surprising). It also looks for an
<a class="reference internal" href="Attributes.html"><span class="doc">Attribute</span></a> on the checked object called <em>get_err_msg</em> in order to return a customized
<a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attribute</span></a> on the checked object called <em>get_err_msg</em> in order to return a customized
error message. Sounds good! Lets start by setting that on the box:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">&gt;</span> <span class="nb">set</span> <span class="n">box</span><span class="o">/</span><span class="n">get_err_msg</span> <span class="o">=</span> <span class="n">You</span> <span class="n">are</span> <span class="ow">not</span> <span class="n">strong</span> <span class="n">enough</span> <span class="n">to</span> <span class="n">lift</span> <span class="n">this</span> <span class="n">box</span><span class="o">.</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> &gt; set box/get_err_msg = You are not strong enough to lift this box.
</pre></div>
</div>
<p>Next we need to craft a Lock of type <em>get</em> on our box. We want it to only be passed if the accessing
@ -394,27 +367,13 @@ object has the attribute <em>strength</em> of the right value. For this we would
function that checks if attributes have a value greater than a given value. Luckily there is already
such a one included in evennia (see <code class="docutils literal notranslate"><span class="pre">evennia/locks/lockfuncs.py</span></code>), called <code class="docutils literal notranslate"><span class="pre">attr_gt</span></code>.</p>
<p>So the lock string will look like this: <code class="docutils literal notranslate"><span class="pre">get:attr_gt(strength,</span> <span class="pre">50)</span></code>. We put this on the box now:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">lock</span> <span class="n">box</span> <span class="o">=</span> <span class="n">get</span><span class="p">:</span><span class="n">attr_gt</span><span class="p">(</span><span class="n">strength</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> lock box = get:attr_gt(strength, 50)
</pre></div>
</div>
<p>Try to <code class="docutils literal notranslate"><span class="pre">get</span></code> the object and you should get the message that we are not strong enough. Increase your
strength above 50 however and youll pick it up no problem. Done! A very heavy box!</p>
<p>If you wanted to set this up in python code, it would look something like this:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
<span class="c1"># create, then set the lock</span>
@ -430,10 +389,10 @@ strength above 50 however and youll pick it up no problem. Done! A very heavy
<span class="c1"># one heavy box, ready to withstand all but the strongest...</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="on-django-s-permission-system">
<h2>On Djangos permission system<a class="headerlink" href="#on-django-s-permission-system" title="Permalink to this headline"></a></h2>
<section id="on-djangos-permission-system">
<h2>On Djangos permission system<a class="headerlink" href="#on-djangos-permission-system" title="Permalink to this headline"></a></h2>
<p>Django also implements a comprehensive permission/security system of its own. The reason we dont
use that is because it is app-centric (app in the Django sense). Its permission strings are of the
form <code class="docutils literal notranslate"><span class="pre">appname.permstring</span></code> and it automatically adds three of them for each database model in the app</p>
@ -483,7 +442,7 @@ interface. Its stand-alone from the permissions described above.</p>
<li><a class="reference internal" href="#default-locks">Default locks</a></li>
<li><a class="reference internal" href="#more-lock-definition-examples">More Lock definition examples</a></li>
<li><a class="reference internal" href="#a-complete-example-of-setting-locks-on-an-object">A complete example of setting locks on an object</a></li>
<li><a class="reference internal" href="#on-django-s-permission-system">On Djangos permission system</a></li>
<li><a class="reference internal" href="#on-djangos-permission-system">On Djangos permission system</a></li>
</ul>
</li>
</ul>
@ -508,7 +467,7 @@ interface. Its stand-alone from the permissions described above.</p>
<h3>Versions</h3>
<ul>
<li><a href="Locks.html">1.0-dev (develop branch)</a></li>
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
<li><a href="../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
</ul>
</div>