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 re
import os import os
from urllib.parse import urlparse from flask import Flask, send_from_directory, render_template, make_response, url_for
from flask import Flask, send_from_directory, render_template, make_response, request
from livereload import Server from livereload import Server
import xml_lexer # Importing performs monkeypatching
import xml_lexer # NOQA: F401
app = Flask(__name__) app = Flask(__name__)
app.jinja_options.setdefault('extensions', []).append('jinja2_highlight.HighlightExtension') 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" TEMPLATES = "templates"
PAGES_BASE = "pages" PAGES_BASE = "pages"
STATIC = ["images"] STATIC = ["images"]
ROOT = os.environ.get("EA_ROOT", "") 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(): def generate_xrpc_list():
@ -46,12 +92,146 @@ def generate_xrpc_list():
return output + "</ul>" 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") @app.route("/styles.css")
def styles(): def styles():
return send_from_directory(".", "styles.css") return send_from_directory(".", "styles.css")
@app.route("/tango.css") @app.route("/tango.css")
def tango(): def tango():
return send_from_directory(".", "tango.css") return send_from_directory(".", "tango.css")
@app.route("/headers.js") @app.route("/headers.js")
def header_script(): def header_script():
return send_from_directory(".", "headers.js") return send_from_directory(".", "headers.js")
@ -82,12 +262,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
for name in files: for name in files:
if name.endswith(".html"): if name.endswith(".html"):
def handler(base, name): def handler(base, name, route):
def handler(): def handler():
return render_template( return render_template(
os.path.join(base, name).strip("/").replace("\\", "/"), os.path.join(base, name).strip("/").replace("\\", "/"),
ROOT=ROOT, 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 return handler
@ -101,17 +283,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
if not route.startswith("/"): if not route.startswith("/"):
route = "/" + route route = "/" + route
handler = handler(base, name) handler = handler(base, name, route)
handler.__name__ == route handler.__name__ == route
app.add_url_rule(route, route, handler) app.add_url_rule(route, route, handler)
from flask import url_for
@app.route("/sitemap.xml") @app.route("/sitemap.xml")
def sitemap(): def sitemap():
host_components = urlparse(request.host_url) host_base = HOST + ROOT
host_base = "https://bsnk.me" + ROOT
links = [] links = []
for rule in app.url_map.iter_rules(): for rule in app.url_map.iter_rules():
@ -133,6 +312,7 @@ def sitemap():
response.headers["Content-Type"] = "application/xml" response.headers["Content-Type"] = "application/xml"
return response return response
if __name__ == '__main__': if __name__ == '__main__':
app.config['TEMPLATES_AUTO_RELOAD'] = True app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['DEBUG'] = True app.config['DEBUG'] = True
@ -141,4 +321,4 @@ if __name__ == '__main__':
server = Server(app.wsgi_app) server = Server(app.wsgi_app)
server.watch(".") 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;" pilcrow.innerHTML = "&para;"
el.prepend(pilcrow) el.prepend(pilcrow)
} }
console.log(hasId);

View File

