|
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
|
|
|
|
|
|
|
|
#![deny(unsafe_code)]
|
|
|
|
#![deny(missing_docs)]
|
|
|
|
|
|
|
|
//! Xash3D protocol between clients, servers and masters.
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
|
|
|
|
|
|
|
mod cursor;
|
|
|
|
mod server_info;
|
|
|
|
|
|
|
|
pub mod admin;
|
|
|
|
pub mod color;
|
|
|
|
pub mod filter;
|
|
|
|
pub mod game;
|
|
|
|
pub mod master;
|
|
|
|
pub mod server;
|
|
|
|
pub mod wrappers;
|
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
pub use cursor::CursorError;
|
|
|
|
pub use server_info::ServerInfo;
|
|
|
|
|
|
|
|
use crate::filter::Version;
|
|
|
|
|
|
|
|
/// Current protocol version.
|
|
|
|
pub const PROTOCOL_VERSION: u8 = 49;
|
|
|
|
/// Current client version.
|
|
|
|
pub const CLIENT_VERSION: Version = Version::new(0, 20);
|
|
|
|
|
|
|
|
/// The error type for decoding and encoding packets.
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum Error {
|
|
|
|
/// Failed to decode a packet.
|
|
|
|
InvalidPacket,
|
|
|
|
/// Invalid region.
|
|
|
|
InvalidRegion,
|
|
|
|
/// Invalid client announce IP.
|
|
|
|
InvalidClientAnnounceIp,
|
|
|
|
/// Invalid last IP.
|
|
|
|
InvalidQueryServersLast,
|
|
|
|
/// Server protocol version is not supported.
|
|
|
|
InvalidProtocolVersion,
|
|
|
|
/// Cursor error.
|
|
|
|
CursorError(CursorError),
|
|
|
|
/// Invalid value for server add packet.
|
|
|
|
InvalidServerValue(&'static str, CursorError),
|
|
|
|
/// Invalid value for query servers packet.
|
|
|
|
InvalidFilterValue(&'static str, CursorError),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::InvalidPacket => "Invalid packet".fmt(fmt),
|
|
|
|
Self::InvalidRegion => "Invalid region".fmt(fmt),
|
|
|
|
Self::InvalidClientAnnounceIp => "Invalid client announce IP".fmt(fmt),
|
|
|
|
Self::InvalidQueryServersLast => "Invalid last server IP".fmt(fmt),
|
|
|
|
Self::InvalidProtocolVersion => "Invalid protocol version".fmt(fmt),
|
|
|
|
Self::CursorError(source) => source.fmt(fmt),
|
|
|
|
Self::InvalidServerValue(key, source) => {
|
|
|
|
write!(
|
|
|
|
fmt,
|
|
|
|
"Invalid value for server add key `{}`: {}",
|
|
|
|
key, source
|
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::InvalidFilterValue(key, source) => {
|
|
|
|
write!(fmt, "Invalid value for filter key `{}`: {}", key, source)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
|
|
|
|
impl From<CursorError> for Error {
|
|
|
|
fn from(source: CursorError) -> Self {
|
|
|
|
Self::CursorError(source)
|
|
|
|
}
|
|
|
|
}
|