// Common shared types for the SoulFire gRPC API.
// This file contains message types, enums, and settings definitions that are shared
// across multiple services including instance management, authentication, proxy handling,
// user permissions, and UI configuration.
syntax = "proto3";

option java_package = "com.soulfiremc.grpc.generated";
option java_multiple_files = true;

package soulfire.v1;

import "soulfire/api_docs.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/struct.proto";

// A block position in a specific dimension. Coordinates are Minecraft block
// integers, not chunk-relative.
message BlockPosition {
  // Block X coordinate. East is positive.
  int32 x = 1 [(google.api.field_behavior) = REQUIRED];
  // Block Y coordinate. Vertical axis.
  int32 y = 2 [(google.api.field_behavior) = REQUIRED];
  // Block Z coordinate. South is positive.
  int32 z = 3 [(google.api.field_behavior) = REQUIRED];
  // Namespaced dimension id. If empty, APIs use the bot's current dimension.
  string dimension = 4;
}

// A precise world position. Used for entity locations and pathfinding goals
// where sub-block precision matters.
message WorldPosition {
  double x = 1 [(google.api.field_behavior) = REQUIRED];
  double y = 2 [(google.api.field_behavior) = REQUIRED];
  double z = 3 [(google.api.field_behavior) = REQUIRED];
  string dimension = 4;
}

// Represents a network proxy configuration used for routing bot connections.
// Proxies can be used to mask the origin of bot traffic or to distribute connections
// across multiple IP addresses. Used in instance configuration and proxy checking services.
message ProxyProto {
  // The type of proxy protocol to use for the connection.
  enum Type {
    // HTTP/HTTPS proxy using the CONNECT method.
    // Does not support UDP traffic. Suitable for basic HTTP tunneling.
    HTTP = 0;
    // SOCKS4 proxy protocol.
    // Does not support UDP traffic or authentication passwords (username only via IDENT).
    // Note: If a password is provided for SOCKS4, it will be rejected.
    SOCKS4 = 1;
    // SOCKS5 proxy protocol.
    // Supports both TCP and UDP traffic, as well as full username/password authentication.
    // Recommended for most use cases due to its flexibility.
    SOCKS5 = 2;
  }

  // The proxy protocol type. Determines how the connection is established.
  Type type = 1 [(google.api.field_behavior) = REQUIRED];
  // The proxy server address in "host:port" format (e.g., "proxy.example.com:8080").
  // The address must be resolvable and the port must be valid (1-65535).
  string address = 2 [(google.api.field_behavior) = REQUIRED];
  // Optional username for proxy authentication.
  // Required if the proxy server requires authentication.
  // If password is set, username must also be set.
  optional string username = 3;
  // Optional password for proxy authentication.
  // Used with username for SOCKS5 or HTTP proxy authentication.
  // Not supported for SOCKS4 proxies (will cause an error if set).
  optional string password = 4;
}

// Authentication service types that accept direct credentials (email/password or username).
// Used in the MCAuthService.LoginCredentials RPC to specify which authentication
// method should be used for batch account authentication.
enum AccountTypeCredentials {
  // Microsoft Java Edition authentication using email and password.
  // Authenticates against Microsoft's OAuth system to obtain a Minecraft Java profile.
  // Payload format: ["email", "password"] pairs, one pair per account.
  MICROSOFT_JAVA_CREDENTIALS = 0;
  // Microsoft Bedrock Edition authentication using email and password.
  // Authenticates against Microsoft's OAuth system to obtain a Minecraft Bedrock profile.
  // Payload format: ["email", "password"] pairs, one pair per account.
  MICROSOFT_BEDROCK_CREDENTIALS = 1;
  // Offline mode authentication (no Microsoft account required).
  // Creates a local-only account with a generated UUID based on the username.
  // Payload format: ["username"] for each account.
  // Note: Offline accounts cannot join online-mode servers.
  OFFLINE = 4;
  // Microsoft Java Edition authentication using an existing refresh token.
  // Useful for re-authenticating accounts without requiring credentials again.
  // Payload format: ["refresh_token"] for each account.
  MICROSOFT_JAVA_REFRESH_TOKEN = 5;
  // Microsoft Java Edition authentication using browser cookies from login.live.com.
  // Exchanges cookies for a refresh token, then authenticates normally.
  // Payload format: cookie string (Netscape jar, Cookie Editor JSON, or raw header).
  MICROSOFT_JAVA_COOKIES = 6;
  // Microsoft Java Edition authentication using a raw Minecraft access token.
  // The token is validated by fetching the profile from Mojang's API.
  // Cannot be refreshed; used until expiry.
  // Payload format: raw JWT access token string.
  MICROSOFT_JAVA_ACCESS_TOKEN = 7;
  // TheAltening Java Edition authentication using a generated account token.
  // Authenticates against TheAltening's Yggdrasil-compatible auth server.
  // Payload format: raw TheAltening account token string.
  THE_ALTENING = 8;
}

