Synvael/crates/shared/src/session.rs

44 lines
1.8 KiB
Rust

// SPDX-License-Identifier: AGPL-3.0-only
//! Session-level concepts describing the relationship between a client and the server it is playing against.
/// Which kind of server a client session is running against.
///
/// Deliberately not part of the wire protocol. The client already knows the answer without asking: it either spawned a server in-process or dialled a socket. A server-declared field would be redundant at best and spoofable at worst, so the value is constructed client-side from facts the client already holds.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ServerKind {
/// The server runs in this process, backing single-player.
Integrated,
/// The server is a separate process reached over the network.
Dedicated {
/// Whether the server's address is off this machine. Decided from the `SocketAddr` the client dialled, not from anything the server says.
remote: bool,
},
}
impl ServerKind {
/// Classifies a dedicated server from the address the client dialled.
///
/// A loopback address means the process is on this machine (a locally hosted server), which is distinct from an integrated one: it is still a separate process reached over a socket.
#[must_use]
pub const fn dedicated(addr: std::net::SocketAddr) -> Self {
Self::Dedicated {
remote: !addr.ip().is_loopback(),
}
}
/// Returns a short human-readable label for the session's server kind.
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Integrated => "integrated",
Self::Dedicated { remote: false } => "dedicated (local)",
Self::Dedicated { remote: true } => "dedicated (remote)",
}
}
}
#[cfg(test)]
#[path = "tests/session.rs"]
mod tests;