mirror of
https://gitea.tendokyu.moe/eamuse/docs.git
synced 2024-11-27 16:10:51 +01:00
Flask
This commit is contained in:
parent
20affcfa63
commit
2da6e2b056
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
build/
|
@ -21,4 +21,4 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
{% endblock %}
|
79
docs.py
Normal file
79
docs.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
from flask import Flask, send_from_directory, render_template
|
||||||
|
from livereload import Server
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/styles.css")
|
||||||
|
def styles():
|
||||||
|
return send_from_directory(".", "styles.css")
|
||||||
|
|
||||||
|
|
||||||
|
for base, folders, files in os.walk("images"):
|
||||||
|
for name in files:
|
||||||
|
def handler(base, name):
|
||||||
|
def handler():
|
||||||
|
return send_from_directory(base, name)
|
||||||
|
return handler
|
||||||
|
local_base = base.replace("\\", "/").strip(".").strip("/")
|
||||||
|
route = local_base + "/" + name
|
||||||
|
if not route.startswith("/"):
|
||||||
|
route = "/" + route
|
||||||
|
|
||||||
|
handler = handler(base, name)
|
||||||
|
handler.__name__ == route
|
||||||
|
app.add_url_rule(route, route, handler)
|
||||||
|
|
||||||
|
TEMPLATES = "templates"
|
||||||
|
PAGES_BASE = "pages"
|
||||||
|
for base, folders, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
|
||||||
|
if ".git" in base:
|
||||||
|
continue
|
||||||
|
if base.startswith(TEMPLATES):
|
||||||
|
base = base[len(TEMPLATES):]
|
||||||
|
|
||||||
|
for name in files:
|
||||||
|
if name.endswith(".html"):
|
||||||
|
def handler(base, name):
|
||||||
|
def handler():
|
||||||
|
return render_template(os.path.join(base, name).strip("/").replace("\\", "/"))
|
||||||
|
return handler
|
||||||
|
|
||||||
|
local_base = base.replace("\\", "/").strip(".").strip("/")
|
||||||
|
if local_base.startswith(PAGES_BASE):
|
||||||
|
local_base = local_base[len(PAGES_BASE):]
|
||||||
|
|
||||||
|
route = local_base + "/" + name
|
||||||
|
if route.endswith("/index.html"):
|
||||||
|
route = route[:-10]
|
||||||
|
if not route.startswith("/"):
|
||||||
|
route = "/" + route
|
||||||
|
|
||||||
|
handler = handler(base, name)
|
||||||
|
handler.__name__ == route
|
||||||
|
app.add_url_rule(route, route, handler)
|
||||||
|
|
||||||
|
|
||||||
|
from flask import url_for
|
||||||
|
def has_no_empty_params(rule):
|
||||||
|
defaults = rule.defaults if rule.defaults is not None else ()
|
||||||
|
arguments = rule.arguments if rule.arguments is not None else ()
|
||||||
|
return len(defaults) >= len(arguments)
|
||||||
|
@app.route("/site-map")
|
||||||
|
def site_map():
|
||||||
|
links = []
|
||||||
|
for rule in app.url_map.iter_rules():
|
||||||
|
# Filter out rules we can't navigate to in a browser
|
||||||
|
# and rules that require parameters
|
||||||
|
if "GET" in rule.methods and has_no_empty_params(rule):
|
||||||
|
url = url_for(rule.endpoint, **(rule.defaults or {}))
|
||||||
|
links.append((url, rule.endpoint))
|
||||||
|
return str(links)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||||
|
app.config['DEBUG'] = True
|
||||||
|
|
||||||
|
server = Server(app.wsgi_app)
|
||||||
|
server.watch("templates")
|
||||||
|
server.serve(port=3000)
|
7
freeze.py
Normal file
7
freeze.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from flask_frozen import Freezer
|
||||||
|
from docs import app
|
||||||
|
|
||||||
|
freezer = Freezer(app)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
freezer.freeze()
|
106
index.html
106
index.html
@ -1,106 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href=".">Contents</a></td>
|
|
||||||
<td><a href="./transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="./packet.html">Packet format</a></td>
|
|
||||||
<td><a href="./protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<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 (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>
|
|
||||||
<p>If you're here because you work on one of those aforementioned closed source projects, hello! Feel free to share
|
|
||||||
knowledge with the rest of the world, or point out corrections. Or don't; you do you.</p>
|
|
||||||
|
|
||||||
<h3>Code snippets</h3>
|
|
||||||
<p>Across these pages there are a number of code snippets. They roughly break down into three categories:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Assembly: Directly disassembled code from game binaries</li>
|
|
||||||
<li>C: Either raw decompilation, or slightly cleaned up decompilation</li>
|
|
||||||
<li>Python: Snippets from my local testing implementations</li>
|
|
||||||
<li>Pseudocode: Used to illustrate some points. Note that it probably started life as Python before being
|
|
||||||
pseudo'd</li>
|
|
||||||
</ul>
|
|
||||||
<p>If you yoink chunks of Python code, attribution is always appreciated, but consider it under CC0 (just don't be
|
|
||||||
that person who tries to take credit for it, yeah?).</p>
|
|
||||||
|
|
||||||
<h2>Contents</h2>
|
|
||||||
<ol>
|
|
||||||
<li><a href="./transport.html">Transport layer</a></li>
|
|
||||||
<ol>
|
|
||||||
<li><a href="./transport.html#packet">Packet structure</a></li>
|
|
||||||
<li><a href="./transport.html#type">Types</a></li>
|
|
||||||
</ol>
|
|
||||||
<li><a href="./packet.html">The inner packet structure</a></li>
|
|
||||||
<ol>
|
|
||||||
<li><a href="./packet.html#xml">XML packets</a></li>
|
|
||||||
<li><a href="./packet.html#binary">Binary packed packets</a></li>
|
|
||||||
<li><a href="./packet.html#schema">Binary schemas</a></li>
|
|
||||||
<li><a href="./packet.html#data">Binary data</a></li>
|
|
||||||
</ol>
|
|
||||||
<li><a href="./protocol.html">Communication protocol details</a></li>
|
|
||||||
<ul>
|
|
||||||
<li>There are a crazy number of sub pages here, so just go check the contents there.</li>
|
|
||||||
</ul>
|
|
||||||
<li>Misc pages</li>
|
|
||||||
<ol>
|
|
||||||
<li><a href="./cardid.html">Parsing and converting card IDs</a></li>
|
|
||||||
</ol>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<h2>Getting started</h2>
|
|
||||||
<p>My aim with these pages is to cover as much as possible, so you don't need to try and figure them out yourself.
|
|
||||||
That said, being able to follow along yourself will almost certainly help get more out of this. For following
|
|
||||||
along with source code, you're really going to want to grab yourself a dumped copy of a game (it's going to be a
|
|
||||||
lot easier, and cheeper, than dumping one yourself). I trust you can figure out where to find that.</p>
|
|
||||||
<p>For network related things, your options are a little broader. The ideal would be physical ownership of a
|
|
||||||
cabinet, and a subscription to genuine e-amusement. Odds are you don't have both of those :P. A connection to an
|
|
||||||
alternative network works just as well. In the more likely case that you don't have a physical cabinet, it's
|
|
||||||
time to crack out that dumped copy of a game and just run it on your own PC (or a VM, if you're not on Windows)
|
|
||||||
(odds are whatever you downloaded came with the program you'll need to start it pre-packaged. If not, it rhymes
|
|
||||||
with rice.).</p>
|
|
||||||
<p>You will also need a local e-amusement-emulating server. By the time I'm done with these pages, there will
|
|
||||||
hopefully be everything you need to be able to write your own. Unfortunately I'm not finished writing them;
|
|
||||||
depending on where you acquired your game, it may have shipped with one of said servers. If it didn't, Asphyxia
|
|
||||||
CORE will do the trick (yes, it's closed source).</p>
|
|
||||||
<p>If this all sounds like way too much work, and/or you're just here because of curiosity, I plan to prepare some
|
|
||||||
pcaps of network traffic to play around with without needing a running copy of a game or a network tap on a cab.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<a href="./transport.html">Next page</a>
|
|
||||||
|
|
||||||
<p><small>This site intentionally looks not-great. I don't feel like changing that, and honestly quite like the
|
|
||||||
aesthetic.</small></p>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
896
packet.html
896
packet.html
@ -1,896 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>Packet format | eAmuse API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href=".">Contents</a></td>
|
|
||||||
<td><a href="./transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="./packet.html">Packet format</a></td>
|
|
||||||
<td><a href="./protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1>Packet format</h1>
|
|
||||||
|
|
||||||
<p>eAmuse uses XML for its application layer payloads*. This XML is either verbatim, or in a custom packed binary
|
|
||||||
format.<br /><small>*Newer games use JSON, but this page is about XML.</small></p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="xml">The XML format</h2>
|
|
||||||
|
|
||||||
<p>Each tag that contains a value has a <code>__type</code> attribute that identifies what type it is. Array types
|
|
||||||
have a <code>__count</code> attribute indicating how many items are in the array. Binary blobs additionally have
|
|
||||||
a <code>__size</code> attribute indicating their length (this is notably not present on strings, however).</p>
|
|
||||||
<p>It is perhaps simpler to illustrate with an example, so:</p>
|
|
||||||
<pre><code><?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<call model="KFC:J:A:A:2019020600" srcid="1000" tag="b0312077">
|
|
||||||
<eventlog method="write">
|
|
||||||
<retrycnt __type="u32" />
|
|
||||||
<data>
|
|
||||||
<eventid __type="str">G_CARDED</eventid>
|
|
||||||
<eventorder __type="s32">5</eventorder>
|
|
||||||
<pcbtime __type="u64">1639669516779</pcbtime>
|
|
||||||
<gamesession __type="s64">1</gamesession>
|
|
||||||
<strdata1 __type="str" />
|
|
||||||
<strdata2 __type="str" />
|
|
||||||
<numdata1 __type="s64">1</numdata1>
|
|
||||||
<numdata2 __type="s64" />
|
|
||||||
<locationid __type="str">ea</locationid>
|
|
||||||
</data>
|
|
||||||
</eventlog>
|
|
||||||
</call></code></pre>
|
|
||||||
<p>Arrays are encoded by concatenating every value together, with spaces between them. Data types that have multiple
|
|
||||||
values, are serialized similarly.</p>
|
|
||||||
<p>Therefore, an element storing an array of <code>3u8</code> (<code>[(1, 2, 3), (4, 5, 6)]</code>) would look like
|
|
||||||
this</p>
|
|
||||||
<pre><code><demo __type="3u8" __count="2">1 2 3 4 5 6</demo></code></pre>
|
|
||||||
<p>Besides this, this is otherwise a rather standard XML.</p>
|
|
||||||
|
|
||||||
<h2 id="binary">Packed binary overview</h2>
|
|
||||||
|
|
||||||
<p>Many packets, rather than using a string-based XML format, use a custom binary packed format instead. While it
|
|
||||||
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 class="code">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>10</td>
|
|
||||||
<td>11</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>13</td>
|
|
||||||
<td>14</td>
|
|
||||||
<td>15</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td><i>A0</i></td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>~E</td>
|
|
||||||
<td colspan="4">Head length</td>
|
|
||||||
<td style="border-bottom: none" colspan="8"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="border-top: none; border-bottom: none;" colspan="16">Schema definition</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="border-top: none;" colspan="12"></td>
|
|
||||||
<td colspan="1"><i>FF</i></td>
|
|
||||||
<td colspan="3">Align</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="4">Data length</td>
|
|
||||||
<td style="border-bottom: none" colspan="12"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="border-top: none; border-bottom: none;" colspan="16">Payload</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="border-top: none;" colspan="13"></td>
|
|
||||||
<td colspan="3">Align</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<p>Every packet starts with the magic byte <code>0xA0</code>. Following this is the content byte, the encoding byte,
|
|
||||||
and then the 2's compliment of the encoding byte.</p>
|
|
||||||
<p>Currently known possible values for the content byte are:</p>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>C</td>
|
|
||||||
<td>Content</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td><code>0x42</code></td>
|
|
||||||
<td>Compressed data</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>0x43</code></td>
|
|
||||||
<td>Compressed, no data</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>0x45</code></td>
|
|
||||||
<td>Decompressed data</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>0x46</code></td>
|
|
||||||
<td>Decompressed, no data</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<p>Decompressed packets contain an XML string. Compressed packets are what we're interested in here.</p>
|
|
||||||
<p>The encoding flag indicates the encoding for all string types in the packet (more on those later). Possible
|
|
||||||
values are:</p>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td><code>E</code></td>
|
|
||||||
<td><code>~E</code></td>
|
|
||||||
<td colspan="3">Encoding name</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td><code>0x20</code></td>
|
|
||||||
<td><code>0xDF</code></td>
|
|
||||||
<td><code>ASCII</code></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>0x40</code></td>
|
|
||||||
<td><code>0xBF</code></td>
|
|
||||||
<td><code>ISO-8859-1</code></td>
|
|
||||||
<td><code>ISO_8859-1</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<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><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><code>0xA0</code></td>
|
|
||||||
<td><code>0x5F</code></td>
|
|
||||||
<td><code>UTF-8</code></td>
|
|
||||||
<td><code>UTF8</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<details>
|
|
||||||
<summary>Source code details</summary>
|
|
||||||
<p>The full table for these values can be found in libavs.</p>
|
|
||||||
<figure>
|
|
||||||
<img src="./images/encoding_table.png">
|
|
||||||
<figcaption><code>libavs-win32.dll:0x1006b960</code></figcaption>
|
|
||||||
</figure>
|
|
||||||
<p>A second table exists just before this on in the source, responsible for the
|
|
||||||
<code><?xml version='1.0' encoding='??'?></code> line in XML files.
|
|
||||||
</p>
|
|
||||||
<figure>
|
|
||||||
<img src="./images/xml_encoding_table.png">
|
|
||||||
<figcaption><code>libavs-win32.dll:0x1006b940</code></figcaption>
|
|
||||||
</figure>
|
|
||||||
<p>This is indexed using the following function, which maps the above encoding IDs to 1, 2, 3, 4 and 5
|
|
||||||
respectively.</p>
|
|
||||||
<pre><code>char* xml_get_encoding_name(uint encoding_id) {
|
|
||||||
return ENCODING_NAME_TABLE[((encoding_id & 0xe0) >> 5) * 4];
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
<p>While validating <code>~E</code> isn't technically required, it acts as a useful assertion that the packet being
|
|
||||||
parsed is valid.</p>
|
|
||||||
|
|
||||||
<h2 id="schema">The packet schema header</h2>
|
|
||||||
<p>Following the 4 byte header, is a 4 byte integer containing the length of the next part of the header (this is
|
|
||||||
technically made redundant as this structure is also terminated).</p>
|
|
||||||
<p>This part of the header defines the schema that the main payload uses.</p>
|
|
||||||
|
|
||||||
<p>A tag definition looks like:</p>
|
|
||||||
|
|
||||||
<table class="code">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>10</td>
|
|
||||||
<td>11</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>13</td>
|
|
||||||
<td>14</td>
|
|
||||||
<td>15</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>Type</td>
|
|
||||||
<td>nlen</td>
|
|
||||||
<td colspan="7">Tag name</td>
|
|
||||||
<td style="border-bottom: none" colspan="8"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="border-top: none;" colspan="15">Attributes and children</td>
|
|
||||||
<td colspan="1"><i>FE</i></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>Structure names are encoded as densely packed 6 bit values, length prefixed (<code>nlen</code>). The acceptable
|
|
||||||
alphabet is <code>0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz</code>, and the packed values
|
|
||||||
are indecies within this alphabet.</p>
|
|
||||||
|
|
||||||
<p>The children can be a combination of either attribute names, or child tags. Attribute names are represented by
|
|
||||||
the byte <code>0x2E</code> followed by a length prefixed name as defined above. Child tags follow the above
|
|
||||||
format. Type <code>0x2E</code> must therefore be considered reserved as a possible structure type.</p>
|
|
||||||
|
|
||||||
<p>Attributes (type <code>0x2E</code>) represent a string attribute. Any other attribute must be defined as a child
|
|
||||||
tag. Is it notable that 0 children is allowable, which is how the majority of values are encoded.</p>
|
|
||||||
<p>All valid IDs, and their respective type, are listed in the following table. The bucket column here will be
|
|
||||||
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 class="code">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>ID</td>
|
|
||||||
<td>Bytes</td>
|
|
||||||
<td>C type</td>
|
|
||||||
<td>Bucket</td>
|
|
||||||
<td colspan="2">XML names</td>
|
|
||||||
<td></td>
|
|
||||||
<td>ID</td>
|
|
||||||
<td>Bytes</td>
|
|
||||||
<td>C type</td>
|
|
||||||
<td>Bucket</td>
|
|
||||||
<td colspan="2">XML names</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>0x01</td>
|
|
||||||
<td>0</td>
|
|
||||||
<td>void</td>
|
|
||||||
<td>-</td>
|
|
||||||
<td>void</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x21</td>
|
|
||||||
<td>24</td>
|
|
||||||
<td>uint64[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3u64</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x02</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>int8</td>
|
|
||||||
<td>byte</td>
|
|
||||||
<td>s8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x22</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>float[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3f</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x03</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>uint8</td>
|
|
||||||
<td>byte</td>
|
|
||||||
<td>u8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x23</td>
|
|
||||||
<td>24</td>
|
|
||||||
<td>double[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3d</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x04</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>int16</td>
|
|
||||||
<td>short</td>
|
|
||||||
<td>s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x24</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>int8[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4s8</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x05</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>uint16</td>
|
|
||||||
<td>short</td>
|
|
||||||
<td>s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x25</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>uint8[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4u8</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x06</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>int32</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>s32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x26</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>int16[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4s16</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x07</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>uint32</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>u32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x27</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>uint8[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4s16</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x08</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>int64</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>s64</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x28</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>int32[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4s32</td>
|
|
||||||
<td>vs32</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x09</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>uint64</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>u64</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x29</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>uint32[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4u32</td>
|
|
||||||
<td>vs32</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0a</td>
|
|
||||||
<td><i>prefix</i></td>
|
|
||||||
<td>char[]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>bin</td>
|
|
||||||
<td>binary</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2a</td>
|
|
||||||
<td>32</td>
|
|
||||||
<td>int64[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4s64</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0b</td>
|
|
||||||
<td><i>prefix</i></td>
|
|
||||||
<td>char[]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>str</td>
|
|
||||||
<td>string</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2b</td>
|
|
||||||
<td>32</td>
|
|
||||||
<td>uint64[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4u64</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0c</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>uint8[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>ip4</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2c</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>float[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4f</td>
|
|
||||||
<td>vf</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0d</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>uint32</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>time</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2d</td>
|
|
||||||
<td>32</td>
|
|
||||||
<td>double[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4d</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0e</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>float</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>float</td>
|
|
||||||
<td>f</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2e</td>
|
|
||||||
<td><i>prefix</i></td>
|
|
||||||
<td>char[]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>attr</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x0f</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>double</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>double</td>
|
|
||||||
<td>d</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x2f</td>
|
|
||||||
<td>0</td>
|
|
||||||
<td></td>
|
|
||||||
<td>-</td>
|
|
||||||
<td>array</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x10</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>int8[2]</td>
|
|
||||||
<td>short</td>
|
|
||||||
<td>2s8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x30</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>int8[16]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>vs8</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x11</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>uint8[2]</td>
|
|
||||||
<td>short</td>
|
|
||||||
<td>2u8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x31</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>uint8[16]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>vu8</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x12</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>int16[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x32</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>int8[8]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>vs16</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x13</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>uint16[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x33</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>uint8[8]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>vu16</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x14</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>int32[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2s32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x34</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>bool</td>
|
|
||||||
<td>byte</td>
|
|
||||||
<td>bool</td>
|
|
||||||
<td>b</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x15</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>uint32[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2u32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x35</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>bool[2]</td>
|
|
||||||
<td>short</td>
|
|
||||||
<td>2b</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x16</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>int16[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2s64</td>
|
|
||||||
<td>vs64</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x36</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>bool[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3b</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x17</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>uint16[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2u64</td>
|
|
||||||
<td>vu64</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x37</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>bool[4]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>4b</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x18</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>float[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2f</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x38</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>bool[16]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>vb</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x19</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td>double[2]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>2d</td>
|
|
||||||
<td>vd</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x38</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1a</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>int8[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3s8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x39</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1b</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>uint8[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3u8</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3a</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1c</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>int16[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3b</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1d</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>uint16[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3s16</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3c</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1e</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>int32[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3s32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3d</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x1f</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>uint32[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3u32</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3e</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>0x20</td>
|
|
||||||
<td>24</td>
|
|
||||||
<td>int64[3]</td>
|
|
||||||
<td>int</td>
|
|
||||||
<td>3s64</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>0x3f</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>Strings should be encoded and decoded according to the encoding specified in the packet header. Null termination is optional, however should be stripped during decoding.</p>
|
|
||||||
<p>All of these IDs are <code>& 0x3F</code>. Any value can be turned into an array by setting the 7<sup>th</sup> bit
|
|
||||||
high (<code>| 0x40</code>). Arrays of this form, in the data section, will be an aligned <code>size: u32</code>
|
|
||||||
immediately followed by <code>size</code> bytes' worth of (unaligned!) values of the unmasked type.</p>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Source code details</summary>
|
|
||||||
<p>The full table for these values can be found in libavs. This table contains the names of every tag, along
|
|
||||||
with additional information such as how many bytes that data type requires, and which parsing function
|
|
||||||
should be used.</p>
|
|
||||||
<figure>
|
|
||||||
<img src="./images/types_table.png">
|
|
||||||
<figcaption><code>libavs-win32.dll:0x100782a8</code></figcaption>
|
|
||||||
</figure>
|
|
||||||
</details>
|
|
||||||
<details>
|
|
||||||
<summary>Note about the <code>array</code> type:</summary>
|
|
||||||
<p>While I'm not totally sure, I have a suspicion this type is used internally as a pseudo-type. Trying to
|
|
||||||
identify its function as a parsable type has some obvious blockers:</p>
|
|
||||||
|
|
||||||
<p>All of the types have convenient <code>printf</code>-using helper functions that are used to emit them when
|
|
||||||
serializing XML. All except one.</p>
|
|
||||||
<img src="./images/no_array.png">
|
|
||||||
<p>If we have a look inside the function that populates node sizes (<code>libavs-win32.dll:0x1000cf00</code>),
|
|
||||||
it has an explicit case, however is the same fallback as the default case.</p>
|
|
||||||
<img src="./images/no_array_2.png">
|
|
||||||
|
|
||||||
<p>In the same function, however, we can find a second (technically first) check for the array type.</p>
|
|
||||||
<img src="./images/yes_array.png">
|
|
||||||
<p>This seems to suggest that internally arrays are represented as a normal node, with the <code>array</code>
|
|
||||||
type, however when serializing it's converted into the array types we're used to (well, will be after the
|
|
||||||
next sections) by masking 0x40 onto the contained type.</p>
|
|
||||||
<p>Also of interest from this snippet is the fact that <code>void</code>, <code>bin</code>, <code>str</code>,
|
|
||||||
and <code>attr</code> cannot be arrays. <code>void</code> and <code>attr</code> make sense, however
|
|
||||||
<code>str</code> and <code>bin</code> are more interesting. I suspect this is because konami want to be able
|
|
||||||
to preallocate the memory, which wouldn't be possible with these variable length structures.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<h2 id="data">The data section</h2>
|
|
||||||
|
|
||||||
<p>This is where all the actual packet data is. For the most part, parsing this is the easy part. We traverse our
|
|
||||||
schema, and read values out of the packet according to the value indicated in the schema. Unfortunately, konami
|
|
||||||
decided all data should be aligned very specifically, and that gaps left during alignment should be backfilled
|
|
||||||
later. This makes both reading and writing somewhat more complicated, however the system can be fairly easily
|
|
||||||
understood.</p>
|
|
||||||
<p>Firstly, we divide the payload up into 4 byte chunks. Each chunk can be allocated to either store individual
|
|
||||||
bytes, shorts, or ints (these are the buckets in the table above). When reading or writing a value, we first
|
|
||||||
check if a chunk allocated to the desired type's bucket is available and has free/as-yet-unread space within it.
|
|
||||||
If so, we will store/read our data to/from there. If there is no such chunk, we claim the next unclaimed chunk
|
|
||||||
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 class="code">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>10</td>
|
|
||||||
<td>11</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td>13</td>
|
|
||||||
<td>14</td>
|
|
||||||
<td>15</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>byte</td>
|
|
||||||
<td>byte</td>
|
|
||||||
<td>byte</td>
|
|
||||||
<td></td>
|
|
||||||
<td colspan="4">int</td>
|
|
||||||
<td colspan="2">short</td>
|
|
||||||
<td colspan="2">short</td>
|
|
||||||
<td colspan="4">int</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>While this might seem a silly system compared to just not aligning values, it is at least possible to intuit that it helps reduce wasted space. It should be noted that any variable-length structure, such as a string or an array, claims all chunks it encroaches on for the <code>int</code> bucket, disallowing the storage of bytes or shorts within them.</p>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Implementing a packer</summary>
|
|
||||||
<p>While the intuitive way to understand the packing algorithm is via chunks and buckets, a far more efficient implementation can be made that uses three pointers. Rather than try to explain in words, hopefully this python implementation should suffice as explanation:<pre><code>class Packer:
|
|
||||||
def __init__(self, offset=0):
|
|
||||||
self._word_cursor = offset
|
|
||||||
self._short_cursor = offset
|
|
||||||
self._byte_cursor = offset
|
|
||||||
self._boundary = offset % 4
|
|
||||||
|
|
||||||
def _next_block(self):
|
|
||||||
self._word_cursor += 4
|
|
||||||
return self._word_cursor - 4
|
|
||||||
|
|
||||||
def request_allocation(self, size):
|
|
||||||
if size == 0:
|
|
||||||
return self._word_cursor
|
|
||||||
elif size == 1:
|
|
||||||
if self._byte_cursor % 4 == self._boundary:
|
|
||||||
self._byte_cursor = self._next_block() + 1
|
|
||||||
else:
|
|
||||||
self._byte_cursor += 1
|
|
||||||
return self._byte_cursor - 1
|
|
||||||
elif size == 2:
|
|
||||||
if self._short_cursor % 4 == self._boundary:
|
|
||||||
self._short_cursor = self._next_block() + 2
|
|
||||||
else:
|
|
||||||
self._short_cursor += 2
|
|
||||||
return self._short_cursor - 2
|
|
||||||
else:
|
|
||||||
old_cursor = self._word_cursor
|
|
||||||
for _ in range(math.ceil(size / 4)):
|
|
||||||
self._word_cursor += 4
|
|
||||||
return old_cursor
|
|
||||||
|
|
||||||
def notify_skipped(self, no_bytes):
|
|
||||||
for _ in range(math.ceil(no_bytes / 4)):
|
|
||||||
self.request_allocation(4)</code></pre></p>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<a href="./transport.html">Prev page</a> | <a href="./protocol.html">Next page</a>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>apsmanager</code></h1>
|
|
||||||
<h2 id="getstat"><code>apsmanager.getstat</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<apsmanager method="getstat" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<apsmanager status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,232 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>cardmng</code></h1>
|
|
||||||
<p>As the name might imply, this service is responsible for handling interactions with physical e-Amusement cards.
|
|
||||||
e-Amusement currently has two different types of cards in circulation. There are classic e-Amusement cards
|
|
||||||
making use of a magnetic stripe, and the newer RFID cards using FeliCa (these are probably what you have). They
|
|
||||||
are identified in requests using the <code>cardtype</code> attribute as in the below table.
|
|
||||||
</p>
|
|
||||||
<p>e-Amusement cards have a "card number" and a "card id". Confusingly, neither is a number. The card number is the
|
|
||||||
one printed on your card. The card ID is your KONAMI ID. You can (and should) read about the algorithm used for
|
|
||||||
these IDs on <a href="../cardid.html">the Card IDs page</a>.</p>
|
|
||||||
<p>In the interest of not wasting space, <code>cardid</code> and <code>cardtype</code> will be omitted from
|
|
||||||
individual breakdowns where their meaning is obvious.</p>
|
|
||||||
|
|
||||||
<h4>Card types:</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td><code>cardtype</code></td>
|
|
||||||
<td>Meaning</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td><code>1</code></td>
|
|
||||||
<td>Old style magnetic stripe card</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>2</code></td>
|
|
||||||
<td>FeliCa RFID card</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code><a href="#inquire">cardmng.inquire</a></code></li>
|
|
||||||
<li><code><a href="#getrefid">cardmng.getrefid</a></code></li>
|
|
||||||
<li><code><a href="#bindmodel">cardmng.bindmodel</a></code></li>
|
|
||||||
<li><code><a href="#bindcard">cardmng.bindcard</a></code></li>
|
|
||||||
<li><code><a href="#authpass">cardmng.authpass</a></code></li>
|
|
||||||
<li><code><a href="#getkeepspan">cardmng.getkeepspan</a></code></li>
|
|
||||||
<li><code><a href="#getkeepremain">cardmng.getkeepremain</a></code></li>
|
|
||||||
<li><code><a href="#getdatalist">cardmng.getdatalist</a></code></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="inquire"><code>cardmng.inquire</code></h2>
|
|
||||||
<p>Request information about a card that has been inserted or touched against a reader.</p>
|
|
||||||
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="inquire" cardid="" cardtype="" update="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><code>update</code></td>
|
|
||||||
<td>Should the tracked last play time be updated by this inquiry? (Just a guess)</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" refid="" dataid="" pcode="" newflag="" binded="" expired=" ecflag="" useridflag="" extidflag="" lastupdate="" />
|
|
||||||
</response></code></pre>
|
|
||||||
<p>To handle this request, we first must lookup if this <code>cardid</code> has ever been seen by our servers
|
|
||||||
before. If not, we abort with a <code>112</code> status. Otherwise, we proceeed to check if this card has been
|
|
||||||
seen for this specific game. If we have never seen this card used on this game, it is possible this card was
|
|
||||||
used with an older version of this game, and migration is supported, in which case we report as if we had found
|
|
||||||
a profile for this game.</p>
|
|
||||||
<table>
|
|
||||||
<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>Inverse of <code>binded</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>? Just set to <code>0</code>.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2 id="getrefid"><code>cardmng.getrefid</code></h2>
|
|
||||||
<p>Register a new card to this server.</p>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="getrefid" cardtype="" cardid=" newflag="" passwd="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><code>newflag</code></td>
|
|
||||||
<td>?</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>passwd</code></td>
|
|
||||||
<td>The pin for this new user. <i>Should</i> always be a four digit number (and that's worth validating),
|
|
||||||
but it's passed as a string so could feasibly be anything desired.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" refid="" dataid="" pcode="" />
|
|
||||||
</response></code></pre>
|
|
||||||
<table>
|
|
||||||
<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>pcode</code></td>
|
|
||||||
<td>? Not present in captured data.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2 id="bindmodel"><code>cardmng.bindmodel</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="bindmodel" refid="" newflag="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" dataid="" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="bindcard"><code>cardmng.bindcard</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="bindcard" cardtype="" newid="" refid="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="authpass"><code>cardmng.authpass</code></h2>
|
|
||||||
<p>Test a pin for a card. This request notably uses the <code>refid</code>, so required a
|
|
||||||
<code>cardmng.inquire</code> call to be made first.
|
|
||||||
</p>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="authpass" refid="" pass="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><code>refid</code></td>
|
|
||||||
<td>The reference we received either during <code>cardmng.inquire</code> or <code>cardmng.getrefid</code>
|
|
||||||
(the latter for new cards)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>pass</code></td>
|
|
||||||
<td>The pin to test. See <code>cardmng.getrefid</code>.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
<p>If the pin is valid, status should be <code>0</code>. Otherwise, <code>116</code>.</p>
|
|
||||||
|
|
||||||
<h2 id="getkeepspan"><code>cardmng.getkeepspan</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="getkeepspan" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" keepspan="" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="getkeepremain"><code>cardmng.getkeepremain</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="getkeepremain" refid="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>" keepremain="" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="getdatalist"><code>cardmng.getdatalist</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<cardmng method="getdatalist" refid="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<cardmng status="<i>status</i>">
|
|
||||||
<item[]>
|
|
||||||
<mcode __type="str" />
|
|
||||||
<dataid __type="str" />
|
|
||||||
<regtime __type="str" />
|
|
||||||
<lasttime __type="str" />
|
|
||||||
<exptime __type="str" />
|
|
||||||
<expflag __type="u8" />
|
|
||||||
</item[]>
|
|
||||||
</cardmng>
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,54 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>dlstatus</code></h1>
|
|
||||||
<h2 id="done"><code>dlstatus.done</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<dlstatus method="done">
|
|
||||||
<url>
|
|
||||||
<param __type="str" />
|
|
||||||
</url>
|
|
||||||
<name __type="str" />
|
|
||||||
<size __type="s32" />
|
|
||||||
</dlstatus>
|
|
||||||
</call></code></pre>
|
|
||||||
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<dlstatus status="<i>status</i>">
|
|
||||||
<progress __type="s32" />
|
|
||||||
</dlstatus>
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="progress"><code>dlstatus.progress</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<dlstatus method="progress" />
|
|
||||||
<progress __type="s32" />
|
|
||||||
</dlstatus>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<dlstatus status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>esign</code></h1>
|
|
||||||
<h2 id="request"><code>esign.request</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<esign method="request">
|
|
||||||
<i>placeholder</i>
|
|
||||||
</esign>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<esign status="<i>status</i>">
|
|
||||||
<i>placeholder</i>
|
|
||||||
</esign>
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,50 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>esoc</code></h1>
|
|
||||||
<h2 id="read"><code>esoc.read</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<esoc method="read">
|
|
||||||
<senddata />
|
|
||||||
</esoc>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<esoc status="<i>status</i>">
|
|
||||||
<recvdata />
|
|
||||||
</esoc>
|
|
||||||
</response></code></pre>
|
|
||||||
<p>Go figure.</p>
|
|
||||||
|
|
||||||
<h2 id="write"><code>esoc.write</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<esoc method="write">
|
|
||||||
<senddata />
|
|
||||||
</esoc>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<esoc status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,58 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>eventlog</code></h1>
|
|
||||||
<h2 id="write"><code>eventlog.write</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<eventlog method="write">
|
|
||||||
<retrycnt __type="u32" />
|
|
||||||
<data>
|
|
||||||
<eventid __type="str" />
|
|
||||||
<eventorder __type="s32" />
|
|
||||||
<pcbtime __type="u64" />
|
|
||||||
<gamesession __type="s64" />
|
|
||||||
<strdata1 __type="str" />
|
|
||||||
<strdata2 __type="str" />
|
|
||||||
<numdata1 __type="s64" />
|
|
||||||
<numdata2 __type="s64" />
|
|
||||||
<locationid __type="str" />
|
|
||||||
</data>
|
|
||||||
</eventlog>
|
|
||||||
</call></code></pre>
|
|
||||||
<p>Event ID list:</p>
|
|
||||||
<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>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<eventlog status="<i>status</i>">
|
|
||||||
<gamesession __type="s64" />
|
|
||||||
<logsendflg __type="s32" />
|
|
||||||
<logerrlevel __type="s32" />
|
|
||||||
<evtidnosendflg __type="s32" />
|
|
||||||
</eventlog>
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,35 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>message</code></h1>
|
|
||||||
<h2 id="get"><code>message.get</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<message method="get" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<message expire="" status="<i>status</i>">
|
|
||||||
<item[] name="" start="" end="" data="" />
|
|
||||||
</message>
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,47 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>package</code></h1>
|
|
||||||
<h2 id="list"><code>package.list</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<package method="list" pkgtype="<i>pkgtype</i>" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<p><code>all</code> is the only currently observed value for <code>pkgtype</code></p>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<package status="<i>status</i>">
|
|
||||||
<item[] url="" />
|
|
||||||
</package>
|
|
||||||
</response></code></pre>
|
|
||||||
<p>A list of all packages available for download.</p>
|
|
||||||
|
|
||||||
<h2 id="intend"><code>package.intend</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<package method="intend" url="" model*="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<package status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,41 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>pcbevent</code></h1>
|
|
||||||
<h2 id="put"><code>pcbevent.put</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<pcbevent method="put">
|
|
||||||
<time __type="time" />
|
|
||||||
<seq __type="u32" />
|
|
||||||
<item[]>
|
|
||||||
<name __type="str" />
|
|
||||||
<value __type="s32" />
|
|
||||||
<time __type="time" />
|
|
||||||
</item[]>
|
|
||||||
</pcbevent>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<pcbevent status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,39 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>pcbtracker</code></h1>
|
|
||||||
<h2 id="alive"><code>pcbtracker.alive</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<pcbtracker method="alive" model*="" hardid="" softid="" accountid="" agree="" ecflag="" />
|
|
||||||
</call></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>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<pcbtracker status="" time="" limit="" ecenable="" eclimit="" >
|
|
||||||
</response></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>
|
|
||||||
</body>
|
|
@ -1,70 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>services</code></h1>
|
|
||||||
<h2 id="get"><code>services.get</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<services method="get" model*="" >
|
|
||||||
<info>
|
|
||||||
<AVS2 __type="str"><i>AVS2 version</i></AVS2>
|
|
||||||
</info>
|
|
||||||
</services>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<services expire="" method="get" mode="" status="<i>status</i>">
|
|
||||||
<item[] name="<i>service</i>" url="<i>url</i>" />
|
|
||||||
</services>
|
|
||||||
</response></code></pre>
|
|
||||||
<p>Known services are:</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>ntp</code></li>
|
|
||||||
<li><code>keepalive</code></li>
|
|
||||||
<li><code>cardmng</code></li>
|
|
||||||
<li><code>facility</code></li>
|
|
||||||
<li><code>message</code></li>
|
|
||||||
<li><code>numbering</code></li>
|
|
||||||
<li><code>package</code></li>
|
|
||||||
<li><code>pcbevent</code></li>
|
|
||||||
<li><code>pcbtracker</code></li>
|
|
||||||
<li><code>pkglist</code></li>
|
|
||||||
<li><code>posevent</code></li>
|
|
||||||
<li><code>userdata</code></li>
|
|
||||||
<li><code>userid</code></li>
|
|
||||||
<li><code>eacoin</code></li>
|
|
||||||
<li><code>local</code></li>
|
|
||||||
<li><code>local2</code></li>
|
|
||||||
<li><code>lobby</code></li>
|
|
||||||
<li><code>lobby2</code></li>
|
|
||||||
<li><code>dlstatus</code></li>
|
|
||||||
<li><code>netlog</code></li>
|
|
||||||
<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><code>mode</code> is one of <code>operation</code>, <code>debug</code>, <code>test</code>, or
|
|
||||||
<code>factory</code>.
|
|
||||||
</p>
|
|
||||||
</body>
|
|
@ -1,94 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>sidmgr</code></h1>
|
|
||||||
<h2 id="create"><code>sidmgr.create</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<sidmgr method="create">
|
|
||||||
<cardtype __type="str" />
|
|
||||||
<cardid __type="str" />
|
|
||||||
<cardgid __type="str" />
|
|
||||||
<steal __type="u8" />
|
|
||||||
</sidmgr>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<sidmgr status="<i>status</i>">
|
|
||||||
<state __type="u32" />
|
|
||||||
<e_count __type="u8" />
|
|
||||||
<last __type="time" />
|
|
||||||
<locked __type="time" />
|
|
||||||
<sid __type="str" />
|
|
||||||
<cardid_status __type="u8" />
|
|
||||||
<refid __type="str" />
|
|
||||||
</sidmgr>
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="open"><code>sidmgr.open</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<sidmgr method="open" sid="" >
|
|
||||||
<pass __type="str" />
|
|
||||||
</sidmgr>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<sidmgr status="<i>status</i>">
|
|
||||||
<state __type="u32" />
|
|
||||||
<refid __type="str" />
|
|
||||||
<locked __type="time" />
|
|
||||||
</sidmgr>
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="touch"><code>sidmgr.touch</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<sidmgr method="touch" sid="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<sidmgr status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="branch"><code>sidmgr.branch</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<sidmgr method="branch" sid="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<sidmgr status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
|
|
||||||
<h2 id="close"><code>sidmgr.close</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<sidmgr method="close" sid="" />
|
|
||||||
<cause __type="u32" />
|
|
||||||
</sidmgr>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<sidmgr status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,40 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>traceroute</code></h1>
|
|
||||||
<h2 id="send"><code>traceroute.send</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<traceroute proto="" method="send">
|
|
||||||
<hop[]>
|
|
||||||
<valid __type="bool">
|
|
||||||
<addr __type="ip4">
|
|
||||||
<usec __type="u64">
|
|
||||||
</hop[]>
|
|
||||||
</traceroute>
|
|
||||||
</call></code></pre>
|
|
||||||
<p><code>hop</code> repeats for every hop (unsurprisingly)</p>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<traceroute status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
@ -1,48 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>userdata</code></h1>
|
|
||||||
<h2 id="read"><code>userdata.read</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<userdata method="read" card*="" model*="" label="" />
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<userdata status="<i>status</i>" time="">
|
|
||||||
<b[] __type="" />
|
|
||||||
</userdata>
|
|
||||||
</response></code></pre>
|
|
||||||
<p><code>__type</code> here can be either <code>bin</code> or <code>str</code></p>
|
|
||||||
|
|
||||||
<h2 id="write"><code>userdata.write</code></h2>
|
|
||||||
<h3>Request:</h3>
|
|
||||||
<pre><code><call <i>...</i>>
|
|
||||||
<userdata method="write" card="" time="" model*="" label*="" >
|
|
||||||
<b[] __type="str" />
|
|
||||||
</userdata>
|
|
||||||
</call></code></pre>
|
|
||||||
<h3>Response:</h3>
|
|
||||||
<pre><code><response>
|
|
||||||
<userdata status="<i>status</i>" />
|
|
||||||
</response></code></pre>
|
|
||||||
</body>
|
|
284
protocol.html
284
protocol.html
@ -1,284 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>Packet format | eAmuse API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href=".">Contents</a></td>
|
|
||||||
<td><a href="./transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="./packet.html">Packet format</a></td>
|
|
||||||
<td><a href="./protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<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#lounce">game.sv4_lounce</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>
|
|
||||||
</body>
|
|
25
templates/base.html
Normal file
25
templates/base.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<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>{% block title %}{% endblock %}{% if self.title() %} | {% endif %}e-Amusement API</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ROOT}}/styles.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{ROOT}}/">Contents</a></td>
|
||||||
|
<td><a href="{{ROOT}}/transport.html">Transport layer</a></td>
|
||||||
|
<td><a href="{{ROOT}}/packet.html">Packet format</a></td>
|
||||||
|
<td><a href="{{ROOT}}/protocol.html">Application Protocol</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href=".">Contents</a></td>
|
|
||||||
<td><a href="transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="packet.html">Packet format</a></td>
|
|
||||||
<td><a href="protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1>Card ID generation</h1>
|
<h1>Card ID generation</h1>
|
||||||
<details>
|
<details>
|
||||||
<summary>I'm just here for code.</summary>
|
<summary>I'm just here for code.</summary>
|
||||||
@ -484,5 +464,4 @@ def load_key(key):
|
|||||||
des3_setkey(KEY_DATA, key_data)</code></pre>
|
des3_setkey(KEY_DATA, key_data)</code></pre>
|
||||||
</details>
|
</details>
|
||||||
</details>
|
</details>
|
||||||
|
{% endblock %}
|
||||||
</body>
|
|
84
templates/pages/index.html
Normal file
84
templates/pages/index.html
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<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 (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>
|
||||||
|
<p>If you're here because you work on one of those aforementioned closed source projects, hello! Feel free to share
|
||||||
|
knowledge with the rest of the world, or point out corrections. Or don't; you do you.</p>
|
||||||
|
|
||||||
|
<h3>Code snippets</h3>
|
||||||
|
<p>Across these pages there are a number of code snippets. They roughly break down into three categories:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Assembly: Directly disassembled code from game binaries</li>
|
||||||
|
<li>C: Either raw decompilation, or slightly cleaned up decompilation</li>
|
||||||
|
<li>Python: Snippets from my local testing implementations</li>
|
||||||
|
<li>Pseudocode: Used to illustrate some points. Note that it probably started life as Python before being
|
||||||
|
pseudo'd</li>
|
||||||
|
</ul>
|
||||||
|
<p>If you yoink chunks of Python code, attribution is always appreciated, but consider it under CC0 (just don't be
|
||||||
|
that person who tries to take credit for it, yeah?).</p>
|
||||||
|
|
||||||
|
<h2>Contents</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="./transport.html">Transport layer</a></li>
|
||||||
|
<ol>
|
||||||
|
<li><a href="./transport.html#packet">Packet structure</a></li>
|
||||||
|
<li><a href="./transport.html#type">Types</a></li>
|
||||||
|
</ol>
|
||||||
|
<li><a href="./packet.html">The inner packet structure</a></li>
|
||||||
|
<ol>
|
||||||
|
<li><a href="./packet.html#xml">XML packets</a></li>
|
||||||
|
<li><a href="./packet.html#binary">Binary packed packets</a></li>
|
||||||
|
<li><a href="./packet.html#schema">Binary schemas</a></li>
|
||||||
|
<li><a href="./packet.html#data">Binary data</a></li>
|
||||||
|
</ol>
|
||||||
|
<li><a href="./protocol.html">Communication protocol details</a></li>
|
||||||
|
<ul>
|
||||||
|
<li>There are a crazy number of sub pages here, so just go check the contents there.</li>
|
||||||
|
</ul>
|
||||||
|
<li>Misc pages</li>
|
||||||
|
<ol>
|
||||||
|
<li><a href="./cardid.html">Parsing and converting card IDs</a></li>
|
||||||
|
</ol>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>Getting started</h2>
|
||||||
|
<p>My aim with these pages is to cover as much as possible, so you don't need to try and figure them out yourself.
|
||||||
|
That said, being able to follow along yourself will almost certainly help get more out of this. For following
|
||||||
|
along with source code, you're really going to want to grab yourself a dumped copy of a game (it's going to be a
|
||||||
|
lot easier, and cheeper, than dumping one yourself). I trust you can figure out where to find that.</p>
|
||||||
|
<p>For network related things, your options are a little broader. The ideal would be physical ownership of a
|
||||||
|
cabinet, and a subscription to genuine e-amusement. Odds are you don't have both of those :P. A connection to an
|
||||||
|
alternative network works just as well. In the more likely case that you don't have a physical cabinet, it's
|
||||||
|
time to crack out that dumped copy of a game and just run it on your own PC (or a VM, if you're not on Windows)
|
||||||
|
(odds are whatever you downloaded came with the program you'll need to start it pre-packaged. If not, it rhymes
|
||||||
|
with rice.).</p>
|
||||||
|
<p>You will also need a local e-amusement-emulating server. By the time I'm done with these pages, there will
|
||||||
|
hopefully be everything you need to be able to write your own. Unfortunately I'm not finished writing them;
|
||||||
|
depending on where you acquired your game, it may have shipped with one of said servers. If it didn't, Asphyxia
|
||||||
|
CORE will do the trick (yes, it's closed source).</p>
|
||||||
|
<p>If this all sounds like way too much work, and/or you're just here because of curiosity, I plan to prepare some
|
||||||
|
pcaps of network traffic to play around with without needing a running copy of a game or a network tap on a cab.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="./transport.html">Next page</a>
|
||||||
|
|
||||||
|
<p><small>This site intentionally looks not-great. I don't feel like changing that, and honestly quite like the
|
||||||
|
aesthetic.</small></p>
|
||||||
|
{% endblock %}
|
881
templates/pages/packet.html
Normal file
881
templates/pages/packet.html
Normal file
@ -0,0 +1,881 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1>Packet format</h1>
|
||||||
|
|
||||||
|
<p>eAmuse uses XML for its application layer payloads*. This XML is either verbatim, or in a custom packed binary
|
||||||
|
format.<br /><small>*Newer games use JSON, but this page is about XML.</small></p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="xml">The XML format</h2>
|
||||||
|
|
||||||
|
<p>Each tag that contains a value has a <code>__type</code> attribute that identifies what type it is. Array types
|
||||||
|
have a <code>__count</code> attribute indicating how many items are in the array. Binary blobs additionally have
|
||||||
|
a <code>__size</code> attribute indicating their length (this is notably not present on strings, however).</p>
|
||||||
|
<p>It is perhaps simpler to illustrate with an example, so:</p>
|
||||||
|
<pre><code><?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<call model="KFC:J:A:A:2019020600" srcid="1000" tag="b0312077">
|
||||||
|
<eventlog method="write">
|
||||||
|
<retrycnt __type="u32" />
|
||||||
|
<data>
|
||||||
|
<eventid __type="str">G_CARDED</eventid>
|
||||||
|
<eventorder __type="s32">5</eventorder>
|
||||||
|
<pcbtime __type="u64">1639669516779</pcbtime>
|
||||||
|
<gamesession __type="s64">1</gamesession>
|
||||||
|
<strdata1 __type="str" />
|
||||||
|
<strdata2 __type="str" />
|
||||||
|
<numdata1 __type="s64">1</numdata1>
|
||||||
|
<numdata2 __type="s64" />
|
||||||
|
<locationid __type="str">ea</locationid>
|
||||||
|
</data>
|
||||||
|
</eventlog>
|
||||||
|
</call></code></pre>
|
||||||
|
<p>Arrays are encoded by concatenating every value together, with spaces between them. Data types that have multiple
|
||||||
|
values, are serialized similarly.</p>
|
||||||
|
<p>Therefore, an element storing an array of <code>3u8</code> (<code>[(1, 2, 3), (4, 5, 6)]</code>) would look like
|
||||||
|
this</p>
|
||||||
|
<pre><code><demo __type="3u8" __count="2">1 2 3 4 5 6</demo></code></pre>
|
||||||
|
<p>Besides this, this is otherwise a rather standard XML.</p>
|
||||||
|
|
||||||
|
<h2 id="binary">Packed binary overview</h2>
|
||||||
|
|
||||||
|
<p>Many packets, rather than using a string-based XML format, use a custom binary packed format instead. While it
|
||||||
|
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 class="code">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>0</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>7</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>9</td>
|
||||||
|
<td>10</td>
|
||||||
|
<td>11</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>13</td>
|
||||||
|
<td>14</td>
|
||||||
|
<td>15</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td><i>A0</i></td>
|
||||||
|
<td>C</td>
|
||||||
|
<td>E</td>
|
||||||
|
<td>~E</td>
|
||||||
|
<td colspan="4">Head length</td>
|
||||||
|
<td style="border-bottom: none" colspan="8"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border-top: none; border-bottom: none;" colspan="16">Schema definition</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border-top: none;" colspan="12"></td>
|
||||||
|
<td colspan="1"><i>FF</i></td>
|
||||||
|
<td colspan="3">Align</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">Data length</td>
|
||||||
|
<td style="border-bottom: none" colspan="12"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border-top: none; border-bottom: none;" colspan="16">Payload</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border-top: none;" colspan="13"></td>
|
||||||
|
<td colspan="3">Align</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p>Every packet starts with the magic byte <code>0xA0</code>. Following this is the content byte, the encoding byte,
|
||||||
|
and then the 2's compliment of the encoding byte.</p>
|
||||||
|
<p>Currently known possible values for the content byte are:</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>C</td>
|
||||||
|
<td>Content</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td><code>0x42</code></td>
|
||||||
|
<td>Compressed data</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>0x43</code></td>
|
||||||
|
<td>Compressed, no data</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>0x45</code></td>
|
||||||
|
<td>Decompressed data</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>0x46</code></td>
|
||||||
|
<td>Decompressed, no data</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p>Decompressed packets contain an XML string. Compressed packets are what we're interested in here.</p>
|
||||||
|
<p>The encoding flag indicates the encoding for all string types in the packet (more on those later). Possible
|
||||||
|
values are:</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td><code>E</code></td>
|
||||||
|
<td><code>~E</code></td>
|
||||||
|
<td colspan="3">Encoding name</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><code>0x20</code></td>
|
||||||
|
<td><code>0xDF</code></td>
|
||||||
|
<td><code>ASCII</code></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>0x40</code></td>
|
||||||
|
<td><code>0xBF</code></td>
|
||||||
|
<td><code>ISO-8859-1</code></td>
|
||||||
|
<td><code>ISO_8859-1</code></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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><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><code>0xA0</code></td>
|
||||||
|
<td><code>0x5F</code></td>
|
||||||
|
<td><code>UTF-8</code></td>
|
||||||
|
<td><code>UTF8</code></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<details>
|
||||||
|
<summary>Source code details</summary>
|
||||||
|
<p>The full table for these values can be found in libavs.</p>
|
||||||
|
<figure>
|
||||||
|
<img src="./images/encoding_table.png">
|
||||||
|
<figcaption><code>libavs-win32.dll:0x1006b960</code></figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>A second table exists just before this on in the source, responsible for the
|
||||||
|
<code><?xml version='1.0' encoding='??'?></code> line in XML files.
|
||||||
|
</p>
|
||||||
|
<figure>
|
||||||
|
<img src="./images/xml_encoding_table.png">
|
||||||
|
<figcaption><code>libavs-win32.dll:0x1006b940</code></figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>This is indexed using the following function, which maps the above encoding IDs to 1, 2, 3, 4 and 5
|
||||||
|
respectively.</p>
|
||||||
|
<pre><code>char* xml_get_encoding_name(uint encoding_id) {
|
||||||
|
return ENCODING_NAME_TABLE[((encoding_id & 0xe0) >> 5) * 4];
|
||||||
|
}</code></pre>
|
||||||
|
</details>
|
||||||
|
<p>While validating <code>~E</code> isn't technically required, it acts as a useful assertion that the packet being
|
||||||
|
parsed is valid.</p>
|
||||||
|
|
||||||
|
<h2 id="schema">The packet schema header</h2>
|
||||||
|
<p>Following the 4 byte header, is a 4 byte integer containing the length of the next part of the header (this is
|
||||||
|
technically made redundant as this structure is also terminated).</p>
|
||||||
|
<p>This part of the header defines the schema that the main payload uses.</p>
|
||||||
|
|
||||||
|
<p>A tag definition looks like:</p>
|
||||||
|
|
||||||
|
<table class="code">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>0</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>7</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>9</td>
|
||||||
|
<td>10</td>
|
||||||
|
<td>11</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>13</td>
|
||||||
|
<td>14</td>
|
||||||
|
<td>15</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>nlen</td>
|
||||||
|
<td colspan="7">Tag name</td>
|
||||||
|
<td style="border-bottom: none" colspan="8"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border-top: none;" colspan="15">Attributes and children</td>
|
||||||
|
<td colspan="1"><i>FE</i></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>Structure names are encoded as densely packed 6 bit values, length prefixed (<code>nlen</code>). The acceptable
|
||||||
|
alphabet is <code>0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz</code>, and the packed values
|
||||||
|
are indecies within this alphabet.</p>
|
||||||
|
|
||||||
|
<p>The children can be a combination of either attribute names, or child tags. Attribute names are represented by
|
||||||
|
the byte <code>0x2E</code> followed by a length prefixed name as defined above. Child tags follow the above
|
||||||
|
format. Type <code>0x2E</code> must therefore be considered reserved as a possible structure type.</p>
|
||||||
|
|
||||||
|
<p>Attributes (type <code>0x2E</code>) represent a string attribute. Any other attribute must be defined as a child
|
||||||
|
tag. Is it notable that 0 children is allowable, which is how the majority of values are encoded.</p>
|
||||||
|
<p>All valid IDs, and their respective type, are listed in the following table. The bucket column here will be
|
||||||
|
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 class="code">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>Bytes</td>
|
||||||
|
<td>C type</td>
|
||||||
|
<td>Bucket</td>
|
||||||
|
<td colspan="2">XML names</td>
|
||||||
|
<td></td>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>Bytes</td>
|
||||||
|
<td>C type</td>
|
||||||
|
<td>Bucket</td>
|
||||||
|
<td colspan="2">XML names</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>0x01</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>void</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>void</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x21</td>
|
||||||
|
<td>24</td>
|
||||||
|
<td>uint64[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3u64</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x02</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>int8</td>
|
||||||
|
<td>byte</td>
|
||||||
|
<td>s8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x22</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>float[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3f</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x03</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>uint8</td>
|
||||||
|
<td>byte</td>
|
||||||
|
<td>u8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x23</td>
|
||||||
|
<td>24</td>
|
||||||
|
<td>double[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3d</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x04</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>int16</td>
|
||||||
|
<td>short</td>
|
||||||
|
<td>s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x24</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>int8[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4s8</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x05</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>uint16</td>
|
||||||
|
<td>short</td>
|
||||||
|
<td>s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x25</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>uint8[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4u8</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x06</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>int32</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>s32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x26</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>int16[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4s16</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x07</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>uint32</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>u32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x27</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>uint8[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4s16</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x08</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>int64</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>s64</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x28</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>int32[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4s32</td>
|
||||||
|
<td>vs32</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x09</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>uint64</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>u64</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x29</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>uint32[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4u32</td>
|
||||||
|
<td>vs32</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0a</td>
|
||||||
|
<td><i>prefix</i></td>
|
||||||
|
<td>char[]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>bin</td>
|
||||||
|
<td>binary</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2a</td>
|
||||||
|
<td>32</td>
|
||||||
|
<td>int64[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4s64</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0b</td>
|
||||||
|
<td><i>prefix</i></td>
|
||||||
|
<td>char[]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>str</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2b</td>
|
||||||
|
<td>32</td>
|
||||||
|
<td>uint64[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4u64</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0c</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>uint8[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>ip4</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2c</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>float[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4f</td>
|
||||||
|
<td>vf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0d</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>uint32</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>time</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2d</td>
|
||||||
|
<td>32</td>
|
||||||
|
<td>double[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4d</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0e</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>float</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>float</td>
|
||||||
|
<td>f</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2e</td>
|
||||||
|
<td><i>prefix</i></td>
|
||||||
|
<td>char[]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>attr</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x0f</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>double</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>double</td>
|
||||||
|
<td>d</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x2f</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td></td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>array</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x10</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>int8[2]</td>
|
||||||
|
<td>short</td>
|
||||||
|
<td>2s8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x30</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>int8[16]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>vs8</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x11</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>uint8[2]</td>
|
||||||
|
<td>short</td>
|
||||||
|
<td>2u8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x31</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>uint8[16]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>vu8</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x12</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>int16[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x32</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>int8[8]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>vs16</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x13</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>uint16[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x33</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>uint8[8]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>vu16</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x14</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>int32[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2s32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x34</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>bool</td>
|
||||||
|
<td>byte</td>
|
||||||
|
<td>bool</td>
|
||||||
|
<td>b</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x15</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>uint32[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2u32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x35</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>bool[2]</td>
|
||||||
|
<td>short</td>
|
||||||
|
<td>2b</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x16</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>int16[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2s64</td>
|
||||||
|
<td>vs64</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x36</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>bool[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3b</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x17</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>uint16[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2u64</td>
|
||||||
|
<td>vu64</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x37</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>bool[4]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>4b</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x18</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>float[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2f</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x38</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>bool[16]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>vb</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x19</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>double[2]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>2d</td>
|
||||||
|
<td>vd</td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x38</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1a</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>int8[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3s8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x39</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1b</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>uint8[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3u8</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3a</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1c</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>int16[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3b</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1d</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>uint16[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3s16</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3c</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1e</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>int32[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3s32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3d</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x1f</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>uint32[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3u32</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3e</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0x20</td>
|
||||||
|
<td>24</td>
|
||||||
|
<td>int64[3]</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>3s64</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>0x3f</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>Strings should be encoded and decoded according to the encoding specified in the packet header. Null termination is
|
||||||
|
optional, however should be stripped during decoding.</p>
|
||||||
|
<p>All of these IDs are <code>& 0x3F</code>. Any value can be turned into an array by setting the 7<sup>th</sup> bit
|
||||||
|
high (<code>| 0x40</code>). Arrays of this form, in the data section, will be an aligned <code>size: u32</code>
|
||||||
|
immediately followed by <code>size</code> bytes' worth of (unaligned!) values of the unmasked type.</p>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Source code details</summary>
|
||||||
|
<p>The full table for these values can be found in libavs. This table contains the names of every tag, along
|
||||||
|
with additional information such as how many bytes that data type requires, and which parsing function
|
||||||
|
should be used.</p>
|
||||||
|
<figure>
|
||||||
|
<img src="./images/types_table.png">
|
||||||
|
<figcaption><code>libavs-win32.dll:0x100782a8</code></figcaption>
|
||||||
|
</figure>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Note about the <code>array</code> type:</summary>
|
||||||
|
<p>While I'm not totally sure, I have a suspicion this type is used internally as a pseudo-type. Trying to
|
||||||
|
identify its function as a parsable type has some obvious blockers:</p>
|
||||||
|
|
||||||
|
<p>All of the types have convenient <code>printf</code>-using helper functions that are used to emit them when
|
||||||
|
serializing XML. All except one.</p>
|
||||||
|
<img src="./images/no_array.png">
|
||||||
|
<p>If we have a look inside the function that populates node sizes (<code>libavs-win32.dll:0x1000cf00</code>),
|
||||||
|
it has an explicit case, however is the same fallback as the default case.</p>
|
||||||
|
<img src="./images/no_array_2.png">
|
||||||
|
|
||||||
|
<p>In the same function, however, we can find a second (technically first) check for the array type.</p>
|
||||||
|
<img src="./images/yes_array.png">
|
||||||
|
<p>This seems to suggest that internally arrays are represented as a normal node, with the <code>array</code>
|
||||||
|
type, however when serializing it's converted into the array types we're used to (well, will be after the
|
||||||
|
next sections) by masking 0x40 onto the contained type.</p>
|
||||||
|
<p>Also of interest from this snippet is the fact that <code>void</code>, <code>bin</code>, <code>str</code>,
|
||||||
|
and <code>attr</code> cannot be arrays. <code>void</code> and <code>attr</code> make sense, however
|
||||||
|
<code>str</code> and <code>bin</code> are more interesting. I suspect this is because konami want to be able
|
||||||
|
to preallocate the memory, which wouldn't be possible with these variable length structures.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<h2 id="data">The data section</h2>
|
||||||
|
|
||||||
|
<p>This is where all the actual packet data is. For the most part, parsing this is the easy part. We traverse our
|
||||||
|
schema, and read values out of the packet according to the value indicated in the schema. Unfortunately, konami
|
||||||
|
decided all data should be aligned very specifically, and that gaps left during alignment should be backfilled
|
||||||
|
later. This makes both reading and writing somewhat more complicated, however the system can be fairly easily
|
||||||
|
understood.</p>
|
||||||
|
<p>Firstly, we divide the payload up into 4 byte chunks. Each chunk can be allocated to either store individual
|
||||||
|
bytes, shorts, or ints (these are the buckets in the table above). When reading or writing a value, we first
|
||||||
|
check if a chunk allocated to the desired type's bucket is available and has free/as-yet-unread space within it.
|
||||||
|
If so, we will store/read our data to/from there. If there is no such chunk, we claim the next unclaimed chunk
|
||||||
|
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 class="code">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>0</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>7</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>9</td>
|
||||||
|
<td>10</td>
|
||||||
|
<td>11</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>13</td>
|
||||||
|
<td>14</td>
|
||||||
|
<td>15</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>byte</td>
|
||||||
|
<td>byte</td>
|
||||||
|
<td>byte</td>
|
||||||
|
<td></td>
|
||||||
|
<td colspan="4">int</td>
|
||||||
|
<td colspan="2">short</td>
|
||||||
|
<td colspan="2">short</td>
|
||||||
|
<td colspan="4">int</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>While this might seem a silly system compared to just not aligning values, it is at least possible to intuit that it
|
||||||
|
helps reduce wasted space. It should be noted that any variable-length structure, such as a string or an array,
|
||||||
|
claims all chunks it encroaches on for the <code>int</code> bucket, disallowing the storage of bytes or shorts
|
||||||
|
within them.</p>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Implementing a packer</summary>
|
||||||
|
<p>While the intuitive way to understand the packing algorithm is via chunks and buckets, a far more efficient
|
||||||
|
implementation can be made that uses three pointers. Rather than try to explain in words, hopefully this python
|
||||||
|
implementation should suffice as explanation:
|
||||||
|
<pre><code>class Packer:
|
||||||
|
def __init__(self, offset=0):
|
||||||
|
self._word_cursor = offset
|
||||||
|
self._short_cursor = offset
|
||||||
|
self._byte_cursor = offset
|
||||||
|
self._boundary = offset % 4
|
||||||
|
|
||||||
|
def _next_block(self):
|
||||||
|
self._word_cursor += 4
|
||||||
|
return self._word_cursor - 4
|
||||||
|
|
||||||
|
def request_allocation(self, size):
|
||||||
|
if size == 0:
|
||||||
|
return self._word_cursor
|
||||||
|
elif size == 1:
|
||||||
|
if self._byte_cursor % 4 == self._boundary:
|
||||||
|
self._byte_cursor = self._next_block() + 1
|
||||||
|
else:
|
||||||
|
self._byte_cursor += 1
|
||||||
|
return self._byte_cursor - 1
|
||||||
|
elif size == 2:
|
||||||
|
if self._short_cursor % 4 == self._boundary:
|
||||||
|
self._short_cursor = self._next_block() + 2
|
||||||
|
else:
|
||||||
|
self._short_cursor += 2
|
||||||
|
return self._short_cursor - 2
|
||||||
|
else:
|
||||||
|
old_cursor = self._word_cursor
|
||||||
|
for _ in range(math.ceil(size / 4)):
|
||||||
|
self._word_cursor += 4
|
||||||
|
return old_cursor
|
||||||
|
|
||||||
|
def notify_skipped(self, no_bytes):
|
||||||
|
for _ in range(math.ceil(no_bytes / 4)):
|
||||||
|
self.request_allocation(4)</code></pre>
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<a href="./transport.html">Prev page</a> | <a href="./protocol.html">Next page</a>
|
||||||
|
{% endblock %}
|
13
templates/pages/proto/apsmanager.html
Normal file
13
templates/pages/proto/apsmanager.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>apsmanager</code></h1>
|
||||||
|
<h2 id="getstat"><code>apsmanager.getstat</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<apsmanager method="getstat" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<apsmanager status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
212
templates/pages/proto/cardmng.html
Normal file
212
templates/pages/proto/cardmng.html
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>cardmng</code></h1>
|
||||||
|
<p>As the name might imply, this service is responsible for handling interactions with physical e-Amusement cards.
|
||||||
|
e-Amusement currently has two different types of cards in circulation. There are classic e-Amusement cards
|
||||||
|
making use of a magnetic stripe, and the newer RFID cards using FeliCa (these are probably what you have). They
|
||||||
|
are identified in requests using the <code>cardtype</code> attribute as in the below table.
|
||||||
|
</p>
|
||||||
|
<p>e-Amusement cards have a "card number" and a "card id". Confusingly, neither is a number. The card number is the
|
||||||
|
one printed on your card. The card ID is your KONAMI ID. You can (and should) read about the algorithm used for
|
||||||
|
these IDs on <a href="../cardid.html">the Card IDs page</a>.</p>
|
||||||
|
<p>In the interest of not wasting space, <code>cardid</code> and <code>cardtype</code> will be omitted from
|
||||||
|
individual breakdowns where their meaning is obvious.</p>
|
||||||
|
|
||||||
|
<h4>Card types:</h4>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td><code>cardtype</code></td>
|
||||||
|
<td>Meaning</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td><code>1</code></td>
|
||||||
|
<td>Old style magnetic stripe card</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>2</code></td>
|
||||||
|
<td>FeliCa RFID card</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><code><a href="#inquire">cardmng.inquire</a></code></li>
|
||||||
|
<li><code><a href="#getrefid">cardmng.getrefid</a></code></li>
|
||||||
|
<li><code><a href="#bindmodel">cardmng.bindmodel</a></code></li>
|
||||||
|
<li><code><a href="#bindcard">cardmng.bindcard</a></code></li>
|
||||||
|
<li><code><a href="#authpass">cardmng.authpass</a></code></li>
|
||||||
|
<li><code><a href="#getkeepspan">cardmng.getkeepspan</a></code></li>
|
||||||
|
<li><code><a href="#getkeepremain">cardmng.getkeepremain</a></code></li>
|
||||||
|
<li><code><a href="#getdatalist">cardmng.getdatalist</a></code></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="inquire"><code>cardmng.inquire</code></h2>
|
||||||
|
<p>Request information about a card that has been inserted or touched against a reader.</p>
|
||||||
|
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="inquire" cardid="" cardtype="" update="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><code>update</code></td>
|
||||||
|
<td>Should the tracked last play time be updated by this inquiry? (Just a guess)</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" refid="" dataid="" pcode="" newflag="" binded="" expired=" ecflag="" useridflag="" extidflag="" lastupdate="" />
|
||||||
|
</response></code></pre>
|
||||||
|
<p>To handle this request, we first must lookup if this <code>cardid</code> has ever been seen by our servers
|
||||||
|
before. If not, we abort with a <code>112</code> status. Otherwise, we proceeed to check if this card has been
|
||||||
|
seen for this specific game. If we have never seen this card used on this game, it is possible this card was
|
||||||
|
used with an older version of this game, and migration is supported, in which case we report as if we had found
|
||||||
|
a profile for this game.</p>
|
||||||
|
<table>
|
||||||
|
<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>Inverse of <code>binded</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>? Just set to <code>0</code>.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2 id="getrefid"><code>cardmng.getrefid</code></h2>
|
||||||
|
<p>Register a new card to this server.</p>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="getrefid" cardtype="" cardid=" newflag="" passwd="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><code>newflag</code></td>
|
||||||
|
<td>?</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>passwd</code></td>
|
||||||
|
<td>The pin for this new user. <i>Should</i> always be a four digit number (and that's worth validating),
|
||||||
|
but it's passed as a string so could feasibly be anything desired.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" refid="" dataid="" pcode="" />
|
||||||
|
</response></code></pre>
|
||||||
|
<table>
|
||||||
|
<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>pcode</code></td>
|
||||||
|
<td>? Not present in captured data.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2 id="bindmodel"><code>cardmng.bindmodel</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="bindmodel" refid="" newflag="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" dataid="" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="bindcard"><code>cardmng.bindcard</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="bindcard" cardtype="" newid="" refid="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="authpass"><code>cardmng.authpass</code></h2>
|
||||||
|
<p>Test a pin for a card. This request notably uses the <code>refid</code>, so required a
|
||||||
|
<code>cardmng.inquire</code> call to be made first.
|
||||||
|
</p>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="authpass" refid="" pass="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><code>refid</code></td>
|
||||||
|
<td>The reference we received either during <code>cardmng.inquire</code> or <code>cardmng.getrefid</code>
|
||||||
|
(the latter for new cards)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>pass</code></td>
|
||||||
|
<td>The pin to test. See <code>cardmng.getrefid</code>.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
<p>If the pin is valid, status should be <code>0</code>. Otherwise, <code>116</code>.</p>
|
||||||
|
|
||||||
|
<h2 id="getkeepspan"><code>cardmng.getkeepspan</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="getkeepspan" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" keepspan="" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="getkeepremain"><code>cardmng.getkeepremain</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="getkeepremain" refid="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>" keepremain="" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="getdatalist"><code>cardmng.getdatalist</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<cardmng method="getdatalist" refid="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<cardmng status="<i>status</i>">
|
||||||
|
<item[]>
|
||||||
|
<mcode __type="str" />
|
||||||
|
<dataid __type="str" />
|
||||||
|
<regtime __type="str" />
|
||||||
|
<lasttime __type="str" />
|
||||||
|
<exptime __type="str" />
|
||||||
|
<expflag __type="u8" />
|
||||||
|
</item[]>
|
||||||
|
</cardmng>
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
34
templates/pages/proto/dlstatus.html
Normal file
34
templates/pages/proto/dlstatus.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>dlstatus</code></h1>
|
||||||
|
<h2 id="done"><code>dlstatus.done</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<dlstatus method="done">
|
||||||
|
<url>
|
||||||
|
<param __type="str" />
|
||||||
|
</url>
|
||||||
|
<name __type="str" />
|
||||||
|
<size __type="s32" />
|
||||||
|
</dlstatus>
|
||||||
|
</call></code></pre>
|
||||||
|
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<dlstatus status="<i>status</i>">
|
||||||
|
<progress __type="s32" />
|
||||||
|
</dlstatus>
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="progress"><code>dlstatus.progress</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<dlstatus method="progress" />
|
||||||
|
<progress __type="s32" />
|
||||||
|
</dlstatus>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<dlstatus status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>eacoin</code></h1>
|
<h1><code>eacoin</code></h1>
|
||||||
<h2 id="checkin"><code>eacoin.checkin</code></h2>
|
<h2 id="checkin"><code>eacoin.checkin</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -197,4 +177,4 @@
|
|||||||
</history>
|
</history>
|
||||||
</eacoin>
|
</eacoin>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
</body>
|
{% endblock %}
|
17
templates/pages/proto/esign.html
Normal file
17
templates/pages/proto/esign.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>esign</code></h1>
|
||||||
|
<h2 id="request"><code>esign.request</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<esign method="request">
|
||||||
|
<i>placeholder</i>
|
||||||
|
</esign>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<esign status="<i>status</i>">
|
||||||
|
<i>placeholder</i>
|
||||||
|
</esign>
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
30
templates/pages/proto/esoc.html
Normal file
30
templates/pages/proto/esoc.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>esoc</code></h1>
|
||||||
|
<h2 id="read"><code>esoc.read</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<esoc method="read">
|
||||||
|
<senddata />
|
||||||
|
</esoc>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<esoc status="<i>status</i>">
|
||||||
|
<recvdata />
|
||||||
|
</esoc>
|
||||||
|
</response></code></pre>
|
||||||
|
<p>Go figure.</p>
|
||||||
|
|
||||||
|
<h2 id="write"><code>esoc.write</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<esoc method="write">
|
||||||
|
<senddata />
|
||||||
|
</esoc>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<esoc status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
38
templates/pages/proto/eventlog.html
Normal file
38
templates/pages/proto/eventlog.html
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>eventlog</code></h1>
|
||||||
|
<h2 id="write"><code>eventlog.write</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<eventlog method="write">
|
||||||
|
<retrycnt __type="u32" />
|
||||||
|
<data>
|
||||||
|
<eventid __type="str" />
|
||||||
|
<eventorder __type="s32" />
|
||||||
|
<pcbtime __type="u64" />
|
||||||
|
<gamesession __type="s64" />
|
||||||
|
<strdata1 __type="str" />
|
||||||
|
<strdata2 __type="str" />
|
||||||
|
<numdata1 __type="s64" />
|
||||||
|
<numdata2 __type="s64" />
|
||||||
|
<locationid __type="str" />
|
||||||
|
</data>
|
||||||
|
</eventlog>
|
||||||
|
</call></code></pre>
|
||||||
|
<p>Event ID list:</p>
|
||||||
|
<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>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<eventlog status="<i>status</i>">
|
||||||
|
<gamesession __type="s64" />
|
||||||
|
<logsendflg __type="s32" />
|
||||||
|
<logerrlevel __type="s32" />
|
||||||
|
<evtidnosendflg __type="s32" />
|
||||||
|
</eventlog>
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>facility</code></h1>
|
<h1><code>facility</code></h1>
|
||||||
<h2 id="get"><code>facility.get</code></h2>
|
<h2 id="get"><code>facility.get</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -137,4 +117,4 @@
|
|||||||
<p><code>region</code> is used for Japan, and has the value <code>JP-[prefecture]</code> where prefecture ranges
|
<p><code>region</code> is used for Japan, and has the value <code>JP-[prefecture]</code> where prefecture ranges
|
||||||
from 1 through 47.</p>
|
from 1 through 47.</p>
|
||||||
<p><b>TODO: Compile the list of regions</b></p>
|
<p><b>TODO: Compile the list of regions</b></p>
|
||||||
</body>
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="../..">Contents</a></td>
|
|
||||||
<td><a href="../../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1 id="game"><code>game</code></h1>
|
<h1 id="game"><code>game</code></h1>
|
||||||
<h2 id="sample"><code>game.sv4_sample</code></h2>
|
<h2 id="sample"><code>game.sv4_sample</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -217,10 +197,10 @@
|
|||||||
</game>
|
</game>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
|
|
||||||
<h2 id="lounce"><code>game.sv4_lounce</code></h2>
|
<h2 id="lounge"><code>game.sv4_lounge</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
<pre><code><call <i>...</i>>
|
<pre><code><call <i>...</i>>
|
||||||
<game method="sv4_lounce">
|
<game method="sv4_lounge">
|
||||||
<i>placeholder</i>
|
<i>placeholder</i>
|
||||||
</game>
|
</game>
|
||||||
</call></code></pre>
|
</call></code></pre>
|
||||||
@ -384,4 +364,4 @@
|
|||||||
<i>placeholder</i>
|
<i>placeholder</i>
|
||||||
</game>
|
</game>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
</body>
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>matching</code></h1>
|
<h1><code>matching</code></h1>
|
||||||
<h2 id="request"><code>matching.request</code></h2>
|
<h2 id="request"><code>matching.request</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -100,4 +80,4 @@
|
|||||||
<result __type="s32" />
|
<result __type="s32" />
|
||||||
</matching>
|
</matching>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
</body>
|
{% endblock %}
|
15
templates/pages/proto/message.html
Normal file
15
templates/pages/proto/message.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>message</code></h1>
|
||||||
|
<h2 id="get"><code>message.get</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<message method="get" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<message expire="" status="<i>status</i>">
|
||||||
|
<item[] name="" start="" end="" data="" />
|
||||||
|
</message>
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
27
templates/pages/proto/package.html
Normal file
27
templates/pages/proto/package.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>package</code></h1>
|
||||||
|
<h2 id="list"><code>package.list</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<package method="list" pkgtype="<i>pkgtype</i>" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<p><code>all</code> is the only currently observed value for <code>pkgtype</code></p>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<package status="<i>status</i>">
|
||||||
|
<item[] url="" />
|
||||||
|
</package>
|
||||||
|
</response></code></pre>
|
||||||
|
<p>A list of all packages available for download.</p>
|
||||||
|
|
||||||
|
<h2 id="intend"><code>package.intend</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<package method="intend" url="" model*="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<package status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
21
templates/pages/proto/pcbevent.html
Normal file
21
templates/pages/proto/pcbevent.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>pcbevent</code></h1>
|
||||||
|
<h2 id="put"><code>pcbevent.put</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<pcbevent method="put">
|
||||||
|
<time __type="time" />
|
||||||
|
<seq __type="u32" />
|
||||||
|
<item[]>
|
||||||
|
<name __type="str" />
|
||||||
|
<value __type="s32" />
|
||||||
|
<time __type="time" />
|
||||||
|
</item[]>
|
||||||
|
</pcbevent>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<pcbevent status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
19
templates/pages/proto/pcbtracker.html
Normal file
19
templates/pages/proto/pcbtracker.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>pcbtracker</code></h1>
|
||||||
|
<h2 id="alive"><code>pcbtracker.alive</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<pcbtracker method="alive" model*="" hardid="" softid="" accountid="" agree="" ecflag="" />
|
||||||
|
</call></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>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<pcbtracker status="" time="" limit="" ecenable="" eclimit="" >
|
||||||
|
</response></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>
|
||||||
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>playerdata</code></h1>
|
<h1><code>playerdata</code></h1>
|
||||||
<h2 id="usergamedata_send"><code>playerdata.usergamedata_send</code></h2>
|
<h2 id="usergamedata_send"><code>playerdata.usergamedata_send</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -153,4 +133,4 @@
|
|||||||
</rank>
|
</rank>
|
||||||
</playerdata>
|
</playerdata>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
</body>
|
{% endblock %}
|
50
templates/pages/proto/services.html
Normal file
50
templates/pages/proto/services.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>services</code></h1>
|
||||||
|
<h2 id="get"><code>services.get</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<services method="get" model*="" >
|
||||||
|
<info>
|
||||||
|
<AVS2 __type="str"><i>AVS2 version</i></AVS2>
|
||||||
|
</info>
|
||||||
|
</services>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<services expire="" method="get" mode="" status="<i>status</i>">
|
||||||
|
<item[] name="<i>service</i>" url="<i>url</i>" />
|
||||||
|
</services>
|
||||||
|
</response></code></pre>
|
||||||
|
<p>Known services are:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>ntp</code></li>
|
||||||
|
<li><code>keepalive</code></li>
|
||||||
|
<li><code>cardmng</code></li>
|
||||||
|
<li><code>facility</code></li>
|
||||||
|
<li><code>message</code></li>
|
||||||
|
<li><code>numbering</code></li>
|
||||||
|
<li><code>package</code></li>
|
||||||
|
<li><code>pcbevent</code></li>
|
||||||
|
<li><code>pcbtracker</code></li>
|
||||||
|
<li><code>pkglist</code></li>
|
||||||
|
<li><code>posevent</code></li>
|
||||||
|
<li><code>userdata</code></li>
|
||||||
|
<li><code>userid</code></li>
|
||||||
|
<li><code>eacoin</code></li>
|
||||||
|
<li><code>local</code></li>
|
||||||
|
<li><code>local2</code></li>
|
||||||
|
<li><code>lobby</code></li>
|
||||||
|
<li><code>lobby2</code></li>
|
||||||
|
<li><code>dlstatus</code></li>
|
||||||
|
<li><code>netlog</code></li>
|
||||||
|
<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><code>mode</code> is one of <code>operation</code>, <code>debug</code>, <code>test</code>, or
|
||||||
|
<code>factory</code>.
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
74
templates/pages/proto/sidmgr.html
Normal file
74
templates/pages/proto/sidmgr.html
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>sidmgr</code></h1>
|
||||||
|
<h2 id="create"><code>sidmgr.create</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<sidmgr method="create">
|
||||||
|
<cardtype __type="str" />
|
||||||
|
<cardid __type="str" />
|
||||||
|
<cardgid __type="str" />
|
||||||
|
<steal __type="u8" />
|
||||||
|
</sidmgr>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<sidmgr status="<i>status</i>">
|
||||||
|
<state __type="u32" />
|
||||||
|
<e_count __type="u8" />
|
||||||
|
<last __type="time" />
|
||||||
|
<locked __type="time" />
|
||||||
|
<sid __type="str" />
|
||||||
|
<cardid_status __type="u8" />
|
||||||
|
<refid __type="str" />
|
||||||
|
</sidmgr>
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="open"><code>sidmgr.open</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<sidmgr method="open" sid="" >
|
||||||
|
<pass __type="str" />
|
||||||
|
</sidmgr>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<sidmgr status="<i>status</i>">
|
||||||
|
<state __type="u32" />
|
||||||
|
<refid __type="str" />
|
||||||
|
<locked __type="time" />
|
||||||
|
</sidmgr>
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="touch"><code>sidmgr.touch</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<sidmgr method="touch" sid="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<sidmgr status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="branch"><code>sidmgr.branch</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<sidmgr method="branch" sid="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<sidmgr status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
|
||||||
|
<h2 id="close"><code>sidmgr.close</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<sidmgr method="close" sid="" />
|
||||||
|
<cause __type="u32" />
|
||||||
|
</sidmgr>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<sidmgr status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
@ -1,25 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block body %}
|
||||||
|
|
||||||
<head>
|
|
||||||
<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>e-Amusement API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href="..">Contents</a></td>
|
|
||||||
<td><a href="../transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="../packet.html">Packet format</a></td>
|
|
||||||
<td><a href="../protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1><code>system</code></h1>
|
<h1><code>system</code></h1>
|
||||||
<h2 id="getmaster"><code>system.getmaster</code></h2>
|
<h2 id="getmaster"><code>system.getmaster</code></h2>
|
||||||
<h3>Request:</h3>
|
<h3>Request:</h3>
|
||||||
@ -123,4 +103,4 @@
|
|||||||
</data>
|
</data>
|
||||||
</system>
|
</system>
|
||||||
</response></code></pre>
|
</response></code></pre>
|
||||||
</body>
|
{% endblock %}
|
20
templates/pages/proto/traceroute.html
Normal file
20
templates/pages/proto/traceroute.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>traceroute</code></h1>
|
||||||
|
<h2 id="send"><code>traceroute.send</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<traceroute proto="" method="send">
|
||||||
|
<hop[]>
|
||||||
|
<valid __type="bool">
|
||||||
|
<addr __type="ip4">
|
||||||
|
<usec __type="u64">
|
||||||
|
</hop[]>
|
||||||
|
</traceroute>
|
||||||
|
</call></code></pre>
|
||||||
|
<p><code>hop</code> repeats for every hop (unsurprisingly)</p>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<traceroute status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
28
templates/pages/proto/userdata.html
Normal file
28
templates/pages/proto/userdata.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1><code>userdata</code></h1>
|
||||||
|
<h2 id="read"><code>userdata.read</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<userdata method="read" card*="" model*="" label="" />
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<userdata status="<i>status</i>" time="">
|
||||||
|
<b[] __type="" />
|
||||||
|
</userdata>
|
||||||
|
</response></code></pre>
|
||||||
|
<p><code>__type</code> here can be either <code>bin</code> or <code>str</code></p>
|
||||||
|
|
||||||
|
<h2 id="write"><code>userdata.write</code></h2>
|
||||||
|
<h3>Request:</h3>
|
||||||
|
<pre><code><call <i>...</i>>
|
||||||
|
<userdata method="write" card="" time="" model*="" label*="" >
|
||||||
|
<b[] __type="str" />
|
||||||
|
</userdata>
|
||||||
|
</call></code></pre>
|
||||||
|
<h3>Response:</h3>
|
||||||
|
<pre><code><response>
|
||||||
|
<userdata status="<i>status</i>" />
|
||||||
|
</response></code></pre>
|
||||||
|
{% endblock %}
|
263
templates/pages/protocol.html
Normal file
263
templates/pages/protocol.html
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
{% 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 %}
|
52
templates/pages/transport.html
Normal file
52
templates/pages/transport.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h1>Network format</h1>
|
||||||
|
|
||||||
|
<p>eAmuse packets are sent and received over HTTP (no S), with requests being in the body of <code>POST</code> requests,
|
||||||
|
and replies being in the, well, reply.</p>
|
||||||
|
<p>The packets are typically both encrypted and compressed. The compression format used is indicated by the
|
||||||
|
<code>X-Compress</code> header, and valid values are
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>none</code></li>
|
||||||
|
<li><code>lz77</code></li>
|
||||||
|
</ul>
|
||||||
|
<details>
|
||||||
|
<summary>Source code details</summary>
|
||||||
|
<figure>
|
||||||
|
<img src="./images/lz77.png">
|
||||||
|
<figcaption><code>libavs-win32-ea3.dll:0x1000fa29</code></figcaption>
|
||||||
|
</figure>
|
||||||
|
</details>
|
||||||
|
<p>Encryption is performed <b>after</b> compression, and uses RC4. RC4 is symmetric, so decryption is performed the same
|
||||||
|
as encryption. That is, <code>packet = encrypt(compress(data))</code> and
|
||||||
|
<code>data = decompress(decrypt(data))</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="keys">Encryption keys</h2>
|
||||||
|
<p>Encryption is not performed using a single static key. Instead, each request and response has its own key that is
|
||||||
|
generated.</p>
|
||||||
|
<p>These keys are generated baesd on the <code>X-Eamuse-Info</code> header.</p>
|
||||||
|
<p>This header loosely follows the format <code>1-[0-9a-f]{8}-[0-9a-f]{4}</code>. This corresponds to
|
||||||
|
<code>[version]-[serial]-[salt]</code>. <b>TODO: Confirm this</b>
|
||||||
|
</p>
|
||||||
|
<p>Our per-packet key is then generated using <code>md5(serial | salt | KEY)</code>. Identifying <code>KEY</code> is
|
||||||
|
left as an exercise for the reader, however should not be especially challenging. <span style="color: #fff">Check
|
||||||
|
the page source if you're stuck.</span></p>
|
||||||
|
<!-- It's 69d74627d985ee2187161570d08d93b12455035b6df0d8205df5, if you were wondering. libavs-win32-ea3.dll:0x10054160 -->
|
||||||
|
|
||||||
|
<h2 id="lz77">LZ77</h2>
|
||||||
|
<p>Packets are compressed using lzss. The compressed data structure is a repeating cycle of an 8 bit flags byte,
|
||||||
|
followed by 8 values. Each value is either a single literal byte, if the corresponding bit in the preceeding flag is
|
||||||
|
high, or is a two byte lookup into the window.</p>
|
||||||
|
<p>The lookup bytes are structured as <code>pppppppp ppppllll</code> where <code>p</code> is a 12 bit index in the
|
||||||
|
window, and <code>l</code> is a 4 bit integer that determines how many times to repeat the value located at that
|
||||||
|
index in the window.</p>
|
||||||
|
|
||||||
|
<p>The exact algorithm used for compression is not especially important, as long as it follows this format. One can
|
||||||
|
feasibly perform no compression at all, and instead insert <code>0xFF</code> every 8 bytes (starting at index 0), to
|
||||||
|
indicate that all values are literals. While obviously poor for compression, this is an easy way to test without
|
||||||
|
first implementing a compressor.</p>
|
||||||
|
|
||||||
|
<a href="./index.html">Prev page</a> | <a href="./packet.html">Next page</a>
|
||||||
|
{% endblock %}
|
@ -1,54 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<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>Transport | eAmuse API</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><a href=".">Contents</a></td>
|
|
||||||
<td><a href="./transport.html">Transport layer</a></td>
|
|
||||||
<td><a href="./packet.html">Packet format</a></td>
|
|
||||||
<td><a href="./protocol.html">Application Protocol</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h1>Network format</h1>
|
|
||||||
|
|
||||||
<p>eAmuse packets are sent and received over HTTP (no S), with requests being in the body of <code>POST</code> requests, and replies being in the, well, reply.</p>
|
|
||||||
<p>The packets are typically both encrypted and compressed. The compression format used is indicated by the <code>X-Compress</code> header, and valid values are</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>none</code></li>
|
|
||||||
<li><code>lz77</code></li>
|
|
||||||
</ul>
|
|
||||||
<details>
|
|
||||||
<summary>Source code details</summary>
|
|
||||||
<figure>
|
|
||||||
<img src="./images/lz77.png">
|
|
||||||
<figcaption><code>libavs-win32-ea3.dll:0x1000fa29</code></figcaption>
|
|
||||||
</figure>
|
|
||||||
</details>
|
|
||||||
<p>Encryption is performed <b>after</b> compression, and uses RC4. RC4 is symmetric, so decryption is performed the same as encryption. That is, <code>packet = encrypt(compress(data))</code> and <code>data = decompress(decrypt(data))</code>.</p>
|
|
||||||
|
|
||||||
<h2 id="keys">Encryption keys</h2>
|
|
||||||
<p>Encryption is not performed using a single static key. Instead, each request and response has its own key that is generated.</p>
|
|
||||||
<p>These keys are generated baesd on the <code>X-Eamuse-Info</code> header.</p>
|
|
||||||
<p>This header loosely follows the format <code>1-[0-9a-f]{8}-[0-9a-f]{4}</code>. This corresponds to <code>[version]-[serial]-[salt]</code>. <b>TODO: Confirm this</b></p>
|
|
||||||
<p>Our per-packet key is then generated using <code>md5(serial | salt | KEY)</code>. Identifying <code>KEY</code> is left as an exercise for the reader, however should not be especially challenging. <span style="color: #fff">Check the page source if you're stuck.</span></p>
|
|
||||||
<!-- It's 69d74627d985ee2187161570d08d93b12455035b6df0d8205df5, if you were wondering. libavs-win32-ea3.dll:0x10054160 -->
|
|
||||||
|
|
||||||
<h2 id="lz77">LZ77</h2>
|
|
||||||
<p>Packets are compressed using lzss. The compressed data structure is a repeating cycle of an 8 bit flags byte, followed by 8 values. Each value is either a single literal byte, if the corresponding bit in the preceeding flag is high, or is a two byte lookup into the window.</p>
|
|
||||||
<p>The lookup bytes are structured as <code>pppppppp ppppllll</code> where <code>p</code> is a 12 bit index in the window, and <code>l</code> is a 4 bit integer that determines how many times to repeat the value located at that index in the window.</p>
|
|
||||||
|
|
||||||
<p>The exact algorithm used for compression is not especially important, as long as it follows this format. One can feasibly perform no compression at all, and instead insert <code>0xFF</code> every 8 bytes (starting at index 0), to indicate that all values are literals. While obviously poor for compression, this is an easy way to test without first implementing a compressor.</p>
|
|
||||||
|
|
||||||
<a href="./index.html">Prev page</a> | <a href="./packet.html">Next page</a>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user