aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-03-19 09:55:56 +0100
committerKatharina Fey <kookie@spacekookie.de>2020-03-19 09:55:56 +0100
commit885fcaf2f272d898a265f1b7416ede5801240867 (patch)
tree037879feac8c2802289bd6b63780fecee775af4c
parent64a0db905d24270a2af0faeef99c11f33aa601a0 (diff)
Adding color handling and basic lobby logic
-rw-r--r--Cargo.lock4
-rw-r--r--Cargo.toml4
-rw-r--r--src/data.rs80
-rw-r--r--src/lobby.rs87
4 files changed, 174 insertions, 1 deletions
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 <kookie@spacekookie.de>"]
[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<Color> {
+ 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<BTreeMap<LobbyId, Arc<MetaLobby>>>,
+}
+
+/// 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<Color>,
+ 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);
+ }
+}