@ -154,4 +154,16 @@ table.nav td {
.pilcrow:hover { .pilcrow:hover {
opacity: 1; opacity: 1;
color: #c7254e; 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 charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <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}}/styles.css?ver=5">
<link rel="stylesheet" href="{{ROOT}}/tango.css"> <link rel="stylesheet" href="{{ROOT}}/tango.css">
@ -21,16 +21,8 @@
</head> </head>
<body> <body>
<table class="nav"> {% block rootbody %}{% endblock %}
<tr> {{ generate_footer()|safe }}
<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 %}
<script src="{{ROOT}}/headers.js"></script> <script src="{{ROOT}}/headers.js"></script>
</body> </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 title %}Card IDs{% endblock %}
{% block body %} {% block body %}
<h1>Card ID generation</h1> <h1>Card ID generation</h1>

View File

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

View File

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

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "konami.html" %}
{% block body %} {% block body %}
<h1>Benami/Konami e-Amusement API</h1> <h1>Benami/Konami e-Amusement API</h1>
@ -18,39 +18,7 @@
</p> </p>
<h2>Contents</h2> <h2>Contents</h2>
<ol start="0"> {{ generate_toc(0)|safe }}
<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>
<h2>Code snippets</h2> <h2>Code snippets</h2>
<p>Across these pages there are a number of code snippets. They roughly break down into three categories:</p> <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 <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 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> 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 %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "konami.html" %}
{% block body %} {% block body %}
<p>Why?</p> <p>Why?</p>
<p>I was curious how these APIs work, yet could find little to nothing on Google. There are a number of <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 title %}Packet format{% endblock %}
{% block body %} {% block body %}
<h1>Packet format</h1> <h1>Packet format</h1>
@ -1023,6 +1023,4 @@
self.request_allocation(4){% endhighlight %}</pre> self.request_allocation(4){% endhighlight %}</pre>
</p> </p>
</details> </details>
<a href="./transport.html">Prev page</a> | <a href="./protocol.html">Next page</a>
{% endblock %} {% endblock %}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "konami.html" %}
{% block title %}Application protocol{% endblock %} {% block title %}Application protocol{% endblock %}
{% block body %} {% block body %}
<h1>Application Protocol</h1> <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" %} {% extends "sega.html" %}
{% block title %}SEGA Games{% endblock %} {% block title %}{% endblock %}
{% block body %} {% block body %}
<h1>SEGA Games</h1> <h1>RingEdge 2</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>Welcome to the sub-site for RingEdge 2 games. What started as a simple desire to start games outside of dev mode
</p> turned into an incredibly deep dive into the inner workings of the RE2 software. Enjoy.</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>
<h2>ALL.Net</h2> <h2 id="toc">Table of Contents</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>
{{ generate_toc(0)|safe }}
{% endblock %} {% 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 title %}Write a server{% endblock %}
{% block body %} {% block body %}
<h1>Let's write an e-Amusement server!</h1> <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 title %}Smart E-Amusement{% endblock %}
{% block body %} {% block body %}
<h1>Smart E-Amusement</h1> <h1>Smart E-Amusement</h1>

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "konami.html" %}
{% block body %} {% block body %}
<h2><code>op2_common.get_music_info</code></h2> <h2><code>op2_common.get_music_info</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?> <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 title %}Network format{% endblock %}
{% block body %} {% block body %}
<h1>Network format</h1> <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 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 indicate that all values are literals. While obviously poor for compression, this is an easy way to test without
first implementing a compressor.</p> first implementing a compressor.</p>
<a href="./index.html">Prev page</a> | <a href="./packet.html">Next page</a>
{% endblock %} {% 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.start() + 2, Comment, m.group()[3:-1]
yield m.end() - 1, String, '"' yield m.end() - 1, String, '"'
def italic_generic(lexer, m): def italic_generic(lexer, m):
yield m.start(), Comment, m.group() yield m.start(), Comment, m.group()
def italic_tag(lexer, m): def italic_tag(lexer, m):
yield m.start(), Name.Tag, "<" yield m.start(), Name.Tag, "<"
name = m.group()[3:] name = m.group()[3:]
@ -21,17 +23,20 @@ def italic_tag(lexer, m):
else: else:
yield m.start() + 1, Comment, name yield m.start() + 1, Comment, name
def italic_tag_close(lexer, m): def italic_tag_close(lexer, m):
yield m.start(), Name.Tag, "</" yield m.start(), Name.Tag, "</"
yield m.start() + 4, Comment, m.group()[4:-1] yield m.start() + 4, Comment, m.group()[4:-1]
yield m.end() - 1, Name.Tag, ">" yield m.end() - 1, Name.Tag, ">"
def repeat_tag_close(lexer, m): def repeat_tag_close(lexer, m):
before, _, after = m.group().partition("[]") before, _, after = m.group().partition("[]")
yield m.start(), Name.Tag, before yield m.start(), Name.Tag, before
yield m.start() + len(before), Operator, "[]" yield m.start() + len(before), Operator, "[]"
yield m.start() + len(before) + 2, Name.Tag, after yield m.start() + len(before) + 2, Name.Tag, after
def italic_attr_name(lexer, m): def italic_attr_name(lexer, m):
name, _, after = m.group().partition("*") name, _, after = m.group().partition("*")
yield m.start(), Name.Attribute, name yield m.start(), Name.Attribute, name
@ -79,6 +84,7 @@ class CustomXMLLexer(RegexLexer):
def analyse_text(text): def analyse_text(text):
print("hi?") print("hi?")
_lexer_cache[CustomXMLLexer.__name__] = CustomXMLLexer _lexer_cache[CustomXMLLexer.__name__] = CustomXMLLexer
LEXERS["CustomXMLLexer"] = ("xml_lexer", "CustomXMLLexer", ("cxml", ), (), ()) LEXERS["CustomXMLLexer"] = ("xml_lexer", "CustomXMLLexer", ("cxml", ), (), ())