Files
DoGaMa-serv/specs/template.schema.json
2026-08-06 19:21:08 +02:00

269 lines
11 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://dogama.dev/schemas/template-v1.json",
"title": "DoGaMa game-server template v1",
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "id", "version", "game", "requirements", "container", "storage", "configuration", "capabilities", "backup", "healthcheck", "imports", "updates", "compatibility"],
"properties": {
"schema_version": { "const": 1 },
"id": { "$ref": "#/$defs/id" },
"version": { "$ref": "#/$defs/semver" },
"source": {
"type": "object",
"additionalProperties": false,
"required": ["type"],
"properties": {
"type": { "enum": ["official", "verified_community", "local", "locally_modified", "unverified"] },
"url": { "type": "string", "format": "uri", "pattern": "^https://" }
}
},
"game": {
"type": "object",
"additionalProperties": false,
"required": ["id", "name", "description"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"description": { "type": "string", "minLength": 1, "maxLength": 2000 },
"website": { "type": "string", "format": "uri", "pattern": "^https://" },
"artwork": {
"type": "object",
"additionalProperties": false,
"properties": {
"poster_source_url": { "type": "string", "format": "uri", "pattern": "^https://" },
"logo_source_url": { "type": "string", "format": "uri", "pattern": "^https://" },
"attribution": { "type": "string", "maxLength": 500 }
}
}
}
},
"requirements": {
"type": "object",
"additionalProperties": false,
"required": ["minimum", "recommended"],
"properties": {
"minimum": { "$ref": "#/$defs/resources" },
"recommended": { "$ref": "#/$defs/resources" }
}
},
"container": {
"type": "object",
"additionalProperties": false,
"required": ["image", "tag", "stop_timeout_seconds", "ports"],
"properties": {
"image": { "type": "string", "pattern": "^[a-zA-Z0-9._/-]+$", "maxLength": 300 },
"tag": { "type": "string", "pattern": "^[a-zA-Z0-9._-]+$", "maxLength": 128 },
"entrypoint": { "type": "array", "items": { "type": "string", "maxLength": 500 }, "maxItems": 8 },
"arguments": { "type": "array", "items": { "type": "string", "maxLength": 500 }, "maxItems": 64 },
"assets": {
"type": "array",
"maxItems": 16,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["source", "destination", "sha256", "read_only"],
"properties": {
"source": { "type": "string", "pattern": "^(?!/)(?!.*\\.\\./).+$", "maxLength": 200 },
"destination": { "type": "string", "pattern": "^/[^\\u0000]*$", "maxLength": 500 },
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
"read_only": { "const": true }
}
}
},
"stop_timeout_seconds": { "type": "integer", "minimum": 5, "maximum": 900 },
"ports": {
"type": "array",
"minItems": 1,
"maxItems": 32,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["id", "container_port", "protocol", "purpose", "publish"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"container_port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"protocol": { "enum": ["tcp", "udp"] },
"purpose": { "enum": ["game", "query", "integration", "other"] },
"publish": { "type": "boolean" },
"required": { "type": "boolean", "default": true }
}
}
}
}
},
"storage": {
"type": "object",
"additionalProperties": false,
"required": ["mounts"],
"properties": {
"mounts": {
"type": "array",
"minItems": 1,
"maxItems": 16,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["id", "container_path", "category", "backup", "user_configurable"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"container_path": { "type": "string", "pattern": "^/[^\\u0000]*$", "maxLength": 500 },
"category": { "enum": ["runtime", "configuration", "player_data", "mods", "logs"] },
"backup": { "type": "boolean" },
"user_configurable": { "type": "boolean" },
"read_only": { "type": "boolean", "default": false }
}
}
}
}
},
"configuration": {
"type": "object",
"additionalProperties": false,
"required": ["fields"],
"properties": {
"fields": {
"type": "array",
"maxItems": 256,
"items": { "$ref": "#/$defs/configField" }
}
}
},
"capabilities": {
"type": "array",
"uniqueItems": true,
"items": { "$ref": "#/$defs/capability" }
},
"integration": {
"type": "object",
"additionalProperties": false,
"required": ["module_id", "version_range", "port_id"],
"properties": {
"module_id": { "$ref": "#/$defs/id" },
"version_range": { "type": "string", "minLength": 1, "maxLength": 50 },
"port_id": { "$ref": "#/$defs/id" },
"required": { "type": "boolean", "default": false }
}
},
"backup": {
"type": "object",
"additionalProperties": false,
"required": ["strategy", "source_mounts"],
"properties": {
"strategy": { "enum": ["online_save", "stop_then_archive"] },
"source_mounts": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/id" } },
"restart_after_backup": { "type": "boolean", "default": true }
}
},
"healthcheck": {
"type": "object",
"additionalProperties": false,
"required": ["type", "startup_timeout_seconds"],
"properties": {
"type": { "enum": ["module", "tcp", "udp", "container"] },
"port_id": { "$ref": "#/$defs/id" },
"startup_timeout_seconds": { "type": "integer", "minimum": 10, "maximum": 1800 },
"interval_seconds": { "type": "integer", "minimum": 2, "maximum": 300, "default": 10 }
}
},
"mods": {
"type": "object",
"additionalProperties": false,
"required": ["supported"],
"properties": {
"supported": { "type": "boolean" },
"provider": { "enum": ["steam_workshop", "remote_archive", "local_upload"] },
"destination_mount": { "$ref": "#/$defs/id" },
"restart_required": { "type": "boolean" }
}
},
"imports": {
"type": "object",
"additionalProperties": false,
"required": ["supported", "accepted_formats", "max_extracted_size_gb", "required_paths", "destination_mount"],
"properties": {
"supported": { "type": "boolean" },
"accepted_formats": { "type": "array", "uniqueItems": true, "items": { "enum": ["zip", "tar", "tar.gz", "tar.zst", "directory"] } },
"max_extracted_size_gb": { "type": "integer", "minimum": 1, "maximum": 10000 },
"required_paths": { "type": "array", "items": { "type": "string", "pattern": "^(?!/)(?!.*\\.\\./).+$", "maxLength": 300 } },
"destination_mount": { "$ref": "#/$defs/id" },
"destination_relative_path": { "type": "string", "pattern": "^(?!/)(?!.*\\.\\./).*$", "maxLength": 300 },
"requires_stopped_server": { "type": "boolean", "default": true }
}
},
"updates": {
"type": "object",
"additionalProperties": false,
"required": ["backup_before_update", "automatic_default", "rollback_on_failure"],
"properties": {
"backup_before_update": { "type": "boolean" },
"automatic_default": { "const": false },
"rollback_on_failure": { "type": "boolean" },
"health_timeout_seconds": { "type": "integer", "minimum": 10, "maximum": 1800 }
}
},
"compatibility": {
"type": "object",
"additionalProperties": false,
"required": ["minimum_manager_version", "requires_instance_migration"],
"properties": {
"minimum_manager_version": { "$ref": "#/$defs/semver" },
"requires_instance_migration": { "type": "boolean" }
}
}
},
"$defs": {
"id": { "type": "string", "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*$", "minLength": 1, "maxLength": 100 },
"semver": { "type": "string", "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?$" },
"resources": {
"type": "object",
"additionalProperties": false,
"required": ["cpu_cores", "memory_mb", "storage_gb"],
"properties": {
"cpu_cores": { "type": "number", "exclusiveMinimum": 0, "maximum": 1024 },
"memory_mb": { "type": "integer", "minimum": 128 },
"storage_gb": { "type": "integer", "minimum": 1 }
}
},
"capability": { "enum": ["server_info", "metrics", "player_list", "online_save", "graceful_shutdown", "announcement", "kick", "ban", "unban"] },
"configField": {
"type": "object",
"additionalProperties": false,
"required": ["id", "label", "type", "target", "apply", "visibility", "required"],
"properties": {
"id": { "$ref": "#/$defs/id" },
"label": { "type": "string", "minLength": 1, "maxLength": 150 },
"description": { "type": "string", "maxLength": 1000 },
"type": { "enum": ["string", "integer", "number", "boolean", "secret", "enum"] },
"target": {
"type": "object",
"additionalProperties": false,
"required": ["kind", "name"],
"properties": {
"kind": { "enum": ["environment", "argument", "ini"] },
"name": { "type": "string", "minLength": 1, "maxLength": 200 }
}
},
"apply": { "enum": ["immediate", "restart_required"] },
"visibility": { "enum": ["public", "members", "managers", "admin", "secret"] },
"required": { "type": "boolean" },
"default": {},
"minimum": { "type": "number" },
"maximum": { "type": "number" },
"pattern": { "type": "string", "maxLength": 300 },
"values": {
"type": "array",
"minItems": 1,
"items": {
"anyOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "boolean" }
]
}
}
}
}
}
}