from pydantic import BaseModel, Field class McAccountConfig(BaseModel): account_id: str = "default" enabled: bool = True name: str = "" host: str = Field(default="", description="Minecraft server address") port: int = Field(default=25565, ge=1, le=65535) version: str = Field(default="auto", description="auto | 1.20.4 | 1.21.4") auth_mode: str = Field(default="offline", description="offline | microsoft | mojang") username: str = Field(default="ForcePilotBot", description="Bot player name") microsoft_email: str | None = None microsoft_password: str | None = None rcon_port: int = 25575 rcon_password: str | None = None dm_enabled: bool = False dm_policy: str = Field(default="pairing", description="open | pairing | allowlist | disabled") group_policy: str = Field(default="mention", description="always | mention | disabled") require_mention: bool = True allow_from: list[str] = Field(default_factory=list) text_chunk_limit: int = Field(default=256, ge=100, le=256) reconnect_max_retries: int = Field(default=5, ge=0, le=100) keep_alive_timeout: int = Field(default=30, ge=10, le=120) rate_limit_window: int = Field(default=10, ge=1, le=60) rate_limit_max: int = Field(default=5, ge=1, le=20) @property def is_configured(self) -> bool: return bool(self.host and self.username) class McConfig(BaseModel): host: str = "" port: int = 25565 version: str = "auto" auth_mode: str = "offline" username: str = "ForcePilotBot" dm_policy: str = "pairing" group_policy: str = "mention" require_mention: bool = True allow_from: list[str] = Field(default_factory=list) text_chunk_limit: int = 256 reconnect_max_retries: int = 5 keep_alive_timeout: int = 30 rate_limit_window: int = 10 rate_limit_max: int = 5 accounts: list[McAccountConfig] = Field(default_factory=list) def get_account(self, account_id: str = "default") -> McAccountConfig | None: for acc in self.accounts: if acc.account_id == account_id: return acc return None def build_config_schema() -> dict: return { "type": "object", "properties": { "channels.minecraft.host": { "type": "string", "description": "Minecraft server address", }, "channels.minecraft.port": { "type": "integer", "default": 25565, "description": "Server port", }, "channels.minecraft.version": { "type": "string", "default": "auto", "enum": ["auto", "1.20.4", "1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5"], "description": "Minecraft version (auto-detect by default)", }, "channels.minecraft.auth_mode": { "type": "string", "enum": ["offline", "microsoft", "mojang"], "default": "offline", "description": "Authentication mode", }, "channels.minecraft.username": { "type": "string", "default": "ForcePilotBot", "description": "Bot player name in game", }, "channels.minecraft.group_policy": { "type": "string", "enum": ["always", "mention", "disabled"], "default": "mention", "description": "Group chat access policy", }, "channels.minecraft.require_mention": { "type": "boolean", "default": True, "description": "Require @mention to respond in group chat", }, "channels.minecraft.allow_from": { "type": "array", "items": {"type": "string"}, "description": "Allowlist of player usernames", }, "channels.minecraft.text_chunk_limit": { "type": "integer", "default": 256, "description": "Max characters per Minecraft chat message", }, "channels.minecraft.reconnect_max_retries": { "type": "integer", "default": 5, "description": "Maximum reconnection attempts", }, "channels.minecraft.accounts": { "type": "array", "description": "Named accounts for multiple servers", "items": { "type": "object", "properties": { "account_id": {"type": "string"}, "name": {"type": "string"}, "enabled": {"type": "boolean", "default": True}, "host": {"type": "string", "description": "Minecraft server address"}, "port": {"type": "integer", "default": 25565}, "version": {"type": "string", "default": "auto"}, "auth_mode": { "type": "string", "enum": ["offline", "microsoft", "mojang"], "default": "offline", }, "username": {"type": "string", "default": "ForcePilotBot"}, "dm_policy": { "type": "string", "enum": ["pairing", "allowlist", "open", "disabled"], "default": "pairing", }, "rcon_port": { "type": "integer", "default": 25575, }, "rcon_password": { "type": "string", "format": "password", }, "microsoft_email": { "type": "string", }, "microsoft_password": { "type": "string", "format": "password", }, "reconnect_max_retries": { "type": "integer", "default": 10, "minimum": 0, }, "text_chunk_limit": { "type": "integer", "default": 256, "minimum": 100, "maximum": 256, }, "group_policy": { "type": "string", "enum": ["always", "mention", "disabled"], "default": "mention", }, "require_mention": {"type": "boolean", "default": True}, "allow_from": { "type": "array", "items": {"type": "string"}, }, }, }, }, }, }