Repository navigation
Command layer
How the command layer works as built: one dispatcher behind every front end, the checks it runs, what it audits, and the first commands. The local console is the only front end so far; the web console, the player portal and in-game commands are on Command layer design.
An admin action is a command: a definition naming its parameters, its permission, whether it's console-only, and what it runs. A front end hands the dispatcher one line of text and the actor who typed it, and gets one reply back.
flowchart TD
CON["Local console"] -->|"a line, as the console actor"| D["Dispatcher"]
D -->|"checks, then runs"| CMD["Command"]
CMD -->|"posts, waits for the reply"| AO["Account owner"]
D -->|"one audit row"| WB["Write-behind queue"]
The dispatcher runs its checks in this order, and stops at the first that fails:
- The line splits into words, double quotes holding a phrase together. An empty line, or one with an open quote, is refused.
-
helplists the commands the actor may run, with their usage. - The command is found by its two-word name, then its one-word name.
- The actor has to hold the command's permission.
- A console-only command is refused from in game.
- A line with control characters or broken text is refused.
- The number of arguments has to fit; the reply shows the usage when it doesn't.
- Each argument passes its parameter's own check.
- The command runs. One that throws is logged and answered as failed.
A command ends one of four ways: done, refused (understood and declined), denied (for want of a permission, or console-only), or failed. The permission check comes before the argument checks, so an actor without the permission learns only that it's denied.
Every command that resolves leaves one audit row, denials included: the time, the actor, the front end, the action, its target, the other arguments, the address and the outcome. Rows go through the write-behind queue into the ops schema, one after another in order, and each value is cut to its column's width so a row can't fail to save. An empty line, a line that doesn't parse, an unknown command and help leave none.
A secret stays out of the audit, the reply and the log. A value is recorded only when its parameter isn't secret and the value passes that parameter's check, so a password typed into the email slot isn't recorded either. A usage line shows parameter names, never values.
Note
This list is kept by hand until the commands get a generated reference page. help at the console is the live list.
| Command | Permission | Console only | Does |
|---|---|---|---|
account create <email> <password> |
account.create |
No | Creates an account that can log in: a random salt and an SRP6 verifier from the email in lower case. A password is 1 to 128 characters |
account suspend <email> <hours or forever> [reason] |
account.suspend |
Yes | Suspends an account, kicking its session if it's online. A reason is at most 200 characters |
account unsuspend <email> |
account.unsuspend |
Yes | Lifts the account's suspensions |
server status |
server.status |
No | The accounts online, each owner's queue, the write-behind backlog, and whether the database is reachable |
help |
none | No | The commands the actor may run |
An email is at most 254 characters and has to look like an address. Each command's answer waits for the owner, and for its commit where it writes.
The local console reads each line from the server's standard input and dispatches it as the actor console, which holds every permission. It runs when Cli:Enabled is on, the default, and input isn't redirected. Host has where it starts.
In game and the web are front ends the dispatcher already knows by name, with no code behind them yet.
| Setting | Default | Sets |
|---|---|---|
Cli:Enabled |
on | Whether the server reads commands from its console |
The field limits above are fixed in code.
- Console-only commands are refused only from in game; decide how the web front end is treated before it's built.
-
helplists console-only commands to an in-game actor who holds their permission. - Roles and in-game GM commands arrive after the first stage, so the console actor's every-permission is the only grant.
| Piece | Path |
|---|---|
| The dispatcher, definitions, actors and the line splitter | Source/NexusTomorrow.Commands/ |
| The account and server commands | Source/NexusTomorrow.Commands/Builtin/ |
| The console front end | Source/NexusTomorrow.Server/ConsoleFrontEnd.cs |
| The audit row | Source/NexusTomorrow.Persistence/Ops/ |
| Tests | Tests/NexusTomorrow.Commands.Tests/ |
Start here
How the server works
- Server core design
- Host
- Gateway
- Owners
- Persistence
- Command layer
- Harness
- Map scheduler design
- Timer wheel design
The protocol
Working on it