veloren_query_server/
proto.rs1#![expect(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))]
22pub enum QueryServerRequest {
23 Init,
30 ServerInfo,
31 }
35
36#[derive(Protocol, Debug, Clone, Copy)]
37pub(crate) struct Init {
38 pub p: u64,
45 pub max_supported_version: u16,
51}
52
53#[derive(Protocol, Debug, Clone, Copy)]
54#[protocol(discriminant = "integer")]
55#[protocol(discriminator(u8))]
56pub(crate) enum RawQueryServerResponse {
57 Response(QueryServerResponse),
58 Init(Init),
59}
60
61#[derive(Protocol, Debug, Clone, Copy)]
62#[protocol(discriminant = "integer")]
63#[protocol(discriminator(u8))]
64pub enum QueryServerResponse {
65 ServerInfo(ServerInfo),
66 }
68
69#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
70pub struct ServerInfo {
71 pub git_hash: u32,
72 pub git_timestamp: i64,
73 pub players_count: u16,
74 pub player_cap: u16,
75 pub battlemode: ServerBattleMode,
76}
77
78#[derive(Protocol, Debug, Clone, Copy, PartialEq, Eq)]
79#[protocol(discriminant = "integer")]
80#[protocol(discriminator(u8))]
81#[repr(u8)]
82pub enum ServerBattleMode {
83 GlobalPvP,
84 GlobalPvE,
85 PerPlayer,
86}
87
88impl RawQueryServerRequest {
89 #[cfg(any(feature = "client", test))]
90 pub fn serialize(&self) -> Result<Vec<u8>, protocol::Error> {
91 use protocol::Parcel;
92
93 let mut buf = Vec::with_capacity(MAX_REQUEST_SIZE);
94
95 buf.extend(VERSION.to_le_bytes());
97 buf.extend({
98 let request_data =
99 <RawQueryServerRequest as Parcel>::raw_bytes(self, &Default::default())?;
100 if request_data.len() > MAX_REQUEST_CONTENT_SIZE {
101 panic!(
102 "Attempted to send request larger than the max size (size: {}, max size: \
103 {MAX_REQUEST_CONTENT_SIZE}, request: {self:?})",
104 request_data.len()
105 );
106 }
107 request_data
108 });
109 const _: () = assert!(MAX_RESPONSE_SIZE + VELOREN_HEADER.len() <= MAX_REQUEST_SIZE);
110 buf.resize(MAX_RESPONSE_SIZE.max(buf.len()), 0);
111 buf.extend(VELOREN_HEADER);
112 Ok(buf)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::{QueryServerRequest, RawQueryServerRequest};
119
120 #[test]
121 fn check_request_sizes() {
122 const ALL_REQUESTS: &[QueryServerRequest] =
123 &[QueryServerRequest::ServerInfo, QueryServerRequest::Init];
124 for request in ALL_REQUESTS {
125 let request = RawQueryServerRequest {
126 p: 0,
127 request: *request,
128 };
129 request.serialize().unwrap(); }
131 }
132}