|
|
|
|
@@ -4,9 +4,9 @@
|
|
|
|
|
how to tell which of the three is wrong when they are not. The contract itself is
|
|
|
|
|
[`PROTOCOL.md`](PROTOCOL.md).
|
|
|
|
|
|
|
|
|
|
There is no installer support for Rust yet — that is a later phase — so everything here is done by
|
|
|
|
|
hand. When the installer gains `--game rust`, this page becomes the fallback path rather than the
|
|
|
|
|
only one.
|
|
|
|
|
**To set a server up, use [`INSTALL.md`](INSTALL.md)**: the installer (`--game rust`), the
|
|
|
|
|
Pterodactyl egg, or its own by-hand path. This page walks the same pieces one at a time, by hand, and
|
|
|
|
|
is mostly useful for understanding them and for diagnosing a link that does not come up.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
@@ -14,17 +14,23 @@ only one.
|
|
|
|
|
|
|
|
|
|
| Piece | Where it comes from |
|
|
|
|
|
|---|---|
|
|
|
|
|
| A Rust dedicated server with **Oxide** | umod.org |
|
|
|
|
|
| `RunicGateway.cs` | [Rust-Plugins](https://gitea.whitlocktech.com/RunicGateway/Rust-Plugins), `overlay/oxide/plugins/` |
|
|
|
|
|
| A Rust dedicated server with **Oxide** or **Carbon** | umod.org, or carbonmod.gg |
|
|
|
|
|
| `RunicGateway.cs`, and its helpers | [Rust-Plugins](https://gitea.whitlocktech.com/RunicGateway/Rust-Plugins), `overlay/oxide/plugins/` |
|
|
|
|
|
| `RunicNPC.cs` — **required** since RunicNPC's stage 9 (D310) | [runicnpc-rust](https://gitea.whitlocktech.com/RunicGateway/runicnpc-rust) |
|
|
|
|
|
| `rust-link-sidecar` | [Rust-Link](https://gitea.whitlocktech.com/RunicGateway/Rust-Link) |
|
|
|
|
|
| A Runic Gateway website with `module-rust` installed | [Module-Rust](https://gitea.whitlocktech.com/RunicGateway/Module-Rust) |
|
|
|
|
|
|
|
|
|
|
Take the plugin, RunicNPC and the sidecar from one bundle (`v2/rust/current.json` on the installer's
|
|
|
|
|
`bundles` branch), never "the latest of each": the bundle is what CI checked speaks one protocol.
|
|
|
|
|
|
|
|
|
|
**One game server, one sidecar, on that server's own host.** Six servers means six of the first two
|
|
|
|
|
pairs and six rows in the website's admin panel.
|
|
|
|
|
|
|
|
|
|
The module also expects four third-party Oxide plugins to be present for the features that follow
|
|
|
|
|
the bridge itself — `Clans`, `Kits`, `PopupNotifications` and `ZoneManager`, all from k1lly0u on
|
|
|
|
|
umod.org. The bridge works without them; the features that read them do not.
|
|
|
|
|
The bridge needs two third-party plugins from uMod for the features that follow it, **Kits** and
|
|
|
|
|
**ZoneManager**; it works without them, and the features that read them do not. **RunicNPC will not
|
|
|
|
|
load without Kits.** PopupNotifications is optional (D141), and so is everything
|
|
|
|
|
[`OPERATING.md`](../modules/rust/OPERATING.md) covers. The uMod **Clans** plugin is deliberately not
|
|
|
|
|
used (D47): a server's clans come from Rust's own clan system.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
@@ -48,10 +54,13 @@ there is no second way to read it back.
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"component": "rust-link-sidecar",
|
|
|
|
|
"protocol": 1,
|
|
|
|
|
"version": "0.3.0",
|
|
|
|
|
"protocol": 14,
|
|
|
|
|
"config_path": "/etc/runicgateway/rust-main.toml",
|
|
|
|
|
"config_created": true,
|
|
|
|
|
"token_generated": true,
|
|
|
|
|
"game": { "bind": "127.0.0.1:7799", "server_id": "" },
|
|
|
|
|
"web": { "bind": "127.0.0.1:8090", "auth_token": "…", "ws_path": "/ws" },
|
|
|
|
|
"web": { "bind": "127.0.0.1:8090", "ws_path": "/ws", "auth_required": true, "auth_token": "…" },
|
|
|
|
|
"store": { "path": "/var/lib/runicgateway/rust-link.db" }
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
@@ -70,7 +79,7 @@ Check it:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl http://127.0.0.1:8090/health
|
|
|
|
|
{"status":"degraded","protocol":1,"plugin_connected":false,"database":"ok","uptime":"0m","last_event":null}
|
|
|
|
|
{"status":"degraded","protocol":14,"plugin_connected":false,"database":"ok","uptime":"0m","last_event":null,"untyped_frames":0}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`degraded` with `plugin_connected: false` is exactly right at this point — nothing is connected yet.
|
|
|
|
|
@@ -81,18 +90,21 @@ curl http://127.0.0.1:8090/health
|
|
|
|
|
cp RunicGateway.cs /path/to/rust/oxide/plugins/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Oxide compiles and loads it on the write. Watch `oxide/logs/`:
|
|
|
|
|
Oxide compiles and loads it on the write. Watch `oxide/logs/` (Carbon: `carbon/plugins/` and
|
|
|
|
|
`carbon/logs/Carbon.Core.log`):
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
[Info] RunicGateway was compiled successfully in 2295ms
|
|
|
|
|
[Info] [Runic Gateway] protocol 1, serverId 'main', sidecar 127.0.0.1:7799
|
|
|
|
|
[Info] [Runic Gateway] protocol 14, serverId 'main', sidecar 127.0.0.1:7799
|
|
|
|
|
[Info] [Runic Gateway] connected to 127.0.0.1:7799
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The first load also writes `oxide/config/RunicGateway.json`. Set `ServerId` before you go further:
|
|
|
|
|
The first load also writes `oxide/config/RunicGateway.json` (Carbon: `carbon/configs/`). Set
|
|
|
|
|
`ServerId` before you go further — or, better, create the file holding just `ServerId` and `Port`
|
|
|
|
|
before the first load, as the installer does. The plugin fills in every other key:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{ "Host": "127.0.0.1", "Port": 7799, "QueueCap": 5000, "ServerId": "main" }
|
|
|
|
|
{ "Host": "127.0.0.1", "Port": 7799, "QueueCap": 5000, "ServerId": "main", "EventsEnabled": false, … }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**`ServerId` is this server's identity as the website knows it, and it is permanent.** It is not
|
|
|
|
|
@@ -102,20 +114,20 @@ not lose its history for it. Changing it later orphans everything recorded under
|
|
|
|
|
Now `/health` should read:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{"status":"ok","protocol":1,"plugin_connected":true,"database":"ok","uptime":"2m","last_event":"…"}
|
|
|
|
|
{"status":"ok","protocol":14,"plugin_connected":true,"database":"ok","uptime":"2m","last_event":"…","untyped_frames":0}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If it does not, ask the game server:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
rg.link
|
|
|
|
|
protocol=1 serverId=main connected=True depth=0 sent=3 dropped=0 received=2
|
|
|
|
|
connects=1 writeErrors=0 bootId=boot-20260915T194502Z
|
|
|
|
|
protocol=14 serverId=main connected=True depth=0 sent=3 dropped=0 received=2
|
|
|
|
|
connects=1 writeErrors=0 bootId=boot-20260915T194502Z wipeId=w-20260915T195817Z
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2.3 The website
|
|
|
|
|
|
|
|
|
|
**Admin → Rust → add a server.** Four values:
|
|
|
|
|
**Admin → Rust servers** (`/admin/rust/servers`) **→ Add a server.** Four values:
|
|
|
|
|
|
|
|
|
|
| Field | Value |
|
|
|
|
|
|---|---|
|
|
|
|
|
@@ -128,14 +140,15 @@ connects=1 writeErrors=0 bootId=boot-20260915T194502Z
|
|
|
|
|
reports only whether one is set. A save that leaves the field blank keeps the stored one — so
|
|
|
|
|
renaming a server does not mean re-pasting a credential.
|
|
|
|
|
|
|
|
|
|
Then press **Test**, which probes the sidecar and reports what came back:
|
|
|
|
|
Then press **Test the sidecar**, which probes the sidecar and reports what came back — *The sidecar
|
|
|
|
|
answered (protocol 14).* on the page, from this answer:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{ "ok": true, "status": "ok",
|
|
|
|
|
"sidecar": { "status": "ok", "protocol": 1, "plugin_connected": true, … } }
|
|
|
|
|
"sidecar": { "status": "ok", "protocol": 14, "plugin_connected": true, … } }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Within a poll interval the server appears at `/rust/servers`.
|
|
|
|
|
Within a poll interval the server appears at `/rust`.
|
|
|
|
|
|
|
|
|
|
### 2.4 The recommended PopupNotifications look (optional)
|
|
|
|
|
|
|
|
|
|
|