1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use bincode::{Decode, Encode};
use de_types::player::Player;
/// Message to be sent from a player/client to a game server (inside of a
/// game).
#[derive(Debug, Encode, Decode)]
pub enum ToGame {
/// Prompts the server to respond [`FromGame::Pong`] with the same ping ID.
Ping(u32),
/// Connect the player to the game.
Join,
/// Disconnect the player from the game.
///
/// The game is automatically closed once all players disconnect.
Leave,
/// Sets readiness of the client.
///
/// New readiness must be greater by one or equal to the current readiness.
/// See [`Readiness::progress`].
Readiness(Readiness),
}
/// Message to be sent from a game server to a player/client (inside of a
/// game).
///
/// # Notes
///
/// * Players are numbered from 1 to `max_players` (inclusive).
#[derive(Debug, Encode, Decode)]
pub enum FromGame {
/// Response to [`ToGame::Ping`].
Pong(u32),
/// Informs the player that the server has discarded one or more incoming
/// messages (to any peer) due to the player not being part of the game.
NotJoined,
/// Informs the player that they were just connected to the game under the
/// player number.
Joined(Player),
/// Informs the player that they were not connected to the game due to an
/// error.
JoinError(JoinError),
/// Informs the player the they is no longer part of the game. They might
/// has been kicked out of the game or left voluntarily.
Left,
/// Informs the player that another player just connected to the same game
/// under the given player number.
PeerJoined(Player),
/// Informs the player that another player with the given player number
/// just disconnected from the same game.
PeerLeft(Player),
/// Game readiness has changed.
GameReadiness(Readiness),
}
#[derive(Debug, Encode, Decode)]
pub enum JoinError {
GameFull,
/// The game is no longer opened.
GameNotOpened,
/// The player has already joined the game.
AlreadyJoined,
/// The player already participates on a different game.
DifferentGame,
}
/// Readiness of an individual client or the game as a whole. It consists of a
/// progression of individual variants / stages. Once all clients progress to a
/// readiness stage, the game progresses to that stage as well.
#[derive(Clone, Copy, Default, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
pub enum Readiness {
/// Initial stage for all clients and the game.
#[default]
NotReady,
/// The client / game is ready for the game to start.
Ready,
/// The client / game is prepared for game initialization to begin.
Prepared,
/// The client / game is ready for the game to start.
///
/// The actually game-play happens in this readiness stage.
Initialized,
}
impl Readiness {
pub fn progress(self) -> Option<Self> {
match self {
Self::NotReady => Some(Self::Ready),
Self::Ready => Some(Self::Prepared),
Self::Prepared => Some(Self::Initialized),
Self::Initialized => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_readiness() {
assert!(Readiness::default() < Readiness::Ready);
assert!(Readiness::NotReady < Readiness::Ready);
assert!(Readiness::Ready < Readiness::Prepared);
assert!(Readiness::Prepared < Readiness::Initialized);
assert!(Readiness::NotReady < Readiness::Initialized);
assert_eq!(Readiness::NotReady.progress().unwrap(), Readiness::Ready);
}
}