mirror of
https://github.com/evennia/evennia.git
synced 2026-04-01 13:37:17 +02:00
Updated HTML docs.
This commit is contained in:
parent
95fc796b1e
commit
e64a9c5a4f
55 changed files with 1432 additions and 162 deletions
|
|
@ -86,7 +86,6 @@
|
|||
|
||||
<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">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.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">logger</span><span class="p">,</span> <span class="n">search</span><span class="p">,</span> <span class="n">utils</span>
|
||||
|
|
@ -644,8 +643,9 @@
|
|||
|
||||
<div class="viewcode-block" id="DiscordBot"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.DiscordBot">[docs]</a><span class="k">class</span> <span class="nc">DiscordBot</span><span class="p">(</span><span class="n">Bot</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Discord bot relay. You will need to set up your own bot (https://discord.com/developers/applications)</span>
|
||||
<span class="sd"> and add the bot token as `DISCORD_BOT_TOKEN` to `secret_settings.py` to use</span>
|
||||
<span class="sd"> Discord bot relay. You will need to set up your own bot</span>
|
||||
<span class="sd"> (https://discord.com/developers/applications) and add the bot token as `DISCORD_BOT_TOKEN` to</span>
|
||||
<span class="sd"> `secret_settings.py` to use</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">factory_path</span> <span class="o">=</span> <span class="s2">"evennia.server.portal.discord.DiscordWebsocketServerFactory"</span>
|
||||
|
|
@ -653,9 +653,11 @@
|
|||
<div class="viewcode-block" id="DiscordBot.at_init"><a class="viewcode-back" href="../../../api/evennia.accounts.bots.html#evennia.accounts.bots.DiscordBot.at_init">[docs]</a> <span class="k">def</span> <span class="nf">at_init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Load required channels back into memory</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">channel_links</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">channels</span><span class="p">:</span>
|
||||
<span class="c1"># this attribute contains a list of evennia<->discord links in the form of ("evennia_channel", "discord_chan_id")</span>
|
||||
<span class="c1"># this attribute contains a list of evennia<->discord links in the form</span>
|
||||
<span class="c1"># of ("evennia_channel", "discord_chan_id")</span>
|
||||
<span class="c1"># grab Evennia channels, cache and connect</span>
|
||||
<span class="n">channel_set</span> <span class="o">=</span> <span class="p">{</span><span class="n">evchan</span> <span class="k">for</span> <span class="n">evchan</span><span class="p">,</span> <span class="n">dcid</span> <span class="ow">in</span> <span class="n">channel_links</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_channels</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
|
|
@ -680,7 +682,8 @@
|
|||
<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="k">elif</span> <span class="n">channel_links</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">channels</span><span class="p">:</span>
|
||||
<span class="c1"># this attribute contains a list of evennia<->discord links in the form of ("evennia_channel", "discord_chan_id")</span>
|
||||
<span class="c1"># this attribute contains a list of evennia<->discord links in the form</span>
|
||||
<span class="c1"># of ("evennia_channel", "discord_chan_id")</span>
|
||||
<span class="c1"># grab Evennia channels, cache and connect</span>
|
||||
<span class="n">channel_set</span> <span class="o">=</span> <span class="p">{</span><span class="n">evchan</span> <span class="k">for</span> <span class="n">evchan</span><span class="p">,</span> <span class="n">dcid</span> <span class="ow">in</span> <span class="n">channel_links</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_channels</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
|
|
@ -705,6 +708,7 @@
|
|||
<span class="sd"> Called by the Channel just before passing a message into `channel_msg`.</span>
|
||||
|
||||
<span class="sd"> We overload this to set the channel tag prefix.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">kwargs</span><span class="p">[</span><span class="s2">"no_prefix"</span><span class="p">]</span> <span class="o">=</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">tag_channel</span>
|
||||
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">at_pre_channel_msg</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="n">senders</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
|
||||
|
|
@ -741,7 +745,7 @@
|
|||
<span class="sd"> sender (tuple) - The Discord info for the sender in the form (id, nickname)</span>
|
||||
|
||||
<span class="sd"> Keyword args:</span>
|
||||
<span class="sd"> kwargs (optional) - Unused by default, but can carry additional data from the protocol.</span>
|
||||
<span class="sd"> **kwargs (optional) - Unused by default, but can carry additional data from the protocol.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
|
@ -750,17 +754,20 @@
|
|||
<span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">to_channel</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">from_channel</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">from_server</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"> Formats and sends a Discord -> Evennia message. Called when the Discord bot receives a channel message on Discord.</span>
|
||||
<span class="sd"> Formats and sends a Discord -> Evennia message. Called when the Discord bot receives a</span>
|
||||
<span class="sd"> channel message on Discord.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> message (str) - Incoming text from Discord.</span>
|
||||
<span class="sd"> to_channel (Channel) - The Evennia channel receiving the message</span>
|
||||
|
||||
<span class="sd"> Keyword args:</span>
|
||||
<span class="sd"> sender (tuple) - The Discord info for the sender in the form (id, nickname)</span>
|
||||
<span class="sd"> sender (tuple) - The Discord info for the sender in the form `(id, nickname)`</span>
|
||||
<span class="sd"> from_channel (str) - The Discord channel name</span>
|
||||
<span class="sd"> from_server (str) - The Discord server name</span>
|
||||
<span class="sd"> kwargs - Any additional keywords. Unused by default, but available for adding additional flags or parameters.</span>
|
||||
<span class="sd"> kwargs - Any additional keywords. Unused by default, but available for adding additional</span>
|
||||
<span class="sd"> flags or parameters.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">tag_str</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
<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">django.core.paginator</span> <span class="kn">import</span> <span class="n">Paginator</span>
|
||||
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Max</span><span class="p">,</span> <span class="n">Min</span><span class="p">,</span> <span class="n">Q</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">InterruptCommand</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="kn">import</span> <span class="n">get_and_merge_cmdsets</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.locks.lockhandler</span> <span class="kn">import</span> <span class="n">LockException</span>
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
<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">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
<span class="kn">from</span> <span class="nn">django.db.models.fields</span> <span class="kn">import</span> <span class="n">exceptions</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.server</span> <span class="kn">import</span> <span class="n">signals</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.typeclasses.managers</span> <span class="kn">import</span> <span class="n">TypeclassManager</span><span class="p">,</span> <span class="n">TypedObjectManager</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
<span class="kn">import</span> <span class="nn">inflect</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">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands</span> <span class="kn">import</span> <span class="n">cmdset</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands.cmdsethandler</span> <span class="kn">import</span> <span class="n">CmdSetHandler</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.objects.manager</span> <span class="kn">import</span> <span class="n">ObjectManager</span>
|
||||
|
|
|
|||
667
docs/1.0-dev/_modules/evennia/server/portal/discord.html
Normal file
667
docs/1.0-dev/_modules/evennia/server/portal/discord.html
Normal file
|
|
@ -0,0 +1,667 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>evennia.server.portal.discord — 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>
|
||||
<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.server.portal.discord</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
|
||||
<div class="documentwrapper">
|
||||
<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="discord.html">1.0-dev (develop branch)</a></li>
|
||||
<ul>
|
||||
<li><a href="../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for evennia.server.portal.discord</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Implements Discord chat channel integration.</span>
|
||||
|
||||
<span class="sd">The Discord API uses a mix of websockets and REST API endpoints.</span>
|
||||
|
||||
<span class="sd">In order for this integration to work, you need to have your own</span>
|
||||
<span class="sd">discord bot set up via https://discord.com/developers/applications</span>
|
||||
<span class="sd">with the MESSAGE CONTENT toggle switched on, and your bot token</span>
|
||||
<span class="sd">added to `server/conf/secret_settings.py` as your DISCORD_BOT_TOKEN</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="kn">import</span> <span class="nn">json</span>
|
||||
<span class="kn">import</span> <span class="nn">os</span>
|
||||
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>
|
||||
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">random</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">autobahn.twisted.websocket</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">WebSocketClientFactory</span><span class="p">,</span>
|
||||
<span class="n">WebSocketClientProtocol</span><span class="p">,</span>
|
||||
<span class="n">connectWS</span><span class="p">,</span>
|
||||
<span class="p">)</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">twisted.internet</span> <span class="kn">import</span> <span class="n">protocol</span><span class="p">,</span> <span class="n">reactor</span><span class="p">,</span> <span class="n">ssl</span><span class="p">,</span> <span class="n">task</span>
|
||||
<span class="kn">from</span> <span class="nn">twisted.web.client</span> <span class="kn">import</span> <span class="n">Agent</span><span class="p">,</span> <span class="n">FileBodyProducer</span><span class="p">,</span> <span class="n">readBody</span>
|
||||
<span class="kn">from</span> <span class="nn">twisted.web.http_headers</span> <span class="kn">import</span> <span class="n">Headers</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.server.session</span> <span class="kn">import</span> <span class="n">Session</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">class_from_module</span><span class="p">,</span> <span class="n">get_evennia_version</span><span class="p">,</span> <span class="n">logger</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">delay</span>
|
||||
|
||||
<span class="n">_AGENT</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span><span class="n">reactor</span><span class="p">)</span>
|
||||
|
||||
<span class="n">_BASE_SESSION_CLASS</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">BASE_SESSION_CLASS</span><span class="p">)</span>
|
||||
|
||||
<span class="n">DISCORD_API_VERSION</span> <span class="o">=</span> <span class="mi">10</span>
|
||||
<span class="c1"># include version number to prevent automatically updating to breaking changes</span>
|
||||
<span class="n">DISCORD_API_BASE_URL</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"https://discord.com/api/v</span><span class="si">{</span><span class="n">DISCORD_API_VERSION</span><span class="si">}</span><span class="s2">"</span>
|
||||
|
||||
<span class="n">DISCORD_USER_AGENT</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Evennia (https://www.evennia.com, </span><span class="si">{</span><span class="n">get_evennia_version</span><span class="p">(</span><span class="n">mode</span><span class="o">=</span><span class="s1">'short'</span><span class="p">)</span><span class="si">}</span><span class="s2">)"</span>
|
||||
<span class="n">DISCORD_BOT_TOKEN</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DISCORD_BOT_TOKEN</span>
|
||||
<span class="n">DISCORD_BOT_INTENTS</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DISCORD_BOT_INTENTS</span>
|
||||
|
||||
<span class="c1"># Discord OP codes, alphabetic</span>
|
||||
<span class="n">OP_DISPATCH</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">OP_HEARTBEAT</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
<span class="n">OP_HEARTBEAT_ACK</span> <span class="o">=</span> <span class="mi">11</span>
|
||||
<span class="n">OP_HELLO</span> <span class="o">=</span> <span class="mi">10</span>
|
||||
<span class="n">OP_IDENTIFY</span> <span class="o">=</span> <span class="mi">2</span>
|
||||
<span class="n">OP_INVALID_SESSION</span> <span class="o">=</span> <span class="mi">9</span>
|
||||
<span class="n">OP_RECONNECT</span> <span class="o">=</span> <span class="mi">7</span>
|
||||
<span class="n">OP_RESUME</span> <span class="o">=</span> <span class="mi">6</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="should_retry"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.should_retry">[docs]</a><span class="k">def</span> <span class="nf">should_retry</span><span class="p">(</span><span class="n">status_code</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Helper function to check if the request should be retried later.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> status_code (int) - The HTTP status code</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> retry (bool) - True if request should be retried False otherwise</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">status_code</span> <span class="o">>=</span> <span class="mi">500</span> <span class="ow">and</span> <span class="n">status_code</span> <span class="o"><=</span> <span class="mi">504</span><span class="p">:</span>
|
||||
<span class="c1"># these are common server error codes when the server is temporarily malfunctioning</span>
|
||||
<span class="c1"># in these cases, we should retry</span>
|
||||
<span class="k">return</span> <span class="kc">True</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># handle all other cases; this can be expanded later if needed for special cases</span>
|
||||
<span class="k">return</span> <span class="kc">False</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory">[docs]</a><span class="k">class</span> <span class="nc">DiscordWebsocketServerFactory</span><span class="p">(</span><span class="n">WebSocketClientFactory</span><span class="p">,</span> <span class="n">protocol</span><span class="o">.</span><span class="n">ReconnectingClientFactory</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A variant of the websocket-factory that auto-reconnects.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">initialDelay</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
<span class="n">factor</span> <span class="o">=</span> <span class="mf">1.5</span>
|
||||
<span class="n">maxDelay</span> <span class="o">=</span> <span class="mi">60</span>
|
||||
<span class="n">gateway</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">resume_url</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.__init__"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sessionhandler</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"uid"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span> <span class="o">=</span> <span class="n">sessionhandler</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">bot</span> <span class="o">=</span> <span class="kc">None</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.get_gateway_url"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.get_gateway_url">[docs]</a> <span class="k">def</span> <span class="nf">get_gateway_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="c1"># get the websocket gateway URL from Discord</span>
|
||||
<span class="n">d</span> <span class="o">=</span> <span class="n">_AGENT</span><span class="o">.</span><span class="n">request</span><span class="p">(</span>
|
||||
<span class="sa">b</span><span class="s2">"GET"</span><span class="p">,</span>
|
||||
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">DISCORD_API_BASE_URL</span><span class="si">}</span><span class="s2">/gateway"</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">),</span>
|
||||
<span class="n">Headers</span><span class="p">(</span>
|
||||
<span class="p">{</span>
|
||||
<span class="s2">"User-Agent"</span><span class="p">:</span> <span class="p">[</span><span class="n">DISCORD_USER_AGENT</span><span class="p">],</span>
|
||||
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"Bot </span><span class="si">{</span><span class="n">DISCORD_BOT_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">],</span>
|
||||
<span class="s2">"Content-Type"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"application/json"</span><span class="p">],</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">),</span>
|
||||
<span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">cbResponse</span><span class="p">(</span><span class="n">response</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="mi">200</span><span class="p">:</span>
|
||||
<span class="n">d</span> <span class="o">=</span> <span class="n">readBody</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
|
||||
<span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">websocket_init</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">d</span>
|
||||
<span class="k">elif</span> <span class="n">should_retry</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">code</span><span class="p">):</span>
|
||||
<span class="n">delay</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_gateway_url</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
|
||||
<span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="n">cbResponse</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.websocket_init"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.websocket_init">[docs]</a> <span class="k">def</span> <span class="nf">websocket_init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> callback for when the URL is gotten</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span> <span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">url</span> <span class="o">:=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</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">gateway</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s2">/?v=</span><span class="si">{</span><span class="n">DISCORD_API_VERSION</span><span class="si">}</span><span class="s2">&encoding=json"</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
|
||||
<span class="n">useragent</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"useragent"</span><span class="p">,</span> <span class="n">DISCORD_USER_AGENT</span><span class="p">)</span>
|
||||
<span class="n">headers</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span>
|
||||
<span class="s2">"headers"</span><span class="p">,</span>
|
||||
<span class="p">{</span>
|
||||
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"Bot </span><span class="si">{</span><span class="n">DISCORD_BOT_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">],</span>
|
||||
<span class="s2">"Content-Type"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"application/json"</span><span class="p">],</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="s2">"Connecting to Discord Gateway..."</span><span class="p">)</span>
|
||||
<span class="n">WebSocketClientFactory</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">useragent</span><span class="o">=</span><span class="n">useragent</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="s2">"Discord did not return a websocket URL; connection cancelled."</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.buildProtocol"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.buildProtocol">[docs]</a> <span class="k">def</span> <span class="nf">buildProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Build new instance of protocol</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> addr (str): Not used, using factory/settings data</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s2">"DISCORD_SESSION_CLASS"</span><span class="p">):</span>
|
||||
<span class="n">protocol_class</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span>
|
||||
<span class="n">settings</span><span class="o">.</span><span class="n">DISCORD_SESSION_CLASS</span><span class="p">,</span> <span class="n">fallback</span><span class="o">=</span><span class="n">DiscordClient</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">protocol</span> <span class="o">=</span> <span class="n">protocol_class</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">protocol</span> <span class="o">=</span> <span class="n">DiscordClient</span><span class="p">()</span>
|
||||
|
||||
<span class="n">protocol</span><span class="o">.</span><span class="n">factory</span> <span class="o">=</span> <span class="bp">self</span>
|
||||
<span class="n">protocol</span><span class="o">.</span><span class="n">sessionhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span>
|
||||
<span class="k">return</span> <span class="n">protocol</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.startedConnecting"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.startedConnecting">[docs]</a> <span class="k">def</span> <span class="nf">startedConnecting</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Tracks reconnections for debugging.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> connector (Connector): Represents the connection.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="s2">"Attempting connection to Discord..."</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.clientConnectionFailed"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.clientConnectionFailed">[docs]</a> <span class="k">def</span> <span class="nf">clientConnectionFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Called when Client failed to connect.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> connector (Connection): Represents the connection.</span>
|
||||
<span class="sd"> reason (str): The reason for the failure.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">protocol</span><span class="o">.</span><span class="n">ReconnectingClientFactory</span><span class="o">.</span><span class="n">clientConnectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">,</span> <span class="n">reason</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.clientConnectionLost"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.clientConnectionLost">[docs]</a> <span class="k">def</span> <span class="nf">clientConnectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Called when Client loses connection.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> connector (Connection): Represents the connection.</span>
|
||||
<span class="sd"> reason (str): The reason for the failure.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_retry</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bot</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">retry</span><span class="p">(</span><span class="n">connector</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.reconnect"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.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 reconnection of the bot protocol. This requires</span>
|
||||
<span class="sd"> de-registering the session and then reattaching a new one.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">bot</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">loseConnection</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">server_disconnect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bot</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">resume_url</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resume_url</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">gateway</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">gateway</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># we don't know where to reconnect to! start from the beginning</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">get_gateway_url</span><span class="p">()</span>
|
||||
<span class="k">return</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordWebsocketServerFactory.start"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordWebsocketServerFactory.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="s2">"Connect protocol to remote server"</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">gateway</span><span class="p">:</span>
|
||||
<span class="c1"># we can't actually start yet</span>
|
||||
<span class="c1"># get the gateway URL from Discord</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">get_gateway_url</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">connectWS</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient">[docs]</a><span class="k">class</span> <span class="nc">DiscordClient</span><span class="p">(</span><span class="n">WebSocketClientProtocol</span><span class="p">,</span> <span class="n">_BASE_SESSION_CLASS</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Implements the grapevine client</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">nextHeartbeatCall</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">pending_heartbeat</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">heartbeat_interval</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">last_sequence</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">session_id</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">discord_id</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.__init__"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">WebSocketClientProtocol</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="n">_BASE_SESSION_CLASS</span><span class="o">.</span><span class="fm">__init__</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">restart_downtime</span> <span class="o">=</span> <span class="kc">None</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.at_login"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.at_login">[docs]</a> <span class="k">def</span> <span class="nf">at_login</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.onOpen"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.onOpen">[docs]</a> <span class="k">def</span> <span class="nf">onOpen</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Called when connection is established.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">restart_downtime</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">restart_task</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">bot</span> <span class="o">=</span> <span class="bp">self</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">init_session</span><span class="p">(</span><span class="s2">"discord"</span><span class="p">,</span> <span class="s2">"discord.gg"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">sessionhandler</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">logged_in</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.onMessage"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.onMessage">[docs]</a> <span class="k">def</span> <span class="nf">onMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span><span class="p">,</span> <span class="n">isBinary</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Callback fired when a complete WebSocket message was received.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> payload (bytes): The WebSocket message received.</span>
|
||||
<span class="sd"> isBinary (bool): Flag indicating whether payload is binary or</span>
|
||||
<span class="sd"> UTF-8 encoded text.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">isBinary</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="s2">"DISCORD: got a binary payload for some reason"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span> <span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">seqid</span> <span class="o">:=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"s"</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">last_sequence</span> <span class="o">=</span> <span class="n">seqid</span>
|
||||
|
||||
<span class="c1"># not sure if that error json format is for websockets</span>
|
||||
<span class="c1"># check for it just in case</span>
|
||||
<span class="k">if</span> <span class="s2">"errors"</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="c1"># check for discord gateway API op codes first</span>
|
||||
<span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_HELLO</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">][</span><span class="s2">"heartbeat_interval"</span><span class="p">]</span> <span class="o">/</span> <span class="mi">1000</span> <span class="c1"># convert millisec to seconds</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">_batched_timer</span><span class="o">.</span><span class="n">call_later</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">*</span> <span class="n">random</span><span class="p">(),</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">doHeartbeat</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_id</span><span class="p">:</span>
|
||||
<span class="c1"># we already have a session; try to resume instead</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">resume</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">identify</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_HEARTBEAT_ACK</span><span class="p">:</span>
|
||||
<span class="c1"># our last heartbeat was acknowledged, so reset the "pending" flag</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">pending_heartbeat</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="k">elif</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_HEARTBEAT</span><span class="p">:</span>
|
||||
<span class="c1"># Discord wants us to send a heartbeat immediately</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">doHeartbeat</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_INVALID_SESSION</span><span class="p">:</span>
|
||||
<span class="c1"># Discord doesn't like our current session; reconnect for a new one</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_msg</span><span class="p">(</span><span class="s2">"Discord: received 'Invalid Session' opcode. Reconnecting."</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">]</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
|
||||
<span class="c1"># can't resume, clear existing resume data</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">session_id</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">resume_url</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">reconnect</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_RECONNECT</span><span class="p">:</span>
|
||||
<span class="c1"># reconnect as requested; Discord does this regularly for server load balancing</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_msg</span><span class="p">(</span><span class="s2">"Discord: received 'Reconnect' opcode. Reconnecting."</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">reconnect</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="n">data</span><span class="p">[</span><span class="s2">"op"</span><span class="p">]</span> <span class="o">==</span> <span class="n">OP_DISPATCH</span><span class="p">:</span>
|
||||
<span class="c1"># handle the general dispatch opcode events by type</span>
|
||||
<span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"t"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"READY"</span><span class="p">:</span>
|
||||
<span class="c1"># our recent identification is valid; process new session info</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">connection_ready</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">])</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># general message, pass on to data_in</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">data_in</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.onClose"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.onClose">[docs]</a> <span class="k">def</span> <span class="nf">onClose</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wasClean</span><span class="p">,</span> <span class="n">code</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> This is executed when the connection is lost for whatever</span>
|
||||
<span class="sd"> reason. it can also be called directly, from the disconnect</span>
|
||||
<span class="sd"> method.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> wasClean (bool): ``True`` if the WebSocket was closed cleanly.</span>
|
||||
<span class="sd"> code (int or None): Close status as sent by the WebSocket peer.</span>
|
||||
<span class="sd"> reason (str or None): Close reason as sent by the WebSocket peer.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">reason</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">code</span> <span class="o">>=</span> <span class="mi">4000</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Discord connection closed: </span><span class="si">{</span><span class="n">reason</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Discord disconnected: </span><span class="si">{</span><span class="n">reason</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_send_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Post JSON data to the websocket</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> data (dict): content to send.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">sendMessage</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_post_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</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"> Post JSON data to a REST API endpoint</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> url (str) - The API path which is being posted to</span>
|
||||
<span class="sd"> data (dict) - Content to be sent</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">DISCORD_API_BASE_URL</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="n">body</span> <span class="o">=</span> <span class="n">FileBodyProducer</span><span class="p">(</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)))</span>
|
||||
<span class="n">d</span> <span class="o">=</span> <span class="n">_AGENT</span><span class="o">.</span><span class="n">request</span><span class="p">(</span>
|
||||
<span class="sa">b</span><span class="s2">"POST"</span><span class="p">,</span>
|
||||
<span class="n">url</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">),</span>
|
||||
<span class="n">Headers</span><span class="p">(</span>
|
||||
<span class="p">{</span>
|
||||
<span class="s2">"User-Agent"</span><span class="p">:</span> <span class="p">[</span><span class="n">DISCORD_USER_AGENT</span><span class="p">],</span>
|
||||
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"Bot </span><span class="si">{</span><span class="n">DISCORD_BOT_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">],</span>
|
||||
<span class="s2">"Content-Type"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"application/json"</span><span class="p">],</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">),</span>
|
||||
<span class="n">body</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">cbResponse</span><span class="p">(</span><span class="n">response</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="mi">200</span><span class="p">:</span>
|
||||
<span class="n">d</span> <span class="o">=</span> <span class="n">readBody</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
|
||||
<span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">post_response</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">d</span>
|
||||
<span class="k">elif</span> <span class="n">should_retry</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">code</span><span class="p">):</span>
|
||||
<span class="n">delay</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_post_json</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
|
||||
<span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="n">cbResponse</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.post_response"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.post_response">[docs]</a> <span class="k">def</span> <span class="nf">post_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">body</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"> Process the response from sending a POST request</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> body (bytes) - The post response body</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="s2">"errors"</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.handle_error"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.handle_error">[docs]</a> <span class="k">def</span> <span class="nf">handle_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</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"> General hook for processing errors.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> data (dict) - The received error data</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">data</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.resume"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.resume">[docs]</a> <span class="k">def</span> <span class="nf">resume</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Called after a reconnection to re-identify and replay missed events</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">last_sequence</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_id</span><span class="p">:</span>
|
||||
<span class="c1"># we have no known state to resume from, identify normally</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">identify</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># build a RESUME request for Discord and send it</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"op"</span><span class="p">:</span> <span class="n">OP_RESUME</span><span class="p">,</span>
|
||||
<span class="s2">"d"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"token"</span><span class="p">:</span> <span class="n">DISCORD_BOT_TOKEN</span><span class="p">,</span>
|
||||
<span class="s2">"session_id"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_id</span><span class="p">,</span>
|
||||
<span class="s2">"s"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequence_id</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">_send_json</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.disconnect"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.disconnect">[docs]</a> <span class="k">def</span> <span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Generic hook for the engine to call in order to</span>
|
||||
<span class="sd"> disconnect this protocol.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> reason (str or None): Motivation for the disconnection.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</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="bp">self</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sendClose</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">CLOSE_STATUS_CODE_NORMAL</span><span class="p">,</span> <span class="n">reason</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.identify"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.identify">[docs]</a> <span class="k">def</span> <span class="nf">identify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Send Discord authentication. This should be sent once heartbeats begin.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"op"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
|
||||
<span class="s2">"d"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"token"</span><span class="p">:</span> <span class="n">DISCORD_BOT_TOKEN</span><span class="p">,</span>
|
||||
<span class="s2">"intents"</span><span class="p">:</span> <span class="n">DISCORD_BOT_INTENTS</span><span class="p">,</span>
|
||||
<span class="s2">"properties"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"os"</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"browser"</span><span class="p">:</span> <span class="n">DISCORD_USER_AGENT</span><span class="p">,</span>
|
||||
<span class="s2">"device"</span><span class="p">:</span> <span class="n">DISCORD_USER_AGENT</span><span class="p">,</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">_send_json</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.connection_ready"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.connection_ready">[docs]</a> <span class="k">def</span> <span class="nf">connection_ready</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Process READY data for relevant bot info.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">resume_url</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"resume_gateway_url"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">session_id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"session_id"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">discord_id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"user"</span><span class="p">][</span><span class="s2">"id"</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.doHeartbeat"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.doHeartbeat">[docs]</a> <span class="k">def</span> <span class="nf">doHeartbeat</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Send heartbeat to Discord.</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">pending_heartbeat</span> <span class="ow">or</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"force"</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
|
||||
<span class="c1"># send the heartbeat</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"op"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_sequence</span><span class="p">}</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_send_json</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||||
<span class="c1"># track that we sent a heartbeat, in case we don't receive an ACK</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">pending_heartbeat</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">nextHeartbeatCall</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">_batched_timer</span><span class="o">.</span><span class="n">call_later</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">doHeartbeat</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># we didn't get a response since the last heartbeat; reconnect</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">reconnect</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.send_channel"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.send_channel">[docs]</a> <span class="k">def</span> <span class="nf">send_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">channel_id</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"> Send a message from an Evennia channel to a Discord channel.</span>
|
||||
|
||||
<span class="sd"> Use with session.msg(channel=(message, channel, sender))</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"content"</span><span class="p">:</span> <span class="n">text</span><span class="p">}</span>
|
||||
<span class="n">data</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_post_json</span><span class="p">(</span><span class="sa">f</span><span class="s2">"channels/</span><span class="si">{</span><span class="n">channel_id</span><span class="si">}</span><span class="s2">/messages"</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.send_default"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.send_default">[docs]</a> <span class="k">def</span> <span class="nf">send_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Ignore other outputfuncs</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DiscordClient.data_in"><a class="viewcode-back" href="../../../../api/evennia.server.portal.discord.html#evennia.server.portal.discord.DiscordClient.data_in">[docs]</a> <span class="k">def</span> <span class="nf">data_in</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</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"> Process incoming data from Discord and sent to the Evennia server</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> data (dict): Converted json data.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">action_type</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"t"</span><span class="p">,</span> <span class="s2">"UNKNOWN"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">action_type</span> <span class="o">==</span> <span class="s2">"MESSAGE_CREATE"</span><span class="p">:</span>
|
||||
<span class="c1"># someone posted a message on Discord that the bot can see</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"author"</span><span class="p">][</span><span class="s2">"id"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">discord_id</span><span class="p">:</span>
|
||||
<span class="c1"># it's by the bot itself! disregard</span>
|
||||
<span class="k">return</span>
|
||||
<span class="n">message</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"content"</span><span class="p">]</span>
|
||||
<span class="n">channel_id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"channel_id"</span><span class="p">]</span>
|
||||
<span class="n">keywords</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"channel_id"</span><span class="p">:</span> <span class="n">channel_id</span><span class="p">}</span>
|
||||
<span class="k">if</span> <span class="s2">"guild_id"</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
||||
<span class="c1"># message received to a Discord channel</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"channel"</span>
|
||||
<span class="n">author</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"member"</span><span class="p">][</span><span class="s2">"nick"</span><span class="p">]</span> <span class="ow">or</span> <span class="n">data</span><span class="p">[</span><span class="s2">"author"</span><span class="p">][</span><span class="s2">"username"</span><span class="p">]</span>
|
||||
<span class="n">author_id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"author"</span><span class="p">][</span><span class="s2">"id"</span><span class="p">]</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"sender"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">author_id</span><span class="p">,</span> <span class="n">author</span><span class="p">)</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"guild_id"</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"guild_id"</span><span class="p">]</span>
|
||||
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># message sent directly to the bot account via DM</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"direct"</span>
|
||||
<span class="n">author</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"author"</span><span class="p">][</span><span class="s2">"username"</span><span class="p">]</span>
|
||||
<span class="n">author_id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"author"</span><span class="p">][</span><span class="s2">"id"</span><span class="p">]</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"sender"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">author_id</span><span class="p">,</span> <span class="n">author</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># pass the processed data to the server</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">data_in</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bot_data_in</span><span class="o">=</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">keywords</span><span class="p">))</span>
|
||||
|
||||
<span class="k">elif</span> <span class="n">action_type</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"GUILD_CREATE"</span><span class="p">,</span> <span class="s2">"GUILD_UPDATE"</span><span class="p">):</span>
|
||||
<span class="c1"># we received the current status of a guild the bot is on; process relevant info</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">]</span>
|
||||
<span class="n">keywords</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"type"</span><span class="p">:</span> <span class="s2">"guild"</span><span class="p">,</span> <span class="s2">"guild_id"</span><span class="p">:</span> <span class="n">data</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span> <span class="s2">"guild_name"</span><span class="p">:</span> <span class="n">data</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]}</span>
|
||||
<span class="n">keywords</span><span class="p">[</span><span class="s2">"channels"</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="n">chan</span><span class="p">[</span><span class="s2">"id"</span><span class="p">]:</span> <span class="p">{</span><span class="s2">"name"</span><span class="p">:</span> <span class="n">chan</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="s2">"guild"</span><span class="p">:</span> <span class="n">data</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]}</span>
|
||||
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">data</span><span class="p">[</span><span class="s2">"channels"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">chan</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span>
|
||||
<span class="p">}</span>
|
||||
<span class="c1"># send the possibly-updated guild and channel data to the server</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">data_in</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bot_data_in</span><span class="o">=</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">keywords</span><span class="p">))</span>
|
||||
|
||||
<span class="k">elif</span> <span class="s2">"DELETE"</span> <span class="ow">in</span> <span class="n">action_type</span><span class="p">:</span>
|
||||
<span class="c1"># deletes should possibly be handled separately to check for channel removal</span>
|
||||
<span class="c1"># for now, just ignore</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># send the data for any other action types on to the bot as-is for optional server-side handling</span>
|
||||
<span class="n">keywords</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"type"</span><span class="p">:</span> <span class="n">action_type</span><span class="p">}</span>
|
||||
<span class="n">keywords</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s2">"d"</span><span class="p">])</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">data_in</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bot_data_in</span><span class="o">=</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">keywords</span><span class="p">))</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</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.server.portal.discord</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -86,6 +86,7 @@
|
|||
|
||||
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span><span class="p">,</span> <span class="n">ExpressionWrapper</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">FloatField</span><span class="p">,</span> <span class="n">Q</span>
|
||||
<span class="kn">from</span> <span class="nn">django.db.models.functions</span> <span class="kn">import</span> <span class="n">Cast</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.typeclasses.attributes</span> <span class="kn">import</span> <span class="n">Attribute</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.typeclasses.tags</span> <span class="kn">import</span> <span class="n">Tag</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">idmapper</span>
|
||||
|
|
|
|||
|
|
@ -275,6 +275,7 @@
|
|||
<li><a href="evennia/server/models.html">evennia.server.models</a></li>
|
||||
<li><a href="evennia/server/portal/amp.html">evennia.server.portal.amp</a></li>
|
||||
<li><a href="evennia/server/portal/amp_server.html">evennia.server.portal.amp_server</a></li>
|
||||
<li><a href="evennia/server/portal/discord.html">evennia.server.portal.discord</a></li>
|
||||
<li><a href="evennia/server/portal/grapevine.html">evennia.server.portal.grapevine</a></li>
|
||||
<li><a href="evennia/server/portal/irc.html">evennia.server.portal.irc</a></li>
|
||||
<li><a href="evennia/server/portal/mccp.html">evennia.server.portal.mccp</a></li>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue