pub struct McClient { /* private fields */ }Expand description
Minecraft server status client.
This client provides methods for querying Minecraft server status with support for both Java Edition and Bedrock Edition servers.
§Features
- Automatic SRV record lookup for Java servers
- DNS caching for improved performance
- Configurable timeouts and concurrency limits
- Batch queries for multiple servers
§Example
use rust_mc_status::{McClient, ServerEdition};
use std::time::Duration;
let client = McClient::new()
.with_timeout(Duration::from_secs(5))
.with_max_parallel(10);
let status = client.ping("mc.hypixel.net", ServerEdition::Java).await?;
println!("Server is online: {}", status.online);Implementations§
Source§impl McClient
impl McClient
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new client with default settings.
Default settings:
- Timeout: 10 seconds
- Max parallel: 10 queries
§Example
use rust_mc_status::McClient;
let client = McClient::new();Sourcepub fn with_timeout(self, timeout: Duration) -> Self
pub fn with_timeout(self, timeout: Duration) -> Self
Set the request timeout.
This timeout applies to all network operations including DNS resolution, connection establishment, and response reading.
§Arguments
timeout- Maximum time to wait for a server response- Default: 10 seconds
- Recommended: 5-10 seconds for most use cases
- Use shorter timeouts (1-3 seconds) for quick checks
§Returns
Returns Self for method chaining.
§Example
use rust_mc_status::McClient;
use std::time::Duration;
// Quick timeout for fast checks
let fast_client = McClient::new()
.with_timeout(Duration::from_secs(2));
// Longer timeout for reliable queries
let reliable_client = McClient::new()
.with_timeout(Duration::from_secs(10));Sourcepub fn with_max_parallel(self, max_parallel: usize) -> Self
pub fn with_max_parallel(self, max_parallel: usize) -> Self
Set the maximum number of parallel queries.
This limit controls how many servers can be queried simultaneously
when using ping_many. Higher values increase
throughput but consume more resources.
§Arguments
max_parallel- Maximum number of concurrent server queries- Default: 10
- Recommended: 5-20 for most use cases
- Higher values (50-100) for batch processing
- Lower values (1-5) for resource-constrained environments
§Returns
Returns Self for method chaining.
§Performance
- Higher values = faster batch processing but more memory/CPU usage
- Lower values = slower but more resource-friendly
- DNS and SRV caches are shared across all parallel queries
§Example
use rust_mc_status::{McClient, ServerEdition, ServerInfo};
// High concurrency for batch processing
let batch_client = McClient::new()
.with_max_parallel(50);
// Low concurrency for resource-constrained environments
let limited_client = McClient::new()
.with_max_parallel(3);Sourcepub fn max_parallel(&self) -> usize
pub fn max_parallel(&self) -> usize
Get the maximum number of parallel queries.
§Example
use rust_mc_status::McClient;
let client = McClient::new().with_max_parallel(20);
assert_eq!(client.max_parallel(), 20);Sourcepub fn timeout(&self) -> Duration
pub fn timeout(&self) -> Duration
Get the request timeout.
§Example
use rust_mc_status::McClient;
use std::time::Duration;
let client = McClient::new().with_timeout(Duration::from_secs(5));
assert_eq!(client.timeout(), Duration::from_secs(5));Sourcepub fn clear_dns_cache(&self)
pub fn clear_dns_cache(&self)
Clear DNS cache.
This method clears all cached DNS resolutions. Useful when you need to force fresh DNS lookups or free memory.
§Example
use rust_mc_status::McClient;
let client = McClient::new();
client.clear_dns_cache();Sourcepub fn clear_srv_cache(&self)
pub fn clear_srv_cache(&self)
Clear SRV record cache.
This method clears all cached SRV record lookups. Useful when you need to force fresh SRV lookups or free memory.
§Example
use rust_mc_status::McClient;
let client = McClient::new();
client.clear_srv_cache();Sourcepub fn clear_all_caches(&self)
pub fn clear_all_caches(&self)
Clear all caches (DNS and SRV).
This method clears both DNS and SRV caches. Useful when you need to force fresh lookups or free memory.
§Example
use rust_mc_status::McClient;
let client = McClient::new();
client.clear_all_caches();Sourcepub fn cache_stats(&self) -> CacheStats
pub fn cache_stats(&self) -> CacheStats
Get cache statistics.
Returns the number of entries in DNS and SRV caches.
§Example
use rust_mc_status::McClient;
let client = McClient::new();
let stats = client.cache_stats();
println!("DNS cache entries: {}", stats.dns_entries);
println!("SRV cache entries: {}", stats.srv_entries);Sourcepub async fn resolve_dns_timed(
&self,
host: &str,
port: u16,
) -> Result<(SocketAddr, f64), McError>
pub async fn resolve_dns_timed( &self, host: &str, port: u16, ) -> Result<(SocketAddr, f64), McError>
Resolve DNS and measure resolution time.
This method resolves a hostname to an IP address and returns both the resolved address and the time taken for resolution. Useful for measuring cache effectiveness and DNS performance.
§Arguments
host- Hostname to resolve (e.g.,"mc.hypixel.net"or"192.168.1.1")port- Port number (e.g.,25565for Java,19132for Bedrock)
§Returns
Returns Ok((SocketAddr, f64)) where:
SocketAddr: Resolved IP address and portf64: Resolution time in milliseconds
§Errors
Returns McError::DnsError if DNS resolution fails.
§Performance Notes
- First resolution (cold cache): Typically 10-100ms
- Subsequent resolutions (warm cache): Typically <1ms
- Cache TTL: 5 minutes
- Use
clear_dns_cacheto force fresh lookups
§Example
use rust_mc_status::McClient;
let client = McClient::new();
// First resolution (cold cache - actual DNS lookup)
let (addr1, time1) = client.resolve_dns_timed("mc.hypixel.net", 25565).await?;
println!("First resolution: {:.2} ms", time1);
println!("Resolved to: {}", addr1);
// Second resolution (warm cache - from cache)
let (addr2, time2) = client.resolve_dns_timed("mc.hypixel.net", 25565).await?;
println!("Cached resolution: {:.2} ms", time2);
println!("Cache speedup: {:.1}x faster", time1 / time2);
println!("Time saved: {:.2} ms", time1 - time2);Sourcepub async fn ping(
&self,
address: &str,
edition: ServerEdition,
) -> Result<ServerStatus, McError>
pub async fn ping( &self, address: &str, edition: ServerEdition, ) -> Result<ServerStatus, McError>
Ping a server and get its status.
This is a convenience method that dispatches to either ping_java
or ping_bedrock based on the server edition.
§Arguments
address- Server address in one of the following formats:"hostname"- Hostname without port (uses default port for edition)"hostname:port"- Hostname with explicit port"192.168.1.1"- IP address without port (uses default port)"192.168.1.1:25565"- IP address with explicit port
edition- Server edition:ServerEdition::JavaorServerEdition::Bedrock
§Returns
Returns a ServerStatus struct containing:
online: Whether the server is onlineip: Resolved IP addressport: Server port numberhostname: Original hostname used for querylatency: Response time in millisecondsdns: Optional DNS information (A records, CNAME, TTL)data: Edition-specific server data (version, players, plugins, etc.)
§Errors
Returns McError if:
- DNS resolution fails (
McError::DnsError) - Connection cannot be established (
McError::ConnectionError) - Request times out (
McError::Timeout) - Server returns invalid response (
McError::InvalidResponse) - Invalid port number in address (
McError::InvalidPort)
§Example
use rust_mc_status::{McClient, ServerEdition};
let client = McClient::new();
// Ping Java server (automatic SRV lookup)
let status = client.ping("mc.hypixel.net", ServerEdition::Java).await?;
println!("Server is online: {}", status.online);
println!("Latency: {:.2}ms", status.latency);
// Ping Bedrock server
let status = client.ping("geo.hivebedrock.network:19132", ServerEdition::Bedrock).await?;
println!("Players: {}/{}", status.players().unwrap_or((0, 0)).0, status.players().unwrap_or((0, 0)).1);Sourcepub async fn ping_java(&self, address: &str) -> Result<ServerStatus, McError>
pub async fn ping_java(&self, address: &str) -> Result<ServerStatus, McError>
Ping a Java Edition server and get its status.
This method automatically performs an SRV DNS lookup if no port is specified in the address. The lookup follows the Minecraft client behavior:
- Queries
_minecraft._tcp.{hostname}for SRV records - Uses the target host and port from the SRV record if found
- Falls back to the default port (25565) if no SRV record exists
- Skips SRV lookup if port is explicitly specified
§Arguments
address- Server address in one of the following formats:"hostname"- Hostname without port (performs SRV lookup, defaults to 25565)"hostname:25565"- Hostname with explicit port (skips SRV lookup)"192.168.1.1"- IP address without port (uses port 25565)"192.168.1.1:25565"- IP address with explicit port
§Returns
Returns a ServerStatus with ServerData::Java containing:
- Version information (name, protocol version)
- Player information (online count, max players, sample list)
- Server description (MOTD)
- Optional favicon (base64-encoded PNG)
- Optional plugins list
- Optional mods list
- Additional metadata (map, gamemode, software)
§Errors
Returns McError if:
- DNS resolution fails (
McError::DnsError) - SRV lookup fails (non-critical, falls back to default port)
- Connection cannot be established (
McError::ConnectionError) - Request times out (
McError::Timeout) - Server returns invalid response (
McError::InvalidResponse) - JSON parsing fails (
McError::JsonError) - Invalid port number (
McError::InvalidPort)
§Example
use rust_mc_status::McClient;
let client = McClient::new();
// Automatic SRV lookup (queries _minecraft._tcp.mc.hypixel.net)
let status = client.ping_java("mc.hypixel.net").await?;
if let rust_mc_status::ServerData::Java(java) = &status.data {
println!("Version: {}", java.version.name);
println!("Players: {}/{}", java.players.online, java.players.max);
println!("Description: {}", java.description);
}
// Skip SRV lookup (uses port 25565 directly)
let status = client.ping_java("mc.hypixel.net:25565").await?;Sourcepub async fn ping_bedrock(&self, address: &str) -> Result<ServerStatus, McError>
pub async fn ping_bedrock(&self, address: &str) -> Result<ServerStatus, McError>
Ping a Bedrock Edition server and get its status.
Bedrock Edition servers use UDP protocol and typically run on port 19132. This method sends a UDP ping packet and parses the response.
§Arguments
address- Server address in one of the following formats:"hostname"- Hostname without port (uses default port 19132)"hostname:19132"- Hostname with explicit port"192.168.1.1"- IP address without port (uses port 19132)"192.168.1.1:19132"- IP address with explicit port
§Returns
Returns a ServerStatus with ServerData::Bedrock containing:
- Edition information (e.g., “MCPE”)
- Version information
- Player counts (online and max)
- Message of the day (MOTD)
- Protocol version
- Server UID
- Game mode information
- Port information (IPv4 and IPv6)
- Optional map name and software
§Errors
Returns McError if:
- DNS resolution fails (
McError::DnsError) - Connection cannot be established (
McError::ConnectionError) - Request times out (
McError::Timeout) - Server returns invalid response (
McError::InvalidResponse) - Invalid port number (
McError::InvalidPort) - UTF-8 conversion fails (
McError::Utf8Error)
§Example
use rust_mc_status::McClient;
let client = McClient::new();
let status = client.ping_bedrock("geo.hivebedrock.network:19132").await?;
if let rust_mc_status::ServerData::Bedrock(bedrock) = &status.data {
println!("Edition: {}", bedrock.edition);
println!("Version: {}", bedrock.version);
println!("Players: {}/{}", bedrock.online_players, bedrock.max_players);
println!("MOTD: {}", bedrock.motd);
}Sourcepub async fn is_online(&self, address: &str, edition: ServerEdition) -> bool
pub async fn is_online(&self, address: &str, edition: ServerEdition) -> bool
Quick check if a server is online.
This method performs a minimal connection check without retrieving
full server status. It’s faster than ping() but provides less information.
Use this method when you only need to know if a server is reachable.
§Arguments
address- Server address in one of the following formats:"hostname"- Hostname without port (uses default port for edition)"hostname:port"- Hostname with explicit port"192.168.1.1"- IP address without port (uses default port)"192.168.1.1:25565"- IP address with explicit port
edition- Server edition:ServerEdition::JavaorServerEdition::Bedrock
§Returns
Returns true if the server is reachable and responds to ping requests,
false if the server is offline, unreachable, or times out.
§Performance
This method is faster than ping() because it:
- Doesn’t parse full server status
- Doesn’t retrieve player information
- Doesn’t parse JSON responses (for Java servers)
§Example
use rust_mc_status::{McClient, ServerEdition};
let client = McClient::new();
// Quick check without full status
if client.is_online("mc.hypixel.net", ServerEdition::Java).await {
println!("Server is online!");
// Now get full status if needed
let status = client.ping("mc.hypixel.net", ServerEdition::Java).await?;
println!("Players: {}/{}", status.players().unwrap_or((0, 0)).0, status.players().unwrap_or((0, 0)).1);
} else {
println!("Server is offline or unreachable");
}Sourcepub async fn ping_many(
&self,
servers: &[ServerInfo],
) -> Vec<(ServerInfo, Result<ServerStatus, McError>)>
pub async fn ping_many( &self, servers: &[ServerInfo], ) -> Vec<(ServerInfo, Result<ServerStatus, McError>)>
Ping multiple servers in parallel.
This method queries multiple servers concurrently with a configurable
concurrency limit. Results are returned in the same order as input.
The concurrency limit is controlled by with_max_parallel.
§Arguments
servers- Slice ofServerInfostructures containing:address: Server address (hostname or IP, optionally with port)edition: Server edition (ServerEdition::JavaorServerEdition::Bedrock)
§Returns
Returns a Vec<(ServerInfo, Result<ServerStatus, McError>)> where:
- Each tuple contains the original
ServerInfoand the query result - Results are in the same order as the input slice
Ok(ServerStatus)contains full server status informationErr(McError)contains error information (timeout, DNS error, etc.)
§Performance
- Queries are executed in parallel up to the configured limit
- DNS and SRV caches are shared across all queries
- Failed queries don’t block other queries
- Use
with_max_parallel()to control resource usage
§Example
use rust_mc_status::{McClient, ServerEdition, ServerInfo};
let client = McClient::new()
.with_max_parallel(5) // Process up to 5 servers concurrently
.with_timeout(std::time::Duration::from_secs(5));
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);
if let Some((online, max)) = status.players() {
println!(" Players: {}/{}", online, max);
}
}
Err(e) => println!("{}: ❌ Error - {}", server.address, e),
}
}