// Authentication service types that use the OAuth 2.0 Device Code flow.
// Used in the MCAuthService.LoginDeviceCode RPC for interactive authentication
// where the user must visit a URL and enter a code on another device.
enum AccountTypeDeviceCode {
  // Microsoft Java Edition authentication via device code flow.
  // Returns a device code that the user enters at microsoft.com/link.
  // Produces an OnlineChainJavaData authentication chain upon success.
  MICROSOFT_JAVA_DEVICE_CODE = 0;
  // Microsoft Bedrock Edition authentication via device code flow.
  // Returns a device code that the user enters at microsoft.com/link.
  // Produces a BedrockData authentication chain upon success.
  MICROSOFT_BEDROCK_DEVICE_CODE = 1;
}

// Represents an authenticated Minecraft account that can be used by bots.
// This can be a Microsoft account (Java or Bedrock), TheAltening Java account,
// raw Java access-token account, or offline account.
// The account contains authentication data, profile information, and per-account settings.
// Used throughout the system for instance configuration and bot management.
message MinecraftAccountProto {
  // The type of authentication that was used to create this account.
  // Determines which account_data oneof field is populated and how the account
  // can be refreshed or re-authenticated.
  enum AccountTypeProto {
    // Authenticated via Microsoft Java credentials (email/password).
    // Account data stored in OnlineChainJavaData.
    MICROSOFT_JAVA_CREDENTIALS = 0;
    // Authenticated via Microsoft Bedrock credentials (email/password).
    // Account data stored in BedrockData.
    MICROSOFT_BEDROCK_CREDENTIALS = 1;
    // Offline mode account (no Microsoft authentication).
    // Account data stored in OfflineJavaData.
    // UUID is derived from username, cannot join online-mode servers.
    OFFLINE = 4;
    // Authenticated via Microsoft Java device code flow.
    // Account data stored in OnlineChainJavaData.
    MICROSOFT_JAVA_DEVICE_CODE = 5;
    // Authenticated via Microsoft Bedrock device code flow.
    // Account data stored in BedrockData.
    MICROSOFT_BEDROCK_DEVICE_CODE = 6;
    // Authenticated via Microsoft Java refresh token.
    // Account data stored in OnlineChainJavaData.
    MICROSOFT_JAVA_REFRESH_TOKEN = 7;
    // Authenticated via Microsoft Java browser cookies.
    // Account data stored in OnlineChainJavaData.
    MICROSOFT_JAVA_COOKIES = 8;
    // Authenticated via raw Minecraft Java access token.
    // Account data stored in OnlineSimpleJavaData.
    MICROSOFT_JAVA_ACCESS_TOKEN = 9;
    // Authenticated via TheAltening account token.
    // Account data stored in TheAlteningJavaData.
    THE_ALTENING = 10;
  }

  // Authentication chain data for online Java Edition accounts.
  // Contains OAuth tokens, Minecraft profile data, and Xbox Live authentication details.
  // Used for Microsoft-authenticated Java accounts to maintain session state.
  message OnlineChainJavaData {
    // JSON structure containing the complete authentication chain from minecraftauth library.
    // Includes Microsoft OAuth tokens, Xbox Live tokens, and Minecraft access tokens.
    // This data can be refreshed to obtain new tokens without re-authentication.
    google.protobuf.Struct auth_chain = 3 [(google.api.field_behavior) = REQUIRED];
  }

  // Account data for offline mode Java accounts.
  // Contains no authentication data since offline accounts don't require Microsoft auth.
  // The profile UUID is derived deterministically from the username.
  message OfflineJavaData {
    // Empty message - offline accounts have no persistent auth data.
    // UUID is calculated as: UUID.nameUUIDFromBytes("OfflinePlayer:<username>")
  }

  // Account data for Java Edition accounts authenticated with a raw access token.
  // Contains only the token and its expiry, without a full authentication chain.
  // Cannot be refreshed; used until the token expires.
  message OnlineSimpleJavaData {
    // The raw Minecraft access token (JWT).
    string access_token = 1 [(google.api.field_behavior) = REQUIRED];
    // Token expiry time in milliseconds since epoch.
    int64 expire_time_ms = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // Account data for Java Edition accounts authenticated through TheAltening.
  // Stores the imported account token and the current Yggdrasil access token.
  message TheAlteningJavaData {
    // The raw TheAltening account token used to authenticate and refresh this account.
    string account_token = 1 [(google.api.field_behavior) = REQUIRED];
    // The current Yggdrasil access token returned by TheAltening.
    string access_token = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // Authentication chain data for Bedrock Edition accounts.
  // Contains Xbox Live and Bedrock-specific authentication details.
  // Used for Microsoft-authenticated Bedrock accounts.
  message BedrockData {
    // JSON structure containing the complete Bedrock authentication chain.
    // Includes Xbox Live tokens and Bedrock-specific session data.
    // Compatible with the ViaBedrock protocol implementation.
    google.protobuf.Struct auth_chain = 7 [(google.api.field_behavior) = REQUIRED];
  }

  // The authentication type used for this account.
  // Determines which account_data field is populated.
  AccountTypeProto type = 1 [(google.api.field_behavior) = REQUIRED];
  // The unique profile identifier (UUID) for this account.
  // For online accounts: The profile UUID returned by the authentication provider.
  // For offline accounts: A deterministic UUID derived from the username.
  // Format: Standard UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000").
  string profile_id = 2 [(google.api.field_behavior) = REQUIRED, (soulfire.v1.api_field).format = "uuid"];
  // The last known username/gamertag for this account.
  // Updated during authentication and refresh operations.
  // For Java: The Minecraft username (up to 16 characters).
  // For Bedrock: The Xbox gamertag.
  string last_known_name = 3 [(google.api.field_behavior) = REQUIRED];
  // The platform-specific authentication data.
  // Exactly one of these fields will be set based on the account type.
  oneof account_data {
    // Authentication chain for online Java accounts (Microsoft-authenticated).
    OnlineChainJavaData online_chain_java_data = 5;
    // Data for offline Java accounts (no authentication required).
    OfflineJavaData offline_java_data = 6;
    // Authentication chain for Bedrock accounts (Microsoft-authenticated).
    BedrockData bedrock_data = 7;
    // Data for Java accounts authenticated with a raw access token.
    OnlineSimpleJavaData online_simple_java_data = 10;
    // Data for Java accounts authenticated through TheAltening.
    TheAlteningJavaData the_altening_java_data = 11;
  }
  // Per-bot configuration settings stored with the account.
  // Organized as namespace -> key -> value mappings.
  // These settings override instance-level settings when the bot is running.
  // Typically includes bot-specific behavior settings.
  repeated SettingsNamespace config = 8 [(google.api.field_behavior) = UNORDERED_LIST];
  // Persistent metadata stored with the account across sessions.
  // Organized as namespace -> key -> value mappings.
  // Used by plugins and the system to store account-specific state
  // that should persist across bot restarts (e.g., last position, inventory cache).
  repeated SettingsNamespace persistent_metadata = 9 [(google.api.field_behavior) = UNORDERED_LIST];
}

// A collection of settings entries grouped under a common namespace.
// Used to organize configuration values hierarchically, where each namespace
// represents a logical grouping (e.g., plugin name, feature area).
// Part of the instance configuration, server configuration, and account settings.
message SettingsNamespace {
  // A single key-value setting entry within a namespace.
  message SettingsEntry {
    // The unique key identifying this setting within its namespace.
    // Should be a valid identifier (alphanumeric with underscores/dashes).
    string key = 1 [(google.api.field_behavior) = REQUIRED];
    // The value of this setting as a protobuf Value.
    // Can be a string, number, boolean, list, or nested object.
    // The expected type depends on the setting definition (see SettingsDefinition).
    google.protobuf.Value value = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // The namespace identifier that groups related settings together.
  // Typically matches a plugin ID or internal system component name.
  // Examples: "bot", "account", "auto-reconnect", "anti-afk".
  string namespace = 1 [(google.api.field_behavior) = REQUIRED];
  // The list of setting entries within this namespace.
  // Each entry has a unique key within the namespace.
  repeated SettingsEntry entries = 2 [(google.api.field_behavior) = UNORDERED_LIST];
}

// Uniquely identifies a single setting entry by its namespace and key.
// Used to reference settings in page definitions and for granular updates.
// The combination of namespace + key must be unique within a configuration scope.
message SettingsEntryIdentifier {
  // The namespace containing this setting.
  // Must match a namespace from a registered SettingsNamespace.
  string namespace = 1 [(google.api.field_behavior) = REQUIRED];
  // The key of the setting within its namespace.
  // Must match a key from a SettingsEntry in the corresponding namespace.
  string key = 2 [(google.api.field_behavior) = REQUIRED];
}

// Server-wide permissions that apply globally across all instances.
// These permissions control access to server administration, user management,
// and self-service operations. Checked via the PermissionContext.global() method.
// ADMIN role users have all global permissions by default.
enum GlobalPermission {
  // Permission to create new SoulFire instances.
  // Required by InstanceService.CreateInstance RPC.
  CREATE_INSTANCE = 0;
  // Permission to subscribe to server-wide log streams.
  // Allows receiving logs from all instances and system components.
  GLOBAL_SUBSCRIBE_LOGS = 1;
  // Permission to read the authenticated user's own client data.
  // Required by ClientService.GetClientData RPC.
  // Returns user profile, permissions, and server information.
  READ_CLIENT_DATA = 2;
  // Permission to read the server configuration.
  // Required by ServerService.GetServerInfo RPC.
  READ_SERVER_CONFIG = 3;
  // Permission to modify the server configuration.
  // Required by ServerService.UpdateServerConfig and UpdateServerConfigEntry RPCs.
  UPDATE_SERVER_CONFIG = 4;
  // Permission to create new user accounts.
  // Required by UserService.CreateUser RPC.
  CREATE_USER = 5;
  // Permission to read information about other users.
  // Required by UserService.ListUsers and GetUserInfo RPCs.
  READ_USER = 6;
  // Permission to modify other users' accounts.
  // Required by UserService.UpdateUser RPC.
  UPDATE_USER = 7;
  // Permission to delete user accounts.
  // Required by UserService.DeleteUser RPC.
  DELETE_USER = 8;
  // Permission to execute commands at the global/server level.
  // Required by CommandService for server-wide command execution.
  GLOBAL_COMMAND_EXECUTION = 9;
  // Permission to invalidate sessions for other users.
  // Required by UserService.InvalidateSessions RPC.
  // Forces other users to re-authenticate.
  INVALIDATE_SESSIONS = 11;
  // Permission to generate a WebDAV authentication token for oneself.
  // Required by ClientService.GenerateWebDAVToken RPC.
  // WebDAV tokens provide file system access to instance data.
  GENERATE_SELF_WEBDAV_TOKEN = 12;
  // Permission to generate an API token for oneself.
  // Required by ClientService.GenerateAPIToken RPC.
  // API tokens can be used for programmatic access.
  GENERATE_SELF_API_TOKEN = 15;
  // Permission to update one's own username.
  // Required by ClientService.UpdateSelfUsername RPC.
  UPDATE_SELF_USERNAME = 13;
  // Permission to update one's own email address.
  // Required by ClientService.UpdateSelfEmail RPC.
  UPDATE_SELF_EMAIL = 14;
  // Permission to generate API tokens for other users.
  // Required by UserService.GenerateUserAPIToken RPC.
  GENERATE_API_TOKEN = 16;
  // Permission to invalidate one's own sessions.
  // Required by ClientService.InvalidateSelfSessions RPC.
  // Logs the user out of all devices.
  INVALIDATE_SELF_SESSIONS = 17;
  // Reserved for removed global script permissions (18-22)
  reserved 18, 19, 20, 21, 22;
}

// Permissions that apply to a specific instance.
// These permissions are scoped to individual instances and control what operations
// a user can perform on that instance. Checked via PermissionContext.instance() method.
// Permission grants are stored per-user per-instance in the database.
enum InstancePermission {
  // Permission to execute commands within this instance.
  // Required by CommandService for instance-level command execution.
  INSTANCE_COMMAND_EXECUTION = 0;
  // Permission to read instance information and configuration.
  // Required by InstanceService.GetInstanceInfo RPC.
  // Also required to see the instance in InstanceService.ListInstances.
  READ_INSTANCE = 2;
  // Permission to update instance metadata (friendly name, icon).
  // Required by InstanceService.UpdateInstanceMeta RPC.
  UPDATE_INSTANCE_META = 3;
  // Permission to update instance configuration (settings, accounts, proxies).
  // Required by InstanceService.UpdateInstanceConfig, UpdateInstanceConfigEntry,
  // and all account/proxy add/remove/update RPCs.
  UPDATE_INSTANCE_CONFIG = 14;
  // Permission to delete this instance entirely.
  // Required by InstanceService.DeleteInstance RPC.
  // This is a destructive operation that cannot be undone.
  DELETE_INSTANCE = 4;
  // Permission to authenticate Minecraft accounts for this instance.
  // Required by MCAuthService RPCs (LoginCredentials, LoginDeviceCode, Refresh).
  // Allows adding new accounts or refreshing existing account tokens.
  AUTHENTICATE_MC_ACCOUNT = 6;
  // Permission to check proxy connectivity and latency for this instance.
  // Required by ProxyCheckService.Check RPC.
  CHECK_PROXY = 7;
  // Permission to download files from URLs through the server.
  // Required by DownloadService.Download RPC.
  // Used for fetching remote resources through instance proxies.
  DOWNLOAD_URL = 8;
  // Permission to access WebDAV object storage for this instance.
  // Required to read/write files in the instance's storage area via WebDAV.
  ACCESS_OBJECT_STORAGE = 9;
  // Permission to subscribe to log streams for this instance.
  // Required by LogService for instance-specific log streaming.
  INSTANCE_SUBSCRIBE_LOGS = 13;
  // Permission to read the audit log for this instance.
  // Required by InstanceService.GetAuditLog RPC.
  // Shows command executions and state changes with user attribution.
  READ_INSTANCE_AUDIT_LOGS = 15;
  // Permission to read information about individual bots in this instance.
  // Required by BotService RPCs for reading bot state and live data.
  // Also required by InstanceService.GetAccountMetadata RPC.
  READ_BOT_INFO = 10;
  // Permission to update configuration for individual bots.
  // Required by BotService RPCs for modifying bot settings.
  // Also required for SetAccountMetadataEntry and DeleteAccountMetadataEntry.
  UPDATE_BOT_CONFIG = 11;
  // Reserved for removed script permissions (16-20)
  reserved 16, 17, 18, 19, 20;
  // Permission to change which bots should be connected.
  // Required by BotService.SetBotsDesiredState and RestartBots.
  CONTROL_BOTS = 21;
  // Permission to activate, deactivate, and dry-run scripts.
  EXECUTE_SCRIPTS = 22;
  // Permission to control a connected bot in the Minecraft world.
  // Required for chat, movement, inventory, interaction, and pathfinding RPCs.
  // This is deliberately separate from UPDATE_BOT_CONFIG so operators can
  // script bots without changing persistent settings.
  CONTROL_BOT_ACTIONS = 23;
  // Permission to inject version-dependent raw Minecraft protocol packets.
  // This is intentionally admin-only by default.
  RAW_PROTOCOL = 24;
}

// The role assigned to a user account, determining their base permission level.
// Roles provide a coarse-grained permission model that is supplemented by
// specific permission grants at the global and instance levels.
enum UserRole {
  // Administrator role with full access to all features.
  // ADMIN users implicitly have all GlobalPermission and InstancePermission values granted.
  // Only ADMIN users can manage other users and server configuration by default.
  ADMIN = 0;
  // Standard user role with limited default permissions.
  // USER role accounts require explicit permission grants for most operations.
  // Default permissions for USER role are controlled by server configuration.
  USER = 1;
}

// UI definition for a string/text setting.
// Used to render text input fields in the client UI with appropriate validation
// and visual styling based on the input type.
message StringSetting {
  // The type of text input to render in the UI.
  // Maps to HTML input types for appropriate keyboard and validation behavior.
  enum InputType {
    // Standard single-line text input.
    TEXT = 0;
    // Password input with masked characters.
    // Value is hidden in the UI for security.
    PASSWORD = 1;
    // Email address input with email validation.
    EMAIL = 2;
    // Search input, typically with a search icon and clear button.
    SEARCH = 3;
    // Telephone number input with numeric keyboard on mobile.
    TEL = 4;
    // URL input with URL validation.
    URL = 5;
    // Multi-line text area for longer text content.
    TEXTAREA = 6;
  }

  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  // Typically shown as a tooltip or help text.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The default value used when no value is configured.
  string def = 3 [(google.api.field_behavior) = REQUIRED];
  // The type of input field to render (affects keyboard, validation, and display).
  InputType input_type = 10 [(google.api.field_behavior) = REQUIRED];
  // Placeholder text shown when the input is empty.
  // Provides a hint about expected format or content.
  string placeholder = 6 [(google.api.field_behavior) = REQUIRED];
  // Minimum required string length (0 means no minimum).
  int32 min_length = 7 [(google.api.field_behavior) = REQUIRED];
  // Maximum allowed string length (0 means no maximum).
  int32 max_length = 8 [(google.api.field_behavior) = REQUIRED];
  // Regular expression pattern for value validation.
  // Empty string means no pattern validation.
  string pattern = 9 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  // Disabled settings display their value but cannot be modified.
  bool disabled = 11 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for an integer number setting.
// Used to render numeric input fields with validation constraints.
// Supports range limits, step increments, and locale-aware formatting.
message IntSetting {
  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The default value used when no value is configured.
  int32 def = 3 [(google.api.field_behavior) = REQUIRED];
  // The minimum allowed value (inclusive).
  int32 min = 4 [(google.api.field_behavior) = REQUIRED];
  // The maximum allowed value (inclusive).
  int32 max = 5 [(google.api.field_behavior) = REQUIRED];
  // The step increment for value adjustments (e.g., for spinbox controls).
  // A value of 0 means any integer is valid within the min/max range.
  int32 step = 6 [(google.api.field_behavior) = REQUIRED];
  // Placeholder text shown when the input is empty.
  string placeholder = 7 [(google.api.field_behavior) = REQUIRED];
  // Whether to display the number with thousand separators (e.g., 1,000,000).
  // Improves readability for large numbers.
  bool thousand_separator = 8 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 9 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for a floating-point number setting.
// Used to render decimal number input fields with precision control.
// Supports range limits, step increments, and decimal formatting options.
message DoubleSetting {
  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The default value used when no value is configured.
  double def = 3 [(google.api.field_behavior) = REQUIRED];
  // The minimum allowed value (inclusive).
  double min = 4 [(google.api.field_behavior) = REQUIRED];
  // The maximum allowed value (inclusive).
  double max = 5 [(google.api.field_behavior) = REQUIRED];
  // The step increment for value adjustments.
  // A value of 0 means any decimal is valid within the min/max range.
  double step = 6 [(google.api.field_behavior) = REQUIRED];
  // Placeholder text shown when the input is empty.
  string placeholder = 7 [(google.api.field_behavior) = REQUIRED];
  // Whether to display the integer part with thousand separators.
  bool thousand_separator = 8 [(google.api.field_behavior) = REQUIRED];
  // The number of decimal places to display/allow.
  // Used for formatting and input validation.
  int32 decimal_scale = 9 [(google.api.field_behavior) = REQUIRED];
  // Whether to always show the exact number of decimal places specified by decimal_scale.
  // If true, trailing zeros are preserved (e.g., 1.50 instead of 1.5).
  bool fixed_decimal_scale = 10 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 11 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for a boolean toggle setting.
// Used to render checkbox or toggle switch controls in the UI.
// Commonly used for enabling/disabling features.
message BoolSetting {
  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The default value used when no value is configured.
  bool def = 3 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 4 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for a dropdown/select setting with predefined options.
// Used to render combo boxes or dropdown menus where users select from a fixed list.
// Each option has an ID (stored value) and a display name (shown to user).
message ComboSetting {
  // A single selectable option in the combo box.
  message Option {
    // The internal identifier for this option.
    // This value is stored in the configuration when selected.
    // Typically a machine-readable string (e.g., enum name, UUID).
    string id = 1 [(google.api.field_behavior) = REQUIRED];
    // The human-readable name displayed to the user.
    // Can include spaces and special characters for readability.
    string display_name = 2 [(google.api.field_behavior) = REQUIRED];
    // Optional icon identifier to display next to the option.
    // Uses lucide.dev icon IDs (e.g., "user", "settings", "shield").
    optional string icon_id = 3;
    // Additional keywords for filtering/searching options.
    // Allows finding this option by typing related terms.
    repeated string keywords = 4;
  }

  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The list of available options to choose from.
  // The order determines display order in the dropdown.
  repeated Option options = 3;
  // The default option ID used when no value is configured.
  // Must match one of the option IDs in the options list.
  string def = 4 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 5 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for a list of strings setting.
// Used to render a multi-value input where users can add/remove string items.
// Commonly used for lists of allowed values, server addresses, or tags.
message StringListSetting {
  // The display name shown in the UI label for this setting.
  string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
  // A longer description explaining what this setting does.
  string description = 2 [(google.api.field_behavior) = REQUIRED];
  // The default list of values used when no value is configured.
  // Can be empty for an initially empty list.
  repeated string def = 3;
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 4 [(google.api.field_behavior) = REQUIRED];
}

// UI definition for a min/max range setting with two integer values.
// Used to render paired input fields for specifying a numeric range.
// Commonly used for delay ranges, count ranges, or any min/max pair.
// Values are stored as a JSON object with "min" and "max" properties.
message MinMaxSetting {
  // Configuration for a single entry in the min/max pair.
  message Entry {
    // The display name for this entry (e.g., "Minimum Delay").
    string ui_name = 1 [(google.api.field_behavior) = REQUIRED];
    // A description explaining what this entry represents.
    string description = 2 [(google.api.field_behavior) = REQUIRED];
    // The default value for this entry.
    int32 def = 3 [(google.api.field_behavior) = REQUIRED];
    // Placeholder text shown when the input is empty.
    string placeholder = 4 [(google.api.field_behavior) = REQUIRED];
  }

  // The minimum allowed value for both entries (inclusive).
  // Both min and max entries must be >= this value.
  int32 min = 1 [(google.api.field_behavior) = REQUIRED];
  // The maximum allowed value for both entries (inclusive).
  // Both min and max entries must be <= this value.
  int32 max = 2 [(google.api.field_behavior) = REQUIRED];
  // The step increment for value adjustments.
  int32 step = 3 [(google.api.field_behavior) = REQUIRED];
  // Whether to display numbers with thousand separators.
  bool thousand_separator = 4 [(google.api.field_behavior) = REQUIRED];
  // Configuration for the minimum value input field.
  // The actual value must be <= maxEntry value.
  Entry minEntry = 5 [(google.api.field_behavior) = REQUIRED];
  // Configuration for the maximum value input field.
  // The actual value must be >= minEntry value.
  Entry maxEntry = 6 [(google.api.field_behavior) = REQUIRED];
  // Whether this setting is disabled (read-only) in the UI.
  bool disabled = 7 [(google.api.field_behavior) = REQUIRED];
}

// The scope/level at which a setting applies.
// Determines where the setting value is stored and when it takes effect.
// Used in SettingsDefinition to indicate the setting's configuration scope.
enum SettingsPageEntryScopeType {
  // Server-level setting that applies globally to the entire SoulFire server.
  // Stored in the server configuration (ServerConfig).
  // Affects all instances and users on the server.
  SERVER = 0;
  // Instance-level setting that applies to a specific instance.
  // Stored in the instance configuration (InstanceConfig.settings).
  // Affects all bots within that instance.
  INSTANCE = 1;
  // Bot-level setting that applies to individual bot accounts.
  // Stored per-account in MinecraftAccountProto.config.
  // Overrides instance settings for that specific bot.
  BOT = 2;
}

// A complete setting definition that describes a single configurable value.
// Contains all information needed for a client to render the setting UI,
// validate input, and store/retrieve values by identifier.
// Definitions are exported from the server and referenced by SettingsPage.
message SettingsDefinition {
  // Unique identifier for this setting (namespace + key).
  // Used to reference this setting from pages and to store/retrieve values.
  SettingsEntryIdentifier id = 1 [(google.api.field_behavior) = REQUIRED];
  // The configuration scope where this setting applies (SERVER, INSTANCE, BOT).
  // Determines where values are stored and how they cascade.
  SettingsPageEntryScopeType scope = 2 [(google.api.field_behavior) = REQUIRED];
  // The setting type and its UI configuration.
  // Exactly one of these fields will be set based on the setting's data type.
  oneof type {
    // String/text setting with optional validation.
    StringSetting string = 3;
    // Integer number setting with range constraints.
    IntSetting int = 4;
    // Floating-point number setting with precision control.
    DoubleSetting double = 5;
    // Boolean toggle setting.
    BoolSetting bool = 6;
    // Dropdown/select setting with predefined options.
    ComboSetting combo = 7;
    // List of strings setting for multi-value input.
    StringListSetting string_list = 8;
    // Min/max range setting with two paired integer values.
    MinMaxSetting min_max = 9;
  }
}

// A settings page that groups related settings together for UI navigation.
// Pages provide a logical organization of settings with visual elements like
// icons and names. Each page references settings by their identifiers rather
// than embedding the definitions, allowing settings to be shared across pages.
message SettingsPage {
  // Unique page identifier, URL-safe for navigation.
  // Examples: "bot", "account", "auto-reconnect", "anti-afk".
  // Should be lowercase with hyphens for word separation.
  string id = 1 [(google.api.field_behavior) = REQUIRED];
  // The ID of the plugin that owns this page (optional).
  // Null/empty for internal SoulFire pages.
  // Used to group pages by plugin in the UI navigation.
  optional string owning_plugin_id = 2;
  // The human-readable display name shown in the UI navigation.
  // Examples: "Bot Settings", "Account", "Auto Reconnect".
  string page_name = 3 [(google.api.field_behavior) = REQUIRED];
  // Ordered list of setting identifiers to display on this page.
  // Settings are rendered in the order they appear in this list.
  // Each identifier must correspond to a valid SettingsDefinition.
  repeated SettingsEntryIdentifier entries = 5;
  // Icon identifier for visual representation of this page.
  // Uses lucide.dev icon IDs (e.g., "bot", "user", "refresh-cw").
  // Rendered next to the page name in navigation menus.
  string icon_id = 6 [(google.api.field_behavior) = REQUIRED];
  // Optional identifier for a boolean setting that controls whether
  // this page/feature is enabled. Used primarily for plugin pages.
  // When set, the page may show an enable/disable toggle.
  optional SettingsEntryIdentifier enabled_identifier = 7;
}

// Metadata about a registered server plugin.
// Plugins extend SoulFire functionality by adding new settings, commands,
// and bot behaviors. This information is displayed in the client UI.
// Returned as part of InstanceInfo and ServerInfoResponse.
message ServerPlugin {
  // The unique plugin identifier.
  // Should be a lowercase, hyphenated string (e.g., "auto-reconnect", "chat-control").
  // Used to reference the plugin in owning_plugin_id fields.
  string id = 1 [(google.api.field_behavior) = REQUIRED];
  // The semantic version of the plugin (e.g., "1.0.0", "2.1.3-beta").
  // Follows semver conventions for compatibility tracking.
  string version = 2 [(google.api.field_behavior) = REQUIRED];
  // A brief description of what the plugin does.
  // Shown in plugin lists and information panels.
  string description = 3 [(google.api.field_behavior) = REQUIRED];
  // The author or organization that created the plugin.
  // Typically a name or organization identifier.
  string author = 4 [(google.api.field_behavior) = REQUIRED];
  // The software license under which the plugin is distributed.
  // Examples: "MIT", "Apache-2.0", "GPL-3.0".
  string license = 5 [(google.api.field_behavior) = REQUIRED];
  // URL to the plugin's website, documentation, or repository.
  // Allows users to find more information or report issues.
  string website = 6 [(google.api.field_behavior) = REQUIRED, (soulfire.v1.api_field).format = "uri"];
}
