Protocol 3.0 §8. Ingests vendor.listing / vendor.listing.remove into a `vendors` table and serves GET /market. The frame is authoritative for one vendor, so the upsert is a whole-row overwrite. Unlike the other 3.0 boards there IS a remove: a vendor is dismissed, expires, or its owner switches off the in-game Vendor Search flag — the last of those is a privacy control, so dropping the row promptly is the point. Items ride inside the stored blob and are deliberately not normalized into a vendor_items table. The sidecar's job for the market is outage resilience (PROTOCOL_2.md §12.2), not search; search lives in MariaDB on the website side, where the query surface, the indexes and the cliloc-resolved names already are. /market is the only PAGED read the sidecar serves, because it is the only board that can be a whole world's inventory. limit clamps to 1..1000 (default 200) and `total` comes back so a caller knows when to stop rather than paging until it sees a short page, which would race a concurrent sweep. Ordering is by SERIAL, not shop name: a serial is stable while a shop name is renameable, so a rename mid-walk cannot make a vendor skip or repeat a page. The route is /market and not /vendors: /vendors/:account next door is the per-account RPC, and two routes a prefix apart meaning "this player's shops" and "every shop on the shard" is a readability trap. Frames are served verbatim, owner names and coordinates included — the sidecar defines no audiences (v3.md §3.2). Verified against the live shard: 27 vendors / 1,040 listings ingested from the plugin, plus a synthetic insert-then-remove confirming the delete path. Co-Authored-By: Claude <noreply@anthropic.com>
uo-link — Rust sidecar
The Rust sidecar half of the Runic Gateway bridge. The ServUO shard dials out to this sidecar over a loopback TCP socket (newline-delimited JSON); the sidecar owns the WebSocket + REST API the website consumes, along with auth, buffering, and fan-out.
ServUO plugin (C#, net48) ──loopback TCP, newline-JSON──► Rust sidecar ──WebSocket/JSON──► website
(RunicGateway/servuo-plugins) >>> THIS REPO <<<
The shard never speaks WebSocket and exposes no port of its own — the sidecar is the only network-facing component, which is what keeps the game unreachable from the internet.
Related repos
| Repo | What |
|---|---|
this — RunicGateway/link |
The Rust sidecar (sidecar/). |
| RunicGateway/servuo-plugins | The C# ServUO plugin — the shard side of the bridge (overlay/, patches/, deploy.ps1, test scaffolding). |
| RunicGateway/docs | All project documentation — design docs, protocol spec, integration guide, research. |
Layout
| Path | What |
|---|---|
sidecar/ |
The Rust sidecar crate — terminates the loopback link to the shard, exposes WS + REST to the website. See sidecar/README.md. |
.gitea/workflows/release.yml |
Builds + releases the sidecar binary (Linux + Windows) on every merge to main. |
Build & run
The sidecar is a standard cargo crate:
cd sidecar
cargo build --release # binary at target/release/uo-link-sidecar
cp sidecar.toml.example sidecar.toml # then edit
cargo run --release
.gitea/workflows/release.yml cross-compiles Linux + Windows binaries and cuts a Gitea release on
every merge to main (conventional-commit versioning). See sidecar/README.md
for configuration and the wire protocol.
Deployment & compatibility
The plugin (RunicGateway/servuo-plugins) and this sidecar are deployed together but built independently:
- The plugin is deployed as source into the ServUO server root and compiled by ServUO at boot — no build artifact, no CI build.
- The sidecar is a standalone Rust binary released from this repo.
The only coupling is the loopback JSON protocol (the shard dials 127.0.0.1). Compatibility is a
protocol concern, not a build-order one — keep the event/command catalog in sync across the two
repos. Canonical spec:
PLAN.md §5/§7 and
INTEGRATION.md.
Because a wedged or absent sidecar cannot stall the shard, either side can be deployed or restarted
independently.
License
Runic Gateway is free software, licensed under the GNU General Public License v3.0 or later — see LICENSE.md.
Copyright (C) 2026 Runic Gateway
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version. It is distributed WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Contributions are welcome — please read CONTRIBUTING.md (note the AI-usage disclosure requirement) and our Code of Conduct. Report vulnerabilities privately per SECURITY.md.