Sega stubs

This commit is contained in:
Bottersnike 2022-04-11 19:27:15 +01:00
parent dd22ce4a38
commit efbde9fba9
57 changed files with 571 additions and 296 deletions

204
docs.py
View File

@ -2,24 +2,70 @@ import datetime
import re
import os
from urllib.parse import urlparse
from flask import Flask, send_from_directory, render_template, make_response, request
from flask import Flask, send_from_directory, render_template, make_response, url_for
from livereload import Server
import xml_lexer
# Importing performs monkeypatching
import xml_lexer # NOQA: F401
app = Flask(__name__)
app.jinja_options.setdefault('extensions', []).append('jinja2_highlight.HighlightExtension')
HTAG = re.compile(r"<h(\d)[^>]*id=\"([^\"]+)\"[^>]*>([^<]*)</h")
TOC_HTAG_LEVELS = {"1", "2"}
HOST = "https://bsnk.me"
TEMPLATES = "templates"
PAGES_BASE = "pages"
STATIC = ["images"]
ROOT = os.environ.get("EA_ROOT", "")
EAMUSE_CONTENTS = {
"getting_started.html": ("Getting started and following along", {
0: ("A quick one-stop shop for getting setup with the tools you'll want on hand if you want to investigate "
+ "things for yourself.")
}),
"transport.html": ("Transport layer", None),
"packet.html": ("The inner packet structure", None),
"protocol.html": ("Communication protocol details", {
0: ("There are a crazy number of sub pages here, so just go check the contents there.")
}),
"server.html": "Let's write a server",
0: ("Misc pages", {
"cardid.html": ("Parsing and converting card IDs", ())
}),
}
SEGA_CONTENTS = {
"intro.html": ("Introduction to RingEdge 2", ()),
"hardware": ("Hardware", ()),
"software": ("Software", {
"drivers": ("Device drivers", {
"columba.html": "columba",
"mxsram.html": "mxsram",
"mxhwreset.html": "mxhwreset",
"mxsuperio.html": "mxsuperio",
"mxjvs.html": "mxjvs",
"mxparallel.html": "mxparallel",
"mxsmbus.html": "mxsmbus",
}),
"jvs.html": "JVS",
"security": ("Security", {
"game.html": "Game encryption",
"dongle.html": "Dongles",
"keychip.html": "Keychips",
})
}),
"network": ("Networking", {
"allnet.html": "ALL.Net"
})
}
CONTENTS = {
"": EAMUSE_CONTENTS,
"sega": SEGA_CONTENTS
}
def generate_xrpc_list():
@ -46,12 +92,146 @@ def generate_xrpc_list():
return output + "</ul>"
def generate_toc(base, name, route, start=1):
parts = route.strip("/").split("/")
toc = CONTENTS
for i in parts:
if i in toc:
toc = toc[i]
if isinstance(toc, tuple):
toc = toc[1]
if not isinstance(toc, dict):
return ""
else:
return ""
def walk(toc, path, start=1):
unordered = len(toc) == 1 and 0 in toc
out = f'<{"u" if unordered else "o"}l start="{start}">'
for url in toc:
if isinstance(toc[url], tuple):
name, children = toc[url]
elif isinstance(toc[url], str):
name, children = toc[url], -1
out += "<li>"
if isinstance(url, str):
fqu = f"{ROOT}/{path}"
if not url.startswith("#"):
fqu += "/"
fqu += url
while "//" in fqu:
fqu = fqu.replace("//", "/")
if not fqu.endswith((".html", "/")) and "#" not in fqu:
fqu += "/"
out += f'<a href="{fqu}">{name}</a>'
else:
out += name
out += "</li>"
if children == -1:
continue
if children is None:
filename = "/".join((TEMPLATES, PAGES_BASE, path, url))
while "//" in filename:
filename = filename.replace("//", "/")
if url == "":
filename += "index.html"
with open(filename) as page:
headers = HTAG.findall(page.read())
children = {}
for level, anchor, text in headers:
if level in TOC_HTAG_LEVELS:
children[f"#{anchor}"] = text
if not children:
children = None
if children is not None:
out += walk(children, f"{path}/{url}" if isinstance(url, str) else path)
out += f'</{"u" if unordered else "o"}l>'
return out
return walk(toc, route, start)
def generate_footer(base, name, route):
parts = route.strip("/").split("/")
if not parts:
return ""
toc = CONTENTS
path = []
for i in parts[:-1]:
if i in toc:
path.append(i)
toc = toc[i]
if isinstance(toc, tuple):
toc = toc[1]
if not isinstance(toc, dict):
toc = None
break
elif toc == CONTENTS:
toc = toc[""]
else:
toc = None
break
if toc == CONTENTS and len(parts) == 1:
toc = toc[""]
if toc is None:
siblings = None
else:
siblings = [i for i in toc.keys() if isinstance(i, str)]
try:
us_idx = siblings.index(parts[-1])
except ValueError:
us_idx = -1
parent = "/" + ("/".join(parts[:-1]))
if not parent.endswith("/"):
parent += "/"
footer = "<footer><span>"
if siblings and us_idx > 0:
footer += f'<a href="{parent}{siblings[us_idx - 1]}">Previous page</a>'
footer += "</span><span>"
if parts:
crumbs = []
built = "/"
for i in parts[:-1]:
built += f"{i}"
if not built.endswith((".html", "/")):
built += "/"
crumbs.append(f'<a href="{built}">{i}</a>')
crumbs.append(parts[-1])
footer += "/".join(crumbs)
footer += "</span><span>"
if siblings and us_idx < len(siblings) - 1 and us_idx != -1:
footer += f'<a href="{parent}{siblings[us_idx + 1]}">Next page</a>'
footer += "</span></footer>"
return footer
@app.route("/styles.css")
def styles():
return send_from_directory(".", "styles.css")
@app.route("/tango.css")
def tango():
return send_from_directory(".", "tango.css")
@app.route("/headers.js")
def header_script():
return send_from_directory(".", "headers.js")
@ -82,12 +262,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
for name in files:
if name.endswith(".html"):
def handler(base, name):
def handler(base, name, route):
def handler():
return render_template(
os.path.join(base, name).strip("/").replace("\\", "/"),
ROOT=ROOT,
generate_xrpc_list=generate_xrpc_list
generate_xrpc_list=generate_xrpc_list,
generate_toc=lambda start=1: generate_toc(base, name, route, start),
generate_footer=lambda: generate_footer(base, name, route),
)
return handler
@ -101,17 +283,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
if not route.startswith("/"):
route = "/" + route
handler = handler(base, name)
handler = handler(base, name, route)
handler.__name__ == route
app.add_url_rule(route, route, handler)
from flask import url_for
@app.route("/sitemap.xml")
def sitemap():
host_components = urlparse(request.host_url)
host_base = "https://bsnk.me" + ROOT
host_base = HOST + ROOT
links = []
for rule in app.url_map.iter_rules():
@ -133,6 +312,7 @@ def sitemap():
response.headers["Content-Type"] = "application/xml"
return response
if __name__ == '__main__':
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['DEBUG'] = True
@ -141,4 +321,4 @@ if __name__ == '__main__':
server = Server(app.wsgi_app)
server.watch(".")
server.serve(port=3000)
server.serve(port=3000)

