Browse Source

Add server images impl

main
ThePerkinrex 4 years ago
parent
commit
09a595a7a9
No known key found for this signature in database GPG Key ID: FD81DE6D75E20917
  1. 6
      server/Cargo.toml
  2. 1
      server/src/logger.rs
  3. 22
      server/src/server.rs
  4. 61
      server/src/server/game.rs
  5. 24
      server/src/server/time.rs

6
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"

1
server/src/logger.rs

@ -16,7 +16,6 @@ use crate::{
server_properties::ServerProperties,
};
pub type Stdout = mpsc::Sender<String>;
pub type Stdin<T> = mpsc::Receiver<T>;

22
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)

61
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(())
}

24
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<SystemTime> for EpochTime {
fn from(a: SystemTime) -> Self {
Self(a.into())
}
fn from(a: SystemTime) -> Self {
Self(a.into())
}
}
impl From<Timestamp> 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<std::cmp::Ordering> {
if other.0.seconds == self.0.seconds {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
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)
}
}
}
}
}

Loading…
Cancel
Save