mirror of
https://gitea.tendokyu.moe/eamuse/docs.git
synced 2025-01-06 00:34:21 +01:00
263 lines
14 KiB
HTML
263 lines
14 KiB
HTML
{% extends "base.html" %}
|
|
{% 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. In addition to the
|
|
<code>X-Compress:</code> and <code>X-Eamuse-Info:</code> headers previously detailed, there is also a
|
|
<code>X-PCB-ID:</code> header. that can be set. Your machine's PCB ID uniquely defines the physical board. This
|
|
header is added in out-bound requests, and allows the server to identify you. Importantly, it's also the value
|
|
that the server uses to identify which machines are authorized to be on the network, and which are not.
|
|
</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><code><call model="<i>model</i>" srcid="<i>srcid</i>" tag="<i>tag</i>">
|
|
<<i>module</i> method="<i>method</i>" <i>...attributes</i>>
|
|
<i>children</i>
|
|
</<i>module</i>>
|
|
</call></code></pre>
|
|
<p>The responses follow a similar format:</p>
|
|
<pre><code><response>
|
|
<<i>module</i> status="<i>status</i>" <i>...attributes</i>>
|
|
<i>children</i>
|
|
</<i>module</i>>
|
|
</response></code></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 are namespaces under the <code>game.%s</code> module and, in the case of SDVX 4, are all
|
|
<code>game.sv4_<i>method</i></code>. I may or may not document the SDVX 4 specific methods, but I've listed them
|
|
here anyway for completeness.
|
|
</p>
|
|
<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>
|
|
|
|
<ul>
|
|
<li><code><a href="proto/eventlog.html">eventlog.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/eventlog.html#eventlog.write">eventlog.write</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/playerdata.html">playerdata.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/playerdata.html#usergamedata_send">playerdata.usergamedata_send</a></code></li>
|
|
<li><code><a href="proto/playerdata.html#usergamedata_recv">playerdata.usergamedata_recv</a></code></li>
|
|
<li><code><a href="proto/playerdata.html#usergamedata_inheritance">playerdata.usergamedata_inheritance</a></code>
|
|
</li>
|
|
<li><code><a href="proto/playerdata.html#usergamedata_condrecv">playerdata.usergamedata_condrecv</a></code>
|
|
</li>
|
|
<li><code><a href="proto/playerdata.html#usergamedata_scorerank">playerdata.usergamedata_scorerank</a></code>
|
|
</li>
|
|
</ul>
|
|
<li><code><a href="proto/matching.html">matching.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/matching.html#request">matching.request</a></code></li>
|
|
<li><code><a href="proto/matching.html#wait">matching.wait</a></code></li>
|
|
<li><code><a href="proto/matching.html#finish">matching.finish</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/system.html">system.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/system.html#getmaster">system.getmaster</a></code></li>
|
|
<li><code><a href="proto/system.html#getlocationiplist">system.getlocationiplist</a></code></li>
|
|
<li><code><a href="proto/system.html#xrpcproxy">system.xrpcproxy</a></code></li>
|
|
<li><code><a href="proto/system.html#convcardnumber">system.convcardnumber</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/esoc.html">esoc.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/esoc.html#read">esoc.read</a></code></li>
|
|
<li><code><a href="proto/esoc.html#write">esoc.write</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/cardmng.html">cardmng.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/cardmng.html#inquire">cardmng.inquire</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#getrefid">cardmng.getrefid</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#bindmodel">cardmng.bindmodel</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#bindcard">cardmng.bindcard</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#authpass">cardmng.authpass</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#getkeepspan">cardmng.getkeepspan</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#getkeepremain">cardmng.getkeepremain</a></code></li>
|
|
<li><code><a href="proto/cardmng.html#getdatalist">cardmng.getdatalist</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/esign.html">esign.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/esign.html#request">esign.request</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/package.html">package.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/package.html#list">package.list</a></code></li>
|
|
<li><code><a href="proto/package.html#intend">package.intend</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/userdata.html">userdata.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/userdata.html#read">userdata.read</a></code></li>
|
|
<li><code><a href="proto/userdata.html#write">userdata.write</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/services.html">services.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/services.html#get">services.get</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/pcbtracker.html">pcbtracker.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/pcbtracker.html#alive">pcbtracker.alive</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/pcbevent.html">pcbevent.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/pcbevent.html#put">pcbevent.put</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/message.html">message.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/message.html#get">message.get</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/facility.html">facility.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/facility.html#get">facility.get</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/apsmanager.html">apsmanager.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/apsmanager.html#getstat">apsmanager.getstat</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/sidmgr.html">sidmgr.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/sidmgr.html#create">sidmgr.create</a></code></li>
|
|
<li><code><a href="proto/sidmgr.html#open">sidmgr.open</a></code></li>
|
|
<li><code><a href="proto/sidmgr.html#touch">sidmgr.touch</a></code></li>
|
|
<li><code><a href="proto/sidmgr.html#branch">sidmgr.branch</a></code></li>
|
|
<li><code><a href="proto/sidmgr.html#close">sidmgr.close</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/dlstatus.html">dlstatus.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/dlstatus.html#done">dlstatus.done</a></code></li>
|
|
<li><code><a href="proto/dlstatus.html#progress">dlstatus.progress</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/eacoin.html">eacoin.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/eacoin.html#checkin">eacoin.checkin</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#checkout">eacoin.checkout</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#consume">eacoin.consume</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#getbalance">eacoin.getbalance</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#getecstatus">eacoin.getecstatus</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#touch">eacoin.touch</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#opchpass">eacoin.opchpass</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#opcheckin">eacoin.opcheckin</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#opcheckout">eacoin.opcheckout</a></code></li>
|
|
<li><code><a href="proto/eacoin.html#getlog">eacoin.getlog</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/traceroute.html">traceroute.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/traceroute.html#send">traceroute.send</a></code></li>
|
|
</ul>
|
|
<li><code><a href="proto/game/sv4.html">game.%s</a></code></li>
|
|
<ul>
|
|
<li><code><a href="proto/game/sv4.html#sample">game.sv4_sample</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#new">game.sv4_new</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#load">game.sv4_load</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#load_m">game.sv4_load_m</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save">game.sv4_save</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_m">game.sv4_save_m</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#common">game.sv4_common</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#shop">game.sv4_shop</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#hiscore">game.sv4_hiscore</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#buy">game.sv4_buy</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#exception">game.sv4_exception</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#entry_s">game.sv4_entry_s</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#entry_e">game.sv4_entry_e</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#frozen">game.sv4_frozen</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#lounge">game.sv4_lounge</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_e">game.sv4_save_e</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_pb">game.sv4_save_pb</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_c">game.sv4_save_c</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#play_s">game.sv4_play_s</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#play_e">game.sv4_play_e</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#serial">game.sv4_serial</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_fi">game.sv4_save_fi</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#print">game.sv4_print</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#print_h">game.sv4_print_h</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#load_r">game.sv4_load_r</a></code></li>
|
|
<li><code><a href="proto/game/sv4.html#save_campaign">game.sv4_save_campaign</a></code></li>
|
|
</ul>
|
|
</ul>
|
|
|
|
<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 %} |