From 09a595a7a9f4f2632887161e854db186851d152a Mon Sep 17 00:00:00 2001 From: ThePerkinrex Date: Sat, 30 Oct 2021 20:13:08 +0200 Subject: [PATCH] Add server images impl --- server/Cargo.toml | 6 ++-- server/src/logger.rs | 1 - server/src/server.rs | 22 ++++++++++---- server/src/server/game.rs | 61 ++++++++++++++++++++++++--------------- server/src/server/time.rs | 24 +++++++-------- 5 files changed, 71 insertions(+), 43 deletions(-) diff --git a/server/Cargo.toml b/server/Cargo.toml index 16b5ba4..3775813 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -23,7 +23,7 @@ fallible-iterator = "0.2" regex = "1" lazy_static = "1" anyhow = "1" -tar = "0.4" + # Game loading rhai = {version = "1", features = ["serde", "sync"]} @@ -36,12 +36,14 @@ schemars = "0.8" bytes = "1" prost = "0.9" prost-types = "0.9" +tar = "0.4" +libflate = "1" # Database (SQLite) rusqlite = {version = "0.26", features=["bundled"]} # TUI -crossterm = {version = "0.21", optional = true} +crossterm = {version = "0.22", optional = true} log = "0.4" fern = {version = "0.6", features = ["colored"]} chrono = "0.4" diff --git a/server/src/logger.rs b/server/src/logger.rs index 65b416d..e7b77b7 100644 --- a/server/src/logger.rs +++ b/server/src/logger.rs @@ -16,7 +16,6 @@ use crate::{ server_properties::ServerProperties, }; - pub type Stdout = mpsc::Sender; pub type Stdin = mpsc::Receiver; diff --git a/server/src/server.rs b/server/src/server.rs index 1e9c41f..8066c57 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -2,7 +2,6 @@ use anyhow::Result; use log::{debug, warn}; -use prost_types::Timestamp; use tokio::{ io::{AsyncReadExt, BufReader}, net::TcpListener, @@ -12,9 +11,18 @@ use uuid::Uuid; use std::{collections::HashMap, io::ErrorKind, net::SocketAddr, sync::Arc}; -use crate::{db, games::RunningGame, server::{connection::{ +use crate::{ + db, + games::RunningGame, + server::{ + connection::{ connect, create_lobby, disconnect, get_public_lobbies, join_lobby_with_code, name, - }, game::{get_card_image, get_cards_images, on_click, query_status}, lobby::{leave, ready, users, vote}, protos::game::{Cards, cards::Card}}, server_properties::ServerProperties}; + }, + game::{get_card_image, get_cards_images, on_click, query_status}, + lobby::{leave, ready, users, vote}, + }, + server_properties::ServerProperties, +}; use prost::Message; @@ -25,8 +33,8 @@ mod game; mod lobby; mod protos; mod socket_manager; -mod votes; mod time; +mod votes; // pub fn decode(bytes: &[u8]) { // let p = protos::protocol::ServerClientPacket::decode(bytes).expect("AAAAH"); @@ -250,7 +258,11 @@ pub async fn serve( .await .expect("Error handling card image query") } - Data::QueryCardImages(cards) => {} + Data::QueryCardImages(cards) => { + get_cards_images(&mut service_data, &socket_manager, cards) + .await + .expect("Error handling card images query") + } Data::CallOnClick(card_id) => { debug!("{:?}", card_id); on_click(&mut service_data, &socket_manager, card_id) diff --git a/server/src/server/game.rs b/server/src/server/game.rs index 4185f3a..722809c 100644 --- a/server/src/server/game.rs +++ b/server/src/server/game.rs @@ -1,4 +1,4 @@ -use std::{borrow::BorrowMut, fs::File, io::Write, path::Path}; +use std::{fs::File, path::Path}; use super::{ protos::game::{game_status::Piles, CardKind, Cards, GameStatus, Image}, @@ -9,16 +9,21 @@ use crate::{ games::{CardId, CardIdx, PileKind, RunningPile}, server::{ protos::{ - game::{cards::Card, game_status::CustomInfoMessage}, + game::{ + cards::Card, + game_status::CustomInfoMessage, + images::{self, DataPacket, SetUp}, + Images, + }, protocol::server_client_packet::{self, Data}, }, time::EpochTime, }, }; use anyhow::{anyhow, Result}; -use bytes::BytesMut; -use prost_types::Timestamp; -use tar::{Archive, Builder}; +use bytes::{Buf, Bytes}; +use libflate::deflate::Encoder; +use tar::Builder; pub(super) async fn get_status( data: &mut ServiceData, @@ -180,13 +185,15 @@ pub(super) async fn get_card_image( Ok(()) } +const MESSAGE_SIZE: usize = 10_000_000; + pub(super) async fn get_cards_images( data: &mut ServiceData, socket_mgr: &SocketManager, cards: Cards, ) -> Result<()> { log::info!("Getting images location"); - let time = std::time::Instant::now(); + // let time = std::time::Instant::now(); let uuid = data.user_id.get()?; let lobby: u32 = match data.db.get_lobby_for_user(uuid).await { Some(l) => l, @@ -197,8 +204,7 @@ pub(super) async fn get_cards_images( None => return Err(anyhow!("User isn't in a lobby with a running game",)), }; let game = &data.games[game_id as usize]; - let mut b = Vec::new(); - let mut ar = Builder::new(b); + let mut ar = Builder::new(Encoder::new(Vec::new())); for card_kind in cards.cards { let (face, back) = game.get_card_paths(&card_kind.kind); // log::info!("Loading face image [{:?}]", time.elapsed()); @@ -234,22 +240,31 @@ pub(super) async fn get_cards_images( ) .unwrap(); } - } - - File::create("a.tar").unwrap().write_all(&ar.into_inner().unwrap()).unwrap(); - // TODO Apply lz4 compression - // log::info!("Loaded images {} [{:?}]", card_kind.kind, time.elapsed()); - // socket_mgr - // .write( - // data.user_id.get_ref()?, - // Data::ReturnCardImage(Image { - // face: face_buf, - // back: back_buf, - // kind: card_kind.kind, - // }), - // ) - // .await?; + let mut b = Bytes::from(ar.into_inner().unwrap().finish().into_result().unwrap()); + let n = (b.len() / MESSAGE_SIZE) + if b.len() % MESSAGE_SIZE == 0 { 0 } else { 1 }; + socket_mgr + .write( + data.user_id.get_ref()?, + Data::ReturnCardsImages(Images { + data: Some(images::Data::Setup(SetUp { number: n as u32 })), + }), + ) + .await?; + for i in 0..(n as u32) { + let mut t = b.take(MESSAGE_SIZE); + let mut v = vec![0; t.remaining()]; + t.copy_to_slice(&mut v); + b = t.into_inner(); + socket_mgr + .write( + data.user_id.get_ref()?, + Data::ReturnCardsImages(Images { + data: Some(images::Data::DataPacket(DataPacket { id: i, data: v })), + }), + ) + .await?; + } Ok(()) } diff --git a/server/src/server/time.rs b/server/src/server/time.rs index 46cac29..a924826 100644 --- a/server/src/server/time.rs +++ b/server/src/server/time.rs @@ -1,27 +1,27 @@ -use std::time::SystemTime; use prost_types::Timestamp; +use std::time::SystemTime; #[derive(PartialEq)] pub struct EpochTime(Timestamp); impl From for EpochTime { - fn from(a: SystemTime) -> Self { - Self(a.into()) - } + fn from(a: SystemTime) -> Self { + Self(a.into()) + } } impl From for EpochTime { - fn from(a: Timestamp) -> Self { - Self(a) - } + fn from(a: Timestamp) -> Self { + Self(a) + } } impl PartialOrd for EpochTime { - fn partial_cmp(&self, other: &Self) -> Option { - if other.0.seconds == self.0.seconds { + fn partial_cmp(&self, other: &Self) -> Option { + if other.0.seconds == self.0.seconds { self.0.seconds.partial_cmp(&other.0.seconds) - }else{ + } else { self.0.nanos.partial_cmp(&other.0.nanos) } - } -} \ No newline at end of file + } +}