Add a few imports
This commit is contained in:
parent
25ae6adda9
commit
ba54f4cf57
58
src/lib.rs
58
src/lib.rs
@ -19,29 +19,23 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io,
|
error::Error,
|
||||||
time::Duration
|
io::{
|
||||||
|
ErrorKind,
|
||||||
|
self,
|
||||||
|
},
|
||||||
|
time::Duration,
|
||||||
|
fmt::{
|
||||||
|
Display,
|
||||||
|
Formatter,
|
||||||
|
self,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
net::{ ToSocketAddrs, UdpSocket },
|
net::{ ToSocketAddrs, UdpSocket },
|
||||||
time::timeout as tokioTimeout,
|
time::timeout as tokioTimeout,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Bitmask to validate a session ID
|
|
||||||
///
|
|
||||||
/// Usually you don't need this.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```
|
|
||||||
/// use mcquery::SESSION_ID_MASK;
|
|
||||||
///
|
|
||||||
/// # #[allow(unused_variables)]
|
|
||||||
/// # fn main() {
|
|
||||||
/// let session_id = 0x12345678_u32;
|
|
||||||
/// let valid_session_id = session_id & SESSION_ID_MASK;
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
pub const SESSION_ID_MASK: u32 = 0x0F0F0F0F;
|
|
||||||
const REQUEST_HEADER: [u8; 2] = [0xFE, 0xFD];
|
const REQUEST_HEADER: [u8; 2] = [0xFE, 0xFD];
|
||||||
|
|
||||||
fn gen_session_id() -> u32 {
|
fn gen_session_id() -> u32 {
|
||||||
@ -61,10 +55,10 @@ fn gen_session_id() -> u32 {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct MaybeIncompleteDataError(usize);
|
pub struct MaybeIncompleteDataError(usize);
|
||||||
|
|
||||||
impl std::error::Error for MaybeIncompleteDataError {}
|
impl Error for MaybeIncompleteDataError {}
|
||||||
|
|
||||||
impl core::fmt::Display for MaybeIncompleteDataError {
|
impl Display for MaybeIncompleteDataError {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "Buffer filled up")
|
write!(f, "Buffer filled up")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,12 +110,12 @@ impl HandshakeRequest {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.take_while(|x| x != &0x00)
|
.take_while(|x| x != &0x00)
|
||||||
.collect()
|
.collect()
|
||||||
).map_err(|_| io::ErrorKind::InvalidData)?
|
).map_err(|_| ErrorKind::InvalidData)?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| io::ErrorKind::InvalidData)?;
|
.map_err(|_| ErrorKind::InvalidData)?;
|
||||||
|
|
||||||
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
||||||
Err(io::ErrorKind::InvalidData.into())
|
Err(ErrorKind::InvalidData.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(HandshakeResponse {
|
Ok(HandshakeResponse {
|
||||||
session_id: res_session_id,
|
session_id: res_session_id,
|
||||||
@ -181,7 +175,7 @@ impl BasicQueryRequest {
|
|||||||
// Receiving
|
// Receiving
|
||||||
let bytes_read = tokioTimeout(timeout, socket.recv(buffer)).await??;
|
let bytes_read = tokioTimeout(timeout, socket.recv(buffer)).await??;
|
||||||
if bytes_read == buffer.len() {
|
if bytes_read == buffer.len() {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, MaybeIncompleteDataError(bytes_read)));
|
return Err(io::Error::new(ErrorKind::Other, MaybeIncompleteDataError(bytes_read)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsing
|
// Parsing
|
||||||
@ -230,10 +224,10 @@ impl BasicQueryRequest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Number of players
|
// Number of players
|
||||||
let res_num_players = res_num_players.parse().map_err(|_| io::ErrorKind::InvalidData)?;
|
let res_num_players = res_num_players.parse().map_err(|_| ErrorKind::InvalidData)?;
|
||||||
|
|
||||||
// Max number of players
|
// Max number of players
|
||||||
let res_max_players = res_max_players.parse().map_err(|_| io::ErrorKind::InvalidData)?;
|
let res_max_players = res_max_players.parse().map_err(|_| ErrorKind::InvalidData)?;
|
||||||
|
|
||||||
// Host port
|
// Host port
|
||||||
let mut res_port = [0; 2];
|
let mut res_port = [0; 2];
|
||||||
@ -243,10 +237,10 @@ impl BasicQueryRequest {
|
|||||||
let res_port = u16::from_le_bytes(res_port);
|
let res_port = u16::from_le_bytes(res_port);
|
||||||
|
|
||||||
// Host IP
|
// Host IP
|
||||||
let res_ip = String::from_utf8(res_address).map_err(|_| io::ErrorKind::InvalidData)?;
|
let res_ip = String::from_utf8(res_address).map_err(|_| ErrorKind::InvalidData)?;
|
||||||
|
|
||||||
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
||||||
Err(io::ErrorKind::InvalidData.into())
|
Err(ErrorKind::InvalidData.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(BasicQueryResponse {
|
Ok(BasicQueryResponse {
|
||||||
session_id: res_session_id,
|
session_id: res_session_id,
|
||||||
@ -308,7 +302,7 @@ impl FullQueryRequest {
|
|||||||
// Receiving
|
// Receiving
|
||||||
let bytes_read = tokioTimeout(timeout, socket.recv(buffer)).await??;
|
let bytes_read = tokioTimeout(timeout, socket.recv(buffer)).await??;
|
||||||
if bytes_read == buffer.len() {
|
if bytes_read == buffer.len() {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, MaybeIncompleteDataError(bytes_read)));
|
return Err(io::Error::new(ErrorKind::Other, MaybeIncompleteDataError(bytes_read)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsing
|
// Parsing
|
||||||
@ -351,7 +345,7 @@ impl FullQueryRequest {
|
|||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
res_kv.remove("splitnum").ok_or(io::ErrorKind::InvalidData)?;
|
res_kv.remove("splitnum").ok_or(ErrorKind::InvalidData)?;
|
||||||
|
|
||||||
// Plugins and server software
|
// Plugins and server software
|
||||||
let (
|
let (
|
||||||
@ -380,7 +374,7 @@ impl FullQueryRequest {
|
|||||||
{
|
{
|
||||||
let player_header = "\x01player_\0\0";
|
let player_header = "\x01player_\0\0";
|
||||||
if !response_buffer.starts_with(player_header.as_bytes()) {
|
if !response_buffer.starts_with(player_header.as_bytes()) {
|
||||||
return Err(io::ErrorKind::InvalidData.into());
|
return Err(ErrorKind::InvalidData.into());
|
||||||
} else {
|
} else {
|
||||||
response_buffer.drain(0..player_header.len());
|
response_buffer.drain(0..player_header.len());
|
||||||
}
|
}
|
||||||
@ -404,7 +398,7 @@ impl FullQueryRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
if res_packet_type != Self::PACKET_TYPE as u8 || res_session_id != self.session_id {
|
||||||
Err(io::ErrorKind::InvalidData.into())
|
Err(ErrorKind::InvalidData.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(FullQueryResponse {
|
Ok(FullQueryResponse {
|
||||||
session_id: res_session_id,
|
session_id: res_session_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user