Lots of protocol stuff

This commit is contained in:
Bottersnike 2021-12-22 03:41:57 +00:00
parent 4827a1eb07
commit aeff96e1d5
8 changed files with 459 additions and 209 deletions

BIN
images/eventlog_ghidra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
images/eventlog_ida.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>eAmuse API</title>
<title>e-Amusement API</title>
<link rel="stylesheet" href="styles.css">
</head>
@ -20,17 +20,22 @@
</tr>
</table>
<h1>Benami/Konami eAmuse API</h1>
<h1>Benami/Konami e-Amusement API</h1>
<p>Why?</p>
<p>I was curious how these APIs work, yet could find little to nothing on Google. There are a number of
closed-source projects, with presumably similarly closed-source internal documentation, and a scattering of
implementations of things, yet I couldn't find a site that actually just documents how the API works. If I'm
going to have to reverse engineer an open source project (or a closed source one, for that matter), I might as
well just go reverse engineer an actual game (or it's stdlib, as most of my time has been spent currently).</p>
<p>For the sake of being lazy, I'll probably end up calling it eAmuse more than anything else throughout these
pages. Other names you may come across include <code>httac</code> and <code>xrpc</code>. The latter are the
suite of HTTP functions used in the Bemani stdlib, and the name of their communication protocol they implement
at the application layer, but whenever someone refers to any of them in the context of a rhythm game, they will
be referring to the things documented here.</p>
<p>These pages are very much a work in progress, and are being written <i>as</i> I reverse engineer parts of the
protocol. I've been asserting all my assumptions by writing my own implementation as I go, however it currently
isn't sharable quality code and, more importantly, the purpose of these pages is to make implementation of one's
own code hopefully trivial.</p>
own code hopefully trivial (teach a man to fish, and all that).</p>
<p>Sharing annotated sources for all of the games' stdlibs would be both impractical and unwise. Where relevant
however I try to include snippets to illustrate concepts, and have included their locations in the source for if
you feel like taking a dive too.</p>

View File

@ -63,7 +63,7 @@
can be a little confusing, remembering that this is encoding an XML tree can make it easier to parse.</p>
<p>To start with, let's take a look at the overall structure of the packets.</p>
<table>
<table class="code">
<thead>
<tr>
<td>0</td>
@ -123,19 +123,19 @@
</tr>
</thead>
<tr>
<td>0x42</td>
<td><code>0x42</code></td>
<td>Compressed data</td>
</tr>
<tr>
<td>0x43</td>
<td><code>0x43</code></td>
<td>Compressed, no data</td>
</tr>
<tr>
<td>0x45</td>
<td><code>0x45</code></td>
<td>Decompressed data</td>
</tr>
<tr>
<td>0x46</td>
<td><code>0x46</code></td>
<td>Decompressed, no data</td>
</tr>
</table>
@ -145,45 +145,45 @@
<table>
<thead>
<tr>
<td>E</td>
<td>~E</td>
<td><code>E</code></td>
<td><code>~E</code></td>
<td colspan="3">Encoding name</td>
</tr>
</thead>
<tr>
<td>0x20</td>
<td>0xDF</td>
<td>ASCII</td>
<td><code>0x20</code></td>
<td><code>0xDF</code></td>
<td><code>ASCII</code></td>
<td></td>
<td></td>
</tr>
<tr>
<td>0x40</td>
<td>0xBF</td>
<td>ISO-8859-1</td>
<td>ISO_8859-1</td>
<td><code>0xBF</code></td>
<td><code>ISO-8859-1</code></td>
<td><code>ISO_8859-1</code></td>
<td></td>
<td></td>
</tr>
<tr>
<td>0x60</td>
<td>0x9F</td>
<td>EUC-JP</td>
<td>EUCJP</td>
<td>EUC_JP</td>
<td><code>0x60</code></td>
<td><code>0x9F</code></td>
<td><code>EUC-JP</code></td>
<td><code>EUCJP</code></td>
<td><code>EUC_JP</code></td>
</tr>
<tr>
<td>0x80</td>
<td>0x7F</td>
<td>SHIFT-JIS</td>
<td>SHIFT_JIS</td>
<td>SJIS</td>
<td><code>0x80</code></td>
<td><code>0x7F</code></td>
<td><code>SHIFT-JIS</code></td>
<td><code>SHIFT_JIS</code></td>
<td><code>SJIS</code></td>
</tr>
<tr>
<td>0xA0</td>
<td>0x5F</td>
<td>UTF-8</td>
<td>UTF8</td>
<td><code>0xA0</code></td>
<td><code>0x5F</code></td>
<td><code>UTF-8</code></td>
<td><code>UTF8</code></td>
<td></td>
</tr>
</table>
@ -217,7 +217,7 @@
<p>A tag definition looks like:</p>
<table>
<table class="code">
<thead>
<tr>
<td>0</td>
@ -264,7 +264,7 @@
used later when unpacking the main data, so we need not worry about it for now, but be warned it exists and is
possibly the least fun part of this format.</p>
<table>
<table class="code">
<thead>
<tr>
<td>ID</td>
@ -815,7 +815,7 @@
for our bucket.</p>
<p>For example, imagine we write the sequence <code>byte, int, byte, short, byte, int, short</code>. The final output should look like:</p>
<table>
<table class="code">
<thead>
<tr>
<td>0</td>

View File

@ -57,13 +57,72 @@
&lt;/response&gt;</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 rest of this document is a big reference for them all. There are a
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>&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>Possible XRPC requests</h2>
<ul>
<li><code><a href="#eventlog">eventlog.%s</a></code></li>
@ -167,7 +226,7 @@
<li><code><a href="#eacoin.getecstatus">eacoin.getecstatus</a></code></li>
<li><code><a href="#eacoin.touch">eacoin.touch</a></code></li>
<li><code><a href="#eacoin.opchpass">eacoin.opchpass</a></code></li>
<li><code><a href="#eacoin.opchecking">eacoin.opchecking</a></code></li>
<li><code><a href="#eacoin.opcheckin">eacoin.opcheckin</a></code></li>
<li><code><a href="#eacoin.opcheckout">eacoin.opcheckout</a></code></li>
<li><code><a href="#eacoin.getlog">eacoin.getlog</a></code></li>
</ul>
@ -228,6 +287,7 @@
<ul>
<li><code>G_GAMED</code></li>
<li><code>S_ERROR</code></li>
<li><code>S_PWRON</code> <b>TODO: find more!</b></li>
<li><code>T_OTDEMO</code></li>
</ul>
<h4>Response:</h4>
@ -333,7 +393,22 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;matching method="request"&gt;
<i>placeholder</i>
&lt;matchtyp __type="s32" /&gt;
&lt;matchgrp __type="s32" /&gt;
&lt;matchflg __type="s32" /&gt;
&lt;waituser __type="s32" /&gt;
&lt;waittime __type="s32" /&gt;
&lt;joinip __type="str" /&gt;
&lt;localip __type="str" /&gt;
&lt;localport __type="s32" /&gt;
&lt;dataid __type="str" /&gt;
&lt;gamekind __type="str" /&gt;
&lt;locationid __type="str" /&gt;
&lt;lineid __type="str" /&gt;
&lt;locationcountry __type="str" /&gt;
&lt;locationregion __type="str" /&gt;
&lt;/matching&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
@ -464,108 +539,115 @@
<h3 id="cardmng.inquire"><code>cardmng.inquire</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="inquire" cardid="" cardtype="" update="" /&gt;
&lt;cardmng method="inquire" cardid="" cardtype="" update="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>" refid="" dataid="" pcode="" newflag="" binded="" expired=" ecflag="" useridflag="" extidflag="" lastupdate="" /&gt;
&lt;/response&gt;</code></pre>
<p>If the <code>cardid</code> cannot be found, <code>status</code> should be set to <code>112</code> with no other
information return. Otherwise, we return information about the found card.</p>
<table class="nocode">
<tr>
<td><code>refid</code></td>
<td>A reference to this card to be used in other requests</td>
</tr>
<tr>
<td><code>dataid</code></td>
<td>Appears to be set the same as <code>refid</code>; presumably to allow different keys for game state vs
login details.</td>
</tr>
<tr>
<td><code>newflag</code></td>
<td><code>1</code> or <code>0</code></td>
</tr>
<tr>
<td><code>binded</code></td>
<td>Has a profile ever been created for this game (or an older version, requiring a migration)
(<code>1</code> or <code>0</code>)</td>
</tr>
<tr>
<td><code>expired</code></td>
<td>Did we find </td>
</tr>
</table>
<h3 id="cardmng.getrefid"><code>cardmng.getrefid</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="getrefid" cardtype="" cardid=" newflag="" passwd="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>" refid="" dataid="" pcode="" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.bindmodel"><code>cardmng.bindmodel</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="bindmodel" refid="" newflag="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>" dataid="" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.bindcard"><code>cardmng.bindcard</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="bindcard" cardtype="" newid="" refid="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.getrefid"><code>cardmng.getrefid</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="getrefid"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.bindmodel"><code>cardmng.bindmodel</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="bindmodel"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.bindcard"><code>cardmng.bindcard</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="bindcard"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.authpass"><code>cardmng.authpass</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="authpass"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng method="authpass" refid="" pass="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.getkeepspan"><code>cardmng.getkeepspan</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="getkeepspan"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng method="getkeepspan" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng status="<i>status</i>" keepspan="" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.getkeepremain"><code>cardmng.getkeepremain</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="getkeepremain"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng method="getkeepremain" refid="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng status="<i>status</i>" keepremain="" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="cardmng.getdatalist"><code>cardmng.getdatalist</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;cardmng method="getdatalist"&gt;
<i>placeholder</i>
&lt;/cardmng&gt;
&lt;cardmng method="getdatalist" refid="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;cardmng status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;item[]&gt;
&lt;mcode __type="str" /&gt;
&lt;dataid __type="str" /&gt;
&lt;regtime __type="str" /&gt;
&lt;lasttime __type="str" /&gt;
&lt;exptime __type="str" /&gt;
&lt;expflag __type="u8" /&gt;
&lt;/item&gt;
&lt;/cardmng&gt;
&lt;/response&gt;</code></pre>
@ -587,32 +669,29 @@
<h2 id="package"><code>package</code></h2>
<h3 id="package.list"><code>package.list</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;package method="list"&gt;
<i>placeholder</i>
&lt;/package&gt;
&lt;package method="list" pkgtype="<i>pkgtype</i>" model*="" /&gt;
&lt;/call&gt;</code></pre>
<p><code>all</code> is the only currently observed value for <code>pkgtype</code></p>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;package status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;item[] url="" /&gt;
&lt;/package&gt;
&lt;/response&gt;</code></pre>
<p>A list of all packages available for download.</p>
<h3 id="package.intend"><code>package.intend</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;package method="intend"&gt;
<i>placeholder</i>
&lt;/package&gt;
&lt;package method="intend" url="" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;package status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/package&gt;
&lt;package status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
@ -620,29 +699,26 @@
<h3 id="userdata.read"><code>userdata.read</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;userdata method="read"&gt;
<i>placeholder</i>
&lt;/userdata&gt;
&lt;userdata method="read" card*="" model*="" label="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;userdata status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;userdata status="<i>status</i>" time=""&gt;
&lt;b[] __type="" /&gt;
&lt;/userdata&gt;
&lt;/response&gt;</code></pre>
<p><code>__type</code> here can be either <code>bin</code> or <code>str</code></p>
<h3 id="userdata.write"><code>userdata.write</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;userdata method="write"&gt;
<i>placeholder</i>
&lt;userdata method="write" card="" time="" model*="" label*="" &gt;
&lt;b[] __type="str" /&gt;
&lt;/userdata&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;userdata status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/userdata&gt;
&lt;userdata status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
@ -650,7 +726,7 @@
<h3 id="services.get"><code>services.get</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;services method="get"&gt;
&lt;services method="get" model*="" &gt;
&lt;info&gt;
&lt;AVS2 __type="str"&gt;<i>AVS2 version</i>&lt;/AVS2&gt;
&lt;/info&gt;
@ -659,7 +735,7 @@
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;services expire="" method="get" mode="" status="<i>status</i>"&gt;
&lt;item name="<i>service</i>" url="<i>url</i>" /&gt;
&lt;item[] name="<i>service</i>" url="<i>url</i>" /&gt;
&lt;/services&gt;
&lt;/response&gt;</code></pre>
<p>Known services are:</p>
@ -687,19 +763,30 @@
<li><code>sidmgr</code></li>
<li><code>globby</code></li>
</ul>
<p>Most of these will usually just return the URL to the eAmuse server (or your fake one ;D). <code>ntp</code> is a notable exception, unless you're planning on reimplementing NTP. <code>keepalive</code> will likely alsop be a custom URL with query parameters pre-baked.</p>
<p>Most of these will usually just return the URL to the eAmuse server (or your fake one ;D). <code>ntp</code> is a
notable exception, unless you're planning on reimplementing NTP. <code>keepalive</code> will likely alsop be a
custom URL with query parameters pre-baked.</p>
<p><code>mode</code> is one of <code>operation</code>, <code>debug</code>, <code>test</code>, or
<code>factory</code>.
</p>
<h2 id="pcbtracker"><code>pcbtracker</code></h2>
<h3 id="pcbtracker.alive"><code>pcbtracker.alive</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;pcbtracker method="alive" accountid="<i>pcbid</i>" ecflag="<i>ecflag</i>" hardid="<i>hardware ID</i>" softid="<i>software ID</i>" /&gt;
&lt;pcbtracker method="alive" model*="" hardid="" softid="" accountid="" agree="" ecflag="" /&gt;
&lt;/call&gt;</code></pre>
<p><code>ecflag</code> here is determining if the arcade operator allows the use of paseli on this machine.</p>
<p><code>agree@</code> and <code>ecflag@</code> appear to either be totally non present, or present with a value of
<code>"1"</code>, but then again I may be reading the code wrong, so take that with a pinch of salt.
</p>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;pcbtracker status="<i>status</i>" ecenable="" eclimit="" expire="" limit="" time=""&gt;
&lt;pcbtracker status="" time="" limit="" ecenable="" eclimit="" &gt;
&lt;/response&gt;</code></pre>
<p>As you might guess, <code>ecenable@</code> is therefore the flag to determine if paseli is enabled (i.e. the
arcade operator and the server both allow its use).</p>
<h2 id="pcbevent"><code>pcbevent</code></h2>
@ -707,14 +794,18 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;pcbevent method="put"&gt;
<i>placeholder</i>
&lt;time __type="time" /&gt;
&lt;seq __type="u32" /&gt;
&lt;item[]&gt;
&lt;name __type="str" /&gt;
&lt;value __type="s32" /&gt;
&lt;time __type="time" /&gt;
&lt;/item&gt;
&lt;/pcbevent&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;pcbevent status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/pcbevent&gt;
&lt;pcbevent status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
@ -722,12 +813,13 @@
<h3 id="message.get"><code>message.get</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;message method="get" /&gt;
&lt;message method="get" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<b>TODO: Investigate this response more</b>
<pre><code>&lt;response&gt;
&lt;message expire="" status="<i>status</i>" /&gt;
&lt;message expire="" status="<i>status</i>"&gt;
&lt;item[] name="" start="" end="" data="" /&gt;
&lt;/message&gt;
&lt;/response&gt;</code></pre>
@ -735,31 +827,129 @@
<h3 id="facility.get"><code>facility.get</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;facility method="get"&gt;
<i>placeholder</i>
&lt;/facility&gt;
&lt;facility method="get" privateip*="" encoding*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;facility status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;facility expire=""\ status="<i>status</i>"&gt;
&lt;calendar*&gt;
&lt;year __type="s16" /&gt;
&lt;holiday __type="s16" /&gt;
&lt;/calendar&gt;
&lt;location&gt;
&lt;id __type="str" /&gt;
&lt;country __type="str" /&gt;
&lt;region __type="str" /&gt;
&lt;name __type="str" /&gt;
&lt;type __type="u8" /&gt;
&lt;countryname __type="str" /&gt;
&lt;countryjname __type="str" /&gt;
&lt;regionname __type="str" /&gt;
&lt;regionjname __type="str" /&gt;
&lt;customercode __type="str" /&gt;
&lt;companycode __type="str" /&gt;
&lt;latitude __type="s32" /&gt;
&lt;longitude __type="s32" /&gt;
&lt;accuracy __type="u8" /&gt;
&lt;/location&gt;
&lt;line&gt;
&lt;id __type="str" /&gt;
&lt;class __type="u8" /&gt;
&lt;/line&gt;
&lt;portfw&gt;
&lt;globalip __type="ip4" /&gt;
&lt;globalport __type="s16" /&gt;
&lt;privateport __type="s16" /&gt;
&lt;/portfw&gt;
&lt;public&gt;
&lt;flag __type="u8" /&gt;1&lt;/ flag&gt;
&lt;name __type="str" /&gt;
&lt;latitude __type="str"&gt;0&lt;latitude&gt;
&lt;longitude __type="str"&gt;0&lt;longitude&gt;
&lt;/public&gt;
&lt;share&gt;
&lt;eapass*&gt;
&lt;valid __type="?" /&gt;
&lt;/eapass&gt;
&lt;eacoin&gt;
&lt;notchamount __type="s32" /&gt;
&lt;notchcount __type="s32" /&gt;
&lt;supplylimit __type="s32"&gt;100000&lt;supplylimit&gt;
&lt;/eacoin&gt;
&lt;url&gt;
&lt;eapass __type="str"&gt;www.ea-pass.konami.net&lt;eapass&gt;
&lt;arcadefan __type="str"&gt;www.konami.jp/am&lt;arcadefan&gt;
&lt;konaminetdx __type="str"&gt;http://am.573.jp&lt;konaminetdx&gt;
&lt;konamiid __type="str"&gt;http://id.konami.jp&lt;konamiid&gt;
&lt;eagate __type="str"&gt;http://eagate.573.jp&lt;eagate&gt;
&lt;/url&gt;
&lt;/share&gt;
&lt;/facility&gt;
&lt;/response&gt;</code></pre>
<p><i>I'm not totally sure what type <code>share/eapass/valid</code> is meant to be, but it's optional, so I'd
suggest just not bothering and leaving it out :).</i></p>
<table>
<thead>
<tr>
<td>Country</td>
<td>Code</td>
</tr>
</thead>
<tr>
<td>Hong Kong</td>
<td><code>HK</code></td>
</tr>
<tr>
<td>Taiwan</td>
<td><code>TW</code></td>
</tr>
<tr>
<td>Korea</td>
<td><code>KR</code></td>
</tr>
<tr>
<td>USA</td>
<td><code>US</code></td>
</tr>
<tr>
<td>Thailand</td>
<td><code>TH</code></td>
</tr>
<tr>
<td>Indonesia</td>
<td><code>ID</code></td>
</tr>
<tr>
<td>Singapore</td>
<td><code>SG</code></td>
</tr>
<tr>
<td>Phillipines</td>
<td><code>PH</code></td>
</tr>
<tr>
<td>Macao</td>
<td><code>MO</code></td>
</tr>
<tr>
<td>Japan</td>
<td><code>JP</code></td>
</tr>
</table>
<p><code>globalip</code> (and associated ports) shold be the IP:port of the cabinet.</p>
<p><code>region</code> is used for Japan, and has the value <code>JP-[prefecture]</code> where prefecture ranges
from 1 through 47.</p>
<p><b>TODO: Compile the list of regions</b></p>
<h2 id="apsmanager"><code>apsmanager</code></h2>
<h3 id="apsmanager.getstat"><code>apsmanager.getstat</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;apsmanager method="getstat"&gt;
<i>placeholder</i>
&lt;/apsmanager&gt;
&lt;apsmanager method="getstat" model*="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;apsmanager status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/apsmanager&gt;
&lt;apsmanager status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
@ -768,70 +958,71 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;sidmgr method="create"&gt;
<i>placeholder</i>
&lt;cardtype __type="str" /&gt;
&lt;cardid __type="str" /&gt;
&lt;cardgid __type="str" /&gt;
&lt;steal __type="u8" /&gt;
&lt;/sidmgr&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;sidmgr status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;state __type="u32" /&gt;
&lt;e_count __type="u8" /&gt;
&lt;last __type="time" /&gt;
&lt;locked __type="time" /&gt;
&lt;sid __type="str" /&gt;
&lt;cardid_status __type="u8" /&gt;
&lt;refid __type="str" /&gt;
&lt;/sidmgr&gt;
&lt;/response&gt;</code></pre>
<h3 id="sidmgr.open"><code>sidmgr.open</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;sidmgr method="open"&gt;
<i>placeholder</i>
&lt;sidmgr method="open" sid="" &gt;
&lt;pass __type="str" /&gt;
&lt;/sidmgr&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;sidmgr status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;state __type="u32" /&gt;
&lt;refid __type="str" /&gt;
&lt;locked __type="time" /&gt;
&lt;/sidmgr&gt;
&lt;/response&gt;</code></pre>
<h3 id="sidmgr.touch"><code>sidmgr.touch</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;sidmgr method="touch"&gt;
<i>placeholder</i>
&lt;/sidmgr&gt;
&lt;sidmgr method="touch" sid="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;sidmgr status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/sidmgr&gt;
&lt;sidmgr status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="sidmgr.branch"><code>sidmgr.branch</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;sidmgr method="branch"&gt;
<i>placeholder</i>
&lt;/sidmgr&gt;
&lt;sidmgr method="branch" sid="" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;sidmgr status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/sidmgr&gt;
&lt;sidmgr status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="sidmgr.close"><code>sidmgr.close</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;sidmgr method="close"&gt;
<i>placeholder</i>
&lt;sidmgr method="close" sid="" /&gt;
&lt;cause __type="u32" /&gt;
&lt;/sidmgr&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;sidmgr status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/sidmgr&gt;
&lt;sidmgr status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
@ -840,13 +1031,18 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;dlstatus method="done"&gt;
<i>placeholder</i>
&lt;url&gt;
&lt;param __type="str" /&gt;
&lt;/url&gt;
&lt;name __type="str" /&gt;
&lt;size __type="s32" /&gt;
&lt;/dlstatus&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;dlstatus status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;progress __type="s32" /&gt;
&lt;/dlstatus&gt;
&lt;/response&gt;</code></pre>
@ -870,13 +1066,21 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="checkin"&gt;
<i>placeholder</i>
&lt;cardtype __type="str" /&gt;
&lt;cardid __type="str" /&gt;
&lt;passwd __type="str" /&gt;
&lt;ectype __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;sequence __type="s16" /&gt;
&lt;acstatus __type="u8" /&gt;
&lt;acid __type="str" /&gt;
&lt;acname __type="str" /&gt;
&lt;balance __type="s32" /&gt;
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
@ -884,27 +1088,32 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="checkout"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/eacoin&gt;
&lt;eacoin status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="eacoin.consume"><code>eacoin.consume</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="consume"&gt;
<i>placeholder</i>
&lt;eacoin method="consume" esid=""&gt;
&lt;sessid __type="str" /&gt;
&lt;sequence __type="s16" /&gt;
&lt;payment __type="s32" /&gt;
&lt;service __type="s16" /&gt;
&lt;itemtype __type="str" /&gt;
&lt;detail __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;acstatus __type="u8" /&gt;
&lt;autocharge __type="u8" /&gt;
&lt;balance __type="s32" /&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
@ -912,27 +1121,27 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="getbalance"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;acstatus __type="u8" /&gt;
&lt;balance __type="s32" /&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
<h3 id="eacoin.getecstatus"><code>eacoin.getecstatus</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="getecstatus"&gt;
<i>placeholder</i>
&lt;/eacoin&gt;
&lt;eacoin method="getecstatus" /&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;ectype __type="str" /&gt;
&lt;ecstatus __type="u8" /&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
@ -940,41 +1149,38 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="touch"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/eacoin&gt;
&lt;eacoin status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="eacoin.opchpass"><code>eacoin.opchpass</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="opchpass"&gt;
<i>placeholder</i>
&lt;passwd __type="str" /&gt;
&lt;newpasswd __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/eacoin&gt;
&lt;eacoin status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="eacoin.opchecking"><code>eacoin.opchecking</code></h3>
<h3 id="eacoin.opcheckin"><code>eacoin.opcheckin</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="opchecking"&gt;
<i>placeholder</i>
&lt;eacoin method="opcheckin"&gt;
&lt;passwd __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
@ -982,27 +1188,54 @@
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="opcheckout"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;/eacoin&gt;
&lt;eacoin status="<i>status</i>" /&gt;
&lt;/response&gt;</code></pre>
<h3 id="eacoin.getlog"><code>eacoin.getlog</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;eacoin method="getlog"&gt;
<i>placeholder</i>
&lt;sessid __type="str" /&gt;
&lt;logtype __type="str" /&gt;
&lt;ectype __type="str" /&gt;
&lt;target __type="str" /&gt;
&lt;perpage __type="s16" /&gt;
&lt;page __type="s16" /&gt;
&lt;sesstype __type="str" /&gt;
&lt;/eacoin&gt;
&lt;/call&gt;</code></pre>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;eacoin status="<i>status</i>"&gt;
<i>placeholder</i>
&lt;processing __type="u8" /&gt;
&lt;topic&gt;
&lt;sumdate __type="str" /&gt;
&lt;sumfrom __type="str" /&gt;
&lt;sumto __type="str" /&gt;
&lt;today __type="s32" /&gt;
&lt;average __type="s32" /&gt;
&lt;total __type="s32" /&gt;
&lt;/topic&gt;
&lt;summary&gt;
&lt;items __type="s32" /&gt;
&lt;/summary&gt;
&lt;history&gt;
&lt;item[]&gt;
&lt;date __type="str" /&gt;
&lt;consume __type="s32" /&gt;
&lt;service __type="s32" /&gt;
&lt;cardtype __type="str" /&gt;
&lt;cardno __type="str" /&gt;
&lt;title __type="str" /&gt;
&lt;systemid __type="str" /&gt;
&lt;/item&gt;
&lt;/history&gt;
&lt;/eacoin&gt;
&lt;/response&gt;</code></pre>
@ -1011,10 +1244,15 @@
<h3 id="traceroute.send"><code>traceroute.send</code></h3>
<h4>Request:</h4>
<pre><code>&lt;call <i>...</i>&gt;
&lt;traceroute method="send"&gt;
<i>placeholder</i>
&lt;traceroute proto="" method="send"&gt;
&lt;hop[]&gt;
&lt;valid __type="bool"&gt;
&lt;addr __type="ip4"&gt;
&lt;usec __type="u64"&gt;
&lt;/hop&gt;
&lt;/traceroute&gt;
&lt;/call&gt;</code></pre>
<p><code>hop</code> repeats for every hop (unsurprisingly)</p>
<h4>Response:</h4>
<pre><code>&lt;response&gt;
&lt;traceroute status="<i>status</i>"&gt;

View File

@ -1,6 +1,6 @@
body {
/* font-family: sans-serif; */
line-height: 1.25;
font-family: sans-serif;
line-height: 1.35;
max-width: 1000px;
margin: 16px auto;
color: #222;
@ -9,12 +9,14 @@ body {
table {
border-collapse: collapse;
font-family: monospace;
letter-spacing: .02em;
max-width: 100%;
overflow-x: auto;
display: block;
}
table.code {
font-family: monospace;
}
thead {
font-weight: bold;
@ -24,9 +26,14 @@ thead {
td {
border: 1px solid #111;
padding: 2px;
text-align: center;
min-width: 32px;
}
table:not(.code) td {
padding: 2px 6px;
}
table.code td {
text-align: center;
}
td a {
display: block;