rust-mc-status 2.0.0

High-performance asynchronous Rust library for querying Minecraft server status (Java & Bedrock)
Documentation
# Rust библиотека для проверки статуса серверов Minecraft

[![Crates.io](https://img.shields.io/crates/v/rust-mc-status)](https://crates.io/crates/rust-mc-status)
[![Documentation](https://docs.rs/rust-mc-status/badge.svg)](https://docs.rs/rust-mc-status)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Высокопроизводительная асинхронная Rust библиотека для проверки статуса серверов Minecraft Java Edition и Bedrock Edition.

## Возможности

*   **Поддержка двух протоколов**: Пинг серверов Minecraft Java Edition (`25565`) и Bedrock Edition (`19132`)
*   **Асинхронность**: Построена на Tokio для неблокирующих операций и высокой параллельности
*   **Массовые запросы**: Параллельная проверка множества серверов с настраиваемыми лимитами параллельности
*   **Кэширование DNS**: Автоматическое кэширование DNS запросов и SRV записей для уменьшения задержек
*   **Поддержка SRV записей**: Автоматическое разрешение SRV записей для Java серверов (имитирует поведение клиента Minecraft)
*   **Структурированные данные**: Возвращает богатые структурированные, сериализуемые данные (с использованием `serde`), включая информацию о версии, количество игроков, MOTD, карту, режим игры, плагины, моды и многое другое
*   **Работа с иконками**: Удобное получение и сохранение иконки сервера (только Java Edition)
*   **Надежная обработка ошибок**: Полноценные типы ошибок с использованием `thiserror`
*   **Расширенная информация**: Подробные данные о плагинах, модах, DNS и другом
*   **Высокая производительность**: Оптимизирована с пулом соединений, кэшированием DNS и эффективным использованием памяти

## Установка

Добавьте в ваш `Cargo.toml`:

```toml
[dependencies]
rust-mc-status = "2.0.0"
tokio = { version = "*", features = ["full"] }
```

## Быстрый старт

### Базовое использование

```rust
use rust_mc_status::{McClient, ServerEdition};
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = McClient::new()
        .with_timeout(Duration::from_secs(5))
        .with_max_parallel(10);

    // Пинг Java сервера (автоматически использует SRV lookup, если порт не указан)
    let status = client.ping("mc.hypixel.net", ServerEdition::Java).await?;
    println!("Сервер онлайн: {}", status.online);
    println!("Задержка: {:.2} мс", status.latency);
    
    if let Some((online, max)) = status.players() {
        println!("Игроки: {}/{}", online, max);
    }

    Ok(())
}
```

### Массовые запросы

```rust
use rust_mc_status::{McClient, ServerEdition, ServerInfo};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = McClient::new();
    let servers = vec![
        ServerInfo {
            address: "mc.hypixel.net".to_string(),
            edition: ServerEdition::Java,
        },
        ServerInfo {
            address: "geo.hivebedrock.network:19132".to_string(),
            edition: ServerEdition::Bedrock,
        },
    ];

    let results = client.ping_many(&servers).await;
    for (server, result) in results {
        match result {
            Ok(status) => println!("{}: Онлайн ({}мс)", server.address, status.latency),
            Err(e) => println!("{}: Ошибка - {}", server.address, e),
        }
    }
    
    Ok(())
}
```

## Поддержка SRV записей

При пинге Java серверов без явного указания порта библиотека автоматически выполняет SRV DNS запрос для `_minecraft._tcp.{hostname}`. Это имитирует поведение официального клиента Minecraft.

### Как это работает

1. **Без явного порта** (например, `"mc.hypixel.net"`):
   - Запрашивает SRV записи для `_minecraft._tcp.mc.hypixel.net`
   - Если найдено, использует целевой хост и порт из SRV записи
   - Если не найдено, использует порт по умолчанию (25565)
   - Результаты кэшируются на 5 минут

2. **С явным портом** (например, `"mc.hypixel.net:25565"`):
   - Полностью пропускает SRV lookup
   - Использует указанный хост и порт напрямую

### Пример

```rust
use rust_mc_status::{McClient, ServerEdition};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = McClient::new();

    // Это выполнит SRV lookup для _minecraft._tcp.example.com
    let status = client.ping("example.com", ServerEdition::Java).await?;

    // Это пропустит SRV lookup и использует порт 25565 напрямую
    let status = client.ping("example.com:25565", ServerEdition::Java).await?;

    Ok(())
}
```

## Примеры

Библиотека включает несколько примеров программ:

*   **`basic_usage.rs`** - Базовые запросы статуса серверов и обработка ошибок
*   **`advanced_usage.rs`** - Продвинутые возможности, включая массовые запросы, плагины, моды и иконки
*   **`srv_lookup_example.rs`** - Подробная демонстрация работы с SRV записями
*   **`performance_test.rs`** - Тестирование производительности и скорости
*   **`cache_management.rs`** - Управление кешем и статистика

Запуск примеров:

```bash
cargo run --example basic_usage
cargo run --example advanced_usage
cargo run --example srv_lookup_example
cargo run --example performance_test --release  # Используйте --release для точных измерений производительности
cargo run --example cache_management
```

## Документация API

### McClient

Основной клиент для выполнения запросов статуса серверов.

```rust
let client = McClient::new()
    .with_timeout(Duration::from_secs(5))      // Установить таймаут запроса
    .with_max_parallel(10);                     // Установить максимум параллельных запросов
```

**Методы:**
*   `new()` - Создать новый клиент с настройками по умолчанию
*   `with_timeout(timeout)` - Установить таймаут запроса
*   `with_max_parallel(max)` - Установить максимальное количество параллельных запросов
*   `timeout()` - Получить текущий таймаут запроса
*   `max_parallel()` - Получить максимальное количество параллельных запросов
*   `ping(address, edition)` - Пинг одного сервера
*   `ping_java(address)` - Пинг Java Edition сервера
*   `ping_bedrock(address)` - Пинг Bedrock Edition сервера
*   `ping_many(servers)` - Пинг множества серверов параллельно
*   `clear_dns_cache()` - Очистить DNS кеш
*   `clear_srv_cache()` - Очистить кеш SRV записей
*   `clear_all_caches()` - Очистить все кеши
*   `cache_stats()` - Получить статистику кеша
*   `resolve_dns_timed(host, port)` - Разрешить DNS и измерить время резолва (полезно для бенчмарков кеша)
*   `is_online(address, edition)` - Быстрая проверка доступности сервера (быстрее чем `ping`)

### ServerStatus

Результат успешного пинга.

```rust
pub struct ServerStatus {
    pub online: bool,              // Онлайн ли сервер
    pub ip: String,                // Разрешенный IP адрес
    pub port: u16,                 // Порт сервера
    pub hostname: String,          // Оригинальное имя хоста
    pub latency: f64,              // Задержка в миллисекундах
    pub dns: Option<DnsInfo>,      // DNS информация
    pub data: ServerData,          // Данные, специфичные для сервера
}

impl ServerStatus {
    pub fn players(&self) -> Option<(i64, i64)>;  // Получить (онлайн, максимум) игроков
}
```

### JavaStatus

Информация о Java Edition сервере.

```rust
pub struct JavaStatus {
    pub version: JavaVersion,       // Информация о версии
    pub players: JavaPlayers,       // Информация об игроках
    pub description: String,        // Описание сервера (MOTD)
    pub favicon: Option<String>,    // Иконка в формате base64
    pub map: Option<String>,        // Название текущей карты
    pub gamemode: Option<String>,   // Режим игры
    pub software: Option<String>,   // ПО сервера
    pub plugins: Option<Vec<JavaPlugin>>,  // Список плагинов
    pub mods: Option<Vec<JavaMod>>,        // Список модов
}

impl JavaStatus {
    pub fn save_favicon(&self, filename: &str) -> Result<(), McError>;
}
```

### BedrockStatus

Информация о Bedrock Edition сервере.

```rust
pub struct BedrockStatus {
    pub edition: String,            // Издание Minecraft
    pub motd: String,               // Сообщение дня
    pub version: String,            // Версия сервера
    pub online_players: String,     // Количество онлайн игроков
    pub max_players: String,        // Максимальное количество игроков
    pub map: Option<String>,        // Название текущей карты
    pub software: Option<String>,   // ПО сервера
    pub game_mode: String,          // Режим игры
    // ... и многое другое
}
```

## Обработка ошибок

Библиотека предоставляет полноценные типы ошибок:

```rust
use rust_mc_status::McError;

match client.ping("server.com", ServerEdition::Java).await {
    Ok(status) => println!("Сервер онлайн!"),
    Err(McError::Timeout) => println!("Запрос превысил время ожидания"),
    Err(McError::DnsError(msg)) => println!("DNS ошибка: {}", msg),
    Err(McError::ConnectionError(msg)) => println!("Ошибка подключения: {}", msg),
    Err(e) => println!("Другая ошибка: {}", e),
}
```

См. [документацию](https://docs.rs/rust-mc-status) для полного списка типов ошибок.

## Производительность

Библиотека оптимизирована для производительности:

*   **Кэширование DNS**: DNS запросы и SRV записи кэшируются на 5 минут
*   **Пул соединений**: Эффективное управление соединениями
*   **Параллельная обработка**: Массовые запросы выполняются параллельно с настраиваемыми лимитами
*   **Эффективное использование памяти**: Предварительно выделенные буферы и эффективные структуры данных
*   **Асинхронный I/O**: Неблокирующие I/O операции с использованием Tokio

## Лицензия

Этот проект лицензирован по лицензии MIT - подробности в файле [LICENSE](LICENSE).

## Вклад

Вклад приветствуется! Пожалуйста, не стесняйтесь отправлять Pull Request.

## Версия

Текущая версия: **2.0.0**

См. [CHANGELOG.md](CHANGELOG.md) для подробной истории версий, новых возможностей и руководства по миграции.