diff --git a/client/src/components/game.rs b/client/src/components/game.rs
index 50514d9..158b416 100644
--- a/client/src/components/game.rs
+++ b/client/src/components/game.rs
@@ -11,7 +11,7 @@ pub fn Game() -> impl IntoView {
let (game_host, set_game_host) = create_signal("".to_string());
let (game_players, set_game_players) = create_signal(vec![]);
let (game_czar, set_game_czar) = create_signal("".to_string());
- let (game_black, set_game_black) = create_signal("".to_string());
+ let (game_black, set_game_black) = create_signal(("".to_string(), 0u8));
let (game_white, set_game_white) = create_signal(vec![]);
create_effect(move |_| {
@@ -28,12 +28,12 @@ pub fn Game() -> impl IntoView {
view! {
Game
-
Name: {move || game_name}
-
Host: {move || game_host}
-
Players: {move || game_players}
-
Czar: {move || game_czar}
-
Black Card: {move || game_black}
-
Your Cards: {move || game_white}
+
Name: {move || game_name()}
+
Host: {move || game_host()}
+
Players: {move || game_players()}
+
Czar: {move || game_czar()}
+
Black Card: {move || game_black().0} Pick: {move || game_black().1}
+
Your Cards: {move || game_white()}
}
}
diff --git a/lib/src/lib.rs b/lib/src/lib.rs
index 02a2fc8..3b03501 100644
--- a/lib/src/lib.rs
+++ b/lib/src/lib.rs
@@ -7,7 +7,7 @@ pub struct GameMeta {
pub host: String,
pub players: Vec,
pub czar: String,
- pub black: String,
+ pub black: (String, u8),
pub white: Vec,
}
diff --git a/server/src/game_handler.rs b/server/src/game_handler.rs
index 48ef034..0012fed 100644
--- a/server/src/game_handler.rs
+++ b/server/src/game_handler.rs
@@ -1,87 +1,171 @@
use crate::user_handler::*;
use crate::AppState;
use crate::User;
-use anyhow::Result;
+use anyhow::{Context, Result};
use lib::*;
use rand::prelude::IteratorRandom;
use rand::thread_rng;
use serde::Deserialize;
use std::{
collections::HashMap,
+ fs::read_to_string,
net::SocketAddr,
sync::{Arc, RwLock},
};
use uuid::Uuid;
-// This file is disgusting, don't look at it
+/// Parse json for card data
+pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
+ // TODO: Repack these cards so every card is stored once and pointers are passed around instead of
+ // cloning stuff
+ let data: String =
+ read_to_string(path).with_context(|| format!("Invalid JSON path: \"{}\"", path))?;
+ let jayson: Vec = serde_json::from_str(&data)
+ .with_context(|| format!("The contents of \"{path}\" is not valid JSON."))?;
+
+ let mut official: HashMap = HashMap::new();
+ let mut unofficial: HashMap = HashMap::new();
+
+ let mut official_meta: Vec = vec![];
+ let mut unofficial_meta: Vec = vec![];
+
+ for set in jayson {
+ let mut num_white = 0;
+ let mut num_black = 0;
+
+ let mut newset = CardSet {
+ white: Option::None,
+ black: Option::None,
+ };
+
+ // No safe default for this so make it an Option
+ let mut pack: Option = Option::None;
+
+ if let Some(ref white) = set.white {
+ num_white = white.len();
+ if num_white > 0 {
+ pack = Some(white[0].pack);
+ newset.white = Some(set.white.unwrap());
+ }
+ }
+
+ if let Some(ref black) = set.black {
+ num_black = black.len();
+ if num_black > 0 {
+ pack = Some(black[0].pack);
+ newset.black = Some(set.black.unwrap());
+ }
+ }
+
+ let meta = CardPackMeta {
+ name: set.name,
+ pack: pack.expect("No card pack number!"),
+ num_white,
+ num_black,
+ };
+
+ if set.official {
+ official_meta.push(meta);
+ official.insert(pack.unwrap(), newset);
+ } else {
+ unofficial_meta.push(meta);
+ unofficial.insert(pack.unwrap(), newset);
+ }
+ }
+
+ official.shrink_to_fit();
+ unofficial.shrink_to_fit();
+
+ official_meta.shrink_to_fit();
+ unofficial_meta.shrink_to_fit();
+
+ tracing::debug!("{} official", official.len());
+ tracing::debug!("{} official meta", official_meta.len());
+ tracing::debug!("{} unofficial", unofficial.len());
+ tracing::debug!("{} unofficial meta", unofficial_meta.len());
+ tracing::debug!("{:#?}", official_meta[0]);
+ tracing::debug!("{:#?}", unofficial_meta[0]);
+
+ let packs = CardPacks {
+ official,
+ unofficial,
+ };
+
+ let packs_meta = CardPacksMeta {
+ official_meta,
+ unofficial_meta,
+ };
+
+ Ok((packs, packs_meta))
+}
/// Card Set
#[derive(Debug)]
-pub struct CardSet {
- pub white: Option>,
- pub black: Option>,
+struct CardSet {
+ white: Option>,
+ black: Option>,
}
/// Card Packs
#[derive(Debug)]
pub struct CardPacks {
- pub official: HashMap,
- pub unofficial: HashMap,
+ official: HashMap,
+ unofficial: HashMap,
}
/// A white card
-#[derive(Debug, Deserialize)]
-pub struct CardWhite {
+// TODO: Remove this clone!
+#[derive(Debug, Deserialize, Clone)]
+struct CardWhite {
/// Card text
- pub text: String,
+ text: String,
/// ID of the pack it came from
- pub pack: u8,
+ pack: u8,
}
/// A black card
-#[derive(Debug, Deserialize)]
-pub struct CardBlack {
+// TODO: Remove this clone!
+#[derive(Debug, Deserialize, Clone)]
+struct CardBlack {
/// Card text
- pub text: String,
+ text: String,
/// Amount of cards to submit for judging
- pub pick: u8,
+ pick: u8,
/// ID of the pack it came from
- pub pack: u8,
+ pack: u8,
}
/// A card pack
#[derive(Debug, Deserialize)]
-pub struct CardPack {
+struct CardPack {
/// Name of the pack
- pub name: String,
+ name: String,
/// Whether or not this is an official card pack
- pub official: bool,
+ official: bool,
/// White card data
- pub white: Option>,
+ white: Option>,
/// Black card data
- pub black: Option>,
+ black: Option>,
}
/// New game request structure
#[derive(Debug)]
-pub struct NewGameManifest {
+struct NewGameManifest {
/// Game name
- pub name: String,
+ name: String,
/// Game host
- pub host: Arc>,
+ host: Arc>,
/// Selected game packs
- pub packs: Vec,
+ packs: Vec,
}
/// A struct that represents a player
#[derive(Debug)]
-pub struct Player {
- /// Player's user's uuid
- pub user_uuid: Uuid,
+struct Player {
/// The player's hand
- pub white: Vec,
+ white: Vec,
/// The player's wins
- pub black: Vec,
+ black: Vec,
}
/// The game master
@@ -92,47 +176,21 @@ pub struct Game {
/// The host user of the game
pub host: Arc>,
/// White draw pile
- pub white: Vec,
+ white: Vec,
/// Black draw pile
- pub black: Vec,
- /// White discard pile
- pub white_discard: Vec,
- /// Black discard pile
- pub black_discard: Vec,
- /// List of current players
- pub players: HashMap,
- // /// Reference to current card czar
- // czar: &Player,
+ black: Vec,
+ players: HashMap,
/// Black card for the current round
- pub current_black: Option,
+ current_black: Option,
}
impl Game {
- /// Build game decks from input data for game start.
- /// This should only run once and at startup.
- fn build_decks(&mut self, selected_packs: Vec) -> Result<()> {
- // for pack in selected_packs {
- // for pack in card_packs {
- // if let Some(white) = pack.white {
- // self.white.extend(white)
- // }
- // if let Some(black) = pack.black {
- // self.black.extend(black)
- // }
- // }
- // }
-
- Ok(())
- }
-
- pub fn new(request: NewGameManifest) -> Result {
+ fn new(state: Arc, request: NewGameManifest) -> Result {
let mut game = Game {
name: request.host.read().unwrap().name.clone(),
host: request.host.clone(),
white: vec![],
black: vec![],
- white_discard: vec![],
- black_discard: vec![],
players: HashMap::new(),
current_black: Option::None,
};
@@ -144,30 +202,43 @@ impl Game {
game.name = request.name;
game.host = request.host.clone();
- game.build_decks(request.packs)?;
+ game.build_decks(state, request.packs)?;
game.create_player(request.host)?;
game.deal_black()?;
Ok(game)
}
- // pub fn join(request:GameJoinRequest)
+ /// Build game decks from input data for game start.
+ /// This should only run once and at startup.
+ fn build_decks(&mut self, state: Arc, selected_packs: Vec) -> Result<()> {
+ // TODO: Make this right -- remove the clones, use references to single cards
+ for pack_num in selected_packs {
+ if let Some(pack) = state.packs.official.get(&pack_num) {
+ if let Some(white) = &pack.white {
+ self.white.extend(white.clone())
+ }
+ if let Some(black) = &pack.black {
+ self.black.extend(black.clone())
+ }
+ } else if let Some(pack) = state.packs.unofficial.get(&pack_num) {
+ if let Some(white) = &pack.white {
+ self.white.extend(white.clone())
+ }
+ if let Some(black) = &pack.black {
+ self.black.extend(black.clone())
+ }
+ }
+ }
- /// Log counts of current drawable cards
- /// For testing
- pub fn deck_counts(&self) {
- tracing::debug!(
- "Deck Counts:\n {} White cards\n {} Black cards",
- self.white.len(),
- self.black.len()
- );
+ Ok(())
}
/// Draw one white card at random from play deck.
fn draw_one_white(&mut self) -> Result {
let deck = &mut self.white;
- // this feels sloppy
+ // TODO: this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
} else {
@@ -182,7 +253,7 @@ impl Game {
fn draw_one_black(&mut self) -> Result {
let deck = &mut self.black;
- // this feels sloppy
+ // TODO: this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
} else {
@@ -202,9 +273,8 @@ impl Game {
}
/// Create a new player and add them to the game.
- pub fn create_player(&mut self, user: Arc>) -> Result<()> {
+ fn create_player(&mut self, user: Arc>) -> Result<()> {
let mut new_player = Player {
- user_uuid: user.read().unwrap().uuid.clone(),
white: vec![],
black: vec![],
};
@@ -225,16 +295,6 @@ impl Game {
Ok(())
}
-
- pub fn game_start(&mut self) -> Result<()> {
- if let Some(black) = &self.current_black {
- tracing::debug!("{}", black.text);
- } else {
- tracing::debug!("YOU DONE FUCKED UP (no current black card)");
- }
-
- Ok(())
- }
}
pub enum GameHandlerMessage {
@@ -288,7 +348,7 @@ impl GameHandler {
};
// create game
- if let Ok(new_game_object) = Game::new(manifest) {
+ if let Ok(new_game_object) = Game::new(self.state.clone(), manifest) {
let tx = self
.state
.online_users
@@ -301,9 +361,9 @@ impl GameHandler {
.tx
.clone();
- let mut black_text = "Error".to_string();
+ let mut black_card = ("Error".to_string(), 0u8);
if let Some(ref current_black) = new_game_object.current_black {
- black_text = current_black.text.to_owned()
+ black_card = (current_black.text.to_owned(), current_black.pick)
}
let meta = GameMeta {
@@ -326,7 +386,7 @@ impl GameHandler {
})
.collect(),
czar: new_game_object.host.read().unwrap().name.clone(),
- black: black_text,
+ black: black_card,
white: new_game_object
.players
.get(&new_game_object.host.read().unwrap().uuid)
diff --git a/server/src/lib.rs b/server/src/lib.rs
index ac57564..3589631 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -7,7 +7,7 @@ use game_handler::GameHandlerMessage;
use lib::*;
use std::{
collections::{HashMap, HashSet},
- fs::{read_to_string, File},
+ fs::File,
io::{BufRead, BufReader},
net::SocketAddr,
sync::{Arc, RwLock},
@@ -44,89 +44,6 @@ impl User {
}
}
-/// Parse json for card data
-pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
- let data: String =
- read_to_string(path).with_context(|| format!("Invalid JSON path: \"{}\"", path))?;
- let jayson: Vec = serde_json::from_str(&data)
- .with_context(|| format!("The contents of \"{path}\" is not valid JSON."))?;
-
- let mut official: HashMap = HashMap::new();
- let mut unofficial: HashMap = HashMap::new();
-
- let mut official_meta: Vec = vec![];
- let mut unofficial_meta: Vec = vec![];
-
- for set in jayson {
- let mut num_white = 0;
- let mut num_black = 0;
-
- let mut newset = CardSet {
- white: Option::None,
- black: Option::None,
- };
-
- // No safe default for this so make it an Option
- let mut pack: Option = Option::None;
-
- if let Some(ref white) = set.white {
- num_white = white.len();
- if num_white > 0 {
- pack = Some(white[0].pack);
- newset.white = Some(set.white.unwrap());
- }
- }
-
- if let Some(ref black) = set.black {
- num_black = black.len();
- if num_black > 0 {
- pack = Some(black[0].pack);
- newset.black = Some(set.black.unwrap());
- }
- }
-
- let meta = CardPackMeta {
- name: set.name,
- pack: pack.expect("No card pack number!"),
- num_white,
- num_black,
- };
-
- if set.official {
- official_meta.push(meta);
- official.insert(pack.unwrap(), newset);
- } else {
- unofficial_meta.push(meta);
- unofficial.insert(pack.unwrap(), newset);
- }
- }
-
- official.shrink_to_fit();
- unofficial.shrink_to_fit();
-
- official_meta.shrink_to_fit();
- unofficial_meta.shrink_to_fit();
-
- tracing::debug!("{} official", official.len());
- tracing::debug!("{} official meta", official_meta.len());
- tracing::debug!("{} unofficial", unofficial.len());
- tracing::debug!("{} unofficial meta", unofficial_meta.len());
- tracing::debug!("{:#?}", official_meta[0]);
- tracing::debug!("{:#?}", unofficial_meta[0]);
-
- let packs = CardPacks {
- official,
- unofficial,
- };
-
- let packs_meta = CardPacksMeta {
- official_meta,
- unofficial_meta,
- };
-
- Ok((packs, packs_meta))
-}
-
/// Parse name list
pub fn load_names(path: &str) -> Result> {
let f = File::open(path).with_context(|| format!("Invalid names path: \"{}\"", path))?;
diff --git a/server/src/main.rs b/server/src/main.rs
index 8e49896..598a682 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -64,16 +64,7 @@ async fn main() -> Result<()> {
}
});
- // Make an outgoing message handler handler
- // DO it
- // DO it
- // DO it
- // DO it
- // DO it
- // DO it
- // DO it
- // DO it
- // DO it
+ // TODO: Make an outgoing message handler handler
// Spawn task to handle User things
let user_handler = UserHandler::new(app_state.clone());
diff --git a/server/src/message_handler.rs b/server/src/message_handler.rs
index 20b5915..1de58a8 100644
--- a/server/src/message_handler.rs
+++ b/server/src/message_handler.rs
@@ -7,9 +7,6 @@ use serde_json::{from_str, to_string};
use std::net::SocketAddr;
use std::sync::Arc;
-// Handle incoming messages over the WebSocket, and probably do more than we should.
-// Also with lots of unwrapping
-
pub struct MessageHandler {
state: Arc,
}
@@ -23,7 +20,7 @@ impl MessageHandler {
match message {
Message::Text(text) => match text {
_chat_message if let Ok(chat_message) = from_str::(&text) => {
- // This should be delegated to user handler and an outgoing message and/or chat handler
+ // TODO: This should be delegated to user handler and an outgoing message and/or chat handler
let msg = format! {"{0}: {1}", self.state.online_users.read().unwrap().get(&addr).unwrap().read().unwrap().name, chat_message.text};
tracing::debug!("{msg}");
self.state
diff --git a/server/src/user_handler.rs b/server/src/user_handler.rs
index 82a21e0..e9730e6 100644
--- a/server/src/user_handler.rs
+++ b/server/src/user_handler.rs
@@ -5,8 +5,6 @@ use serde_json::to_string;
use std::net::SocketAddr;
use std::sync::{Arc, RwLock};
-// This file is a mess, don't read it
-
pub enum UserHandlerMessage {
NewUser { user: User, addr: SocketAddr },
UserLogIn { username: String, addr: SocketAddr },
@@ -24,7 +22,7 @@ impl UserHandler {
pub async fn handle(&self, message: UserHandlerMessage) {
match message {
UserHandlerMessage::NewUser { user, addr } => {
- // make this not async
+ // TODO: make this not async
self.set_up_new_user(user, addr).await
}
UserHandlerMessage::UserLogIn { username, addr } => self.login(username, addr).await,
@@ -65,7 +63,7 @@ impl UserHandler {
.unwrap();
// Broadcast new user's existence
- // this should probably be combined and sent as one
+ // TODO: this should probably be combined and sent as one
let _ = &self
.state
.broadcast_tx
@@ -82,8 +80,7 @@ impl UserHandler {
.send(meta_chat_update(&self.state))
.unwrap();
- // this races the broadcasts but if it's done last it'll probably show up
- // last
+ // TODO: this races the broadcasts but if it's done last it'll probably show up last
tx.send(meta_motd()).await.unwrap();
}
@@ -245,7 +242,7 @@ pub fn user_client_self_update(new_user: &Arc>) -> String {
/// Generate chatroom metadata update
pub fn meta_chat_update(state: &Arc) -> String {
- // this may get expensive if there are many users
+ // TODO: this may get expensive if there are many users
let mut names = vec![];
for user in state.online_users.read().unwrap().iter() {
@@ -285,7 +282,7 @@ pub fn meta_server_summary_update(state: &Arc) -> String {
/// Generate games list update
pub fn meta_games_browser_update(state: &Arc) -> String {
- // this may get expensive if there are many games
+ // TODO: this may get expensive if there are many games
let mut names = vec![];
for game in state.games.read().unwrap().values() {
diff --git a/server/src/websocket.rs b/server/src/websocket.rs
index 9deb6c9..86838ed 100644
--- a/server/src/websocket.rs
+++ b/server/src/websocket.rs
@@ -37,9 +37,8 @@ pub async fn websocket_on_connection(stream: WebSocket, state: Arc, ad
let mut map = HashMap::new();
map.insert(addr, dm_tx.clone());
- let _ = state
+ state
.users_tx
- // add tx
.send(UserHandlerMessage::NewUser {
user: User::new(
format!(
@@ -51,7 +50,8 @@ pub async fn websocket_on_connection(stream: WebSocket, state: Arc, ad
),
addr,
})
- .await;
+ .await
+ .unwrap();
// Subscribe to receive from global broadcast channel
let mut rx = state.broadcast_tx.subscribe();