# Rust Minecraft Server Status Library
[](https://crates.io/crates/rust-mc-status)
[](https://docs.rs/rust-mc-status)
[](LICENSE)
A high-performance, asynchronous Rust library for querying the status of both Minecraft Java Edition and Bedrock Edition servers.
## Features
* **Dual Protocol Support**: Ping both Minecraft Java Edition (`25565`) and Bedrock Edition (`19132`) servers
* **Async/Await**: Built on Tokio for non-blocking operations and high concurrency
* **Batch Queries**: Ping multiple servers in parallel with configurable concurrency limits
* **DNS Caching**: Automatically caches DNS lookups and SRV records to reduce latency for repeated queries
* **SRV Record Support**: Automatically resolves SRV records for Java servers (mimics Minecraft client behavior)
* **Structured Data**: Returns richly structured, serializable data (using `serde`), including version info, player counts, MOTD, map, gamemode, plugins, mods and more
* **Favicon Handling**: Easily retrieve and save server favicons (Java Edition only)
* **Robust Error Handling**: Comprehensive error types using `thiserror`
* **Extended Information**: Detailed data about plugins, mods, DNS and more
* **High Performance**: Optimized with connection pooling, DNS caching, and efficient memory usage
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
rust-mc-status = "2.0.0"
tokio = { version = "*", features = ["full"] }
```
## Quick Start
### Basic Usage
```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);
// Ping a Java server (automatically uses SRV lookup if port not specified)
let status = client.ping("mc.hypixel.net", ServerEdition::Java).await?;
println!("Server is online: {}", status.online);
println!("Latency: {:.2} ms", status.latency);
if let Some((online, max)) = status.players() {
println!("Players: {}/{}", online, max);
}
Ok(())
}
```
### Batch Queries
```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!("{}: Online ({}ms)", server.address, status.latency),
Err(e) => println!("{}: Error - {}", server.address, e),
}
}
Ok(())
}
```
## SRV Record Lookup
When pinging Java servers without an explicit port, the library automatically performs an SRV DNS lookup for `_minecraft._tcp.{hostname}`. This mimics the behavior of the official Minecraft client.
### How It Works
1. **Without explicit port** (e.g., `"mc.hypixel.net"`):
- Queries `_minecraft._tcp.mc.hypixel.net` for SRV records
- If found, uses the target host and port from the SRV record
- If not found, uses the default port (25565)
- Results are cached for 5 minutes
2. **With explicit port** (e.g., `"mc.hypixel.net:25565"`):
- Skips SRV lookup entirely
- Uses the specified host and port directly
### Example
```rust
use rust_mc_status::{McClient, ServerEdition};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = McClient::new();
// This will perform SRV lookup for _minecraft._tcp.example.com
let status = client.ping("example.com", ServerEdition::Java).await?;
// This will skip SRV lookup and use port 25565 directly
let status = client.ping("example.com:25565", ServerEdition::Java).await?;
Ok(())
}
```
## Examples
The library includes several example programs:
* **`basic_usage.rs`** - Basic server status queries and error handling
* **`advanced_usage.rs`** - Advanced features including batch queries, plugins, mods, and favicons
* **`srv_lookup_example.rs`** - Detailed demonstration of SRV record lookup
* **`performance_test.rs`** - Performance benchmarking and speed tests
* **`cache_management.rs`** - Cache management and statistics
Run examples with:
```bash
cargo run --example basic_usage
cargo run --example advanced_usage
cargo run --example srv_lookup_example
cargo run --example performance_test --release # Use --release for accurate performance measurements
cargo run --example cache_management
```
## API Documentation
### McClient
The main client for making server status queries.
```rust
let client = McClient::new()
.with_timeout(Duration::from_secs(5)) // Set request timeout
.with_max_parallel(10); // Set max concurrent queries
```
**Methods:**
* `new()` - Create a new client with default settings
* `with_timeout(timeout)` - Set the request timeout
* `with_max_parallel(max)` - Set the maximum number of parallel queries
* `timeout()` - Get the current request timeout
* `max_parallel()` - Get the maximum number of parallel queries
* `ping(address, edition)` - Ping a single server
* `ping_java(address)` - Ping a Java Edition server
* `ping_bedrock(address)` - Ping a Bedrock Edition server
* `ping_many(servers)` - Ping multiple servers in parallel
* `clear_dns_cache()` - Clear DNS cache
* `clear_srv_cache()` - Clear SRV record cache
* `clear_all_caches()` - Clear all caches
* `cache_stats()` - Get cache statistics
* `resolve_dns_timed(host, port)` - Resolve DNS and measure resolution time (useful for cache benchmarking)
* `is_online(address, edition)` - Quick check if server is online (faster than `ping`)
### ServerStatus
The result of a successful ping.
```rust
pub struct ServerStatus {
pub online: bool, // Whether the server is online
pub ip: String, // Resolved IP address
pub port: u16, // Server port
pub hostname: String, // Original hostname
pub latency: f64, // Latency in milliseconds
pub dns: Option<DnsInfo>, // DNS information
pub data: ServerData, // Server-specific data
}
impl ServerStatus {
pub fn players(&self) -> Option<(i64, i64)>; // Get (online, max) players
}
```
### JavaStatus
Java Edition server information.
```rust
pub struct JavaStatus {
pub version: JavaVersion, // Version information
pub players: JavaPlayers, // Player information
pub description: String, // Server description (MOTD)
pub favicon: Option<String>, // Base64-encoded favicon
pub map: Option<String>, // Current map name
pub gamemode: Option<String>, // Game mode
pub software: Option<String>, // Server software
pub plugins: Option<Vec<JavaPlugin>>, // List of plugins
pub mods: Option<Vec<JavaMod>>, // List of mods
}
impl JavaStatus {
pub fn save_favicon(&self, filename: &str) -> Result<(), McError>;
}
```
### BedrockStatus
Bedrock Edition server information.
```rust
pub struct BedrockStatus {
pub edition: String, // Minecraft edition
pub motd: String, // Message of the day
pub version: String, // Server version
pub online_players: String, // Online players count
pub max_players: String, // Maximum players
pub map: Option<String>, // Current map name
pub software: Option<String>, // Server software
pub game_mode: String, // Game mode
// ... and more
}
```
## Error Handling
The library provides comprehensive error types:
```rust
use rust_mc_status::McError;
match client.ping("server.com", ServerEdition::Java).await {
Ok(status) => println!("Server is online!"),
Err(McError::Timeout) => println!("Request timed out"),
Err(McError::DnsError(msg)) => println!("DNS error: {}", msg),
Err(McError::ConnectionError(msg)) => println!("Connection error: {}", msg),
Err(e) => println!("Other error: {}", e),
}
```
See the [documentation](https://docs.rs/rust-mc-status) for a complete list of error types.
## Performance
The library is optimized for performance:
* **DNS Caching**: DNS lookups and SRV records are cached for 5 minutes
* **Connection Pooling**: Efficient connection management
* **Parallel Processing**: Batch queries run in parallel with configurable limits
* **Memory Efficient**: Pre-allocated buffers and efficient data structures
* **Async I/O**: Non-blocking I/O operations using Tokio
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Version
Current version: **2.0.0**
See [CHANGELOG.md](CHANGELOG.md) for detailed version history, new features, and migration guide.