docs/templates/pages/protocol.html

223 lines
7.8 KiB
HTML

{% extends "konami.html" %}
{% block title %}Application protocol{% endblock %}
{% block body %}
<h1>Application Protocol</h1>
<p>As the previous pages have eluded to (you <i>did</i> read them, didn't you?), eAmuse uses HTTP as its main way of
getting data around. This means we need an HTTP server running but, as we'll see, we don't need to think too
hard about that.</p>
<p>Every request made is a <code>POST</code> request, to <code>//&lt;model&gt;/&lt;module&gt;/&lt;method&gt;</code>,
with its body being encoded data as described in the previous sections. This behaviour can be altered using the
<code>url_slash</code> flag in <code>ea3-config.xml</code>. Disabling this switches to using
<code>/?model=...&module=...&method=...</code> for requests instead. Make sure to implement both of these if
implementing a server!
</p>
<p>Every request is followed immediately by a response. Any response code other than <code>200</code> is considered
a failure.</p>
<details>
<summary>Source code details</summary>
<figure>
<img src="images/200_only.png">
<figcaption><code>libavs-win32-ea3.dll:0x1000f8e7</code></figcaption>
</figure>
</details>
<p>All requests follow a basic format:</p>
<pre>{% highlight "cxml" %}<call model="??model" srcid="??srcid" tag="??tag">
<??module method="??method" ...attributes>
...children
</??module>
</call>{% endhighlight %}</pre>
<p>The responses follow a similar format:</p>
<pre>{% highlight "cxml" %}<response>
<??module status="??status" ...attributes>
...children
</??module>
</response>{% endhighlight %}</pre>
<p>With <code>"0"</code> being a successful status. Convention is to identify a specific method as
<code><i>module</i>.<i>method</i></code>, and we'll be following this convention in this document too. There are
a <i>lot</i> of possible methods, so the majority of this document is a big reference for them all. There are a
number of generic methods, and a number of game specific ones. If you haven't clocked yet, I've been working on
an SDVX 4 build for most of these pages, and each game also comes with its own set of game-specific methods.
These methods are sometimes namespaced tidily, and in other cases are strewn all over the place. Namespaces I'm
currently aware of are listed below. Note that <code>game.*</code> is used by many games, and has identically named
methods within the <code>game</code> module. Expect to need to filter based on model code for this one.
</p>
<table>
<tr>
<td><code>game.*</code></td>
<td>Sound Voltex I</td>
</tr>
<tr>
<td><code>game.sv4_*</code></td>
<td>Sound Voltex IV</td>
</tr>
<tr>
<td><code>game.sv5_*</code></td>
<td>Sound Voltex V</td>
</tr>
<tr>
<td><code>game.sv6_*</code></td>
<td>Sound Voltex VI</td>
</tr>
<tr>
<td><code>exchain_*</code></td>
<td>GITADORA EXCHAIN</td>
</tr>
<tr>
<td><code>matixx_*</code></td>
<td>GITADORA Matixx</td>
</tr>
<tr>
<td><code>nextage_*</code></td>
<td>GITADORA NEXTAGE</td>
</tr>
<tr>
<td><code>op2_*</code></td>
<td>Nostalgia Op.2</td>
</tr>
<tr>
<td><code>game.*</code>, <code>playerdata.*</code></td>
<td>Pop'n Music</td>
</tr>
<tr>
<td><code>game.*</code></td>
<td>HELLO! POP'N MUSIC</td>
</tr>
<tr>
<td><code>info22.*</code>, <code>player22.*</code></td>
<td>Pop'n Music 22 (Lapistoria)</td>
</tr>
<tr>
<td><code>info23.*</code>, <code>player23.*</code></td>
<td>Pop'n Music 23 (éclale)</td>
</tr>
<tr>
<td><code>info24.*</code>, <code>player24.*</code></td>
<td>Pop'n Music 24 (Usagi to Neko to Shounen no Yume)</td>
</tr>
<tr>
<td><code>game_3.*</code></td>
<td>Museca</td>
</tr>
<tr>
<td><code>info2.*</code>, <code>player2.*</code></td>
<td>BeatStream</td>
</tr>
</table>
<p>Paths in the XML bodies are formatted using an XPath-like syntax. That is, <code>status@/response</code> gets the
<code>status</code> attribute from <code>response</code>, and <code>response/eacoin/sequence</code> would return
that node's value.
</p>
<p><b>NOTE:</b> I am using the non-standard notation of <code>&lt;node* ...</code> and
<code>&lt;node attr*="" ...</code> to indicate that an attribute or node is not always present! Additionally, I
am going to use the notation of <code>&lt;node[]&gt;</code> to indicate that a node repeats.
</p>
<table>
<thead>
<tr>
<td>Status</td>
<td>Meaning</td>
</tr>
</thead>
<tr>
<td><code>0</code></td>
<td>Success</td>
</tr>
<tr>
<td><code>109</code></td>
<td>No profile</td>
</tr>
<tr>
<td><code>110</code></td>
<td>Not allowed</td>
</tr>
<tr>
<td><code>112</code></td>
<td>Card not found (<code>cardmng.inquire</code>)</td>
</tr>
<tr>
<td><code>116</code></td>
<td>Card pin invalid (<code>cardmng.authpass</code>)</td>
</tr>
</table>
<details>
<summary>How to reverse engineer these calls</summary>
<p>Turns out bemani have been quite sensible in how they implemented their code for creating structures, so it's
rather readable. That said, if you've been using Ghidra (like me!), this is the time to switch to IDA. I'll
let the below screenshots below speak for themselves:
</p>
<details>
<summary>Ghidra</summary>
<img src="images/eventlog_ghidra.png">
<img src="images/matching_request_ghidra.png">
</details>
<details>
<summary>IDA Pro</summary>
<img src="images/eventlog_ida.png">
<img src="images/matching_request_ida.png">
</details>
<p>I know which of these I'd rather use for reverse engineering (sorry, Ghidra)!</p>
</details>
<h2>Service URLs</h2>
<p>By design, different modules call to different service endpoints. This is totally optional (all endpoints can be set
to the same value) however it can also be leveraged to simplify deployment. The first request any game makes when
starting is <code>services.get</code>, which is made to the service URL configured in the ea3 configuration. The
response to this request returns a list of endpoints and their corresponding URLs.</p>
<p>Notably, the <code>services.get</code> request contains everything required to identify a game, so it may be
beneficial to route different games to different URLs (where appropriate).</p>
<p>The endpoint names <b>are not</b> the same as module names. Many are, but similarly, many aren't.</p>
<table>
<thead>
<tr>
<td>Endpoint</td>
<td>Modules serviced</td>
</tr>
</thead>
<tr>
<td><code>lobby</code></td>
<td></td>
</tr>
<tr>
<td><code>lobby2</code></td>
<td></td>
</tr>
<tr>
<td><code>local</code></td>
<td><code>eventlog</code>, <code>game_3</code></td>
</tr>
<tr>
<td><code>local2</code></td>
<td><code>eventlog</code>, <code>playerdata</code>, <code>matching</code>, <code>system</code>,
<code>esoc</code>, <code>game</code>
</td>
</tr>
<tr>
<td><code>globby</code></td>
<td></td>
</tr>
<tr>
<td><code>pkglist</code></td>
<td></td>
</tr>
<tr>
<td><code>posevent</code></td>
<td></td>
</tr>
<tr>
<td><code>netlog</code></td>
<td></td>
</tr>
</table>
<p>Modules not listed can be assumed to be served by the endpoint of the same name. <b>This table is very
incomplete.</b></p>
<h2>Possible XRPC requests</h2>
{{ generate_xrpc_list()|safe }}
{% endblock %}