mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 22:06:30 +01:00
403 lines
34 KiB
HTML
403 lines
34 KiB
HTML
|
|
|
|||
|
|
<!DOCTYPE html>
|
|||
|
|
|
|||
|
|
<html>
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8" />
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
|||
|
|
|
|||
|
|
<title>Messagepath — Evennia 0.9.5 documentation</title>
|
|||
|
|
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
|
|||
|
|
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
|||
|
|
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
|
|||
|
|
<script src="_static/jquery.js"></script>
|
|||
|
|
<script src="_static/underscore.js"></script>
|
|||
|
|
<script src="_static/doctools.js"></script>
|
|||
|
|
<script src="_static/language_data.js"></script>
|
|||
|
|
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
|||
|
|
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
|
|||
|
|
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
|||
|
|
<link rel="index" title="Index" href="genindex.html" />
|
|||
|
|
<link rel="search" title="Search" href="search.html" />
|
|||
|
|
</head><body>
|
|||
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|||
|
|
<h3>Navigation</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li class="right" style="margin-right: 10px">
|
|||
|
|
<a href="genindex.html" title="General Index"
|
|||
|
|
accesskey="I">index</a></li>
|
|||
|
|
<li class="right" >
|
|||
|
|
<a href="py-modindex.html" title="Python Module Index"
|
|||
|
|
>modules</a> |</li>
|
|||
|
|
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> »</li>
|
|||
|
|
<li class="nav-item nav-item-this"><a href="">Messagepath</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="document">
|
|||
|
|
<div class="documentwrapper">
|
|||
|
|
<div class="bodywrapper">
|
|||
|
|
<div class="body" role="main">
|
|||
|
|
|
|||
|
|
<section class="tex2jax_ignore mathjax_ignore" id="messagepath">
|
|||
|
|
<h1>Messagepath<a class="headerlink" href="#messagepath" title="Permalink to this headline">¶</a></h1>
|
|||
|
|
<p>The main functionality of Evennia is to communicate with clients connected to it; a player enters
|
|||
|
|
commands or their client queries for a gui update (ingoing data). The server responds or sends data
|
|||
|
|
on its own as the game changes (outgoing data). It’s important to understand how this flow of
|
|||
|
|
information works in Evennia.</p>
|
|||
|
|
<section id="the-ingoing-message-path">
|
|||
|
|
<h2>The ingoing message path<a class="headerlink" href="#the-ingoing-message-path" title="Permalink to this headline">¶</a></h2>
|
|||
|
|
<p>We’ll start by tracing data from the client to the server. Here it is in short:</p>
|
|||
|
|
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Client ->
|
|||
|
|
PortalSession ->
|
|||
|
|
PortalSessionhandler ->
|
|||
|
|
(AMP) ->
|
|||
|
|
ServerSessionHandler ->
|
|||
|
|
ServerSession ->
|
|||
|
|
Inputfunc
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<section id="client-ingoing">
|
|||
|
|
<h3>Client (ingoing)<a class="headerlink" href="#client-ingoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>The client sends data to Evennia in two ways.</p>
|
|||
|
|
<ul class="simple">
|
|||
|
|
<li><p>When first connecting, the client can send data to the server about its
|
|||
|
|
capabilities. This is things like “I support xterm256 but not unicode” and is
|
|||
|
|
mainly used when a Telnet client connects. This is called a “handshake” and
|
|||
|
|
will generally set some flags on the <a class="reference internal" href="Portal-And-Server.html"><span class="doc std std-doc">Portal Session</span></a> that
|
|||
|
|
are later synced to the Server Session. Since this is not something the player
|
|||
|
|
controls, we’ll not explore this further here.</p></li>
|
|||
|
|
<li><p>The client can send an <em>inputcommand</em> to the server. Traditionally this only
|
|||
|
|
happens when the player enters text on the command line. But with a custom
|
|||
|
|
client GUI, a command could also come from the pressing of a button. Finally
|
|||
|
|
the client may send commands based on a timer or some trigger.</p></li>
|
|||
|
|
</ul>
|
|||
|
|
<p>Exactly how the inputcommand looks when it travels from the client to Evennia
|
|||
|
|
depends on the <a class="reference internal" href="Custom-Protocols.html"><span class="doc std std-doc">Protocol</span></a> used:</p>
|
|||
|
|
<ul class="simple">
|
|||
|
|
<li><p>Telnet: A string. If GMCP or MSDP OOB protocols are used, this string will
|
|||
|
|
be formatted in a special way, but it’s still a raw string. If Telnet SSL is
|
|||
|
|
active, the string will be encrypted.</p></li>
|
|||
|
|
<li><p>SSH: An encrypted string</p></li>
|
|||
|
|
<li><p>Webclient: A JSON-serialized string.</p></li>
|
|||
|
|
</ul>
|
|||
|
|
</section>
|
|||
|
|
<section id="portal-session-ingoing">
|
|||
|
|
<h3>Portal Session (ingoing)<a class="headerlink" href="#portal-session-ingoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>Each client is connected to the game via a <em>Portal Session</em>, one per connection. This Session is
|
|||
|
|
different depending on the type of connection (telnet, webclient etc) and thus know how to handle
|
|||
|
|
that particular data type. So regardless of how the data arrives, the Session will identify the type
|
|||
|
|
of the instruction and any arguments it should have. For example, the telnet protocol will figure
|
|||
|
|
that anything arriving normally over the wire should be passed on as a “text” type.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="portalsessionhandler-ingoing">
|
|||
|
|
<h3>PortalSessionHandler (ingoing)<a class="headerlink" href="#portalsessionhandler-ingoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>The <em>PortalSessionhandler</em> manages all connected Sessions in the Portal. Its <code class="docutils literal notranslate"><span class="pre">data_in</span></code> method
|
|||
|
|
(called by each Portal Session) will parse the command names and arguments from the protocols and
|
|||
|
|
convert them to a standardized form we call the <em>inputcommand</em>:</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="n">commandname</span><span class="p">,</span> <span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="p">{</span><span class="n">kwargs</span><span class="p">})</span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>All inputcommands must have a name, but they may or may not have arguments and keyword arguments -
|
|||
|
|
in fact no default inputcommands use kwargs at all. The most common inputcommand is “text”, which
|
|||
|
|
has the argument the player input on the command line:</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="s2">"text"</span><span class="p">,</span> <span class="p">(</span><span class="s2">"look"</span><span class="p">,),</span> <span class="p">{})</span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>This inputcommand-structure is pickled together with the unique session-id of the Session to which
|
|||
|
|
it belongs. This is then sent over the AMP connection.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="serversessionhandler-ingoing">
|
|||
|
|
<h3>ServerSessionHandler (ingoing)<a class="headerlink" href="#serversessionhandler-ingoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>On the Server side, the AMP unpickles the data and associates the session id with the server-side
|
|||
|
|
<a class="reference internal" href="Sessions.html"><span class="doc std std-doc">Session</span></a>. Data and Session are passed to the server-side <code class="docutils literal notranslate"><span class="pre">SessionHandler.data_in</span></code>. This
|
|||
|
|
in turn calls <code class="docutils literal notranslate"><span class="pre">ServerSession.data_in()</span></code></p>
|
|||
|
|
</section>
|
|||
|
|
<section id="serversession-ingoing">
|
|||
|
|
<h3>ServerSession (ingoing)<a class="headerlink" href="#serversession-ingoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>The method <code class="docutils literal notranslate"><span class="pre">ServerSession.data_in</span></code> is meant to offer a single place to override if they want to
|
|||
|
|
examine <em>all</em> data passing into the server from the client. It is meant to call the
|
|||
|
|
<code class="docutils literal notranslate"><span class="pre">ssessionhandler.call_inputfuncs</span></code> with the (potentially processed) data (so this is technically a
|
|||
|
|
sort of detour back to the sessionhandler).</p>
|
|||
|
|
<p>In <code class="docutils literal notranslate"><span class="pre">call_inputfuncs</span></code>, the inputcommand’s name is compared against the names of all the <em>inputfuncs</em>
|
|||
|
|
registered with the server. The inputfuncs are named the same as the inputcommand they are supposed
|
|||
|
|
to handle, so the (default) inputfunc for handling our “look” command is called “text”. These are
|
|||
|
|
just normal functions and one can plugin new ones by simply putting them in a module where Evennia
|
|||
|
|
looks for such functions.</p>
|
|||
|
|
<p>If a matching inputfunc is found, it will be called with the Session and the inputcommand’s
|
|||
|
|
arguments:</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">text</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="s2">"look"</span><span class="p">,),</span> <span class="o">**</span><span class="p">{})</span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>If no matching inputfunc is found, an inputfunc named “default” will be tried and if that is also
|
|||
|
|
not found, an error will be raised.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="inputfunc">
|
|||
|
|
<h3>Inputfunc<a class="headerlink" href="#inputfunc" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>The <a class="reference internal" href="Inputfuncs.html"><span class="doc std std-doc">Inputfunc</span></a> must be on the form <code class="docutils literal notranslate"><span class="pre">func(session,</span> <span class="pre">*args,</span> <span class="pre">**kwargs)</span></code>. An exception is
|
|||
|
|
the <code class="docutils literal notranslate"><span class="pre">default</span></code> inputfunc which has form <code class="docutils literal notranslate"><span class="pre">default(session,</span> <span class="pre">cmdname,</span> <span class="pre">*args,</span> <span class="pre">**kwargs)</span></code>, where <code class="docutils literal notranslate"><span class="pre">cmdname</span></code>
|
|||
|
|
is the un-matched inputcommand string.</p>
|
|||
|
|
<p>This is where the message’s path diverges, since just what happens next depends on the type of
|
|||
|
|
inputfunc was triggered. In the example of sending “look”, the inputfunc is named “text”. It will
|
|||
|
|
pass the argument to the <code class="docutils literal notranslate"><span class="pre">cmdhandler</span></code> which will eventually lead to the <code class="docutils literal notranslate"><span class="pre">look</span></code> command being
|
|||
|
|
executed.</p>
|
|||
|
|
</section>
|
|||
|
|
</section>
|
|||
|
|
<section id="the-outgoing-message-path">
|
|||
|
|
<h2>The outgoing message path<a class="headerlink" href="#the-outgoing-message-path" title="Permalink to this headline">¶</a></h2>
|
|||
|
|
<p>Next let’s trace the passage from server to client.</p>
|
|||
|
|
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>msg ->
|
|||
|
|
ServerSession ->
|
|||
|
|
ServerSessionHandler ->
|
|||
|
|
(AMP) ->
|
|||
|
|
PortalSessionHandler ->
|
|||
|
|
PortalSession ->
|
|||
|
|
Client
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<section id="msg">
|
|||
|
|
<h3>msg<a class="headerlink" href="#msg" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>All outgoing messages start in the <code class="docutils literal notranslate"><span class="pre">msg</span></code> method. This is accessible from three places:</p>
|
|||
|
|
<ul class="simple">
|
|||
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">Object.msg</span></code></p></li>
|
|||
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">Account.msg</span></code></p></li>
|
|||
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">Session.msg</span></code></p></li>
|
|||
|
|
</ul>
|
|||
|
|
<p>The call sign of the <code class="docutils literal notranslate"><span class="pre">msg</span></code> method looks like this:</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">msg</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>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>For our purposes, what is important to know is that with the exception of <code class="docutils literal notranslate"><span class="pre">from_obj</span></code>, <code class="docutils literal notranslate"><span class="pre">session</span></code> and
|
|||
|
|
<code class="docutils literal notranslate"><span class="pre">options</span></code>, all keywords given to the <code class="docutils literal notranslate"><span class="pre">msg</span></code> method is the name of an <em>outputcommand</em> and its
|
|||
|
|
arguments. So <code class="docutils literal notranslate"><span class="pre">text</span></code> is actually such a command, taking a string as its argument. The reason <code class="docutils literal notranslate"><span class="pre">text</span></code>
|
|||
|
|
sits as the first keyword argument is that it’s so commonly used (<code class="docutils literal notranslate"><span class="pre">caller.msg("Text")</span></code> for example).
|
|||
|
|
Here are some examples</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">msg</span><span class="p">(</span><span class="s2">"Hello!"</span><span class="p">)</span> <span class="c1"># using the 'text' outputfunc</span>
|
|||
|
|
<span class="n">msg</span><span class="p">(</span><span class="n">prompt</span><span class="o">=</span><span class="s2">"HP:</span><span class="si">%i</span><span class="s2">, SP: </span><span class="si">%i</span><span class="s2">, MP: </span><span class="si">%i</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">HP</span><span class="p">,</span> <span class="n">SP</span><span class="p">,</span> <span class="n">MP</span><span class="p">))</span>
|
|||
|
|
<span class="n">msg</span><span class="p">(</span><span class="n">mycommand</span><span class="o">=</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="p">{</span><span class="s2">"foo"</span><span class="p">:</span> <span class="s2">"bar"</span><span class="p">})</span>
|
|||
|
|
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>Note the form of the <code class="docutils literal notranslate"><span class="pre">mycommand</span></code> outputfunction. This explicitly defines the arguments and keyword
|
|||
|
|
arguments for the function. In the case of the <code class="docutils literal notranslate"><span class="pre">text</span></code> and <code class="docutils literal notranslate"><span class="pre">prompt</span></code> calls we just specify a string -
|
|||
|
|
this works too: The system will convert this into a single argument for us later in the message
|
|||
|
|
path.</p>
|
|||
|
|
<blockquote>
|
|||
|
|
<div><p>Note: The <code class="docutils literal notranslate"><span class="pre">msg</span></code> method sits on your Object- and Account typeclasses. It means you can easily
|
|||
|
|
override <code class="docutils literal notranslate"><span class="pre">msg</span></code> and make custom- or per-object modifications to the flow of data as it passes
|
|||
|
|
through.</p>
|
|||
|
|
</div></blockquote>
|
|||
|
|
</section>
|
|||
|
|
<section id="serversession-outgoing">
|
|||
|
|
<h3>ServerSession (outgoing)<a class="headerlink" href="#serversession-outgoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>Nothing is processed on the Session, it just serves as a gathering points for all different <code class="docutils literal notranslate"><span class="pre">msg</span></code>.
|
|||
|
|
It immediately passes the data on to …</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="serversessionhandler-outgoing">
|
|||
|
|
<h3>ServerSessionHandler (outgoing)<a class="headerlink" href="#serversessionhandler-outgoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>In the <em>ServerSessionhandler</em>, the keywords from the <code class="docutils literal notranslate"><span class="pre">msg</span></code> method are collated into one or more
|
|||
|
|
<em>outputcommands</em> on a standardized form (identical to inputcommands):</p>
|
|||
|
|
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="n">commandname</span><span class="p">,</span> <span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="p">{</span><span class="n">kwargs</span><span class="p">})</span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>This will intelligently convert different input to the same form. So <code class="docutils literal notranslate"><span class="pre">msg("Hello")</span></code> will end up as
|
|||
|
|
an outputcommand <code class="docutils literal notranslate"><span class="pre">("text",</span> <span class="pre">("Hello",),</span> <span class="pre">{})</span></code>.</p>
|
|||
|
|
<p>This is also the point where <a class="reference internal" href="TextTags.html#inline-functions"><span class="std std-doc">Inlinefuncs</span></a> are parsed, depending on the
|
|||
|
|
session to receive the data. Said data is pickled together with the Session id then sent over the
|
|||
|
|
AMP bridge.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="portalsessionhandler-outgoing">
|
|||
|
|
<h3>PortalSessionHandler (outgoing)<a class="headerlink" href="#portalsessionhandler-outgoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>After the AMP connection has unpickled the data and paired the session id to the matching
|
|||
|
|
PortalSession, the handler next determines if this Session has a suitable method for handling the
|
|||
|
|
outputcommand.</p>
|
|||
|
|
<p>The situation is analogous to how inputfuncs work, except that protocols are fixed things that don’t
|
|||
|
|
need a plugin infrastructure like the inputfuncs are handled. So instead of an “outputfunc”, the
|
|||
|
|
handler looks for methods on the PortalSession with names of the form <code class="docutils literal notranslate"><span class="pre">send_<commandname></span></code>.</p>
|
|||
|
|
<p>For example, the common sending of text expects a PortalSession method <code class="docutils literal notranslate"><span class="pre">send_text</span></code>. This will be
|
|||
|
|
called as <code class="docutils literal notranslate"><span class="pre">send_text(*("Hello",),</span> <span class="pre">**{})</span></code>. If the “prompt” outputfunction was used, send_prompt is
|
|||
|
|
called. In all other cases the <code class="docutils literal notranslate"><span class="pre">send_default(cmdname,</span> <span class="pre">*args,</span> <span class="pre">**kwargs)</span></code> will be called - this is the
|
|||
|
|
case for all client-custom outputcommands, like when wanting to tell the client to update a graphic
|
|||
|
|
or play a sound.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="portalsession-outgoing">
|
|||
|
|
<h3>PortalSession (outgoing)<a class="headerlink" href="#portalsession-outgoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>At this point it is up to the session to convert the command into a form understood by this
|
|||
|
|
particular protocol. For telnet, <code class="docutils literal notranslate"><span class="pre">send_text</span></code> will just send the argument as a string (since that is
|
|||
|
|
what telnet clients expect when “text” is coming). If <code class="docutils literal notranslate"><span class="pre">send_default</span></code> was called (basically
|
|||
|
|
everything that is not traditional text or a prompt), it will pack the data as an GMCP or MSDP
|
|||
|
|
command packet if the telnet client supports either (otherwise it won’t send at all). If sending to
|
|||
|
|
the webclient, the data will get packed into a JSON structure at all times.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="client-outgoing">
|
|||
|
|
<h3>Client (outgoing)<a class="headerlink" href="#client-outgoing" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>Once arrived at the client, the outputcommand is handled in the way supported by the client (or it
|
|||
|
|
may be quietly ignored if not). “text” commands will be displayed in the main window while others
|
|||
|
|
may trigger changes in the GUI or play a sound etc.</p>
|
|||
|
|
</section>
|
|||
|
|
<section id="full-example-of-outgoing-message">
|
|||
|
|
<h3>Full example of Outgoing Message<a class="headerlink" href="#full-example-of-outgoing-message" title="Permalink to this headline">¶</a></h3>
|
|||
|
|
<p>For a full outgoing message, you need to have the outgoing function defined in the javascript. See
|
|||
|
|
<a class="reference external" href="https://evennia.readthedocs.io/en/latest/Web-Client-Webclient.html">https://evennia.readthedocs.io/en/latest/Web-Client-Webclient.html</a> for getting set up with custom
|
|||
|
|
webclient code. Once you have a custom plugin defined and loaded, create a new function in the
|
|||
|
|
plugin, onCustomFunc() for example:</p>
|
|||
|
|
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">onCustomFunc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span><span class="w"> </span><span class="nx">kwargs</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">args</span><span class="p">.</span><span class="kd">var</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="kd">var</span><span class="p">)</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>You’ll also need to add the function to what the main plugin function returns:</p>
|
|||
|
|
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">init</span><span class="o">:</span><span class="w"> </span><span class="nx">init</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onCustomFunc</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>This defines the function and looks for “var” as a variable that is passed to it. Once you have this
|
|||
|
|
in place in your custom plugin, you also need to update the static/webclient/js/webclient_gui.js
|
|||
|
|
file to recognize the new function when it’s called. First you should add a new function inside the
|
|||
|
|
plugin_handler function to recognize the new function:</p>
|
|||
|
|
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">onCustomFunc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">cmdname</span><span class="p">,</span><span class="w"> </span><span class="nx">args</span><span class="p">,</span><span class="w"> </span><span class="nx">kwargs</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">n</span><span class="o">=</span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">ordered_plugins</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"> </span><span class="nx">n</span><span class="o">++</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">plugin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ordered_plugins</span><span class="p">[</span><span class="nx">n</span><span class="p">];</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="s1">'onCustomFunc'</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="nx">plugin</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="nx">plugin</span><span class="p">.</span><span class="nx">onCustomFunc</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span><span class="w"> </span><span class="nx">kwargs</span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="c1">// True -- means this plugin claims this command exclusively.</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>This looks through all the plugins for a function that corresponds to the custom function being
|
|||
|
|
called. Next, add the custom function to the return statement of the plugin handler:</p>
|
|||
|
|
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">add</span><span class="o">:</span><span class="w"> </span><span class="nx">add</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onKeydown</span><span class="o">:</span><span class="w"> </span><span class="nx">onKeydown</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onBeforeUnload</span><span class="o">:</span><span class="w"> </span><span class="nx">onBeforeUnload</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onLoggedIn</span><span class="o">:</span><span class="w"> </span><span class="nx">onLoggedIn</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onText</span><span class="o">:</span><span class="w"> </span><span class="nx">onText</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onGotOptions</span><span class="o">:</span><span class="w"> </span><span class="nx">onGotOptions</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onPrompt</span><span class="o">:</span><span class="w"> </span><span class="nx">onPrompt</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onDefault</span><span class="o">:</span><span class="w"> </span><span class="nx">onDefault</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onSilence</span><span class="o">:</span><span class="w"> </span><span class="nx">onSilence</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onConnectionClose</span><span class="o">:</span><span class="w"> </span><span class="nx">onConnectionClose</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onSend</span><span class="o">:</span><span class="w"> </span><span class="nx">onSend</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">init</span><span class="o">:</span><span class="w"> </span><span class="nx">init</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">postInit</span><span class="o">:</span><span class="w"> </span><span class="nx">postInit</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="nx">onCustomFunc</span><span class="o">:</span><span class="w"> </span><span class="nx">onCustomFunc</span><span class="p">,</span><span class="w"></span>
|
|||
|
|
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>Lastly, you will also need to need to add an entry to the Evennia emitter to tie the python function
|
|||
|
|
call to this new javascript function (this is in the $(document).ready function):</p>
|
|||
|
|
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="nx">Evennia</span><span class="p">.</span><span class="nx">emitter</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"customFunc"</span><span class="p">,</span><span class="w"> </span><span class="nx">plugin_handler</span><span class="p">.</span><span class="nx">onCustomFunc</span><span class="p">);</span><span class="w"></span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>Now you can make a call from your python code to the new custom function to pass information from
|
|||
|
|
the server to the client:</p>
|
|||
|
|
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">character</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">customFunc</span><span class="o">=</span><span class="p">({</span><span class="s2">"var"</span><span class="p">:</span> <span class="s2">"blarg"</span><span class="p">}))</span>
|
|||
|
|
</pre></div>
|
|||
|
|
</div>
|
|||
|
|
<p>When this code in your python is run, you should be able to see the “blarg” string printed in the
|
|||
|
|
web client console. You should now be able to update the function call and definition to pass any
|
|||
|
|
information needed between server and client.</p>
|
|||
|
|
</section>
|
|||
|
|
</section>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<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>
|
|||
|
|
<p><h3><a href="index.html">Table of Contents</a></h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><a class="reference internal" href="#">Messagepath</a><ul>
|
|||
|
|
<li><a class="reference internal" href="#the-ingoing-message-path">The ingoing message path</a><ul>
|
|||
|
|
<li><a class="reference internal" href="#client-ingoing">Client (ingoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#portal-session-ingoing">Portal Session (ingoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#portalsessionhandler-ingoing">PortalSessionHandler (ingoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#serversessionhandler-ingoing">ServerSessionHandler (ingoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#serversession-ingoing">ServerSession (ingoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#inputfunc">Inputfunc</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</li>
|
|||
|
|
<li><a class="reference internal" href="#the-outgoing-message-path">The outgoing message path</a><ul>
|
|||
|
|
<li><a class="reference internal" href="#msg">msg</a></li>
|
|||
|
|
<li><a class="reference internal" href="#serversession-outgoing">ServerSession (outgoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#serversessionhandler-outgoing">ServerSessionHandler (outgoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#portalsessionhandler-outgoing">PortalSessionHandler (outgoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#portalsession-outgoing">PortalSession (outgoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#client-outgoing">Client (outgoing)</a></li>
|
|||
|
|
<li><a class="reference internal" href="#full-example-of-outgoing-message">Full example of Outgoing Message</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
|
|||
|
|
<div role="note" aria-label="source link">
|
|||
|
|
<!--h3>This Page</h3-->
|
|||
|
|
<ul class="this-page-menu">
|
|||
|
|
<li><a href="_sources/Messagepath.md.txt"
|
|||
|
|
rel="nofollow">Show Page Source</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</div><h3>Links</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><a href="https://www.evennia.com">Home page</a> </li>
|
|||
|
|
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
|||
|
|
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
|||
|
|
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
|||
|
|
<a href="https://discord.gg/NecFePw">Discord</a> -
|
|||
|
|
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
|||
|
|
</li>
|
|||
|
|
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
|||
|
|
</ul>
|
|||
|
|
<h3>Versions</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><a href="../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
|
|||
|
|
<li><a href="Messagepath.html">0.9.5 (v0.9.5 branch)</a></li>
|
|||
|
|
</ul>
|
|||
|
|
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="clearer"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|||
|
|
<h3>Navigation</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li class="right" style="margin-right: 10px">
|
|||
|
|
<a href="genindex.html" title="General Index"
|
|||
|
|
>index</a></li>
|
|||
|
|
<li class="right" >
|
|||
|
|
<a href="py-modindex.html" title="Python Module Index"
|
|||
|
|
>modules</a> |</li>
|
|||
|
|
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> »</li>
|
|||
|
|
<li class="nav-item nav-item-this"><a href="">Messagepath</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</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>
|