mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 10:37:16 +01:00
686 lines
No EOL
76 KiB
HTML
686 lines
No EOL
76 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>evennia.accounts.bots — 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> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">evennia.accounts.bots</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.accounts.bots</h1><div class="highlight"><pre>
|
|
<span></span><span class="sd">"""</span>
|
|
<span class="sd">Bots are a special child typeclasses of</span>
|
|
<span class="sd">Account that are controlled by the server.</span>
|
|
|
|
<span class="sd">"""</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.accounts.accounts</span> <span class="kn">import</span> <span class="n">DefaultAccount</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.scripts.scripts</span> <span class="kn">import</span> <span class="n">DefaultScript</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">search</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">utils</span>
|
|
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
|
|
|
|
<span class="n">_IDLE_TIMEOUT</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">IDLE_TIMEOUT</span>
|
|
|
|
<span class="n">_IRC_ENABLED</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">IRC_ENABLED</span>
|
|
<span class="n">_RSS_ENABLED</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">RSS_ENABLED</span>
|
|
<span class="n">_GRAPEVINE_ENABLED</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">GRAPEVINE_ENABLED</span>
|
|
|
|
|
|
<span class="n">_SESSIONS</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
|
|
<span class="c1"># Bot helper utilities</span>
|
|
|
|
|
|
<div class="viewcode-block" id="BotStarter"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter">[docs]</a><span class="k">class</span> <span class="nc">BotStarter</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This non-repeating script has the</span>
|
|
<span class="sd"> sole purpose of kicking its bot</span>
|
|
<span class="sd"> into gear when it is initialized.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="BotStarter.at_script_creation"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter.at_script_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Called once, when script is created.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">"botstarter"</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="s2">"bot start/keepalive"</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">persistent</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">False</span></div>
|
|
|
|
<div class="viewcode-block" id="BotStarter.at_start"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter.at_start">[docs]</a> <span class="k">def</span> <span class="nf">at_start</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Kick bot into gear.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">started</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">True</span></div>
|
|
|
|
<div class="viewcode-block" id="BotStarter.at_repeat"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter.at_repeat">[docs]</a> <span class="k">def</span> <span class="nf">at_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Called self.interval seconds to keep connection. We cannot use</span>
|
|
<span class="sd"> the IDLE command from inside the game since the system will</span>
|
|
<span class="sd"> not catch it (commands executed from the server side usually</span>
|
|
<span class="sd"> has no sessions). So we update the idle counter manually here</span>
|
|
<span class="sd"> instead. This keeps the bot getting hit by IDLE_TIMEOUT.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">global</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_SESSIONS</span><span class="p">:</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="k">as</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">for</span> <span class="n">session</span> <span class="ow">in</span> <span class="n">_SESSIONS</span><span class="o">.</span><span class="n">sessions_from_account</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">):</span>
|
|
<span class="n">session</span><span class="o">.</span><span class="n">update_session_counters</span><span class="p">(</span><span class="n">idle</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="BotStarter.at_server_reload"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter.at_server_reload">[docs]</a> <span class="k">def</span> <span class="nf">at_server_reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> If server reloads we don't need to reconnect the protocol</span>
|
|
<span class="sd"> again, this is handled by the portal reconnect mechanism.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">True</span></div>
|
|
|
|
<div class="viewcode-block" id="BotStarter.at_server_shutdown"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.BotStarter.at_server_shutdown">[docs]</a> <span class="k">def</span> <span class="nf">at_server_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Make sure we are shutdown.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">False</span></div></div>
|
|
|
|
|
|
<span class="c1">#</span>
|
|
<span class="c1"># Bot base class</span>
|
|
|
|
|
|
<div class="viewcode-block" id="Bot"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot">[docs]</a><span class="k">class</span> <span class="nc">Bot</span><span class="p">(</span><span class="n">DefaultAccount</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> A Bot will start itself when the server starts (it will generally</span>
|
|
<span class="sd"> not do so on a reload - that will be handled by the normal Portal</span>
|
|
<span class="sd"> session resync)</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="Bot.basetype_setup"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot.basetype_setup">[docs]</a> <span class="k">def</span> <span class="nf">basetype_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This sets up the basic properties for the bot.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># the text encoding to use.</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">encoding</span> <span class="o">=</span> <span class="s2">"utf-8"</span>
|
|
<span class="c1"># A basic security setup (also avoid idle disconnects)</span>
|
|
<span class="n">lockstring</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"examine:perm(Admin);edit:perm(Admin);delete:perm(Admin);"</span>
|
|
<span class="s2">"boot:perm(Admin);msg:false();noidletimeout:true()"</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
|
|
<span class="c1"># set the basics of being a bot</span>
|
|
<span class="n">script_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">scripts</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">BotStarter</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">script_key</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">is_bot</span> <span class="o">=</span> <span class="kc">True</span></div>
|
|
|
|
<div class="viewcode-block" id="Bot.start"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This starts the bot, whatever that may mean.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="Bot.msg"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot.msg">[docs]</a> <span class="k">def</span> <span class="nf">msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">from_obj</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Evennia -> outgoing protocol</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="n">text</span><span class="p">,</span> <span class="n">from_obj</span><span class="o">=</span><span class="n">from_obj</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="n">options</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="Bot.execute_cmd"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot.execute_cmd">[docs]</a> <span class="k">def</span> <span class="nf">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">raw_string</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Incoming protocol -> Evennia</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">raw_string</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="Bot.at_server_shutdown"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.Bot.at_server_shutdown">[docs]</a> <span class="k">def</span> <span class="nf">at_server_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> We need to handle this case manually since the shutdown may be</span>
|
|
<span class="sd"> a reset.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">for</span> <span class="n">session</span> <span class="ow">in</span> <span class="bp">self</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">session</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">session</span><span class="p">)</span></div></div>
|
|
|
|
|
|
<span class="c1"># Bot implementations</span>
|
|
|
|
<span class="c1"># IRC</span>
|
|
|
|
|
|
<div class="viewcode-block" id="IRCBot"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot">[docs]</a><span class="k">class</span> <span class="nc">IRCBot</span><span class="p">(</span><span class="n">Bot</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Bot for handling IRC connections.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="c1"># override this on a child class to use custom factory</span>
|
|
<span class="n">factory_path</span> <span class="o">=</span> <span class="s2">"evennia.server.portal.irc.IRCBotFactory"</span>
|
|
|
|
<div class="viewcode-block" id="IRCBot.start"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">ev_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">irc_botname</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">irc_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">irc_network</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">irc_port</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">irc_ssl</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Start by telling the portal to start a new session.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> ev_channel (str): Key of the Evennia channel to connect to.</span>
|
|
<span class="sd"> irc_botname (str): Name of bot to connect to irc channel. If</span>
|
|
<span class="sd"> not set, use `self.key`.</span>
|
|
<span class="sd"> irc_channel (str): Name of channel on the form `#channelname`.</span>
|
|
<span class="sd"> irc_network (str): URL of the IRC network, like `irc.freenode.net`.</span>
|
|
<span class="sd"> irc_port (str): Port number of the irc network, like `6667`.</span>
|
|
<span class="sd"> irc_ssl (bool): Indicates whether to use SSL connection.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IRC_ENABLED</span><span class="p">:</span>
|
|
<span class="c1"># the bot was created, then IRC was turned off. We delete</span>
|
|
<span class="c1"># ourselves (this will also kill the start script)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">global</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_SESSIONS</span><span class="p">:</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="k">as</span> <span class="n">_SESSIONS</span>
|
|
|
|
<span class="c1"># if keywords are given, store (the BotStarter script</span>
|
|
<span class="c1"># will not give any keywords, so this should normally only</span>
|
|
<span class="c1"># happen at initialization)</span>
|
|
<span class="k">if</span> <span class="n">irc_botname</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span> <span class="o">=</span> <span class="n">irc_botname</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span>
|
|
<span class="k">if</span> <span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># connect to Evennia channel</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">ev_channel</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Evennia Channel '</span><span class="si">{</span><span class="n">ev_channel</span><span class="si">}</span><span class="s2">' not found."</span><span class="p">)</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="n">channel</span>
|
|
<span class="k">if</span> <span class="n">irc_channel</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span> <span class="o">=</span> <span class="n">irc_channel</span>
|
|
<span class="k">if</span> <span class="n">irc_network</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span> <span class="o">=</span> <span class="n">irc_network</span>
|
|
<span class="k">if</span> <span class="n">irc_port</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span> <span class="o">=</span> <span class="n">irc_port</span>
|
|
<span class="k">if</span> <span class="n">irc_ssl</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_ssl</span> <span class="o">=</span> <span class="n">irc_ssl</span>
|
|
|
|
<span class="c1"># instruct the server and portal to create a new session with</span>
|
|
<span class="c1"># the stored configuration</span>
|
|
<span class="n">configdict</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"uid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbid</span><span class="p">,</span>
|
|
<span class="s2">"botname"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span><span class="p">,</span>
|
|
<span class="s2">"channel"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span><span class="p">,</span>
|
|
<span class="s2">"network"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span><span class="p">,</span>
|
|
<span class="s2">"port"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span><span class="p">,</span>
|
|
<span class="s2">"ssl"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_ssl</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="n">_SESSIONS</span><span class="o">.</span><span class="n">start_bot_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">factory_path</span><span class="p">,</span> <span class="n">configdict</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.at_msg_send"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.at_msg_send">[docs]</a> <span class="k">def</span> <span class="nf">at_msg_send</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="s2">"Shortcut here or we can end up in infinite loop"</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.get_nicklist"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.get_nicklist">[docs]</a> <span class="k">def</span> <span class="nf">get_nicklist</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="sd">"""</span>
|
|
<span class="sd"> Retrive the nick list from the connected channel.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> caller (Object or Account): The requester of the list. This will</span>
|
|
<span class="sd"> be stored and echoed to when the irc network replies with the</span>
|
|
<span class="sd"> requested info.</span>
|
|
|
|
<span class="sd"> Notes: Since the return is asynchronous, the caller is stored internally</span>
|
|
<span class="sd"> in a list; all callers in this list will get the nick info once it</span>
|
|
<span class="sd"> returns (it is a custom OOB inputfunc option). The callback will not</span>
|
|
<span class="sd"> survive a reload (which should be fine, it's very quick).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_nicklist_callers"</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_nicklist_callers</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_nicklist_callers</span><span class="o">.</span><span class="n">append</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="n">msg</span><span class="p">(</span><span class="n">request_nicklist</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">return</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.ping"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.ping">[docs]</a> <span class="k">def</span> <span class="nf">ping</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="sd">"""</span>
|
|
<span class="sd"> Fire a ping to the IRC server.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> caller (Object or Account): The requester of the ping.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_ping_callers"</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_ping_callers</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_ping_callers</span><span class="o">.</span><span class="n">append</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="n">msg</span><span class="p">(</span><span class="n">ping</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.reconnect"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.reconnect">[docs]</a> <span class="k">def</span> <span class="nf">reconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Force a protocol-side reconnect of the client without</span>
|
|
<span class="sd"> having to destroy/recreate the bot "account".</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">reconnect</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.msg"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.msg">[docs]</a> <span class="k">def</span> <span class="nf">msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Takes text from connected channel (only).</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> text (str, optional): Incoming text from channel.</span>
|
|
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> options (dict): Options dict with the following allowed keys:</span>
|
|
<span class="sd"> - from_channel (str): dbid of a channel this text originated from.</span>
|
|
<span class="sd"> - from_obj (list): list of objects sending this text.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">from_obj</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"from_obj"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">options</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"options"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># cache channel lookup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="s2">"from_channel"</span> <span class="ow">in</span> <span class="n">options</span>
|
|
<span class="ow">and</span> <span class="n">text</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="o">.</span><span class="n">dbid</span> <span class="o">==</span> <span class="n">options</span><span class="p">[</span><span class="s2">"from_channel"</span><span class="p">]</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">from_obj</span> <span class="ow">or</span> <span class="n">from_obj</span> <span class="o">!=</span> <span class="p">[</span><span class="bp">self</span><span class="p">]:</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">channel</span><span class="o">=</span><span class="n">text</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="IRCBot.execute_cmd"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.IRCBot.execute_cmd">[docs]</a> <span class="k">def</span> <span class="nf">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">txt</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Take incoming data and send it to connected channel. This is</span>
|
|
<span class="sd"> triggered by the bot_data_in Inputfunc.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> session (Session, optional): Session responsible for this</span>
|
|
<span class="sd"> command. Note that this is the bot.</span>
|
|
<span class="sd"> txt (str, optional): Command string.</span>
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> user (str): The name of the user who sent the message.</span>
|
|
<span class="sd"> channel (str): The name of channel the message was sent to.</span>
|
|
<span class="sd"> type (str): Nature of message. Either 'msg', 'action', 'nicklist'</span>
|
|
<span class="sd"> or 'ping'.</span>
|
|
<span class="sd"> nicklist (list, optional): Set if `type='nicklist'`. This is a list</span>
|
|
<span class="sd"> of nicks returned by calling the `self.get_nicklist`. It must look</span>
|
|
<span class="sd"> for a list `self._nicklist_callers` which will contain all callers</span>
|
|
<span class="sd"> waiting for the nicklist.</span>
|
|
<span class="sd"> timings (float, optional): Set if `type='ping'`. This is the return</span>
|
|
<span class="sd"> (in seconds) of a ping request triggered with `self.ping`. The</span>
|
|
<span class="sd"> return must look for a list `self._ping_callers` which will contain</span>
|
|
<span class="sd"> all callers waiting for the ping return.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"nicklist"</span><span class="p">:</span>
|
|
<span class="c1"># the return of a nicklist request</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_nicklist_callers"</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nicklist_callers</span><span class="p">:</span>
|
|
<span class="n">chstr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span><span class="si">}</span><span class="s2">)"</span>
|
|
<span class="n">nicklist</span> <span class="o">=</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s2">"nicklist"</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">()))</span>
|
|
<span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nicklist_callers</span><span class="p">:</span>
|
|
<span class="n">obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
|
|
<span class="s2">"Nicks at </span><span class="si">{chstr}</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">{nicklist}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">chstr</span><span class="o">=</span><span class="n">chstr</span><span class="p">,</span> <span class="n">nicklist</span><span class="o">=</span><span class="n">nicklist</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_nicklist_callers</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"ping"</span><span class="p">:</span>
|
|
<span class="c1"># the return of a ping</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_ping_callers"</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ping_callers</span><span class="p">:</span>
|
|
<span class="n">chstr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span><span class="si">}</span><span class="s2">)"</span>
|
|
<span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ping_callers</span><span class="p">:</span>
|
|
<span class="n">obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
|
|
<span class="s2">"IRC ping return from </span><span class="si">{chstr}</span><span class="s2"> took </span><span class="si">{time}</span><span class="s2">s."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">chstr</span><span class="o">=</span><span class="n">chstr</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="n">kwargs</span><span class="p">[</span><span class="s2">"timing"</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">_ping_callers</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">elif</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"privmsg"</span><span class="p">:</span>
|
|
<span class="c1"># A private message to the bot - a command.</span>
|
|
<span class="n">user</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"user"</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">txt</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"who"</span><span class="p">):</span>
|
|
<span class="c1"># return server WHO list (abbreviated for IRC)</span>
|
|
<span class="k">global</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_SESSIONS</span><span class="p">:</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="k">as</span> <span class="n">_SESSIONS</span>
|
|
<span class="n">whos</span> <span class="o">=</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="k">for</span> <span class="n">sess</span> <span class="ow">in</span> <span class="n">_SESSIONS</span><span class="o">.</span><span class="n">get_sessions</span><span class="p">():</span>
|
|
<span class="n">delta_cmd</span> <span class="o">=</span> <span class="n">t0</span> <span class="o">-</span> <span class="n">sess</span><span class="o">.</span><span class="n">cmd_last_visible</span>
|
|
<span class="n">delta_conn</span> <span class="o">=</span> <span class="n">t0</span> <span class="o">-</span> <span class="n">session</span><span class="o">.</span><span class="n">conn_time</span>
|
|
<span class="n">account</span> <span class="o">=</span> <span class="n">sess</span><span class="o">.</span><span class="n">get_account</span><span class="p">()</span>
|
|
<span class="n">whos</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">/</span><span class="si">%s</span><span class="s2">)"</span>
|
|
<span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">utils</span><span class="o">.</span><span class="n">crop</span><span class="p">(</span><span class="s2">"|w</span><span class="si">%s</span><span class="s2">|n"</span> <span class="o">%</span> <span class="n">account</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">25</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">delta_conn</span><span class="p">,</span> <span class="mi">0</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">delta_cmd</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Who list (online/idle): </span><span class="si">{</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">whos</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">w</span><span class="p">:</span> <span class="n">w</span><span class="o">.</span><span class="n">lower</span><span class="p">()))</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">elif</span> <span class="n">txt</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"about"</span><span class="p">):</span>
|
|
<span class="c1"># some bot info</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"This is an Evennia IRC bot connecting from '</span><span class="si">{</span><span class="n">settings</span><span class="o">.</span><span class="n">SERVERNAME</span><span class="si">}</span><span class="s2">'."</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="s2">"I understand 'who' and 'about'."</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">privmsg</span><span class="o">=</span><span class="p">((</span><span class="n">text</span><span class="p">,),</span> <span class="p">{</span><span class="s2">"user"</span><span class="p">:</span> <span class="n">user</span><span class="p">}))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># something to send to the main channel</span>
|
|
<span class="k">if</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"action"</span><span class="p">:</span>
|
|
<span class="c1"># An action (irc pose)</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]</span><span class="si">}</span><span class="s2">@</span><span class="si">{</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'channel'</span><span class="p">]</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">txt</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># msg - A normal channel message</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]</span><span class="si">}</span><span class="s2">@</span><span class="si">{</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'channel'</span><span class="p">]</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">txt</span><span class="si">}</span><span class="s2">"</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># cache channel lookup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span></div></div>
|
|
|
|
|
|
<span class="c1">#</span>
|
|
<span class="c1"># RSS</span>
|
|
<span class="c1">#</span>
|
|
|
|
|
|
<div class="viewcode-block" id="RSSBot"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.RSSBot">[docs]</a><span class="k">class</span> <span class="nc">RSSBot</span><span class="p">(</span><span class="n">Bot</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> An RSS relayer. The RSS protocol itself runs a ticker to update</span>
|
|
<span class="sd"> its feed at regular intervals.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="RSSBot.start"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.RSSBot.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ev_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">rss_url</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">rss_rate</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Start by telling the portal to start a new RSS session</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> ev_channel (str): Key of the Evennia channel to connect to.</span>
|
|
<span class="sd"> rss_url (str): Full URL to the RSS feed to subscribe to.</span>
|
|
<span class="sd"> rss_rate (int): How often for the feedreader to update.</span>
|
|
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> RuntimeError: If `ev_channel` does not exist.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_RSS_ENABLED</span><span class="p">:</span>
|
|
<span class="c1"># The bot was created, then RSS was turned off. Delete ourselves.</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">global</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_SESSIONS</span><span class="p">:</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="k">as</span> <span class="n">_SESSIONS</span>
|
|
|
|
<span class="k">if</span> <span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># connect to Evennia channel</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">ev_channel</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Evennia Channel '</span><span class="si">{</span><span class="n">ev_channel</span><span class="si">}</span><span class="s2">' not found."</span><span class="p">)</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="n">channel</span>
|
|
<span class="k">if</span> <span class="n">rss_url</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_url</span> <span class="o">=</span> <span class="n">rss_url</span>
|
|
<span class="k">if</span> <span class="n">rss_rate</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_rate</span> <span class="o">=</span> <span class="n">rss_rate</span>
|
|
<span class="c1"># instruct the server and portal to create a new session with</span>
|
|
<span class="c1"># the stored configuration</span>
|
|
<span class="n">configdict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"uid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbid</span><span class="p">,</span> <span class="s2">"url"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_url</span><span class="p">,</span> <span class="s2">"rate"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_rate</span><span class="p">}</span>
|
|
<span class="n">_SESSIONS</span><span class="o">.</span><span class="n">start_bot_session</span><span class="p">(</span><span class="s2">"evennia.server.portal.rss.RSSBotFactory"</span><span class="p">,</span> <span class="n">configdict</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="RSSBot.execute_cmd"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.RSSBot.execute_cmd">[docs]</a> <span class="k">def</span> <span class="nf">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">txt</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Take incoming data and send it to connected channel. This is</span>
|
|
<span class="sd"> triggered by the bot_data_in Inputfunc.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> session (Session, optional): Session responsible for this</span>
|
|
<span class="sd"> command.</span>
|
|
<span class="sd"> txt (str, optional): Command string.</span>
|
|
<span class="sd"> kwargs (dict, optional): Additional Information passed from bot.</span>
|
|
<span class="sd"> Not used by the RSSbot by default.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># cache channel lookup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">txt</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span></div></div>
|
|
|
|
|
|
<span class="c1"># Grapevine bot</span>
|
|
|
|
|
|
<div class="viewcode-block" id="GrapevineBot"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.GrapevineBot">[docs]</a><span class="k">class</span> <span class="nc">GrapevineBot</span><span class="p">(</span><span class="n">Bot</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> g Grapevine (https://grapevine.haus) relayer. The channel to connect to is the first</span>
|
|
<span class="sd"> name in the settings.GRAPEVINE_CHANNELS list.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">factory_path</span> <span class="o">=</span> <span class="s2">"evennia.server.portal.grapevine.RestartingWebsocketServerFactory"</span>
|
|
|
|
<div class="viewcode-block" id="GrapevineBot.start"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.GrapevineBot.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ev_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">grapevine_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Start by telling the portal to connect to the grapevine network.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_GRAPEVINE_ENABLED</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">global</span> <span class="n">_SESSIONS</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_SESSIONS</span><span class="p">:</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="k">as</span> <span class="n">_SESSIONS</span>
|
|
|
|
<span class="c1"># connect to Evennia channel</span>
|
|
<span class="k">if</span> <span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># connect to Evennia channel</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">ev_channel</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Evennia Channel '</span><span class="si">{</span><span class="n">ev_channel</span><span class="si">}</span><span class="s2">' not found."</span><span class="p">)</span>
|
|
<span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="n">channel</span>
|
|
|
|
<span class="k">if</span> <span class="n">grapevine_channel</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">grapevine_channel</span> <span class="o">=</span> <span class="n">grapevine_channel</span>
|
|
|
|
<span class="c1"># these will be made available as properties on the protocol factory</span>
|
|
<span class="n">configdict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"uid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbid</span><span class="p">,</span> <span class="s2">"grapevine_channel"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">grapevine_channel</span><span class="p">}</span>
|
|
|
|
<span class="n">_SESSIONS</span><span class="o">.</span><span class="n">start_bot_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">factory_path</span><span class="p">,</span> <span class="n">configdict</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="GrapevineBot.at_msg_send"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.GrapevineBot.at_msg_send">[docs]</a> <span class="k">def</span> <span class="nf">at_msg_send</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="s2">"Shortcut here or we can end up in infinite loop"</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="GrapevineBot.msg"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.GrapevineBot.msg">[docs]</a> <span class="k">def</span> <span class="nf">msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Takes text from connected channel (only).</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> text (str, optional): Incoming text from channel.</span>
|
|
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> options (dict): Options dict with the following allowed keys:</span>
|
|
<span class="sd"> - from_channel (str): dbid of a channel this text originated from.</span>
|
|
<span class="sd"> - from_obj (list): list of objects sending this text.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">from_obj</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"from_obj"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">options</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"options"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># cache channel lookup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="s2">"from_channel"</span> <span class="ow">in</span> <span class="n">options</span>
|
|
<span class="ow">and</span> <span class="n">text</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="o">.</span><span class="n">dbid</span> <span class="o">==</span> <span class="n">options</span><span class="p">[</span><span class="s2">"from_channel"</span><span class="p">]</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">from_obj</span> <span class="ow">or</span> <span class="n">from_obj</span> <span class="o">!=</span> <span class="p">[</span><span class="bp">self</span><span class="p">]:</span>
|
|
<span class="c1"># send outputfunc channel(msg, chan, sender)</span>
|
|
|
|
<span class="c1"># TODO we should refactor channel formatting to operate on the</span>
|
|
<span class="c1"># account/object level instead. For now, remove the channel/name</span>
|
|
<span class="c1"># prefix since we pass that explicitly anyway</span>
|
|
<span class="n">prefix</span><span class="p">,</span> <span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
|
|
<span class="n">channel</span><span class="o">=</span><span class="p">(</span>
|
|
<span class="n">text</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">grapevine_channel</span><span class="p">,</span>
|
|
<span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">from_obj</span><span class="p">),</span>
|
|
<span class="p">{},</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="GrapevineBot.execute_cmd"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.GrapevineBot.execute_cmd">[docs]</a> <span class="k">def</span> <span class="nf">execute_cmd</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">txt</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">event</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">grapevine_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">sender</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">game</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
|
|
<span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Take incoming data from protocol and send it to connected channel. This is</span>
|
|
<span class="sd"> triggered by the bot_data_in Inputfunc.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">event</span> <span class="o">==</span> <span class="s2">"channels/broadcast"</span><span class="p">:</span>
|
|
<span class="c1"># A private message to the bot - a command.</span>
|
|
|
|
<span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">sender</span><span class="si">}</span><span class="s2">@</span><span class="si">{</span><span class="n">game</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">txt</span><span class="si">}</span><span class="s2">"</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="c1"># simple cache of channel lookup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">ev_channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</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="bots.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> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">evennia.accounts.bots</a></li>
|
|
</ul>
|
|
<div class="develop">develop branch</div>
|
|
</div>
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2020, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
|
</div>
|
|
</body>
|
|
</html> |