#![allow(non_local_definitions)] use protocol::Protocol;
pub(crate) const VERSION: u16 = 0;
pub(crate) const VELOREN_HEADER: [u8; 7] = [b'v', b'e', b'l', b'o', b'r', b'e', b'n'];
pub(crate) const MAX_REQUEST_CONTENT_SIZE: usize = 300;
pub(crate) const MAX_REQUEST_SIZE: usize = MAX_REQUEST_CONTENT_SIZE + VELOREN_HEADER.len() + 2;
pub(crate) const MAX_RESPONSE_SIZE: usize = 256;
#[derive(Protocol, Debug, Clone, Copy)]
pub(crate) struct RawQueryServerRequest {
pub p: u64,
pub request: QueryServerRequest,
}
#[derive(Protocol, Debug, Clone, Copy)]
#[protocol(discriminant = "integer")]
#[protocol(discriminator(u8))]
#[allow(clippy::large_enum_variant)]
pub enum QueryServerRequest {
Init,
ServerInfo,
}
#[derive(Protocol, Debug, Clone, Copy)]
pub(crate) struct Init {
pub p: u64,
pub max_supported_version: u16,
}
#[derive(Protocol, Debug, Clone, Copy)]
#[protocol(discriminant = "integer")]
#[protocol(discriminator(u8))]
pub(crate) enum RawQueryServerResponse {
Response(QueryServerResponse),
Init(Init),
}
#[derive(Protocol, Debug, Clone, Copy)]
#[protocol(discriminant = "integer")]
#[protocol(discriminator(u8))]
pub enum QueryServerResponse {
ServerInfo(ServerInfo),
}
#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ServerInfo {
pub git_hash: u32,
pub git_timestamp: i64,
pub players_count: u16,
pub player_cap: u16,
pub battlemode: ServerBattleMode,
}
#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
#[protocol(discriminant = "integer")]
#[protocol(discriminator(u8))]
#[repr(u8)]
pub enum ServerBattleMode {
GlobalPvP,
GlobalPvE,
PerPlayer,
}
impl RawQueryServerRequest {
#[cfg(any(feature = "client", test))]
pub fn serialize(&self) -> Result<Vec<u8>, protocol::Error> {
use protocol::Parcel;
let mut buf = Vec::with_capacity(MAX_REQUEST_SIZE);
buf.extend(VERSION.to_le_bytes());
buf.extend({
let request_data =
<RawQueryServerRequest as Parcel>::raw_bytes(self, &Default::default())?;
if request_data.len() > MAX_REQUEST_CONTENT_SIZE {
panic!(
"Attempted to send request larger than the max size (size: {}, max size: \
{MAX_REQUEST_CONTENT_SIZE}, request: {self:?})",
request_data.len()
);
}
request_data
});
const _: () = assert!(MAX_RESPONSE_SIZE + VELOREN_HEADER.len() <= MAX_REQUEST_SIZE);
buf.resize(MAX_RESPONSE_SIZE.max(buf.len()), 0);
buf.extend(VELOREN_HEADER);
Ok(buf)
}
}
#[cfg(test)]
mod tests {
use super::{QueryServerRequest, RawQueryServerRequest};
#[test]
fn check_request_sizes() {
const ALL_REQUESTS: &[QueryServerRequest] =
&[QueryServerRequest::ServerInfo, QueryServerRequest::Init];
for request in ALL_REQUESTS {
let request = RawQueryServerRequest {
p: 0,
request: *request,
};
request.serialize().unwrap(); }
}
}