Complete C# server cutover
This commit is contained in:
+97
-199
@@ -1,152 +1,42 @@
|
||||
# Commonwealth Online Server - Quick Start
|
||||
# Commonwealth Online Dedicated Server
|
||||
|
||||
Standalone dedicated relay server. No Qt/Host GUI build is required.
|
||||
The dedicated server is implemented in C# on .NET 8. Python is not used by the server runtime, utilities, test suite, launch scripts, or Host GUI integration.
|
||||
|
||||
## Quick Launch
|
||||
Valve GameNetworkingSockets remains in the native C++ bridge under `native_transport/`. The C# server loads its C ABI directly.
|
||||
|
||||
### Windows
|
||||
## Run
|
||||
|
||||
Double-click `start.bat`, or run it from a terminal:
|
||||
Packaged Windows:
|
||||
|
||||
```bat
|
||||
start.bat
|
||||
CommonwealthOnline.Server.exe serve --config commonwealth-server.json
|
||||
```
|
||||
|
||||
### Linux / macOS
|
||||
Packaged Linux:
|
||||
|
||||
```bash
|
||||
chmod +x start.sh fix-port.sh # recovery step if the executable bit was lost
|
||||
./start.sh
|
||||
./CommonwealthOnline.Server serve --config commonwealth-server.json
|
||||
```
|
||||
|
||||
The start script will:
|
||||
|
||||
1. Check that Python 3.9+ is installed
|
||||
2. Create a local `.venv` virtual environment (never installs into the OS Python)
|
||||
3. Install dedicated-server dependencies from `requirements-server.txt` when needed
|
||||
4. Generate a default `commonwealth-server.json` config file (if needed)
|
||||
5. Start `consumer_server_cli.py` listening on `0.0.0.0:7777` by default
|
||||
6. Open an interactive `commonwealth>` prompt when stdin/stdout are a real terminal
|
||||
|
||||
At the prompt you can type commands directly, for example:
|
||||
|
||||
```text
|
||||
help
|
||||
users
|
||||
users once
|
||||
ban 2 --reason griefing
|
||||
world time 1430
|
||||
quit
|
||||
```
|
||||
|
||||
`users` live-updates the player table every second (press Enter to stop).
|
||||
|
||||
Update dependencies explicitly when needed:
|
||||
Source checkout:
|
||||
|
||||
```bash
|
||||
./start.sh --update-dependencies
|
||||
dotnet build CommonwealthOnline.Server.csproj -c Release
|
||||
dotnet run --project tests/CommonwealthOnline.Server.Tests.csproj -c Release
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- serve --config commonwealth-server.json --interactive
|
||||
```
|
||||
|
||||
`--update-dependencies` is consumed by the start script and is **not** forwarded to the server.
|
||||
`start.bat` and `start.sh` prefer a published apphost, then a framework-dependent DLL, then `dotnet run` in a source checkout.
|
||||
|
||||
If a file manager “Open with” passes `commonwealth-server.json` as an argument, `start.sh` treats that path as the config file and still launches with `--config` (it is not forwarded as a bare positional argument).
|
||||
## Config
|
||||
|
||||
---
|
||||
|
||||
## Linux Installation
|
||||
|
||||
Do **not** run `sudo ./start.sh`. Do **not** use `pip install --break-system-packages`.
|
||||
The script creates `.venv` automatically and invokes `.venv/bin/python` directly.
|
||||
Fish users do not need to activate anything.
|
||||
|
||||
### Ubuntu and Debian
|
||||
Generate defaults:
|
||||
|
||||
```bash
|
||||
sudo apt install python3 python3-venv
|
||||
chmod +x start.sh
|
||||
./start.sh
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- config init commonwealth-server.json
|
||||
```
|
||||
|
||||
### Arch Linux and CachyOS
|
||||
|
||||
```bash
|
||||
sudo pacman -S --needed python
|
||||
chmod +x start.sh
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### Fedora
|
||||
|
||||
```bash
|
||||
sudo dnf install python3
|
||||
chmod +x start.sh
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### Firewall and networking
|
||||
|
||||
- Allow **TCP 7777** (or your configured game port) through the host firewall.
|
||||
- LAN discovery uses **UDP 7778**. If discovery is blocked, clients can still connect directly by IP/port.
|
||||
- The admin channel binds to **127.0.0.1:7779** and should stay localhost-only.
|
||||
- Router port forwarding is only needed when hosting behind a home router for outside connections.
|
||||
- VPS users normally only need the provider firewall and OS firewall configured.
|
||||
- `0.0.0.0` is a **bind address**, not the address clients should enter.
|
||||
- Direct connections still work if LAN discovery is unavailable.
|
||||
|
||||
Example firewall openings:
|
||||
|
||||
```bash
|
||||
# firewalld
|
||||
sudo firewall-cmd --add-port=7777/tcp --permanent
|
||||
sudo firewall-cmd --add-port=7778/udp --permanent
|
||||
sudo firewall-cmd --reload
|
||||
|
||||
# ufw
|
||||
sudo ufw allow 7777/tcp
|
||||
sudo ufw allow 7778/udp
|
||||
```
|
||||
|
||||
### systemd (optional)
|
||||
|
||||
1. Install the server files under `/opt/commonwealth-online` (or another path).
|
||||
2. Create an unprivileged `commonwealth` user/group.
|
||||
3. Run `./start.sh --update-dependencies` once as that user to create `.venv`.
|
||||
4. Copy and edit [`commonwealth-online.service.example`](commonwealth-online.service.example):
|
||||
|
||||
```bash
|
||||
sudo cp commonwealth-online.service.example /etc/systemd/system/commonwealth-online.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now commonwealth-online
|
||||
journalctl -u commonwealth-online -f
|
||||
```
|
||||
|
||||
Manage a headless/systemd server from another shell with the admin CLI:
|
||||
|
||||
```bash
|
||||
.venv/bin/python -u consumer_server_cli.py status
|
||||
.venv/bin/python -u consumer_server_cli.py users
|
||||
.venv/bin/python -u consumer_server_cli.py help
|
||||
```
|
||||
|
||||
`systemctl stop commonwealth-online` sends SIGTERM and the server shuts down cleanly.
|
||||
|
||||
### CRLF / executable-bit recovery
|
||||
|
||||
Git clones should keep LF endings for `start.sh` because of `.gitattributes`.
|
||||
If you extracted a ZIP on Windows or otherwise lost Unix permissions/line endings:
|
||||
|
||||
```bash
|
||||
sed -i 's/\r$//' start.sh
|
||||
chmod +x start.sh
|
||||
```
|
||||
|
||||
Prefer `.tar.gz` Linux releases so the executable bit is retained.
|
||||
|
||||
---
|
||||
|
||||
### First Run
|
||||
|
||||
On first run, a default `commonwealth-server.json` file is created in the server directory with these settings:
|
||||
Existing field names remain supported:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -156,89 +46,97 @@ On first run, a default `commonwealth-server.json` file is created in the server
|
||||
"server_description": "",
|
||||
"max_players": 16,
|
||||
"log_verbosity": "info",
|
||||
"admin_port": 7779
|
||||
"admin_port": 7779,
|
||||
"enable_gns_transport": false,
|
||||
"gns_bridge_path": null
|
||||
}
|
||||
```
|
||||
|
||||
### Port Already in Use?
|
||||
When GNS is enabled, `host` must be an explicit IPv4 bind address. TCP and GNS may use the same numeric game port because they use TCP and UDP separately.
|
||||
|
||||
If you get an address-already-in-use error, the game port is already taken.
|
||||
## Ports
|
||||
|
||||
**Option 1: Kill the blocking process**
|
||||
- TCP 7777 by default: gameplay compatibility
|
||||
- UDP 7777 by default: GNS gameplay when enabled
|
||||
- UDP 7778: LAN discovery
|
||||
- TCP 127.0.0.1:7779 by default: authenticated administration
|
||||
|
||||
Run `fix-port.bat` (Windows) or `./fix-port.sh` (Linux / macOS).
|
||||
|
||||
**Option 2: Use a different port**
|
||||
|
||||
Use the same helper and choose “Use a different port”, or edit `commonwealth-server.json`.
|
||||
|
||||
### Customizing the Server
|
||||
|
||||
Edit `commonwealth-server.json` to customize:
|
||||
|
||||
- **host**: Bind address (default `0.0.0.0` for all interfaces)
|
||||
- **port**: Game TCP port (default `7777`)
|
||||
- **server_name**: Display name
|
||||
- **server_description**: Optional short description
|
||||
- **max_players**: Metadata for client displays
|
||||
- **log_verbosity**: `debug`, `info`, `warning`, or `error`
|
||||
- **admin_port**: Localhost admin TCP port (default `7779`)
|
||||
|
||||
### Connecting Clients
|
||||
|
||||
Once the server is running:
|
||||
|
||||
- **Local PC**: Connect to `127.0.0.1:7777` (or your custom port)
|
||||
- **LAN**: Connect to your PC's local IP (displayed on startup, e.g. `192.168.1.64:7777`)
|
||||
- **Remote**: Forward TCP 7777 on your router and use your public IP
|
||||
|
||||
### Stopping the Server
|
||||
|
||||
Type `quit` at the `commonwealth>` prompt, or press `Ctrl+C`.
|
||||
Under systemd use `systemctl stop commonwealth-online`.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `requirements-server.txt` | Dedicated CLI/headless server (typer, rich) |
|
||||
| `requirements-host-gui.txt` | Optional Python PySide6 GUI (`dev_server_app.py`) |
|
||||
| `requirements.txt` | Compatibility aggregate (includes PySide6) |
|
||||
|
||||
Dedicated servers should install only `requirements-server.txt`. The Windows Qt Host GUI wraps this CLI and does not need PySide6.
|
||||
|
||||
---
|
||||
|
||||
## For Advanced Users (Command Line)
|
||||
## Admin CLI
|
||||
|
||||
```bash
|
||||
cd server
|
||||
python3 -m venv .venv
|
||||
.venv/bin/python -m pip install -r requirements-server.txt
|
||||
|
||||
# Generate config
|
||||
.venv/bin/python -u consumer_server_cli.py config init my-config.json
|
||||
|
||||
# Start server with interactive prompt (same as start.sh on a TTY)
|
||||
.venv/bin/python -u consumer_server_cli.py serve --config my-config.json --interactive
|
||||
|
||||
# Start server without a prompt (Host GUI / systemd / headless)
|
||||
.venv/bin/python -u consumer_server_cli.py serve --config my-config.json
|
||||
|
||||
# Management commands from another terminal while a server is running
|
||||
.venv/bin/python -u consumer_server_cli.py help
|
||||
.venv/bin/python -u consumer_server_cli.py status
|
||||
.venv/bin/python -u consumer_server_cli.py users
|
||||
.venv/bin/python -u consumer_server_cli.py world time 1430
|
||||
.venv/bin/python -u consumer_server_cli.py world weather 0002b52a
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- status --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- clients --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- kick 2 --reason griefing --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- ban 2 --reason griefing --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- unban 192.0.2.5 --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- bans --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- world time 1430 --config commonwealth-server.json
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- world weather 0002b52a --config commonwealth-server.json
|
||||
```
|
||||
|
||||
Run `.venv/bin/python -u consumer_server_cli.py --help` to see all available commands.
|
||||
The admin channel authenticates with `.admin-token` beside the config file and binds to localhost only.
|
||||
|
||||
### Troubleshooting: Port in Use
|
||||
## Load test
|
||||
|
||||
The C# synthetic Protocol V2 client replaces the old scripted fake clients:
|
||||
|
||||
```bash
|
||||
.venv/bin/python -u consumer_server_cli.py serve --config commonwealth-server.json --port 8000
|
||||
dotnet run --project CommonwealthOnline.Server.csproj -- load-test --host 127.0.0.1 --port 7777 --clients 16
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
C# owns:
|
||||
|
||||
- Protocol V2 decoding/validation
|
||||
- session admission and server-owned player IDs
|
||||
- movement validation and corrections
|
||||
- cell/worldspace interest filtering
|
||||
- durable player state
|
||||
- scoped NPC authority and epochs
|
||||
- combat routing
|
||||
- world state
|
||||
- bans and rate limits
|
||||
- handshake and idle timeouts
|
||||
- TCP compatibility
|
||||
- GNS sequencing/envelope handling
|
||||
- LAN discovery
|
||||
- admin control
|
||||
|
||||
C++ owns only the Valve GNS transport bridge:
|
||||
|
||||
- initialization/shutdown
|
||||
- UDP listen socket
|
||||
- GNS connection lifecycle
|
||||
- message polling/sending
|
||||
- disconnects
|
||||
- remote endpoint lookup
|
||||
|
||||
## Protocol guarantees
|
||||
|
||||
- Maximum message size remains 64 KiB.
|
||||
- `transform` and `npcState` are unreliable/sequenced under GNS.
|
||||
- Reliable gameplay/control packets remain reliable/ordered.
|
||||
- Snapshot sequences are wrap-safe; stale and duplicate snapshots are rejected.
|
||||
- Server-owned identity is applied before mutation/relay.
|
||||
- Movement validation runs before transform mutation/relay.
|
||||
- Interest filtering remains authoritative.
|
||||
- NPC authority is scoped by cell/worldspace and epoch.
|
||||
- Durable player state is cached; action events are not replay-cached.
|
||||
- Ban, connection throttle and packet-rate checks remain server-side.
|
||||
|
||||
## Publish
|
||||
|
||||
Linux self-contained:
|
||||
|
||||
```bash
|
||||
dotnet publish CommonwealthOnline.Server.csproj -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -o publish/linux-x64
|
||||
```
|
||||
|
||||
Windows self-contained:
|
||||
|
||||
```bat
|
||||
dotnet publish CommonwealthOnline.Server.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish\win-x64
|
||||
```
|
||||
|
||||
`commonwealth-online.service.example` is provided for Linux systemd deployment.
|
||||
|
||||
Reference in New Issue
Block a user