feat: web dashboard and playground work

The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch:
accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy
reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live
events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved
captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes
they need.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-26 17:52:10 -05:00
parent 854d02f509
commit e213a7aeff
681 changed files with 88310 additions and 1321 deletions

View File

@@ -0,0 +1,395 @@
{
"title": "DarkflameServer",
"uid": "darkflame-overview",
"schemaVersion": 39,
"version": 1,
"editable": true,
"time": {
"from": "now-24h",
"to": "now"
},
"refresh": "1m",
"tags": [
"darkflame"
],
"templating": {
"list": [
{
"name": "datasource",
"type": "datasource",
"query": "prometheus",
"label": "Prometheus"
}
]
},
"panels": [
{
"id": 1,
"type": "stat",
"title": "Servers",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 0,
"y": 0,
"w": 12,
"h": 4
},
"fieldConfig": {
"defaults": {
"mappings": [
{
"type": "value",
"options": {
"0": {
"text": "Down",
"color": "red"
},
"1": {
"text": "Up",
"color": "green"
}
}
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "red",
"value": null
},
{
"color": "green",
"value": 1
}
]
}
},
"overrides": []
},
"options": {
"colorMode": "background",
"graphMode": "none",
"reduceOptions": {
"calcs": [
"lastNotNull"
]
}
},
"targets": [
{
"refId": "A",
"expr": "darkflame_master_connected",
"legendFormat": "Master"
},
{
"refId": "B",
"expr": "darkflame_auth_up",
"legendFormat": "Auth"
},
{
"refId": "C",
"expr": "darkflame_chat_up",
"legendFormat": "Chat"
},
{
"refId": "D",
"expr": "darkflame_db_up",
"legendFormat": "Database"
}
]
},
{
"id": 2,
"type": "stat",
"title": "Now",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 12,
"y": 0,
"w": 12,
"h": 4
},
"options": {
"graphMode": "area",
"reduceOptions": {
"calcs": [
"lastNotNull"
]
}
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "darkflame_players_online",
"legendFormat": "Players"
},
{
"refId": "B",
"expr": "darkflame_world_instances",
"legendFormat": "Worlds"
},
{
"refId": "C",
"expr": "darkflame_websocket_clients",
"legendFormat": "Dashboard sockets"
}
]
},
{
"id": 3,
"type": "timeseries",
"title": "Players by zone",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 0,
"y": 4,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "short",
"custom": {
"fillOpacity": 10,
"stacking": {
"mode": "normal"
}
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "sum by (zone_name) (darkflame_zone_players)",
"legendFormat": "{{zone_name}}"
}
]
},
{
"id": 4,
"type": "timeseries",
"title": "Instances by zone",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 12,
"y": 4,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "short",
"custom": {
"fillOpacity": 10,
"stacking": {
"mode": "normal"
}
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "sum by (zone_name) (darkflame_zone_instances)",
"legendFormat": "{{zone_name}}"
}
]
},
{
"id": 5,
"type": "timeseries",
"title": "Memory by server",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 0,
"y": 12,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "bytes",
"custom": {
"fillOpacity": 10,
"stacking": {
"mode": "normal"
}
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "darkflame_server_memory_bytes",
"legendFormat": "{{server}}"
}
]
},
{
"id": 6,
"type": "timeseries",
"title": "Chat messages per minute",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 12,
"y": 12,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "short",
"custom": {
"fillOpacity": 10,
"stacking": {
"mode": "none"
}
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "sum by (channel) (rate(darkflame_chat_messages_total[5m])) * 60",
"legendFormat": "{{channel}}"
},
{
"refId": "B",
"expr": "sum(rate(darkflame_chat_messages_blocked_total[5m])) * 60",
"legendFormat": "blocked"
}
]
},
{
"id": 7,
"type": "bargauge",
"title": "Moderation queues",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 0,
"y": 20,
"w": 12,
"h": 8
},
"options": {
"orientation": "horizontal",
"displayMode": "basic",
"reduceOptions": {
"calcs": [
"lastNotNull"
]
}
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "darkflame_moderation_queue",
"legendFormat": "{{queue}}"
},
{
"refId": "B",
"expr": "darkflame_active_strikes",
"legendFormat": "active strikes"
}
]
},
{
"id": 8,
"type": "timeseries",
"title": "Coins today",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 12,
"y": 20,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "short",
"custom": {
"fillOpacity": 10,
"stacking": {
"mode": "none"
}
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"expr": "sum by (direction) (darkflame_economy_coins_today)",
"legendFormat": "{{direction}}"
}
]
},
{
"id": 9,
"type": "table",
"title": "Scheduled tasks that failed last time",
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"gridPos": {
"x": 0,
"y": 28,
"w": 24,
"h": 6
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"options": {
"showHeader": true
},
"targets": [
{
"refId": "A",
"expr": "darkflame_task_last_run_success == 0",
"format": "table",
"instant": true
}
]
}
]
}

View File

@@ -0,0 +1,16 @@
# Example Prometheus scrape config for the DarkflameServer dashboard's /metrics.
# Switch metrics_enabled on (Settings > Dashboard > Metrics) first. Then either:
# - set metrics_token on the Settings page and put the same value in the file below, or
# - make an API token on the account page of an account with the metrics_view permission and use that.
# The dashboard works the numbers out at most every metrics_cache_seconds (10), so scraping more often gains nothing.
scrape_configs:
- job_name: darkflame
scrape_interval: 30s
metrics_path: /metrics
# https if the dashboard is behind a reverse proxy with TLS
scheme: http
authorization:
type: Bearer
credentials_file: /etc/prometheus/darkflame_metrics_token
static_configs:
- targets: ["127.0.0.1:2006"]