mirror of
https://gitea.tendokyu.moe/eamuse/docs.git
synced 2024-12-01 01:27:20 +01:00
183 lines
6.4 KiB
HTML
183 lines
6.4 KiB
HTML
{% extends "base.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>//<model>/<module>/<method></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><node* ...</code> and
|
|
<code><node attr*="" ...</code> to indicate that an attribute or node is not always present! Additionally, I
|
|
am going to use the notation of <code><node[]></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>Possible XRPC requests</h2>
|
|
|
|
{{ generate_xrpc_list()|safe }}
|
|
|
|
<b>Totally undocumented services (based on <code>services.get</code>):</b>
|
|
<ul>
|
|
<li><code>numbering</code></li>
|
|
<li><code>pkglist</code></li>
|
|
<li><code>userid</code></li>
|
|
<li><code>local</code></li>
|
|
<li><code>local2</code></li>
|
|
<li><code>lobby</code></li>
|
|
<li><code>lobby2</code></li>
|
|
<li><code>netlog</code></li>
|
|
<li><code>globby</code></li>
|
|
</ul>
|
|
<p>I'll try and figure these out in due course, promise!</p>
|
|
{% endblock %} |