Align runtime profiles with plugin-owned records

This commit is contained in:
npc0-hue
2026-09-02 10:22:14 +08:00
parent 6018d8f0fc
commit a027ca70eb
36 changed files with 234 additions and 1590 deletions
@@ -1,40 +0,0 @@
package companion
import (
"testing"
"time"
)
func TestConsoleSemanticEventProducerParsesOnlyBoundedKnownOutput(t *testing.T) {
availability := VerifiedSemanticEventProducer()
if !availability.Available || availability.Reason == "" {
t.Fatalf("console event producer should be available: %+v", availability)
}
batch := ParseConsoleRecords("server-1", []ConsoleRecord{{ServerID: "server-1", Stream: "stdout", Sequence: 1, OccurredAt: time.Now(), Text: "SCUM LOGIN 76561198000000001 10.0.0.1"}, {ServerID: "server-1", Stream: "stderr", Sequence: 2, OccurredAt: time.Now(), Text: "unrecognised output"}}, "fixture-secret")
if len(batch.Events) != 1 || batch.Events[0].Type != "scum.login" || batch.Events[0].NetworkCorrelation == "" || len(batch.Diagnostics) != 1 || batch.Diagnostics[0].Code != "unknown-console-format" {
t.Fatalf("unsafe console parsing result: %+v", batch)
}
if batch.Events[0].NetworkCorrelation == "10.0.0.1" {
t.Fatal("raw network value leaked")
}
if len(batch.Events[0].NetworkCorrelation) != 64 {
t.Fatalf("network correlation must be full sha256 hex, got %q", batch.Events[0].NetworkCorrelation)
}
}
func TestConsoleSemanticEventProducerParsesScumLoginLog(t *testing.T) {
observedAt := time.Date(2026, 8, 27, 12, 0, 0, 0, time.UTC)
batch := ParseConsoleRecords("server-1", []ConsoleRecord{
{ServerID: "server-1", Stream: "stdout", Sequence: 1, OccurredAt: observedAt, Text: "2026.08.27-12.00.00: '10.0.0.2 76561198000000002:Ada(42)' logged in at: X=1 Y=2 Z=3"},
{ServerID: "server-1", Stream: "stdout", Sequence: 2, OccurredAt: observedAt.Add(time.Second), Text: "2026.08.27-12.00.01: '10.0.0.2 76561198000000002:Ada(42)' logged out"},
}, "fixture-secret")
if len(batch.Events) != 2 || batch.Events[0].Type != "scum.login" || batch.Events[1].Type != "scum.logout" {
t.Fatalf("login log events not parsed: %+v", batch)
}
if batch.Events[0].PlayerID != "76561198000000002" || batch.Events[0].DisplayName != "Ada" || len(batch.Events[0].NetworkCorrelation) != 64 {
t.Fatalf("login event fields are incomplete: %+v", batch.Events[0])
}
if batch.Events[0].NetworkCorrelation == "10.0.0.2" {
t.Fatal("raw login log IP leaked")
}
}
@@ -1,30 +0,0 @@
{
"version": 2,
"encoding": "utf-16le",
"lineEnding": "lf",
"continuationPolicy": "append-to-previous-timestamped-record",
"timestampFormat": "yyyy.MM.dd-HH.mm.ss",
"defaultPattern": "^([0-9]{4}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}):?\\s*(.*)$",
"defaultFields": ["occurredAt", "payload"],
"parsers": [
{ "key": "login", "filePattern": "^login_[0-9]{14}\\.log$", "eventType": "scum.login" },
{ "key": "chat", "filePattern": "^chat_[0-9]{14}\\.log$", "eventType": "scum.chat" },
{ "key": "admin", "filePattern": "^admin_[0-9]{14}\\.log$", "eventType": "scum.admin" },
{ "key": "kill", "filePattern": "^kill_[0-9]{14}\\.log$", "eventType": "scum.kill" },
{ "key": "event-kill", "filePattern": "^event_kill_[0-9]{14}\\.log$", "eventType": "scum.event.kill" },
{ "key": "quests", "filePattern": "^quests_[0-9]{14}\\.log$", "eventType": "scum.quest" },
{ "key": "famepoints", "filePattern": "^famepoints_[0-9]{14}\\.log$", "eventType": "scum.famepoints" },
{ "key": "economy", "filePattern": "^economy_[0-9]{14}\\.log$", "eventType": "scum.economy" },
{ "key": "gameplay", "filePattern": "^gameplay_[0-9]{14}\\.log$", "eventType": "scum.gameplay" },
{ "key": "vehicle-destruction", "filePattern": "^vehicle_destruction_[0-9]{14}\\.log$", "eventType": "scum.vehicle.destruction" },
{ "key": "raid-protection", "filePattern": "^raid_protection_[0-9]{14}\\.log$", "eventType": "scum.raid.protection" },
{ "key": "base-building-destruction", "filePattern": "^base_building_destruction_[0-9]{14}\\.log$", "eventType": "scum.base.destruction" },
{ "key": "chest-ownership", "filePattern": "^chest_ownership_[0-9]{14}\\.log$", "eventType": "scum.chest.ownership" },
{ "key": "loot", "filePattern": "^loot_[0-9]{14}\\.log$", "eventType": "scum.loot" },
{ "key": "violations", "filePattern": "^violations_[0-9]{14}\\.log$", "eventType": "scum.violation" },
{ "key": "sentry", "filePattern": "^sentry_[0-9]{14}\\.log$", "eventType": "scum.sentry" },
{ "key": "server-notifications", "filePattern": "^server_notifications_[0-9]{14}\\.log$", "eventType": "scum.server.notification" },
{ "key": "armor-absorption", "filePattern": "^armor_absorption_[0-9]{14}\\.log$", "eventType": "scum.armor.absorption" },
{ "key": "network-objects", "filePattern": "^network_objects_[0-9]{14}\\.log$", "eventType": "scum.network.object" }
]
}
@@ -1 +0,0 @@
{"type":"object","additionalProperties":false,"required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["type","occurredAt"],"properties":{"type":{"type":"string","enum":["scum.login","scum.logout"],"maxLength":16},"occurredAt":{"type":"string","minLength":20,"maxLength":40},"playerId":{"type":"string","minLength":1,"maxLength":96},"displayName":{"type":"string","minLength":1,"maxLength":80},"networkCorrelation":{"type":"string","pattern":"^[a-f0-9]{64}$","maxLength":64}}}}}}
@@ -1,14 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "adminActorId", "actionCategory", "approved"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"adminActorId": { "type": "string", "minLength": 1, "maxLength": 96 },
"actionCategory": { "type": "string", "enum": ["announcement", "teleport", "spawn", "kick", "ban", "unban", "restart", "config-review", "other"] },
"targetPlayerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"reason": { "type": "string", "minLength": 1, "maxLength": 256 },
"approved": { "type": "boolean" }
}
}
@@ -1,13 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "playerName", "channel", "message"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"playerName": { "type": "string", "minLength": 1, "maxLength": 80 },
"channel": { "type": "string", "enum": ["local", "global", "squad", "admin", "unknown"] },
"message": { "type": "string", "minLength": 1, "maxLength": 512 }
}
}
@@ -1,16 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "victimPlayerId", "victimName", "weaponClass", "distanceMeters"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"killerPlayerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"killerName": { "type": "string", "minLength": 1, "maxLength": 80 },
"victimPlayerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"victimName": { "type": "string", "minLength": 1, "maxLength": 80 },
"weaponClass": { "type": "string", "minLength": 1, "maxLength": 80 },
"distanceMeters": { "type": "number", "minimum": 0, "maximum": 5000 },
"suicide": { "type": "boolean" }
}
}
@@ -1,14 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "playerName", "sessionId", "outcome"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"playerName": { "type": "string", "minLength": 1, "maxLength": 80 },
"sessionId": { "type": "string", "minLength": 1, "maxLength": 96 },
"outcome": { "type": "string", "enum": ["accepted", "rejected"] },
"networkFingerprint": { "type": "string", "minLength": 1, "maxLength": 128, "writeOnly": true, "description": "Transient source material for server-local irreversible correlation only; Platform never persists or returns this value." }
}
}
@@ -1,13 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "playerName", "sessionId", "reason"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"playerName": { "type": "string", "minLength": 1, "maxLength": 80 },
"sessionId": { "type": "string", "minLength": 1, "maxLength": 96 },
"reason": { "type": "string", "enum": ["disconnect", "timeout", "kicked", "server-stop", "unknown"] }
}
}
@@ -1,14 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "action", "mineClass", "zone", "suspicious"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"action": { "type": "string", "enum": ["placed", "triggered", "detonated", "disarmed", "removed"] },
"mineClass": { "type": "string", "minLength": 1, "maxLength": 80 },
"zone": { "type": "string", "minLength": 1, "maxLength": 32 },
"suspicious": { "type": "boolean" }
}
}
@@ -1,13 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "serverFps", "frameTimeMs", "onlinePlayers", "entityCount"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"serverFps": { "type": "number", "minimum": 0, "maximum": 1000 },
"frameTimeMs": { "type": "number", "minimum": 0, "maximum": 1000 },
"onlinePlayers": { "type": "integer", "minimum": 0, "maximum": 1000 },
"entityCount": { "type": "integer", "minimum": 0, "maximum": 10000000 }
}
}
@@ -1,20 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "tradeKind", "itemCount", "currencyDelta", "suspicious"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"source": { "type": "string", "enum": ["companion", "log-projection", "scum.trade"] },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"counterpartyPlayerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"itemCode": { "type": "string", "pattern": "^[A-Za-z0-9_.-]{1,128}$", "minLength": 1, "maxLength": 128 },
"tradeVerb": { "type": "string", "enum": ["purchased", "sold"] },
"tradeKind": { "type": "string", "enum": ["purchase", "sale", "transfer", "unknown"] },
"quantity": { "type": "integer", "minimum": 0, "maximum": 1000000000 },
"itemCount": { "type": "integer", "minimum": 0, "maximum": 1000 },
"price": { "type": "integer", "minimum": -1000000000, "maximum": 1000000000 },
"currencyDelta": { "type": "integer", "minimum": -1000000000, "maximum": 1000000000 },
"suspicious": { "type": "boolean" }
}
}
@@ -1,14 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["occurredAt", "playerId", "targetKind", "targetId", "outcome", "suspicious"],
"properties": {
"occurredAt": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40 },
"playerId": { "type": "string", "minLength": 1, "maxLength": 96 },
"targetKind": { "type": "string", "enum": ["door", "container", "vehicle", "base", "unknown"] },
"targetId": { "type": "string", "minLength": 1, "maxLength": 128 },
"outcome": { "type": "string", "enum": ["success", "failed", "cancelled"] },
"suspicious": { "type": "boolean" }
}
}