View File

@ -6,5 +6,3 @@ for (const el of document.querySelectorAll("[id]")) {
pilcrow.innerHTML = "&para;"
el.prepend(pilcrow)
}
console.log(hasId);

View File

@ -154,4 +154,16 @@ table.nav td {
.pilcrow:hover {
opacity: 1;
color: #c7254e;
}
}
footer {
width: 100%;
text-align: center;
margin-top: 8px;
}
footer>*:first-child {
float: left;
}
footer>*:last-child {
float: right;
}

View File

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}{% if self.title() %} | {% endif %}e-Amusement API</title>
<title>{% block title %}{% endblock %}{% if self.title() %} | {% endif %}{% block roottitle %}Arcade Reverse Engineering{% endblock %}</title>
<link rel="stylesheet" href="{{ROOT}}/styles.css?ver=5">
<link rel="stylesheet" href="{{ROOT}}/tango.css">
@ -21,16 +21,8 @@
</head>
<body>
<table class="nav">
<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>
<td><a href="{{ROOT}}/server.html">Let's write a server</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% block rootbody %}{% endblock %}
{{ generate_footer()|safe }}
<script src="{{ROOT}}/headers.js"></script>
</body>

14
templates/konami.html Normal file
View File

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block roottitle %}e-Amusement API{% endblock %}
{% block rootbody %}
<table class="nav">
<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>
<td><a href="{{ROOT}}/server.html">Let's write a server</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Card IDs{% endblock %}
{% block body %}
<h1>Card ID generation</h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Curious flags{% endblock %}
{% block body %}
<br>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Following along{% endblock %}
{% block body %}
<h1>Following along</h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<h1>Benami/Konami e-Amusement API</h1>
@ -18,39 +18,7 @@
</p>
<h2>Contents</h2>
<ol start="0">
<li><a href="./getting_started.html">Getting started and following along</a></li>
<ul>
<li>A quick one-stop shop for getting setup with the tools you'll want on hand if you want to investigate things
for yourself.</li>
</ul>
<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><a href="./server.html">Let's write a server</a></li>
<ol>
<li><a href="./server.html#groundwork">Groundwork</a></li>
<li><a href="./server.html#handlers">Implementing handlers</a></li>
<li><a href="./server.html#extra">Extra endpoints</a></li>
</ol>
<li>Misc pages</li>
<ol>
<li><a href="./cardid.html">Parsing and converting card IDs</a></li>
</ol>
</ol>
{{ generate_toc(0)|safe }}
<h2>Code snippets</h2>
<p>Across these pages there are a number of code snippets. They roughly break down into three categories:</p>
@ -66,7 +34,4 @@
<p>Assembly and C snippets often come with an accompanying filename and address. If you're interested in learning how
things work in more detail, I'd strongly recommend checking them out. Not all games come with the same version of
files; the provided addresses are for build SDVX build KFC-2019020600, using the default base offset.</p>
<a href="./transport.html">Next page</a>
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<p>Why?</p>
<p>I was curious how these APIs work, yet could find little to nothing on Google. There are a number of

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Packet format{% endblock %}
{% block body %}
<h1>Packet format</h1>
@ -1023,6 +1023,4 @@
self.request_allocation(4){% endhighlight %}</pre>
</p>
</details>
<a href="./transport.html">Prev page</a> | <a href="./protocol.html">Next page</a>
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}apsmanager{% endblock %}
{% block body %}
<h1><code>apsmanager</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}cardmng{% endblock %}
{% block body %}
<h1><code>cardmng</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}dlstatus{% endblock %}
{% block body %}
<h1><code>dlstatus</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}eacoin{% endblock %}
{% block body %}
<h1><code>eacoin</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}esign{% endblock %}
{% block body %}
<h1><code>esign</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}esoc{% endblock %}
{% block body %}
<h1><code>esoc</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}eventlog{% endblock %}
{% block body %}
<h1><code>eventlog</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}facility{% endblock %}
{% block body %}
<h1><code>facility</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}game.sv4{% endblock %}
{% block body %}
<h1 id="game"><code>game</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}matching{% endblock %}
{% block body %}
<h1><code>matching</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}message{% endblock %}
{% block body %}
<h1><code>message</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}package{% endblock %}
{% block body %}
<h1><code>package</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}pcbevent{% endblock %}
{% block body %}
<h1><code>pcbevent</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}pcbtracker{% endblock %}
{% block body %}
<h1><code>pcbtracker</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}playerdata{% endblock %}
{% block body %}
<h1><code>playerdata</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}services{% endblock %}
{% block body %}
<h1><code>services</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}sidmgr{% endblock %}
{% block body %}
<h1><code>sidmgr</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}system{% endblock %}
{% block body %}
<h1><code>system</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}traceroute{% endblock %}
{% block body %}
<h1><code>traceroute</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}userdata{% endblock %}
{% block body %}
<h1><code>userdata</code></h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Application protocol{% endblock %}
{% block body %}
<h1>Application Protocol</h1>

