Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ module.exports = function(eleventyConfig) {
"node_modules/d3-geo/dist/d3-geo.min.js": "js/d3-geo.js",
"node_modules/topojson-client/dist/topojson-client.min.js": "js/topojson-client.js",
"node_modules/world-atlas/land-110m.json": "land-110m.json",
"node_modules/yaml/browser/dist": "js/yaml",
"node_modules/drawflow/dist/drawflow.min.js": "js/drawflow.js",
"node_modules/drawflow/dist/drawflow.min.css": "js/drawflow.css",
"src/lib": "/lib",
});

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ package-lock.json
!.gitignore
!.eleventy.js
!.nvmrc
!src/docs/
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ npm install
npm run dev
```

## Relay and dump worker

`worker/` contains the Cloudflare Worker used by setup, the editor, and support dumps. It deploys separately from the Pages site; see [worker/README.md](worker/README.md) for local tests and deployment configuration.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "index.js",
"scripts": {
"clean": "rm -rf _site",
"test": "node --test tests/",
"dev": "eleventy --serve & npx tailwindcss -i ./src/styles/main.css -o ./_site/styles.css --watch",
"build": "ELEVENTY_PRODUCTION=true eleventy && NODE_ENV=production npx tailwindcss -i ./src/styles/main.css -o ./_site/styles.css --minify"
},
Expand Down Expand Up @@ -34,6 +35,7 @@
"canvas-sketch-util": "^1.10.0",
"d3-array": "^3.2.4",
"d3-geo": "^3.1.1",
"drawflow": "0.0.60",
"eleventy-plugin-toc": "^1.1.5",
"glsl-noise": "^0.0.0",
"lucide": "^0.507.0",
Expand All @@ -42,6 +44,7 @@
"theatre": "^0.2.3",
"three": "^0.176.0",
"topojson-client": "^3.1.0",
"world-atlas": "^2.0.2"
"world-atlas": "^2.0.2",
"yaml": "2.6.1"
}
}
7 changes: 6 additions & 1 deletion src/_data/docVersions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
module.exports = {
latest: "3.3.6",
latest: "3.3.7",
versions: [
{
id: "3.3.7",
label: "3.3.7",
pathPrefix: "/docs/3.3.7",
},
{
id: "3.3.6",
label: "3.3.6",
Expand Down
10 changes: 8 additions & 2 deletions src/_includes/layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
<meta name="theme-color" content="#0a0a0a" media="(prefers-color-scheme: dark)"/>
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/>
<link rel="canonical" href="{{ site.url + page.url }}"/>
{% if appPage %}
{# scripts only from this site, connections only to this site and the relay; Alpine needs eval, the layout has inline scripts #}
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://cb.objz.dev data: blob:; connect-src 'self' wss://cb.objz.dev ws://localhost:8787 ws://localhost:8080; object-src 'none'; base-uri 'none'; form-action 'none'">
<meta name="referrer" content="no-referrer">
{% endif %}
<script>
(function () {
try {
Expand Down Expand Up @@ -176,7 +181,8 @@
{% endif %}
{% endif %}
<script src="/js/alpine.js" defer></script>
{% include "partials/analytics.njk" %}
{# the editor and the setup carry a secret in the link: no third-party scripts there #}
{% if not appPage %}{% include "partials/analytics.njk" %}{% endif %}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
Expand All @@ -191,7 +197,7 @@
{% if not hideFooter %}
{% include "partials/footer.njk" %}
{% endif %}
{% include "partials/cookie-banner.njk" %}
{% if not appPage %}{% include "partials/cookie-banner.njk" %}{% endif %}
</body>

</html>
7 changes: 7 additions & 0 deletions src/assets/_headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/editor/*
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'

/setup/*
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
6 changes: 6 additions & 0 deletions src/docs/3.3.7/3.3.7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"layout": "layouts/docs.njk",
"type": "article",
"tags": [ "docs" ],
"docVersion": "3.3.7"
}
200 changes: 200 additions & 0 deletions src/docs/3.3.7/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
title: Commands
order: 6
description: "Reference for all CommandBridge admin commands including reload, info, debug, dump, and the resource-scoped script, task, client, and config trees."
---

CommandBridge has admin commands for managing the plugin itself. These are not the custom commands you define in your scripts, those are covered in [Scripting](/docs/scripting/). The commands here are for checking connections, reloading configs, debugging issues, and things like that.

All admin commands require the `commandbridge.admin` permission. If you don't have a permissions plugin on Velocity, you won't be able to use them in-game. Console always works.

{% hint "info" %}
v3.3.5 reorganised the `/cb` tree by resource (`script`, `task`, `client`, `config`). The old top-level forms (`/cb scripts`, `/cb tasks`, `/cb list`, `/cb ping`) are gone in v3 with no backwards-compat aliases. Every argument-taking subcommand has live tab-completion: script names, script groups, task ids, client ids, and config keys.
{% endhint %}

---

### Quick command list

If you just want to know what exists, this is the full list:

| Where | Command | What it does |
|---|---|---|
| Velocity | `/commandbridge` or `/cb` | Opens the help menu (same as `/cb help`). |
| Velocity | `/cb help` | Shows all admin subcommands. |
| Velocity | `/cb info` | Shows runtime/system info (Java, OS, uptime, memory, CPU). |
| Velocity | `/cb reload` | Reloads config + scripts and re-registers commands. |
| Velocity | `/cb debug` | Toggles debug logging on/off. |
| Velocity | `/cb dump` | Generates a diagnostics dump for support/issue reports. |
| Velocity | `/cb migrate` | Migrates script files to the latest schema version. |
| Velocity | `/cb script list [page]` | Lists loaded scripts (paginated). |
| Velocity | `/cb script show <name> [group]` | Opens a script overview, or drills into a single group. |
| Velocity | `/cb script enable <name>` | Flips `enabled: true` in the script file and re-pushes registrations. |
| Velocity | `/cb script disable <name>` | Flips `enabled: false` in the script file and re-pushes registrations. |
| Velocity | `/cb task list [page]` | Lists pending scheduled tasks (paginated). |
| Velocity | `/cb task clear <id>` | Removes a pending scheduled task by id. |
| Velocity | `/cb client list` | Lists authenticated backend clients. |
| Velocity | `/cb client ping [id]` | Measures latency to one client or all clients. |
| Velocity | `/cb client players <id>` | Lists players currently on a given backend. |
| Velocity | `/cb config show [key]` | Shows the config overview, or drills into a section. |
| Velocity | `/cb config reload` | Reloads only `config.yml` (no script reload, no re-registration). |
| Backend | `/commandbridgeclient reconnect` or `/cbc reconnect` | Forces reconnect to the proxy. |

---

## What each command does

### `/commandbridge` or `/cb`

Running the base command with no subcommand opens the help menu. Internally this behaves like `/cb help`.

### `/cb help`

Shows the full admin command list. In-game, each command entry is clickable so you can run it directly from the help output.

### `/cb info`

Shows runtime info of the current Velocity instance: OS name and arch, Java version, uptime, memory usage, and CPU core count.

In-game it also shows a memory load bar so you can quickly see if this proxy is under memory pressure.

### `/cb reload`

Reloads `config.yml`, reloads scripts from disk, rebuilds command registration, and pushes registrations to authenticated clients.

It also gives a result summary per client (`OK`, `FAILED`, `TIMEOUT`) for the registration step, so you can immediately see which backend did not update cleanly.

{% hint "info" %}
This command reloads config/scripts only. It does not restart the websocket server or Redis connection layer. If endpoint mode/host/port changed, restart the server.
{% endhint %}

### `/cb debug`

Toggles debug mode on/off immediately at runtime (`ENABLED` / `DISABLED`). No reload needed.

{% hint "warning" %}
Debug logging is noisy and can get big fast. Turn it on for troubleshooting, then turn it off again.
{% endhint %}

### `/cb dump`

Builds a support snapshot, uploads it to the dump viewer, and saves a local copy.

- Local copy path: `plugins/commandbridge/dumps/dump-<timestamp>.json`
- Upload retention: currently 14 days
- Sensitive keys like `secret`, passwords, tokens, and pins are redacted

The dump still contains configuration and script metadata, so review it before sharing publicly.

### `/cb migrate`

Migrates script files in `plugins/commandbridge/scripts/` to the latest script schema.

It prints a per-file result (`MIGRATED`, `SKIPPED`, or `ERROR`) and only touches script files (not `config.yml`).

Current built-in rules cover `2 -> 3` and `3 -> 4`.

For a short practical flow, see [Migration](/docs/migration/).

---

### `/cb script list [page]`

Lists loaded scripts with name, description, and enabled/disabled state.

- Default page is `1`
- Page size is `5` scripts
- In-game output has clickable previous/next arrows and each entry links to `/cb script show <name>`

The summary at the top shows totals for loaded, enabled, disabled, and script errors.

If a script fails validation, it does not appear here. Check logs for the parser/validation error.

### `/cb script show <name> [group]`

Without a group, this opens an overview card for the script: status, schema version, aliases, register targets, and counts for args and commands. Below the summary, it lists clickable section links (`permissions`, `register`, `defaults`, `args`, `commands`).

With a group, it drills into just that group, rendered the same way the old `/cb scripts` view rendered a full script — as a syntax-highlighted yaml card on console, and as nested key/value lines in chat.

Tab-completion suggests loaded script names for `<name>` and the five group keys above for `[group]`.

### `/cb script enable <name>` / `/cb script disable <name>`

Edits the `enabled:` line of the matching yaml file in place. Comments and formatting are preserved.

After the flip, the registration set is rebuilt and pushed to connected clients, so enabling or disabling a script takes effect immediately — no `/cb reload` needed.

Tab-completion only suggests scripts that are currently in the opposite state (disabled scripts for `enable`, enabled scripts for `disable`).

---

### `/cb task list [page]`

Lists pending scheduled tasks created by scripts using `<schedule>` placeholders. Each entry shows the short task id, the source script, the player it is queued for, and how long ago it was queued.

- Default page is `1`
- Page size is `5` tasks

Tasks expire after the duration set in `tasks.expire-after` (default `86400` seconds; set to `0` to disable). Expired tasks are pruned on load and on the 5-minute save tick.

### `/cb task clear <id>`

Removes a pending scheduled task by id. The id is the full UUID — use tab-completion to insert it from the list view.

---

### `/cb client list`

Lists authenticated and currently open client sessions only. Each entry shows:

- client ID
- platform location (`VELOCITY` or `BACKEND`)
- remote address
- current player count on that backend

If a server is missing here, it has not completed auth (or connection is closed).

### `/cb client ping [id]`

Measures round-trip latency to clients.

- No argument: ping all authenticated clients
- With `id`: ping just that client

Latency quality shown by the command:

| Latency | Rating |
|---|---|
| `< 50ms` | Excellent |
| `< 150ms` | Good |
| `150ms+` | Poor |

If a ping request fails or times out, it is shown as `FAILED` in the output.

### `/cb client players <id>`

Lists players currently online on the given backend client. The summary at the bottom shows the total count. Useful for spot-checking that the proxy and a backend agree on who is connected.

---

### `/cb config show [key]`

Without a key, this shows a flat summary of all top-level scalar config values and a clickable list of nested sections (`server`, `auth`, `commands`, `tasks`, `timeouts`, and so on).

With a key, it drills into just that section as a yaml card on console or as nested key/value lines in chat.

Tab-completion suggests top-level config keys.

### `/cb config reload`

Reloads only `config.yml`. This does not reload scripts and does not push a registration update to connected clients — use `/cb reload` for that.

Useful when you only changed a value like `debug` or `tasks.expire-after` and want to apply it without disturbing connected backends.

---

### `/commandbridgeclient reconnect` or `/cbc reconnect`

Backend-only command. It closes the current backend->proxy session, starts a reconnect attempt, waits briefly, then prints the new connection status.

Use this when a backend got stuck and you want to refresh the link without restarting the whole server.
22 changes: 22 additions & 0 deletions src/docs/3.3.7/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Configuration
order: 4
description: "Overview of CommandBridge configuration for Velocity and backend servers, including WebSocket, Redis, and multi-proxy networking modes."
---

CommandBridge has two different configurations. The one on the Velocity proxy and one on each backend. For each backend, every server that is not Velocity is counted.

---

### CommandBridge offers two ways to build up the network:

Either **Redis** or **WebSockets**. WebSockets are the standard and the first implementation, and it was originally built on this system.
Redis is the newer method, but an alternative that is not reliable for everyone. The key difference is that in **WebSocket mode**, one Velocity hosts a server while the other backend servers connect to it.
This proxy then manages all traffic. No other setup is required. **Redis mode**, on the other hand, requires a Redis server running externally. CommandBridge will not host a Redis server.
With Redis mode, every CB instance will try to connect to it, including Velocity, but one Velocity instance still manages all message traffic, just the network stack isn’t managed by it anymore.

I was talking a lot about 'one Velocity instance', because CB supports **multi proxy setups**. What that exactly means is explained here: [Multi proxy](/docs/configuration/multi-proxy/).
But for that to work, there can’t be multiple proxies that manage these messages, so each proxy has in its config the value `act-as-client`.
This enables the client mode for that Velocity instance. So by design it will just act as the other client (as the title says).
For this mode, a `client.yml` will be created with the default client config. Advanced configuration can be viewed in the article.

Loading