diff options
Diffstat (limited to 'games/rstnode/rst-core/src')
23 files changed, 472 insertions, 84 deletions
diff --git a/games/rstnode/rst-core/src/_if.rs b/games/rstnode/rst-core/src/_if.rs index 1a842840708c..f3ed8ee5ffde 100644 --- a/games/rstnode/rst-core/src/_if.rs +++ b/games/rstnode/rst-core/src/_if.rs @@ -1,8 +1,8 @@ //! A common trait interface between the server and the client use crate::wire::{ - Action, AuthErr, Lobby, LobbyErr, LobbyId, LobbyUpdate, MatchErr, MatchId, RegErr, UpdateState, - User, UserId, + game::Action, AuthErr, Lobby, LobbyErr, LobbyId, LobbyUpdate, MatchErr, MatchId, RegErr, + UpdateState, User, UserId, }; use async_std::sync::Arc; use async_trait::async_trait; diff --git a/games/rstnode/rst-core/src/_match.rs b/games/rstnode/rst-core/src/_match.rs index ce75af5af393..e1cc45374ebc 100644 --- a/games/rstnode/rst-core/src/_match.rs +++ b/games/rstnode/rst-core/src/_match.rs @@ -1,8 +1,9 @@ use crate::{ data::Player, lobby::MetaLobby, + mailbox::{Inbox, Outbox}, map::Map, - wire::{Action, LobbyUser, MatchId, UserId}, + wire::{game::Action, LobbyUser, MatchId, UserId}, }; use async_std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; @@ -23,7 +24,9 @@ pub struct Match { /// The active game map pub map: Map, /// Input inbox (handled in-order each game tick) - inbox: RwLock<VecDeque<Action>>, + inbox: Inbox, + /// Update outbox + outbox: Outbox, /// The time the match was initialised init_t: DateTime<Utc>, /// The synced time the match was started @@ -46,7 +49,8 @@ impl From<MetaLobby> for Match { }) .collect(), map: Map::new(), - inbox: Default::default(), + inbox: Inbox::new(), + outbox: Outbox::new(), init_t: Utc::now(), start_t: None, } @@ -61,7 +65,7 @@ impl Match { /// Queue a new game action pub async fn queue(&self, cmd: Action) { - self.inbox.write().await.push_back(cmd); + self.inbox.queue(cmd).await; } pub async fn handle_inbox(&mut self) { diff --git a/games/rstnode/rst-core/src/data.rs b/games/rstnode/rst-core/src/data.rs index d0494fdef3e2..44d4e2a1a456 100644 --- a/games/rstnode/rst-core/src/data.rs +++ b/games/rstnode/rst-core/src/data.rs @@ -4,10 +4,13 @@ use crate::io::Io; use async_std::sync::Arc; -use rand::seq::SliceRandom; -use rand::thread_rng; +use rand::{seq::SliceRandom, thread_rng}; +use ratman::Router; use serde::{Deserialize, Serialize}; -use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU32}; +use std::{ + collections::VecDeque, + sync::atomic::{AtomicBool, AtomicU16, AtomicU32, Ordering}, +}; pub type NodeId = usize; @@ -31,9 +34,12 @@ pub struct Node { pub links: u8, /// Active link states pub link_states: Vec<Arc<Link>>, + /// Router state + #[serde(skip)] + pub router: Option<Router>, /// Input buffer #[serde(skip)] - pub buffer: Vec<Packet>, + pub buffer: VecDeque<Packet>, } pub type LinkId = usize; @@ -42,19 +48,19 @@ pub type LinkId = usize; #[derive(Serialize, Deserialize)] pub struct Link { /// This link ID - id: LinkId, + pub id: LinkId, /// Node 1 - a: NodeId, + pub a: NodeId, /// Node 2 - b: NodeId, + pub b: NodeId, /// The step length - length: usize, + pub length: usize, /// Packets present on this link #[serde(skip)] - pp: Vec<(Packet, AtomicU32)>, + pub pp: Vec<(Packet, AtomicU32)>, /// Actual Rx, Tx pair #[serde(skip)] - io: Io, + pub io: Io, } pub type PacketId = usize; @@ -86,8 +92,27 @@ pub struct Player { pub money: AtomicU16, } +// This is required because atomics can't safely be cloned +impl Clone for Player { + fn clone(&self) -> Self { + let Self { + ref id, + ref name, + ref color, + ref money, + } = self; + + Self { + id: id.clone(), + name: name.clone(), + color: color.clone(), + money: money.load(Ordering::Relaxed).into(), + } + } +} + /// Optionally, players can create teams -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct Team { /// Name of the team name: String, @@ -189,8 +214,6 @@ pub enum Owner { Player(Player), } - - /// Encodes upgrade level without numbers #[derive(Copy, Clone, Serialize, Deserialize)] pub enum Level { diff --git a/games/rstnode/rst-core/src/error.rs b/games/rstnode/rst-core/src/error.rs new file mode 100644 index 000000000000..38c93bbe823f --- /dev/null +++ b/games/rstnode/rst-core/src/error.rs @@ -0,0 +1,51 @@ +pub use crate::wire::{AuthErr, LobbyErr, MatchErr, RegErr}; +use serde::{Deserialize, Serialize}; +use std::fmt::{self, Display, Formatter}; + +/// A wrapper around the different RST node errors that can occur +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Error { + /// Failure in the registration process + Register(RegErr), + /// Failure in the authentication process + Auth(AuthErr), + /// Failure handling a lobby + Lobby(LobbyErr), + /// Failure in a match setting + Match(MatchErr), +} + +impl std::error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "An RST error") + } +} + +/// A RST Node specific error +pub type Result<T> = std::result::Result<T, Error>; + +impl From<RegErr> for Error { + fn from(e: RegErr) -> Self { + Error::Register(e) + } +} + +impl From<AuthErr> for Error { + fn from(e: AuthErr) -> Self { + Error::Auth(e) + } +} + +impl From<LobbyErr> for Error { + fn from(e: LobbyErr) -> Self { + Error::Lobby(e) + } +} + +impl From<MatchErr> for Error { + fn from(e: MatchErr) -> Self { + Error::Match(e) + } +} diff --git a/games/rstnode/rst-core/src/lib.rs b/games/rstnode/rst-core/src/lib.rs index 5ee4e49750c9..dc1a84f63b58 100644 --- a/games/rstnode/rst-core/src/lib.rs +++ b/games/rstnode/rst-core/src/lib.rs @@ -13,9 +13,15 @@ //! which is them implemented by [Server](crate::server::Server), and //! [MatchClient](crate::client::MatchClient). +// Remove the warning spam +#![allow(warnings)] + #[macro_use] extern crate const_env; +#[macro_use] +extern crate tracing; + pub(crate) mod _loop; mod _if; @@ -26,11 +32,14 @@ pub use _match::Match; pub mod config; pub mod data; +pub mod error; pub mod gens; pub mod io; pub mod lobby; +pub mod mailbox; pub mod map; pub mod mapstore; +pub mod net; pub mod server; pub mod stats; pub mod users; diff --git a/games/rstnode/rst-core/src/lobby.rs b/games/rstnode/rst-core/src/lobby.rs index 496f98bd7b6f..d58ba7ceb8ee 100644 --- a/games/rstnode/rst-core/src/lobby.rs +++ b/games/rstnode/rst-core/src/lobby.rs @@ -2,6 +2,7 @@ use crate::{ data::{Color, ColorPalette}, + mailbox::Outbox, users::MetaUser, wire::{Lobby, LobbyErr, LobbyId, LobbyUpdate, LobbyUser, User, UserId}, }; @@ -68,6 +69,7 @@ impl LobbyList { pub struct MetaLobby { pub palette: Vec<Color>, pub inner: Lobby, + pub outbox: Outbox, } impl MetaLobby { @@ -80,6 +82,7 @@ impl MetaLobby { players: vec![], settings: vec![], }, + outbox: Outbox::new(), } } diff --git a/games/rstnode/rst-core/src/mailbox.rs b/games/rstnode/rst-core/src/mailbox.rs new file mode 100644 index 000000000000..c7e4512dbeae --- /dev/null +++ b/games/rstnode/rst-core/src/mailbox.rs @@ -0,0 +1,78 @@ +use crate::wire::{ + game::{Action, Update}, + Lobby, +}; + +use async_std::sync::RwLock; +use std::collections::VecDeque; + +pub enum ClientUpdate { + /// Change to the lobby state + Lobby(Lobby), + /// A game simulation update + GameUpdate(Update), +} + +impl<'l> From<&'l Lobby> for ClientUpdate { + fn from(l: &'l Lobby) -> Self { + ClientUpdate::Lobby(l.clone()) + } +} + +impl<'l> From<&'l Update> for ClientUpdate { + fn from(u: &'l Update) -> Self { + ClientUpdate::GameUpdate(u.clone()) + } +} + +/// A message out buffer that can be attached to any server entity +pub struct Outbox { + queue: RwLock<VecDeque<ClientUpdate>>, +} + +impl Outbox { + pub fn new() -> Self { + Self { + queue: Default::default(), + } + } + + /// Queue a new item to send out + pub async fn queue(&self, update: impl Into<ClientUpdate>) { + let mut q = self.queue.write().await; + q.push_back(update.into()); + } + + /// Run a closure for all queued items + pub async fn run_for<F: Fn(&ClientUpdate)>(&self, handle: F) { + let q = self.queue.read().await; + q.iter().for_each(|item| handle(item)); + } + + /// Clear the outbox for the next update interval + pub async fn clear(&self) { + self.queue.write().await.clear(); + } +} + +pub struct Inbox { + queue: RwLock<VecDeque<Action>>, +} + +impl Inbox { + pub fn new() -> Self { + Self { + queue: Default::default(), + } + } + + /// Queue a new item to send out + pub async fn queue(&self, update: impl Into<Action>) { + let mut q = self.queue.write().await; + q.push_back(update.into()); + } + + pub async fn pop(&self) -> Option<Action> { + self.queue.write().await.pop_front() + } +} diff --git a/games/rstnode/rst-core/src/map.rs b/games/rstnode/rst-core/src/map.rs index 37f758b4a433..8c6578177e6c 100644 --- a/games/rstnode/rst-core/src/map.rs +++ b/games/rstnode/rst-core/src/map.rs @@ -1,17 +1,11 @@ //! Implements a map graph and world logic use crate::{ - config::{LinkCfg, MapCfg, NodeCfg}, data::{Link, Node, NodeId}, - server::{ServerErr, ServerResult}, wire::Response, }; use async_std::sync::Arc; -use quadtree_rs::{ - area::{Area, AreaBuilder}, - point::Point, - Quadtree, -}; +use quadtree_rs::{area::AreaBuilder, point::Point, Quadtree}; use std::collections::BTreeMap; pub struct MapNode { @@ -29,7 +23,7 @@ pub struct Map { /// Node IDs mapped to coordinates nodes: BTreeMap<NodeId, (i64, i64)>, /// Link IDs mapped to link objects - links: BTreeMap<u16, Arc<Link>>, + _links: BTreeMap<u16, Arc<Link>>, /// A coordinate map for the network coord: Quadtree<i64, Arc<MapNode>>, } @@ -38,16 +32,14 @@ impl Map { pub fn new() -> Self { Self { nodes: BTreeMap::new(), - links: BTreeMap::new(), + _links: BTreeMap::new(), coord: Quadtree::new(2), } } - pub fn update<F>(&mut self, cb: F) -> ServerResult<Response> - where - F: Fn(&mut Map) -> ServerResult<Response>, - { - unimplemented!() + /// Get the position of a node by its ID + pub fn node_position(&self, id: NodeId) -> Option<(i64, i64)> { + self.nodes.get(&id).cloned() } /// Get all objects that can be selected by a single point diff --git a/games/rstnode/rst-core/src/net/endpoint.rs b/games/rstnode/rst-core/src/net/endpoint.rs new file mode 100644 index 000000000000..0c8e2f912421 --- /dev/null +++ b/games/rstnode/rst-core/src/net/endpoint.rs @@ -0,0 +1,49 @@ +use crate::{server::Server, Id}; +use async_std::{ + net::UdpSocket, + sync::{Arc, RwLock}, + task, +}; +use std::{ + collections::BTreeMap, + net::SocketAddr, + sync::atomic::{AtomicBool, Ordering}, +}; + +pub struct Endpoint { + running: AtomicBool, + socket: UdpSocket, + bind: String, + clients: RwLock<BTreeMap<Id, Client>>, +} + +pub struct Client {} + +impl Endpoint { + pub async fn new(bind: &str) -> Arc<Self> { + let socket = UdpSocket::bind(bind).await.unwrap(); + Arc::new(Self { + running: true.into(), + socket, + bind: bind.into(), + clients: Default::default(), + }) + } + + /// Stop the endpoint + pub fn stop(self: &Arc<Self>) { + self.running.store(false, Ordering::Relaxed); + } + + pub async fn listen(self: &Arc<Self>, serv: Arc<Server>) { + let mut buf = vec![0; 1024]; + + info!("Listening for connections on {}", self.bind); + while self.running.load(Ordering::Relaxed) { + let (int, peer) = self.socket.recv_from(&mut buf).await.unwrap(); + if int > 1024 { + warn!("Read a larger chunk than buffer?"); + } + } + } +} diff --git a/games/rstnode/rst-core/src/net/gen.rs b/games/rstnode/rst-core/src/net/gen.rs new file mode 100644 index 000000000000..f0a1f58f1905 --- /dev/null +++ b/games/rstnode/rst-core/src/net/gen.rs @@ -0,0 +1,52 @@ +use crate::{ + error::Error, + wire::{ + AuthErr, Lobby, LobbyErr, LobbyId, LobbyUpdate, MatchErr, RegErr, Response, UpdateState, + User, UserId, + }, +}; +use chrono::{DateTime, Utc}; + +pub fn register(r: Result<UserId, RegErr>) -> Response { + Response::Register(r) +} + +pub fn login(r: Result<User, AuthErr>) -> Response { + Response::Login(r) +} + +pub fn logout(r: Result<(), AuthErr>) -> Response { + Response::Logout(r) +} + +pub fn rooms(r: Vec<(String, LobbyId)>) -> Response { + Response::Rooms(r) +} + +pub fn join(r: Result<Lobby, LobbyErr>) -> Response { + Response::Join(r) +} + +pub fn leave(r: Result<(), LobbyErr>) -> Response { + Response::Leave(r) +} + +pub fn ready(r: LobbyUpdate) -> Response { + Response::Ready(r) +} + +pub fn start_req(r: DateTime<Utc>) -> Response { + Response::StartReq(r) +} + +pub fn game_update(r: UpdateState) -> Response { + Response::GameUpdate(r) +} + +pub fn leave_game(r: Result<(), MatchErr>) -> Response { + Response::LeaveGame(r) +} + +pub fn invalid() -> Response { + Response::Invalid +} diff --git a/games/rstnode/rst-core/src/net/handler.rs b/games/rstnode/rst-core/src/net/handler.rs new file mode 100644 index 000000000000..aa0ab6a281c5 --- /dev/null +++ b/games/rstnode/rst-core/src/net/handler.rs @@ -0,0 +1,17 @@ +use crate::{ + net::Client, + server::Server, + wire::{Request, Response}, +}; +use async_std::sync::{Receiver, Sender}; + +pub struct Handler { + tx: Sender<Response>, +} + +impl Handler { + /// Start a message handler with a handle to send a reply back to the clients + pub fn start(req: Request) { + + } +} diff --git a/games/rstnode/rst-core/src/net/mod.rs b/games/rstnode/rst-core/src/net/mod.rs new file mode 100644 index 000000000000..f60cb3b97668 --- /dev/null +++ b/games/rstnode/rst-core/src/net/mod.rs @@ -0,0 +1,20 @@ +mod endpoint; +pub use endpoint::*; + +mod gen; +pub use gen::*; + +mod handler; +pub use handler::*; + +mod parser; +pub use parser::*; + +// #[async_std::test] +// async fn user_connection() { +// let serv = Server::new(); +// let ep = Endpoint::new("localhost:9999").await; +// task::spawn(async move { ep.listen(serv).await }); + +// // Create a fake client here +// } diff --git a/games/rstnode/rst-core/src/net/parser.rs b/games/rstnode/rst-core/src/net/parser.rs new file mode 100644 index 000000000000..d7fdf3de964a --- /dev/null +++ b/games/rstnode/rst-core/src/net/parser.rs @@ -0,0 +1,17 @@ +use crate::{ + error::Error, + wire::{Request, Response}, + GameIf, +}; +use std::sync::Arc; + +/// Parse a request and call a game interface function for it +pub async fn request(req: Request, game: Arc<impl GameIf>) -> Response { + use Request::*; + match req { + Register(name, pw) => super::register(game.register(name, pw).await), + Login(name, pw_hash) => super::login(game.login(name, pw_hash).await), + Logout(user) => super::logout(game.logout(user).await), + _ => super::invalid(), + } +} diff --git a/games/rstnode/rst-core/src/server.rs b/games/rstnode/rst-core/src/server.rs index 3d95c3638c98..68fa2a074e34 100644 --- a/games/rstnode/rst-core/src/server.rs +++ b/games/rstnode/rst-core/src/server.rs @@ -4,18 +4,17 @@ //! connections according to a address given to the initialiser. use crate::{ - _if::GameIf, - _match::Match, data::Player, lobby::LobbyList, map::Map, users::UserStore, wire::{ - Action, AuthErr, Lobby, LobbyErr, LobbyId, LobbyUpdate, MatchErr, MatchId, RegErr, + game::Action, AuthErr, Lobby, LobbyErr, LobbyId, LobbyUpdate, MatchErr, MatchId, RegErr, Response, UpdateState, User, UserId, }, + GameIf, Match, }; -use async_std::sync::{Arc, Mutex, RwLock}; +use async_std::sync::{Arc, Mutex}; use async_trait::async_trait; use chrono::{DateTime, Utc}; use std::{collections::BTreeMap, path::Path}; @@ -40,12 +39,12 @@ pub struct Server { impl Server { /// Create a new game server - fn new() -> Self { - Self { + pub(crate) fn new() -> Arc<Self> { + Arc::new(Self { matches: Default::default(), users: UserStore::new(), lobbies: LobbyList::new(), - } + }) } /// Open the state dir of a game server @@ -68,15 +67,15 @@ impl Server { Ok(0) } - pub async fn update_map<F>(self: Arc<Self>, id: MatchId, cb: F) -> ServerResult<Response> - where - F: Fn(&mut Map) -> ServerResult<Response>, - { - match self.matches.get(&id) { - Some(ref m) => m.lock().await.map.update(cb), - None => Err(ServerErr::NoSuchMatch), - } - } + // pub async fn update_map<F>(self: Arc<Self>, id: MatchId, cb: F) -> ServerResult<Response> + // where + // F: Fn(&mut Map) -> ServerResult<Response>, + // { + // match self.matches.get(&id) { + // Some(ref m) => m.lock().await.map.update(cb), + // None => Err(ServerErr::NoSuchMatch), + // } + // } pub async fn update_players<F>(self: Arc<Self>, id: MatchId, cb: F) -> ServerResult<Response> where @@ -91,31 +90,32 @@ impl Server { #[async_trait] impl GameIf for Server { - async fn register(self: Arc<Self>, name: String, pw: String) -> Result<UserId, RegErr> { - unimplemented!() + async fn register(self: Arc<Self>, _name: String, _pw: String) -> Result<UserId, RegErr> { + todo!() } - async fn login(self: Arc<Self>, name: String, pw: String) -> Result<User, AuthErr> { - unimplemented!() + async fn login(self: Arc<Self>, _name: String, _pw: String) -> Result<User, AuthErr> { + todo!() } - async fn logout(self: Arc<Self>, user: User) -> Result<(), AuthErr> { - unimplemented!() + async fn logout(self: Arc<Self>, _user: User) -> Result<(), AuthErr> { + todo!() } async fn anonymous(self: Arc<Self>, name: String) -> Result<User, AuthErr> { - let (_, auth) = self.users.add(name, None, true).await; - Ok(auth) + // let (_, auth) = self.users.add(name, None, true).await; + // Ok(auth) + todo!() } async fn join(self: Arc<Self>, user: User, lobby: LobbyId) -> Result<Lobby, LobbyErr> { let mu = self.users.get(&user).await?; - self.lobbies.get_mut(lobby, |mut l| l.join(&mu)).await + self.lobbies.get_mut(lobby, |l| l.join(&mu)).await } async fn leave(self: Arc<Self>, user: User, lobby: LobbyId) -> Result<(), LobbyErr> { let mu = self.users.get(&user).await?; - self.lobbies.get_mut(lobby, |mut l| l.leave(&mu)).await + self.lobbies.get_mut(lobby, |l| l.leave(&mu)).await } async fn ready( @@ -124,9 +124,7 @@ impl GameIf for Server { lobby: LobbyId, ready: bool, ) -> Result<LobbyUpdate, LobbyErr> { - self.lobbies - .get_mut(lobby, |mut l| l.ready(user, ready)) - .await + self.lobbies.get_mut(lobby, |l| l.ready(user, ready)).await } /// A start request was received @@ -135,8 +133,8 @@ impl GameIf for Server { user: UserId, lobby: LobbyId, ) -> Result<DateTime<Utc>, LobbyErr> { - self.lobbies.get_mut(lobby, |mut l| l.start(user)).await?; - let lob = self.lobbies.consume(lobby).await?; + self.lobbies.get_mut(lobby, |l| l.start(user)).await??; + let _lob = self.lobbies.consume(lobby).await?; Ok(Utc::now()) } @@ -149,7 +147,7 @@ impl GameIf for Server { unimplemented!() } - async fn leave_match(self: Arc<Self>, user: User, mtch: MatchId) -> Result<(), MatchErr> { + async fn leave_match(self: Arc<Self>, _user: User, _mtch: MatchId) -> Result<(), MatchErr> { unimplemented!() } } diff --git a/games/rstnode/rst-core/src/wire/action.rs b/games/rstnode/rst-core/src/wire/game/action.rs index 22ab7ce6868e..22ab7ce6868e 100644 --- a/games/rstnode/rst-core/src/wire/action.rs +++ b/games/rstnode/rst-core/src/wire/game/action.rs diff --git a/games/rstnode/rst-core/src/wire/game/mod.rs b/games/rstnode/rst-core/src/wire/game/mod.rs new file mode 100644 index 000000000000..2cb32cbaa79c --- /dev/null +++ b/games/rstnode/rst-core/src/wire/game/mod.rs @@ -0,0 +1,5 @@ +mod action; +pub use action::*; + +mod update; +pub use update::*; diff --git a/games/rstnode/rst-core/src/wire/update.rs b/games/rstnode/rst-core/src/wire/game/update.rs index a1b47ff07e50..44a2e646bd34 100644 --- a/games/rstnode/rst-core/src/wire/update.rs +++ b/games/rstnode/rst-core/src/wire/game/update.rs @@ -1,11 +1,13 @@ //! Update to the game state -use super::UserId; -use crate::data::{NodeId, PacketId, Player, Upgrade}; +use crate::{ + data::{NodeId, PacketId, Player, Upgrade}, + wire::UserId, +}; use serde::{Deserialize, Serialize}; /// An update provided by the game server -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum Update { /// Update made to a node Node(NodeUpdate), @@ -20,7 +22,7 @@ pub enum Update { } /// Update made to a node -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum NodeUpdate { /// The node owner changed Owner(Player), @@ -35,7 +37,7 @@ pub enum NodeUpdate { } /// Update made to a link -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum LinkUpdate { /// Take a packet from a node's buffer TakePacket(PacketId), @@ -44,20 +46,21 @@ pub enum LinkUpdate { } /// Update made to a packet -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum PacketUpdate { /// Advance a packet along one step along the link Increment(PacketId), } /// Update made to the user set -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum UserUpdate { UserLeft(UserId), + UserPaused(UserId), } /// An error occured, can be non-fatal -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum UpdateError { /// You are the last user in the match LastUser, diff --git a/games/rstnode/rst-core/src/wire/mod.rs b/games/rstnode/rst-core/src/wire/mod.rs index 493f0bcb6885..1f15bca79028 100644 --- a/games/rstnode/rst-core/src/wire/mod.rs +++ b/games/rstnode/rst-core/src/wire/mod.rs @@ -1,20 +1,19 @@ //! Network formats and container messages -mod action; -pub use action::*; - mod env; pub use env::*; +pub mod game; + +mod proto; +pub use proto::*; + mod resp; pub use resp::*; mod req; pub use req::*; -mod update; -pub use update::*; - use crate::{data::Color, Id}; use serde::{Deserialize, Serialize}; diff --git a/games/rstnode/rst-core/src/wire/proto/mod.rs b/games/rstnode/rst-core/src/wire/proto/mod.rs new file mode 100644 index 000000000000..07598bc85540 --- /dev/null +++ b/games/rstnode/rst-core/src/wire/proto/mod.rs @@ -0,0 +1,25 @@ +//! This module implements the client-server game protocol + +use super::{Request, Response}; + +pub enum NetErr { + Refused, + Dropped, + Timeout, + BadData, +} + +/// Use this function to send a request to a partical remote +/// +/// The function makes sure that you get a valid response back, but +/// does not yet ensure that this response is correct for the request +/// in question. +pub fn request_to(r: Request, remote: String) -> Result<Response, NetErr> { + todo!() +} + +/// Use this function to send a response to a client +pub fn response_to(r: Response, client: String) -> Result<(), NetErr> { + todo!() +} + diff --git a/games/rstnode/rst-core/src/wire/proto/request.rs b/games/rstnode/rst-core/src/wire/proto/request.rs new file mode 100644 index 000000000000..a95c240c4a14 --- /dev/null +++ b/games/rstnode/rst-core/src/wire/proto/request.rs @@ -0,0 +1,41 @@ +use crate::wire::{Action, LobbyId, MatchId, Request, User}; + +pub fn register(name: String, pw: String) -> Request { + Request::Register(name, pw) +} +c +pub fn login(name: String, pw: String) -> Request { + Request::Login(name, pw) +} + +pub fn logout(user: User) -> Request { + Request::Logout(user) +} + +pub fn anonymous(name: String) -> Request { + Request::Anonymous(name) +} + +pub fn join(user: User, lid: LobbyId) -> Request { + Request::Join(user, lid) +} + +pub fn leave(user: User, lid: LobbyId) -> Request { + Request::Leave(user, lid) +} + +pub fn ready(user: User, lid: LobbyId, ready: bool) -> Request { + Request::Ready(user, lid, ready) +} + +pub fn start_req(user: User, lid: LobbyId) -> Request { + Request::StartReq(user, lid) +} + +pub fn game_action(user: User, mid: MatchId, act: Action) -> Request { + Request::GameAction(user, mid, act) +} + +pub fn leave_game(user: User, mid: MatchId) -> Request { + Request::LeaveGame(user, mid) +} diff --git a/games/rstnode/rst-core/src/wire/proto/response.rs b/games/rstnode/rst-core/src/wire/proto/response.rs new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/games/rstnode/rst-core/src/wire/proto/response.rs diff --git a/games/rstnode/rst-core/src/wire/req.rs b/games/rstnode/rst-core/src/wire/req.rs index ffefcbdb6ac7..be5c905795a9 100644 --- a/games/rstnode/rst-core/src/wire/req.rs +++ b/games/rstnode/rst-core/src/wire/req.rs @@ -1,4 +1,4 @@ -use super::{action::Action, LobbyId, MatchId, User}; +use super::{game::Action, LobbyId, MatchId, User}; use serde::{Deserialize, Serialize}; /// A message sent from the game client to the server diff --git a/games/rstnode/rst-core/src/wire/resp.rs b/games/rstnode/rst-core/src/wire/resp.rs index ef2e192a6044..99598cceb9e6 100644 --- a/games/rstnode/rst-core/src/wire/resp.rs +++ b/games/rstnode/rst-core/src/wire/resp.rs @@ -27,9 +27,11 @@ pub enum Response { GameUpdate(UpdateState), /// Leave the match (forfeit) LeaveGame(Result<(), MatchErr>), + /// The given request was entirely invalid + Invalid, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum RegErr { /// The password is way too bad BadPassword, @@ -39,7 +41,7 @@ pub enum RegErr { OtherError, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum AuthErr { /// Wrong password for the user WrongPassword, @@ -51,7 +53,7 @@ pub enum AuthErr { OtherError, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum LobbyErr { /// The requested room is already full RoomFull, @@ -85,7 +87,7 @@ pub enum UpdateState { } /// An error that can occur in a match -#[derive(Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum MatchErr { /// The provided player wasn't in the match (anymore?) NotInMatch, |