From 885fcaf2f272d898a265f1b7416ede5801240867 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Thu, 19 Mar 2020 09:55:56 +0100 Subject: Adding color handling and basic lobby logic --- Cargo.lock | 4 +++ Cargo.toml | 4 +++ src/data.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/lobby.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 src/lobby.rs diff --git a/Cargo.lock b/Cargo.lock index 7bbf4fb18eda..e770659226e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1910,6 +1910,7 @@ dependencies = [ "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2004,11 +2005,14 @@ name = "rstnode" version = "0.0.0" dependencies = [ "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "ggez 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "netmod-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "ratman 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ratman-identity 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 0d259f5b1824..8e9c96152b5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,12 +11,16 @@ authors = ["Katharina Fey "] [dependencies] serde = { version = "1.0", features = ["derive", "rc"] } async-std = { version = "1.0", features = ["unstable"] } +async-trait = "0.1" + ratman = "0.1.0" netmod-mem = "0.1.0" +identity = { version = "0.4", features = ["random"], package = "ratman-identity"} ggez = "0.5" cgmath = { version = "*", features = ["mint"] } chrono = { version = "0.4", features = ["serde"] } +rand = "0.7" # [profile.release.overrides."*"] # opt-level = 3 \ No newline at end of file diff --git a/src/data.rs b/src/data.rs index edec158d9963..4cfe0c09e463 100644 --- a/src/data.rs +++ b/src/data.rs @@ -2,6 +2,8 @@ use crate::io::Io; use async_std::sync::Arc; +use rand::seq::SliceRandom; +use rand::thread_rng; use serde::{Deserialize, Serialize}; use std::{ collections::BTreeMap, @@ -97,9 +99,85 @@ pub struct Team { } /// An RGB color without alpha -#[derive(Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Color(u8, u8, u8); +impl Color { + pub fn black() -> Self { + Self(50, 50, 50) + } + + pub fn red() -> Self { + Self(250, 50, 50) + } + + pub fn green() -> Self { + Self(100, 250, 100) + } + + pub fn blue() -> Self { + Self(100, 100, 250) + } + + pub fn teal() -> Self { + Self(150, 250, 250) + } + + pub fn purple() -> Self { + Self(150, 100, 250) + } + + pub fn orange() -> Self { + Self(250, 200, 100) + } + + pub fn yellow() -> Self { + Self(250, 250, 100) + } + + pub fn white() -> Self { + Self(225, 225, 225) + } +} + +pub trait ColorPalette { + /// Create a new color palette + fn palette() -> Self; + /// Get a palette without a certain colour + fn without(b: &Color) -> Self; + /// Mix a color back into the available palette + fn remix(&mut self, new: Color); +} + +impl ColorPalette for Vec { + fn palette() -> Self { + let mut rng = thread_rng(); + let mut pal = vec![ + Color::black(), + Color::red(), + Color::green(), + Color::blue(), + Color::teal(), + Color::purple(), + Color::orange(), + Color::yellow(), + Color::white(), + ]; + pal.shuffle(&mut rng); + pal + } + + fn without(b: &Color) -> Self { + Self::palette().into_iter().filter(|a| a == b).collect() + } + + fn remix(&mut self, new: Color) { + let mut rng = thread_rng(); + self.push(new); + self.shuffle(&mut rng); + } +} + /// Describes ownership state #[derive(Serialize, Deserialize)] pub enum Owner { diff --git a/src/lobby.rs b/src/lobby.rs new file mode 100644 index 000000000000..ac6ab305414a --- /dev/null +++ b/src/lobby.rs @@ -0,0 +1,87 @@ +//! The code that handles the lobby logic + +use crate::{ + data::{Color, ColorPalette}, + users::MetaUser, + wire::{Lobby, LobbyId, LobbyUser}, +}; +use async_std::sync::{Arc, RwLock}; +use std::{ + collections::BTreeMap, + sync::atomic::{AtomicUsize, Ordering}, +}; + +/// A list of all the lobbies on the server +pub struct LobbyList { + max: AtomicUsize, + users: RwLock>>, +} + +/// Additional state held by the server +/// +/// The meta lobby will also sync updates to all connected users, when updates are made to the lobby +pub struct MetaLobby { + palette: Vec, + inner: Lobby, +} + +impl MetaLobby { + pub fn create(id: LobbyId, map: String) -> Self { + Self { + palette: Vec::palette(), + inner: Lobby { + id, + map, + players: vec![], + settings: vec![], + }, + } + } + + pub fn join(&mut self, user: MetaUser) { + let color = if &user.name == "spacekookie" { + let color = Color::blue(); + + let num = self.inner.players.len(); + self.palette = Vec::without(&color); + let in_use = self.palette.split_off(num); + + self.inner + .players + .iter_mut() + .zip(in_use.into_iter()) + .for_each(|(user, color)| { + user.color = color; + }); + + color + } else { + self.palette.remove(0) + }; + + self.inner.players.push(LobbyUser { + id: user.id, + name: user.name, + ready: false, + color, + }); + } + + pub fn leave(&mut self, user: MetaUser) { + let (pos, user) = self + .inner + .players + .iter() + .enumerate() + .find_map(|(num, u)| { + if u.id == user.id { + Some((num, u)) + } else { + None + } + }) + .unwrap(); + self.palette.remix(user.color); + self.inner.players.remove(pos); + } +} -- cgit v1.2.3