View File

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Hardware{% endblock %}
{% block body %}
<h1>Hardware</h1>
{{ generate_toc()|safe }}
{% endblock %}

View File

@ -1,203 +1,11 @@
{% extends "base.html" %}
{% block title %}SEGA Games{% endblock %}
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
<h1>SEGA Games</h1>
<p>This may get its own micro-site at some point if it grows large enough. For now it's mostly just a rambling of notes.
</p>
<p>In some ways SEGA's protocols are simpler than Konami's (none of that XML mess) but in other ways they're more
complicated (hardcoded URLs, multiple services required, etc.)</p>
<h1>RingEdge 2</h1>
<p>Welcome to the sub-site for RingEdge 2 games. What started as a simple desire to start games outside of dev mode
turned into an incredibly deep dive into the inner workings of the RE2 software. Enjoy.</p>
<h2>ALL.Net</h2>
<p>A simple service that exposes two URLs. The hostname must be <code>http://naominet.jp</code>.</p>
<p>Requests should be made with a number of standard HTTP headers, and must be either HTTP version 1.0 or 1.1</p>
<table>
<tr>
<td><code>Connection</code></td>
<td><code>Close</code></td>
</tr>
<tr>
<td><code>Pragma</code></td>
<td><code>DFI</code></td>
</tr>
<tr>
<td><code>User-Agent</code></td>
<td><code>ALL.Net_PC_Win2/ver1.0</code></td>
</tr>
<tr>
<td><code>Content-Type</code></td>
<td><code>application/x-www-form-urlencoded</code></td>
</tr>
<tr>
<td><code>Content-Length</code></td>
<td><i>variable</i></td>
</tr>
</table>
<p>Note that the <code>Pragma</code> header is optional, and the <code>Content-Type</code> header is a lie.</p>
<p>Requests and responses should be <code>POST</code>s, and their body should be base64 encoded, zlib compressed,
<code>x-www-form-urlencoded</code> data. For example, <code>{key: "value", other: "another"}</code> should encode to
<code>eJwdxcEJACAMA8Bt3CLD5BEQFIXSFtw+4OuWHpq7NG5OBXi+BmwzCRo=</code>.
</p>
<p>Responses are expected to contain <code>stat</code> indicating status:</p>
<table>
<tr>
<td><code>1</code></td>
<td>Success</td>
</tr>
<tr>
<td><code>0</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-1</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-2</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-3</code></td>
<td>Failure</td>
</tr>
</table>
<p>This service provides two endpoints, documented below:</p>
<h3><code>/sys/servlet/PowerOn</code></h3>
<h4>Request:</h4>
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&encode=%s&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s\r\n"
"game_id=%s&ver=%s&serial=%s&encode=%s\r\n"
"keychipid=%s&functype=%u&gameid=%s&gamever=%s&boardid=%s&tenpoip=%s&libalibver=%s&datamax=%s&billingtype=%d&protocolver=%s&operatingfix=%d"
(libalibver = 1.110, protocolver = 1.000)
SDBT: Chunithm
SBXL: Maimai
<table>
<tr>
<td><code>game_id</code></td>
<td>4-character game ID</td>
</tr>
<tr>
<td><code>ver</code></td>
<td></td>
</tr>
<tr>
<td><code>serial</code></td>
<td></td>
</tr>
<tr>
<td><code>ip</code></td>
<td></td>
</tr>
<tr>
<td><code>firm_ver</code></td>
<td><code>%01d%02d%02d</code></td>
</tr>
<tr>
<td><code>boot_ver</code></td>
<td><code>%02X%02X</code></td>
</tr>
<tr>
<td><code>format_ver</code></td>
<td></td>
</tr>
<tr>
<td><code>hops</code></td>
<td></td>
</tr>
<tr>
<td><code>encode</code></td>
<td></td>
</tr>
</table>
<h4>Response:</h4>
<table>
<tr>
<td><code>stat</code></td>
<td>See above</td>
</tr>
<tr>
<td><code>uri</code></td>
<td></td>
</tr>
<tr>
<td><code>host</code></td>
<td></td>
</tr>
<tr>
<td><code>region0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name1</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name2</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name3</code></td>
<td></td>
</tr>
<tr>
<td><code>year</code></td>
<td></td>
</tr>
<tr>
<td><code>month</code></td>
<td></td>
</tr>
<tr>
<td><code>day</code></td>
<td></td>
</tr>
<tr>
<td><code>hour</code></td>
<td></td>
</tr>
<tr>
<td><code>minute</code></td>
<td></td>
</tr>
<tr>
<td><code>second</code></td>
<td></td>
</tr>
<tr>
<td><code>place_id</code></td>
<td></td>
</tr>
<tr>
<td><code>setting</code></td>
<td></td>
</tr>
<tr>
<td><code>country</code></td>
<td></td>
</tr>
<tr>
<td><code>timezone</code></td>
<td></td>
</tr>
<tr>
<td><code>res_class</code></td>
<td></td>
</tr>
</table>
<h3><code>/sys/servlet/DownloadOrder</code></h3>
<h2 id="toc">Table of Contents</h2>
{{ generate_toc(0)|safe }}
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
<h1>Introduction to RingEdge 2</h1>
<p>RingEdge 2 (RE2 henceforth) is the main computer used by Sega in a number of their arcade games. In their cronology
it exists as the successor to the RingEdge (no huge surprise there), which itself was the successor to the
Lindbergh, and is the predecessor of Nu. There also exists the RingWide, a slightly less powerful variant of the
Ring* computers. These pages focus on the RE2. I have no reason to believe the RE2 software stack is especially
differnet to that of the RE, but I haven't confirmed this. Nu, however, uses different systems in many places, and
most of the deep-dive pages will not be applicable.</p>
<h2 id="tech">Technical Specifications</h2>
<ul>
<li>Intel Core i3-540, 3.06GHz</li>
<li>Nvidia GeForce GT 545</li>
<li>2GB RAM</li>
<li>32GB SSD (TDK GBDISK RS3)</li>
<li>Intel Q57 Express Motherboard</li>
</ul>
<a href="{{ROOT}}/sega/hardware/">Next chapter</a>
{% endblock %}

