Browse Source

Add initial multiimage packet

main
ThePerkinrex 4 years ago
parent
commit
045e489e76
  1. 5
      server/Cargo.toml
  2. 17
      server/src/server.rs
  3. 89
      server/src/server/game.rs
  4. 42
      server/src/server/protos/game.rs
  5. 8
      server/src/server/protos/protocol.rs
  6. 27
      server/src/server/time.rs

5
server/Cargo.toml

@ -22,10 +22,11 @@ server_client = {git = "https://github.com/Mr-Llama-s-Wonderful-Soundboard/serve
fallible-iterator = "0.2"
regex = "1"
lazy_static = "1"
anyhow = "1.0"
anyhow = "1"
tar = "0.4"
# Game loading
rhai = {version = "1.0", features = ["serde", "sync"]}
rhai = {version = "1", features = ["serde", "sync"]}
serde_json = "1"
serde = "1"
schemars = "0.8"

17
server/src/server.rs

@ -2,6 +2,7 @@
use anyhow::Result;
use log::{debug, warn};
use prost_types::Timestamp;
use tokio::{
io::{AsyncReadExt, BufReader},
net::TcpListener,
@ -11,18 +12,9 @@ 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, on_click, query_status},
lobby::{leave, ready, users, vote},
},
server_properties::ServerProperties,
};
}, game::{get_card_image, get_cards_images, on_click, query_status}, lobby::{leave, ready, users, vote}, protos::game::{Cards, cards::Card}}, server_properties::ServerProperties};
use prost::Message;
@ -34,6 +26,7 @@ mod lobby;
mod protos;
mod socket_manager;
mod votes;
mod time;
// pub fn decode(bytes: &[u8]) {
// let p = protos::protocol::ServerClientPacket::decode(bytes).expect("AAAAH");
@ -252,10 +245,12 @@ pub async fn serve(
// GAME
Data::QueryCardImage(card_kind) => {
// get_cards_images(&mut service_data, &socket_manager, Cards { cards: vec![Card { kind: card_kind.kind.clone(), time: Some(Timestamp {seconds: 0, nanos: 0}) }] }).await.unwrap();
get_card_image(&mut service_data, &socket_manager, card_kind)
.await
.expect("Error handling card image query")
}
Data::QueryCardImages(cards) => {}
Data::CallOnClick(card_id) => {
debug!("{:?}", card_id);
on_click(&mut service_data, &socket_manager, card_id)

89
server/src/server/game.rs

@ -1,16 +1,24 @@
use std::{borrow::BorrowMut, fs::File, io::Write, path::Path};
use super::{
protos::game::{game_status::Piles, CardKind, GameStatus, Image},
protos::game::{game_status::Piles, CardKind, Cards, GameStatus, Image},
socket_manager::SocketManager,
ServiceData,
};
use crate::{
games::{CardId, CardIdx, PileKind, RunningPile},
server::protos::{
game::game_status::CustomInfoMessage,
protocol::server_client_packet::{self, Data},
server::{
protos::{
game::{cards::Card, game_status::CustomInfoMessage},
protocol::server_client_packet::{self, Data},
},
time::EpochTime,
},
};
use anyhow::{anyhow, Result};
use bytes::BytesMut;
use prost_types::Timestamp;
use tar::{Archive, Builder};
pub(super) async fn get_status(
data: &mut ServiceData,
@ -172,6 +180,79 @@ pub(super) async fn get_card_image(
Ok(())
}
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 uuid = data.user_id.get()?;
let lobby: u32 = match data.db.get_lobby_for_user(uuid).await {
Some(l) => l,
None => return Err(anyhow!("User isn't in a lobby")),
};
let game_id = match data.running_games.read().await.get(&lobby) {
Some(x) => x.read().await.0,
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);
for card_kind in cards.cards {
let (face, back) = game.get_card_paths(&card_kind.kind);
// log::info!("Loading face image [{:?}]", time.elapsed());
while !face.exists() || !back.exists() {
tokio::task::yield_now().await;
}
fn is_newer<P: AsRef<Path>>(c: &Card, p: &P) -> bool {
c.time
.clone()
.and_then(|x| {
p.as_ref()
.metadata()
.and_then(|x| x.modified())
.ok()
.map(|y| (y.into(), x.into()))
})
.map_or(false, |(x, y): (EpochTime, EpochTime)| x > y)
}
if is_newer(&card_kind, &face) {
ar.append_file(
format!("{}/face.png", card_kind.kind),
&mut File::open(face).unwrap(),
)
.unwrap();
}
if is_newer(&card_kind, &back) {
ar.append_file(
format!("{}/back.png", card_kind.kind),
&mut File::open(back).unwrap(),
)
.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?;
Ok(())
}
pub(super) async fn on_click(
data: &mut ServiceData,
socket_mgr: &SocketManager,

42
server/src/server/protos/game.rs

@ -12,6 +12,48 @@ pub struct CardKind {
pub kind: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Cards {
#[prost(message, repeated, tag="1")]
pub cards: ::prost::alloc::vec::Vec<cards::Card>,
}
/// Nested message and enum types in `Cards`.
pub mod cards {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Card {
#[prost(string, tag="1")]
pub kind: ::prost::alloc::string::String,
#[prost(message, optional, tag="2")]
pub time: ::core::option::Option<::prost_types::Timestamp>,
}
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Images {
#[prost(oneof="images::Data", tags="1, 2")]
pub data: ::core::option::Option<images::Data>,
}
/// Nested message and enum types in `Images`.
pub mod images {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetUp {
#[prost(uint32, tag="1")]
pub number: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DataPacket {
#[prost(uint32, tag="1")]
pub id: u32,
#[prost(bytes="vec", tag="2")]
pub data: ::prost::alloc::vec::Vec<u8>,
}
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum Data {
#[prost(message, tag="1")]
Setup(SetUp),
#[prost(message, tag="2")]
DataPacket(DataPacket),
}
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Image {
#[prost(bytes="vec", tag="1")]
pub face: ::prost::alloc::vec::Vec<u8>,

8
server/src/server/protos/protocol.rs

@ -1,6 +1,6 @@
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ClientServerPacket {
#[prost(oneof="client_server_packet::Data", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14")]
#[prost(oneof="client_server_packet::Data", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15")]
pub data: ::core::option::Option<client_server_packet::Data>,
}
/// Nested message and enum types in `ClientServerPacket`.
@ -38,11 +38,13 @@ pub mod client_server_packet {
CallOnClick(super::super::game::CardId),
#[prost(message, tag="14")]
QueryGameStatus(()),
#[prost(message, tag="15")]
QueryCardImages(super::super::game::Cards),
}
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ServerClientPacket {
#[prost(oneof="server_client_packet::Data", tags="1, 2, 3, 4, 5, 6, 7, 8, 9")]
#[prost(oneof="server_client_packet::Data", tags="1, 2, 3, 4, 5, 6, 7, 8, 10, 9")]
pub data: ::core::option::Option<server_client_packet::Data>,
}
/// Nested message and enum types in `ServerClientPacket`.
@ -68,6 +70,8 @@ pub mod server_client_packet {
/// GAME
#[prost(message, tag="8")]
ReturnCardImage(super::super::game::Image),
#[prost(message, tag="10")]
ReturnCardsImages(super::super::game::Images),
#[prost(message, tag="9")]
GameStatus(super::super::game::GameStatus),
}

27
server/src/server/time.rs

@ -0,0 +1,27 @@
use std::time::SystemTime;
use prost_types::Timestamp;
#[derive(PartialEq)]
pub struct EpochTime(Timestamp);
impl From<SystemTime> for EpochTime {
fn from(a: SystemTime) -> Self {
Self(a.into())
}
}
impl From<Timestamp> for EpochTime {
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 {
self.0.seconds.partial_cmp(&other.0.seconds)
}else{
self.0.nanos.partial_cmp(&other.0.nanos)
}
}
}
Loading…
Cancel
Save