- Revamp architecture for modular game server support (Arma 3 first, extensible) - Merge ConfigSchema into ConfigGenerator per council decision (8→7 protocols) - Add has_capability() method to GameAdapter protocol for explicit capability probing - Add FRONTEND.md: production-grade dark neumorphism design with amber/orange palette - Update all docs (ARCHITECTURE, MODULES, DATABASE, API, IMPLEMENTATION_PLAN, THREADING) to reflect protocol merge and multi-game adapter patterns
898 lines
20 KiB
Markdown
898 lines
20 KiB
Markdown
# Languard Servers Manager — API Contract
|
|
|
|
## Base URL
|
|
```
|
|
http://localhost:8000/api
|
|
```
|
|
|
|
## Authentication
|
|
- All endpoints except `POST /auth/login` and `GET /system/health` require: `Authorization: Bearer <JWT>`
|
|
- WebSocket: pass token as query param: `ws://localhost:8000/ws/{server_id}?token=<JWT>`
|
|
- JWT payload: `{ "sub": "user_id", "username": "string", "role": "admin|viewer", "exp": timestamp }`
|
|
|
|
## Common Response Envelope
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": { ... },
|
|
"error": null
|
|
}
|
|
```
|
|
Error response:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"data": null,
|
|
"error": {
|
|
"code": "NOT_FOUND",
|
|
"message": "Server with id 5 not found"
|
|
}
|
|
}
|
|
```
|
|
|
|
## HTTP Status Codes
|
|
| Code | Meaning |
|
|
|------|---------|
|
|
| 200 | Success |
|
|
| 201 | Created |
|
|
| 204 | No content (DELETE) |
|
|
| 400 | Validation error |
|
|
| 401 | Unauthenticated |
|
|
| 403 | Forbidden (insufficient role) |
|
|
| 404 | Not found (or capability not supported by adapter) |
|
|
| 409 | Conflict (already running, duplicate) |
|
|
| 422 | Unprocessable (Pydantic validation) |
|
|
| 500 | Internal server error |
|
|
|
|
## Capability-Based Routing
|
|
|
|
Some endpoints depend on the server's game adapter supporting a specific capability. If the adapter does not support the capability, the endpoint returns **404** with a clear message:
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"data": null,
|
|
"error": {
|
|
"code": "CAPABILITY_NOT_SUPPORTED",
|
|
"message": "Missions not supported for game type 'rust'"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Auth Endpoints
|
|
|
|
### POST /auth/login
|
|
Login and receive JWT.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"username": "admin",
|
|
"password": "secret"
|
|
}
|
|
```
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
|
"token_type": "bearer",
|
|
"expires_in": 86400,
|
|
"user": {
|
|
"id": 1,
|
|
"username": "admin",
|
|
"role": "admin"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /auth/logout
|
|
Invalidate token (client-side token deletion; server-side blacklist optional).
|
|
|
|
### GET /auth/me
|
|
Return current user info.
|
|
|
|
### PUT /auth/password
|
|
Change password. Admin only.
|
|
```json
|
|
{ "current_password": "old", "new_password": "new" }
|
|
```
|
|
|
|
### GET /auth/users
|
|
List all users. Admin only.
|
|
|
|
### POST /auth/users
|
|
Create user. Admin only.
|
|
```json
|
|
{ "username": "viewer1", "password": "pass", "role": "viewer" }
|
|
```
|
|
|
|
### DELETE /auth/users/{user_id}
|
|
Delete user. Admin only.
|
|
|
|
---
|
|
|
|
## Game Type Discovery Endpoints
|
|
|
|
### GET /games
|
|
List all registered game types and their capabilities.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"game_type": "arma3",
|
|
"display_name": "Arma 3",
|
|
"version": "1.0.0",
|
|
"capabilities": ["config_generator", "process_config",
|
|
"log_parser", "remote_admin", "mission_manager", "mod_manager", "ban_manager"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### GET /games/{game_type}
|
|
Get details for a specific game type.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"game_type": "arma3",
|
|
"display_name": "Arma 3",
|
|
"version": "1.0.0",
|
|
"capabilities": ["config_generator", "process_config",
|
|
"log_parser", "remote_admin", "mission_manager", "mod_manager", "ban_manager"],
|
|
"config_sections": ["server", "basic", "profile", "launch", "rcon"],
|
|
"allowed_executables": ["arma3server_x64.exe", "arma3server.exe"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /games/{game_type}/config-schema
|
|
Returns JSON Schema for each config section defined by the adapter. Used by frontend to build dynamic config forms.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"server": { /* JSON Schema for server.cfg params */ },
|
|
"basic": { /* JSON Schema for basic.cfg params */ },
|
|
"profile": { /* JSON Schema for Arma3Profile params */ },
|
|
"launch": { /* JSON Schema for launch params */ },
|
|
"rcon": { /* JSON Schema for RCon params */ }
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /games/{game_type}/defaults
|
|
Default config values for new server creation.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"server": { "hostname": "My Arma 3 Server", "max_players": 40, ... },
|
|
"basic": { "min_bandwidth": 800000, ... },
|
|
"profile": { "reduced_damage": 0, ... },
|
|
"launch": { "world": "empty", "limit_fps": 50, ... },
|
|
"rcon": { "max_ping": 200, "enabled": 1 }
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Server Endpoints
|
|
|
|
### GET /servers
|
|
List all servers with current status. Supports filtering by game type.
|
|
|
|
**Query params:** `?limit=50&offset=0&game_type=arma3`
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"name": "Main Server",
|
|
"description": "Primary COOP server",
|
|
"game_type": "arma3",
|
|
"status": "running",
|
|
"pid": 12345,
|
|
"game_port": 2302,
|
|
"rcon_port": 2306,
|
|
"player_count": 15,
|
|
"max_players": 40,
|
|
"cpu_percent": 34.2,
|
|
"ram_mb": 1850.5,
|
|
"started_at": "2026-04-16T10:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /servers
|
|
Create a new server. Admin only. `game_type` determines which adapter handles this server.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"name": "Main Server",
|
|
"description": "Primary COOP server",
|
|
"game_type": "arma3",
|
|
"exe_path": "C:/Arma3Server/arma3server_x64.exe",
|
|
"game_port": 2302,
|
|
"rcon_port": 2306,
|
|
"auto_restart": true,
|
|
"max_restarts": 3
|
|
}
|
|
```
|
|
|
|
The adapter provides default config values for all sections. Auto-generated credentials (e.g., `password_admin`, `rcon_password` for Arma 3) are returned in the response and not stored in plaintext.
|
|
|
|
**Response 201:** Returns full server object including auto-generated credentials.
|
|
|
|
### GET /servers/{server_id}
|
|
Get server detail with full status.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": 1,
|
|
"name": "Main Server",
|
|
"game_type": "arma3",
|
|
"status": "running",
|
|
"pid": 12345,
|
|
"game_port": 2302,
|
|
"rcon_port": 2306,
|
|
"auto_restart": true,
|
|
"restart_count": 0,
|
|
"player_count": 15,
|
|
"max_players": 40,
|
|
"cpu_percent": 34.2,
|
|
"ram_mb": 1850.5,
|
|
"started_at": "2026-04-16T10:00:00Z",
|
|
"uptime_seconds": 3600
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /servers/{server_id}
|
|
Update server metadata (name, description, exe_path, ports). Admin only.
|
|
|
|
### DELETE /servers/{server_id}
|
|
Delete server (must be stopped first). Admin only. Removes DB rows and `servers/{id}/` directory.
|
|
|
|
### POST /servers/{server_id}/start
|
|
Start the server. Admin only. Core resolves the adapter and delegates config generation + launch arg building.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{ "success": true, "data": { "status": "starting", "pid": null } }
|
|
```
|
|
**Response 409:** Server already running.
|
|
|
|
### POST /servers/{server_id}/stop
|
|
Graceful stop (sends shutdown via adapter's RemoteAdmin, then force-kill after 30s). Admin only.
|
|
|
|
**Request (optional):**
|
|
```json
|
|
{ "force": false, "reason": "Maintenance" }
|
|
```
|
|
|
|
### POST /servers/{server_id}/restart
|
|
Stop then start. Admin only.
|
|
|
|
### POST /servers/{server_id}/kill
|
|
Force-kill the process immediately. Admin only. Emergency use only.
|
|
|
|
---
|
|
|
|
## Server Config Endpoints
|
|
|
|
Config sections are defined by the server's game adapter. The core `game_configs` table stores them as JSON. The adapter's Pydantic models validate input.
|
|
|
|
### GET /servers/{server_id}/config
|
|
Get all config sections combined. Each section includes its `config_version` for optimistic locking.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"server": { /* section JSON */, "_meta": {"config_version": 3, "schema_version": "1.0"} },
|
|
"basic": { /* section JSON */, "_meta": {"config_version": 1, "schema_version": "1.0"} },
|
|
"profile": { /* section JSON */, "_meta": {"config_version": 2, "schema_version": "1.0"} },
|
|
"launch": { /* section JSON */, "_meta": {"config_version": 1, "schema_version": "1.0"} },
|
|
"rcon": { "rcon_password": "***", "max_ping": 200, "enabled": 1, "_meta": {"config_version": 1, "schema_version": "1.0"} }
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /servers/{server_id}/config/{section}
|
|
Get a single config section. Section names are defined by the adapter (e.g., `server`, `basic`, `profile`, `launch`, `rcon` for Arma 3).
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"hostname": "My Server",
|
|
"max_players": 40,
|
|
"_meta": { "config_version": 3, "schema_version": "1.0" }
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /servers/{server_id}/config/{section}
|
|
Update a config section. Admin only. Validated against the adapter's Pydantic model for that section. Sensitive fields (passwords) are encrypted before storage. **Optimistic locking** — client must send `config_version` from their last read.
|
|
|
|
**Request:** Partial object matching the adapter's section schema. Any omitted field keeps current value. Must include `config_version` for conflict detection.
|
|
|
|
**Arma 3 `server` section example:**
|
|
```json
|
|
{
|
|
"hostname": "Updated Server Name",
|
|
"max_players": 64,
|
|
"battleye": 1,
|
|
"verify_signatures": 2,
|
|
"motd_lines": ["Welcome!", "Have fun"],
|
|
"motd_interval": 5.0,
|
|
"config_version": 3
|
|
}
|
|
```
|
|
|
|
**Response 409 (Conflict):** Another admin updated this section since you read it.
|
|
```json
|
|
{
|
|
"success": false,
|
|
"data": {
|
|
"current_config": { /* latest values */ },
|
|
"current_version": 5
|
|
},
|
|
"error": {
|
|
"code": "CONFIG_VERSION_CONFLICT",
|
|
"message": "Config section 'server' was modified by another user. Re-read and merge your changes."
|
|
}
|
|
}
|
|
```
|
|
|
|
**Arma 3 `basic` section example:**
|
|
```json
|
|
{
|
|
"max_bandwidth": 50000000,
|
|
"max_msg_send": 256
|
|
}
|
|
```
|
|
|
|
**Arma 3 `profile` section example:**
|
|
```json
|
|
{
|
|
"third_person_view": 0,
|
|
"weapon_crosshair": 0,
|
|
"ai_level_preset": 3,
|
|
"skill_ai": 0.7,
|
|
"precision_ai": 0.6
|
|
}
|
|
```
|
|
|
|
**Arma 3 `launch` section example:**
|
|
```json
|
|
{
|
|
"world": "empty",
|
|
"limit_fps": 50,
|
|
"auto_init": false,
|
|
"load_mission_to_memory": true
|
|
}
|
|
```
|
|
|
|
**Arma 3 `rcon` section example:**
|
|
```json
|
|
{
|
|
"rcon_password": "newpassword",
|
|
"rcon_port": 2306,
|
|
"max_ping": 300,
|
|
"enabled": true
|
|
}
|
|
```
|
|
|
|
**Note:** `rcon_port` is stored in the `servers` table, not in the config JSON. The service layer updates both tables as needed.
|
|
|
|
### GET /servers/{server_id}/config/preview
|
|
Returns rendered config for preview in UI. **Admin only** — may contain plaintext credentials. Returns a dict of `{label: rendered_content}` — labels are filenames for file-based configs, variable names for env-var configs, or argument names for CLI configs.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"server.cfg": "// Generated server.cfg\nhostname = \"My Server\";\n...",
|
|
"basic.cfg": "// Generated basic.cfg\n...",
|
|
"server.Arma3Profile": "// Generated profile\n..."
|
|
}
|
|
}
|
|
```
|
|
|
|
(Non-file games would return e.g. `{"SERVER_NAME": "My Server", "MAX_PLAYERS": "40"}` for env-var configs.)
|
|
|
|
### GET /servers/{server_id}/config/download/{filename}
|
|
Download generated config file. Filename must be in adapter's allowlist (whitelist-validated, no path traversal). **Admin only**.
|
|
|
|
---
|
|
|
|
## Mission Endpoints (Capability: `mission_manager`)
|
|
|
|
Returns **404** if adapter does not support `mission_manager`.
|
|
|
|
### GET /servers/{server_id}/missions
|
|
List all mission/scenario files for a server.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"filename": "MyMission.Altis.pbo",
|
|
"mission_name": "MyMission.Altis",
|
|
"terrain": "Altis",
|
|
"file_size": 102400,
|
|
"uploaded_at": "2026-04-16T09:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /servers/{server_id}/missions/upload
|
|
Upload a mission/scenario file. Admin only. `multipart/form-data`. File extension validated by adapter's `MissionManager.file_extension`.
|
|
|
|
**Form fields:**
|
|
- `file`: the mission file (filename sanitized; only adapter-allowed extensions accepted)
|
|
|
|
**Response 201:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": 2,
|
|
"filename": "NewMission.Stratis.pbo",
|
|
"mission_name": "NewMission.Stratis",
|
|
"terrain": "Stratis",
|
|
"file_size": 51200
|
|
}
|
|
}
|
|
```
|
|
|
|
### DELETE /servers/{server_id}/missions/{mission_id}
|
|
Delete a mission file (removes file from disk). Admin only.
|
|
|
|
### GET /servers/{server_id}/missions/rotation
|
|
Get current mission/scenario rotation (ordered list).
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"sort_order": 0,
|
|
"mission": { "id": 1, "mission_name": "MyMission.Altis" },
|
|
"difficulty": "Regular",
|
|
"params_json": { "RespawnDelay": 15 }
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### PUT /servers/{server_id}/missions/rotation
|
|
Replace the entire mission rotation. Admin only.
|
|
|
|
```json
|
|
{
|
|
"rotation": [
|
|
{ "mission_id": 1, "difficulty": "Regular", "params": {} },
|
|
{ "mission_id": 2, "difficulty": "Veteran", "params": { "RespawnDelay": 30 } }
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Mod Endpoints (Capability: `mod_manager`)
|
|
|
|
Returns **404** if adapter does not support `mod_manager`.
|
|
|
|
### GET /mods
|
|
List all registered mods. Optionally filter by game type.
|
|
|
|
**Query params:** `?game_type=arma3`
|
|
|
|
### POST /mods
|
|
Register a mod folder. Admin only.
|
|
|
|
```json
|
|
{
|
|
"game_type": "arma3",
|
|
"name": "@CBA_A3",
|
|
"folder_path": "C:/Arma3Server/@CBA_A3",
|
|
"workshop_id": "450814997",
|
|
"description": "Community Base Addons"
|
|
}
|
|
```
|
|
|
|
### DELETE /mods/{mod_id}
|
|
Delete mod registration. Admin only.
|
|
|
|
### GET /servers/{server_id}/mods
|
|
Get mods enabled for a server.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"mod_id": 1,
|
|
"name": "@CBA_A3",
|
|
"folder_path": "C:/Arma3Server/@CBA_A3",
|
|
"is_server_mod": false,
|
|
"sort_order": 0
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### PUT /servers/{server_id}/mods
|
|
Replace the mod list for a server. Admin only.
|
|
|
|
```json
|
|
{
|
|
"mods": [
|
|
{ "mod_id": 1, "is_server_mod": false, "sort_order": 0 },
|
|
{ "mod_id": 2, "is_server_mod": true, "sort_order": 1 }
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Player Endpoints
|
|
|
|
### GET /servers/{server_id}/players
|
|
Get currently connected players.
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"slot_id": "1",
|
|
"name": "PlayerOne",
|
|
"guid": "abc123...",
|
|
"ping": 45,
|
|
"game_data": { "verified": true, "steam_uid": "76561198..." },
|
|
"joined_at": "2026-04-16T10:15:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /servers/{server_id}/players/{slot_id}/kick
|
|
Kick a player. Admin only. Requires adapter `remote_admin` capability.
|
|
|
|
```json
|
|
{ "reason": "AFK" }
|
|
```
|
|
|
|
### POST /servers/{server_id}/players/{slot_id}/ban
|
|
Ban a player. Admin only. Requires adapter `remote_admin` capability.
|
|
|
|
```json
|
|
{
|
|
"reason": "Griefing",
|
|
"duration_minutes": 0
|
|
}
|
|
```
|
|
|
|
### GET /servers/{server_id}/players/history
|
|
Player connection history. Supports pagination.
|
|
|
|
**Query params:** `?limit=50&offset=0&search=PlayerName`
|
|
|
|
---
|
|
|
|
## Ban Endpoints
|
|
|
|
### GET /servers/{server_id}/bans
|
|
List all bans for a server.
|
|
|
|
**Query params:** `?active_only=true&limit=50&offset=0`
|
|
|
|
### POST /servers/{server_id}/bans
|
|
Add ban manually. Admin only. If adapter has `ban_manager`, also syncs to the game's ban file.
|
|
|
|
```json
|
|
{
|
|
"guid": "abc123...",
|
|
"name": "PlayerName",
|
|
"reason": "Cheating",
|
|
"duration_minutes": 0
|
|
}
|
|
```
|
|
|
|
### DELETE /servers/{server_id}/bans/{ban_id}
|
|
Remove a ban. Admin only. If adapter has `ban_manager`, also removes from the game's ban file.
|
|
|
|
---
|
|
|
|
## Remote Admin Endpoints (Capability: `remote_admin`)
|
|
|
|
Returns **404** if adapter does not support `remote_admin`.
|
|
|
|
### POST /servers/{server_id}/remote-admin/command
|
|
Send raw remote admin command. Admin only.
|
|
|
|
```json
|
|
{ "command": "#restart" }
|
|
```
|
|
|
|
**Arma 3 available commands:**
|
|
- `#restart` — Restart mission
|
|
- `#reassign` — Restart with roles unassigned
|
|
- `#missions` — Open mission selection
|
|
- `#lock` / `#unlock` — Lock/unlock server
|
|
- `#mission NAME.TERRAIN [difficulty]` — Load specific mission
|
|
- `#shutdown` — Shut down server
|
|
- `#monitor N` — Toggle performance monitoring
|
|
- `say -1 MESSAGE` — Message all players
|
|
|
|
### POST /servers/{server_id}/remote-admin/say
|
|
Broadcast a message to all players. Admin only.
|
|
|
|
```json
|
|
{ "message": "Server restarting in 5 minutes!" }
|
|
```
|
|
|
|
---
|
|
|
|
## Log Endpoints
|
|
|
|
### GET /servers/{server_id}/logs
|
|
Query stored log lines.
|
|
|
|
**Query params:** `?limit=200&offset=0&level=error&since=2026-04-16T10:00:00Z&search=BattlEye`
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"total": 1542,
|
|
"logs": [
|
|
{
|
|
"id": 100,
|
|
"timestamp": "2026-04-16T10:05:23Z",
|
|
"level": "info",
|
|
"message": "Player PlayerOne connected"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### DELETE /servers/{server_id}/logs
|
|
Clear all stored log lines for a server. Admin only.
|
|
|
|
---
|
|
|
|
## Metrics Endpoints
|
|
|
|
### GET /servers/{server_id}/metrics
|
|
Get time-series metrics.
|
|
|
|
**Query params:** `?from=2026-04-16T00:00:00Z&to=2026-04-16T23:59:59Z&resolution=5m`
|
|
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"timestamp": "2026-04-16T10:00:00Z",
|
|
"cpu_percent": 34.2,
|
|
"ram_mb": 1850.5,
|
|
"player_count": 15
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Event Log Endpoints
|
|
|
|
### GET /servers/{server_id}/events
|
|
Get server event history (audit trail).
|
|
|
|
**Query params:** `?limit=50&offset=0&event_type=crashed`
|
|
|
|
---
|
|
|
|
## System Endpoints
|
|
|
|
### GET /system/status
|
|
Overall system status. **Requires authentication** (admin or viewer).
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"version": "1.0.0",
|
|
"running_servers": 2,
|
|
"total_servers": 3,
|
|
"supported_games": ["arma3"],
|
|
"uptime_seconds": 86400
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /system/health
|
|
Health check (for load balancer/Docker). Returns 200 if healthy.
|
|
|
|
---
|
|
|
|
## WebSocket API
|
|
|
|
### Connection
|
|
```
|
|
ws://localhost:8000/ws/{server_id}?token=<JWT>
|
|
```
|
|
Use `server_id = "all"` to subscribe to events from all servers.
|
|
|
|
### Client → Server Messages
|
|
|
|
```json
|
|
{ "type": "ping" }
|
|
{ "type": "subscribe", "channels": ["logs", "players", "metrics", "status"] }
|
|
{ "type": "unsubscribe", "channels": ["metrics"] }
|
|
```
|
|
|
|
**Channel subscription**: The `ConnectionManager` tracks per-connection channel subscriptions. Only messages matching subscribed channels are delivered. Default subscriptions on connect: `["status"]`.
|
|
|
|
### Server → Client Messages
|
|
|
|
#### Status Update
|
|
```json
|
|
{
|
|
"type": "status",
|
|
"server_id": 1,
|
|
"data": {
|
|
"status": "running",
|
|
"pid": 12345,
|
|
"started_at": "2026-04-16T10:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Log Line
|
|
```json
|
|
{
|
|
"type": "log",
|
|
"server_id": 1,
|
|
"data": {
|
|
"timestamp": "2026-04-16T10:05:23Z",
|
|
"level": "info",
|
|
"message": "BattlEye Server: Initialized (v1.240)"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Player List Update
|
|
```json
|
|
{
|
|
"type": "players",
|
|
"server_id": 1,
|
|
"data": {
|
|
"players": [
|
|
{ "slot_id": "1", "name": "PlayerOne", "ping": 45 }
|
|
],
|
|
"count": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Metrics Update
|
|
```json
|
|
{
|
|
"type": "metrics",
|
|
"server_id": 1,
|
|
"data": {
|
|
"cpu_percent": 34.2,
|
|
"ram_mb": 1850.5,
|
|
"player_count": 1,
|
|
"timestamp": "2026-04-16T10:05:25Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Server Event
|
|
```json
|
|
{
|
|
"type": "event",
|
|
"server_id": 1,
|
|
"data": {
|
|
"event_type": "crashed",
|
|
"detail": { "exit_code": 1 },
|
|
"timestamp": "2026-04-16T10:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Pong
|
|
```json
|
|
{ "type": "pong" }
|
|
```
|
|
|
|
---
|
|
|
|
## Adapter-Specific Routes
|
|
|
|
Adapters may register additional routes under `/api/servers/{server_id}/game/{game_type}/...` for features that have no generic counterpart.
|
|
|
|
**Arma 3 example:**
|
|
```
|
|
POST /api/servers/{server_id}/game/arma3/battleye/reload
|
|
```
|
|
|
|
These routes are registered at app startup by iterating over all registered adapters.
|
|
|
|
---
|
|
|
|
## Rate Limiting
|
|
|
|
- `POST /auth/login`: 5 attempts per minute per IP. Exceeded returns `429 Too Many Requests`.
|
|
- All other endpoints: 60 requests per minute per token. Exceeded returns `429`.
|
|
- Implemented via FastAPI middleware (e.g., `slowapi`).
|
|
|
|
---
|
|
|
|
## Error Codes Reference
|
|
|
|
| Code | Description |
|
|
|------|-------------|
|
|
| `UNAUTHORIZED` | Missing or invalid token |
|
|
| `FORBIDDEN` | Role insufficient |
|
|
| `NOT_FOUND` | Resource not found |
|
|
| `CAPABILITY_NOT_SUPPORTED` | Adapter lacks required capability for this endpoint |
|
|
| `SERVER_ALREADY_RUNNING` | Start called on running server |
|
|
| `SERVER_NOT_RUNNING` | Stop/command on stopped server |
|
|
| `REMOTE_ADMIN_UNAVAILABLE` | Remote admin connection failed |
|
|
| `INVALID_CONFIG` | Config validation failed (adapter-specific) |
|
|
| `CONFIG_WRITE_ERROR` | Config file write failed (disk, permissions) |
|
|
| `CONFIG_VERSION_CONFLICT` | Optimistic locking conflict on config update |
|
|
| `EXE_NOT_ALLOWED` | Executable not in adapter's allowlist |
|
|
| `PORT_IN_USE` | Game port already occupied |
|
|
| `UPLOAD_FAILED` | File upload error |
|
|
| `VALIDATION_ERROR` | Pydantic validation failure |
|
|
| `GAME_TYPE_NOT_FOUND` | No adapter registered for this game type |
|
|
| `INTERNAL_ERROR` | Unexpected server error |
|
|
| `MOD_IN_USE` | Cannot delete mod — enabled on one or more servers |
|
|
| `MISSION_IN_ROTATION` | Cannot delete mission — in active rotation |
|
|
| `RATE_LIMITED` | Too many requests | |