will generally set some flags on the <aclass="reference internal"href="../Components/Portal-And-Server.html"><spanclass="doc std std-doc">Portal Session</span></a> that
<p>The <em>PortalSessionhandler</em> manages all connected Sessions in the Portal. Its <codeclass="docutils literal notranslate"><spanclass="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>
<aclass="reference internal"href="../Components/Sessions.html"><spanclass="doc std std-doc">Session</span></a>. Data and Session are passed to the server-side <codeclass="docutils literal notranslate"><spanclass="pre">SessionHandler.data_in</span></code>. This
<p>The method <codeclass="docutils literal notranslate"><spanclass="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
<codeclass="docutils literal notranslate"><spanclass="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 <codeclass="docutils literal notranslate"><spanclass="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
<p>The <aclass="reference internal"href="../Components/Inputfuncs.html"><spanclass="doc std std-doc">Inputfunc</span></a> must be on the form <codeclass="docutils literal notranslate"><spanclass="pre">func(session,</span><spanclass="pre">*args,</span><spanclass="pre">**kwargs)</span></code>. An exception is
the <codeclass="docutils literal notranslate"><spanclass="pre">default</span></code> inputfunc which has form <codeclass="docutils literal notranslate"><spanclass="pre">default(session,</span><spanclass="pre">cmdname,</span><spanclass="pre">*args,</span><spanclass="pre">**kwargs)</span></code>, where <codeclass="docutils literal notranslate"><spanclass="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 <codeclass="docutils literal notranslate"><spanclass="pre">cmdhandler</span></code> which will eventually lead to the <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> command being
<h3>msg<aclass="headerlink"href="#msg"title="Permalink to this headline">¶</a></h3>
<p>All outgoing messages start in the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method. This is accessible from three places:</p>
<p>For our purposes, what is important to know is that with the exception of <codeclass="docutils literal notranslate"><spanclass="pre">from_obj</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">session</span></code> and
<codeclass="docutils literal notranslate"><spanclass="pre">options</span></code>, all keywords given to the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method is the name of an <em>outputcommand</em> and its
arguments. So <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code> is actually such a command, taking a string as its argument. The reason <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code>
sits as the first keyword argument is that it’s so commonly used (<codeclass="docutils literal notranslate"><spanclass="pre">caller.msg("Text")</span></code> for example).
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Hello!"</span><spanclass="p">)</span><spanclass="c1"># using the 'text' outputfunc</span>
<p>Note the form of the <codeclass="docutils literal notranslate"><spanclass="pre">mycommand</span></code> outputfunction. This explicitly defines the arguments and keyword
arguments for the function. In the case of the <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code> and <codeclass="docutils literal notranslate"><spanclass="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
<div><p>Note: The <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method sits on your Object- and Account typeclasses. It means you can easily
override <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> and make custom- or per-object modifications to the flow of data as it passes
<p>Nothing is processed on the Session, it just serves as a gathering points for all different <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code>.
<p>In the <em>ServerSessionhandler</em>, the keywords from the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method are collated into one or more
<em>outputcommands</em> on a standardized form (identical to inputcommands):</p>
<p>This will intelligently convert different input to the same form. So <codeclass="docutils literal notranslate"><spanclass="pre">msg("Hello")</span></code> will end up as
an outputcommand <codeclass="docutils literal notranslate"><spanclass="pre">("text",</span><spanclass="pre">("Hello",),</span><spanclass="pre">{})</span></code>.</p>
<p>This is also the point where the <aclass="reference internal"href="../Components/FuncParser.html"><spanclass="doc std std-doc">FuncParser</span></a>) is applied, depending on the
<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 <codeclass="docutils literal notranslate"><spanclass="pre">send_<commandname></span></code>.</p>
<p>For example, the common sending of text expects a PortalSession method <codeclass="docutils literal notranslate"><spanclass="pre">send_text</span></code>. This will be
called as <codeclass="docutils literal notranslate"><spanclass="pre">send_text(*("Hello",),</span><spanclass="pre">**{})</span></code>. If the “prompt” outputfunction was used, send_prompt is
called. In all other cases the <codeclass="docutils literal notranslate"><spanclass="pre">send_default(cmdname,</span><spanclass="pre">*args,</span><spanclass="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
<p>At this point it is up to the session to convert the command into a form understood by this
particular protocol. For telnet, <codeclass="docutils literal notranslate"><spanclass="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 <codeclass="docutils literal notranslate"><spanclass="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>