Integrate the hongshic kernel into your launcher.
Everything below is what a launcher needs: where to get the binary, how to spawn it, which line of its output to read, and where to pick a relay.
How the pieces fit
Your launcher starts hongshic on the player's machine. The kernel opens one control connection to a relay, is handed a tunnel port, and from then on forwards bytes between that port and the player's local game port. You never touch the game traffic.
Do not reimplement the relay protocol. The kernel-to-relay wire format exists but is not frozen, and getting a data-pipe rule wrong produces failures that look like the game, not like the network. Run the kernel and read its output; that contract is stable.
- Fetch the binary for the player's platform with the download endpoint below.
- Pick a relay from the official list.
- Spawn the kernel with
-t <relay>and capture its output. - Read the
endpoint=value and show it to the player. - When the process exits, the room is over. Relaunch for a new one.
Get the binary
GET /api/download/{kind}?platform={platform}&arch={arch}
kind selects which program you are asking for. For a launcher this is almost always client.
| kind | Binary | What it is | Example file |
|---|---|---|---|
| client | hongshic | The kernel you spawn on the host's machine | hongshic-windows-amd64.exe |
| server | hongshis | The relay, for people running their own node | hongshis-linux-arm64 |
| webui | hongshi | The official graphical shell | hongshi-macos-arm64 |
Naming: {binary}-{platform}-{arch}, and .exe is appended only for windows. platform is windows, linux or macos; arch is amd64 or arm64. darwin, x86_64 and aarch64 are accepted as aliases.
No CDN on purpose. The kernel is under a megabyte, so it is served straight from the origin rather than through a CDN. It arrives as application/octet-stream with a Content-Disposition filename, and the response supports Range if you want to resume.
| Status | Meaning |
|---|---|
| 200 | The file, as a download. |
| 400 | Unknown platform or arch. |
| 404 | Unknown kind, or that build is not published. The body names the exact file it looked for. |
| 422 | A required query parameter is missing. |
| 429 | Rate limited. Respect the Retry-After header. |
Errors answer in two shapes. A browser navigating to a broken link gets a page styled like the rest of the site explaining what is missing; a launcher, a script or fetch() gets JSON carrying the same facts, including expected_file. The split is on the Accept header, and it only changes the body — the status code is real either way, never a 200 with an error inside, so curl -f and your HTTP client can be trusted to notice.
Spawn it
hongshic -t <relay-address> [-p <local-game-port>] [--control-port <N>] [--data-port <N>]
| Argument | Short | Default | Meaning |
|---|---|---|---|
| --to <ADDR> | -t | required | Relay address, IP or hostname. |
| --game-port <N> | -p | 25565 | The port the local game listens on. |
| --game-host <IP> | 127.0.0.1 | Where the local game listens. | |
| --control-port <N> | 8080 | Relay control plane. Only change it if the relay did. | |
| --data-port <N> | 8000 | Relay data plane. Same caveat. | |
| --print-version | -v | Print the version and exit. | |
| --print-help | -h | Print help and exit. |
The kernel has no configuration file. Every setting is a command-line argument, so there is nothing to write to disk and nothing to clean up.
Read the address off stdout
The kernel logs to stdout. Capture that stream and match the endpoint= field; it is the only thing you need from the output.
INFO hongshi::client: tunnel created, hand the endpoint above to the players
uuid=550e8400-e29b-41d4-a716-446655440000 port=34575 endpoint=1.2.3.4:34575
Everything before endpoint= is decoration and may change. Split on endpoint=, take the address up to the next whitespace, and show that to the player verbatim: it is exactly what goes into their game's Direct Connect box.
Exit codes
| Code | Meaning | What to do |
|---|---|---|
| 0 | The tunnel ended. The relay reclaimed it after it sat idle, or the relay shut down. | The room is over. Say so, and relaunch if the player wants another. |
| 1 | It never got a tunnel: the relay was unreachable, refused the request, or a required argument was missing. | Surface the failure, then retry against another relay from the list. |
There is no exit code 2 from hongshic. Code 2 belongs to hongshis, which reports bad configuration.
Pick a relay
GET /api/server/list
Returns the public relays, keyed by region. The value is what you pass to -t.
{
"南京": "nj.hongshi.site",
"成都": "cd.hongshi.site",
"广州": "gz.hongshi.site"
}
The keys are not a fixed vocabulary: they are whatever the maintainers wrote. Pick a value, pass it through, and do not try to interpret the key — match on nothing, and never hardcode a region name. An empty object means no relay is listed right now.
All listed relays are inside mainland China, because game traffic is not allowed to leave it. That also means the region is a rough latency hint for a mainland player and nothing more.
Behaviour worth knowing
- The local game port is a lazy connection. The kernel does not touch it until a real player sends bytes, so the kernel can sit running before the game is open. Do not gate your UI on the game already being up.
- The tunnel port changes every run. Never cache the endpoint or show a stale one; read it fresh from each process you start.
- Scan probes die at the kernel. HTTP and TLS scanners that hit the tunnel port are dropped on the host's machine before they ever reach the game. The relay never sees game payload at all.
- Relaunching is the normal path. A room ends when the process exits, and every relaunch is a fresh tunnel with a fresh port. There is no resume.
- One kernel per machine. Two at once on the same host will both try to serve the same local game port.
Source and licence
The kernel, the relay and this site live in one repository: github.com/hongshionline/hongshi2. Build instructions, the protocol notes and the relay's configuration reference are in there.
The licence is not settled yet. The likely choice is GPL-3.0, but it has not been applied, so treat the repository as all rights reserved until a licence file lands. If you are planning to ship the kernel inside a closed-source launcher, ask before you build on it.
Rate limits
Both public endpoints are rate limited per IP address over a rolling minute. Exceeding a limit returns 429 with a Retry-After header; honour it instead of retrying immediately.
| Endpoint | Requests per minute |
|---|---|
| /api/server/list | 120 |
| /api/download/* | 30 |
| /api/server | 10 |
The list is cheap and meant to be polled; downloads are whole files, so that budget is deliberately tighter. Cache the binary you already fetched — there is no reason for a launcher to download the same build twice in a session.