View File

@ -0,0 +1,197 @@
{% extends "sega.html" %}
{% block title %}ALL.Net{% endblock %}
{% block body %}
<h1>ALL.Net</h1>
<p>A simple service that exposes two URLs. The hostname must be <code>http://naominet.jp</code>.</p>
<p>Requests should be made with a number of standard HTTP headers, and must be either HTTP version 1.0 or 1.1</p>
<table>
<tr>
<td><code>Connection</code></td>
<td><code>Close</code></td>
</tr>
<tr>
<td><code>Pragma</code></td>
<td><code>DFI</code></td>
</tr>
<tr>
<td><code>User-Agent</code></td>
<td><code>ALL.Net_PC_Win2/ver1.0</code></td>
</tr>
<tr>
<td><code>Content-Type</code></td>
<td><code>application/x-www-form-urlencoded</code></td>
</tr>
<tr>
<td><code>Content-Length</code></td>
<td><i>variable</i></td>
</tr>
</table>
<p>Note that the <code>Pragma</code> header is optional, and the <code>Content-Type</code> header is a lie.</p>
<p>Requests and responses should be <code>POST</code>s, and their body should be base64 encoded, zlib compressed,
<code>x-www-form-urlencoded</code> data. For example, <code>{key: "value", other: "another"}</code> should encode to
<code>eJwdxcEJACAMA8Bt3CLD5BEQFIXSFtw+4OuWHpq7NG5OBXi+BmwzCRo=</code>.
</p>
<p>Responses are expected to contain <code>stat</code> indicating status:</p>
<table>
<tr>
<td><code>1</code></td>
<td>Success</td>
</tr>
<tr>
<td><code>0</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-1</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-2</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-3</code></td>
<td>Failure</td>
</tr>
</table>
<p>This service provides two endpoints, documented below:</p>
<h3><code>/sys/servlet/PowerOn</code></h3>
<h4>Request:</h4>
<!--
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&encode=%s&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s\r\n"
"game_id=%s&ver=%s&serial=%s&encode=%s\r\n"
"keychipid=%s&functype=%u&gameid=%s&gamever=%s&boardid=%s&tenpoip=%s&libalibver=%s&datamax=%s&billingtype=%d&protocolver=%s&operatingfix=%d"
(libalibver = 1.110, protocolver = 1.000)
SDBT: Chunithm
SBXL: Maimai -->
<table>
<tr>
<td><code>game_id</code></td>
<td>4-character game ID</td>
</tr>
<tr>
<td><code>ver</code></td>
<td></td>
</tr>
<tr>
<td><code>serial</code></td>
<td></td>
</tr>
<tr>
<td><code>ip</code></td>
<td></td>
</tr>
<tr>
<td><code>firm_ver</code></td>
<td><code>%01d%02d%02d</code></td>
</tr>
<tr>
<td><code>boot_ver</code></td>
<td><code>%02X%02X</code></td>
</tr>
<tr>
<td><code>format_ver</code></td>
<td></td>
</tr>
<tr>
<td><code>hops</code></td>
<td></td>
</tr>
<tr>
<td><code>encode</code></td>
<td></td>
</tr>
</table>
<h4>Response:</h4>
<table>
<tr>
<td><code>stat</code></td>
<td>See above</td>
</tr>
<tr>
<td><code>uri</code></td>
<td></td>
</tr>
<tr>
<td><code>host</code></td>
<td></td>
</tr>
<tr>
<td><code>region0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name1</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name2</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name3</code></td>
<td></td>
</tr>
<tr>
<td><code>year</code></td>
<td></td>
</tr>
<tr>
<td><code>month</code></td>
<td></td>
</tr>
<tr>
<td><code>day</code></td>
<td></td>
</tr>
<tr>
<td><code>hour</code></td>
<td></td>
</tr>
<tr>
<td><code>minute</code></td>
<td></td>
</tr>
<tr>
<td><code>second</code></td>
<td></td>
</tr>
<tr>
<td><code>place_id</code></td>
<td></td>
</tr>
<tr>
<td><code>setting</code></td>
<td></td>
</tr>
<tr>
<td><code>country</code></td>
<td></td>
</tr>
<tr>
<td><code>timezone</code></td>
<td></td>
</tr>
<tr>
<td><code>res_class</code></td>
<td></td>
</tr>
</table>
<h3><code>/sys/servlet/DownloadOrder</code></h3>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Networking{% endblock %}
{% block body %}
<h1>Networking</h1>
{{ generate_toc()|safe }}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Drivers{% endblock %}
{% block body %}
<h1>Drivers</h1>
{{ generate_toc()|safe }}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Software{% endblock %}
{% block body %}
<h1>Software</h1>
{{ generate_toc()|safe }}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Security{% endblock %}
{% block body %}
<h1>Security</h1>
{{ generate_toc()|safe }}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Write a server{% endblock %}
{% block body %}
<h1>Let's write an e-Amusement server!</h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Smart E-Amusement{% endblock %}
{% block body %}
<h1>Smart E-Amusement</h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<h2><code>op2_common.get_music_info</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Network format{% endblock %}
{% block body %}
<h1>Network format</h1>
@ -118,6 +118,4 @@ int xrpc_key_and_crypt(char *packet, char *eamuse_info, size_t size) {
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 %}

