veloren_query_server/
proto.rs1#![allow(non_local_definitions)] use protocol::Protocol;
3
4pub(crate) const VERSION: u16 = 0;
5pub(crate) const VELOREN_HEADER: [u8; 7] = [b'v', b'e', b'l', b'o', b'r', b'e', b'n'];
6pub(crate) const MAX_REQUEST_CONTENT_SIZE: usize = 300;
7pub(crate) const MAX_REQUEST_SIZE: usize = MAX_REQUEST_CONTENT_SIZE + VELOREN_HEADER.len() + 2;
10pub(crate) const MAX_RESPONSE_SIZE: usize = 256;
11
12#[derive(Protocol, Debug, Clone, Copy)]
13pub(crate) struct RawQueryServerRequest {
14 pub p: u64,
16 pub request: QueryServerRequest,
17}
18
19#[derive(Protocol, Debug, Clone, Copy)]
20#[protocol(discriminant = "integer")]
21#[protocol(discriminator(u8))]
22#[allow(clippy::large_enum_variant)]
23pub enum QueryServerRequest {
24 Init,
31 ServerInfo,
32 }
36
37#[derive(Protocol, Debug, Clone, Copy)]
38pub(crate) struct Init {
39 pub p: u64,
46 pub max_supported_version: u16,
52}
53
54#[derive(Protocol, Debug, Clone, Copy)]
55#[protocol(discriminant = "integer")]
56#[protocol(discriminator(u8))]
57pub(crate) enum RawQueryServerResponse {
58 Response(QueryServerResponse),
59 Init(Init),
60}
61
62#[derive(Protocol, Debug, Clone, Copy)]
63#[protocol(discriminant = "integer")]
64#[protocol(discriminator(u8))]
65pub enum QueryServerResponse {
66 ServerInfo(ServerInfo),
67 }
69
70#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
71pub struct ServerInfo {
72 pub git_hash: u32,
73 pub git_timestamp: i64,
74 pub players_count: u16,
75 pub player_cap: u16,
76 pub battlemode: ServerBattleMode,
77}
78
79#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
80#[protocol(discriminant = "integer")]
81#[protocol(discriminator(u8))]
82#[repr(u8)]
83pub enum ServerBattleMode {
84 GlobalPvP,
85 GlobalPvE,
86 PerPlayer,
87}
88
89impl RawQueryServerRequest {
90 #[cfg(any(feature = "client", test))]
91 pub fn serialize(&self) -> Result<Vec<u8>, protocol::Error> {
92 use protocol::Parcel;
93
94 let mut buf = Vec::with_capacity(MAX_REQUEST_SIZE);
95
96 buf.extend(VERSION.to_le_bytes());
98 buf.extend({
99 let request_data =
100 <RawQueryServerRequest as Parcel>::raw_bytes(self, &Default::default())?;
101 if request_data.len() > MAX_REQUEST_CONTENT_SIZE {
102 panic!(
103 "Attempted to send request larger than the max size (size: {}, max size: \
104 {MAX_REQUEST_CONTENT_SIZE}, request: {self:?})",
105 request_data.len()
106 );
107 }
108 request_data
109 });
110 const _: () = assert!(MAX_RESPONSE_SIZE + VELOREN_HEADER.len() <= MAX_REQUEST_SIZE);
111 buf.resize(MAX_RESPONSE_SIZE.max(buf.len()), 0);
112 buf.extend(VELOREN_HEADER);
113 Ok(buf)
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::{QueryServerRequest, RawQueryServerRequest};
120
121 #[test]
122 fn check_request_sizes() {
123 const ALL_REQUESTS: &[QueryServerRequest] =
124 &[QueryServerRequest::ServerInfo, QueryServerRequest::Init];
125 for request in ALL_REQUESTS {
126 let request = RawQueryServerRequest {
127 p: 0,
128 request: *request,
129 };
130 request.serialize().unwrap(); }
132 }
133}