11
templates/sega.html Normal file
View File

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block roottitle %}RingEdge 2{% endblock %}
{% block rootbody %}
<table class="nav">
<tr>
<td><a href="{{ROOT}}/sega/">Contents</a></td>
<td><a href="{{ROOT}}/sega/network/allnet.html">ALL.Net</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% endblock %}

View File

@ -9,9 +9,11 @@ def italic_attr(lexer, m):
yield m.start() + 2, Comment, m.group()[3:-1]
yield m.end() - 1, String, '"'
def italic_generic(lexer, m):
yield m.start(), Comment, m.group()
def italic_tag(lexer, m):
yield m.start(), Name.Tag, "<"
name = m.group()[3:]
@ -21,17 +23,20 @@ def italic_tag(lexer, m):
else:
yield m.start() + 1, Comment, name
def italic_tag_close(lexer, m):
yield m.start(), Name.Tag, "</"
yield m.start() + 4, Comment, m.group()[4:-1]
yield m.end() - 1, Name.Tag, ">"
def repeat_tag_close(lexer, m):
before, _, after = m.group().partition("[]")
yield m.start(), Name.Tag, before
yield m.start() + len(before), Operator, "[]"
yield m.start() + len(before) + 2, Name.Tag, after
def italic_attr_name(lexer, m):
name, _, after = m.group().partition("*")
yield m.start(), Name.Attribute, name
@ -79,6 +84,7 @@ class CustomXMLLexer(RegexLexer):
def analyse_text(text):
print("hi?")
_lexer_cache[CustomXMLLexer.__name__] = CustomXMLLexer
LEXERS["CustomXMLLexer"] = ("xml_lexer", "CustomXMLLexer", ("cxml", ), (), ())