diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 5fa068d5..df097afd 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -78,7 +78,7 @@ const addState = connect( function Vbox(args) { const { combiner, - instance, + // instance, itemInfo, player, reclaiming, diff --git a/client/src/events.jsx b/client/src/events.jsx index a271a81c..69d8ec4a 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -6,16 +6,6 @@ const { TIMES } = require('./constants'); const { getCombatSequence } = require('./utils'); function registerEvents(store) { - - // timeout handlers - store.subscribe(() => { - const { game, instance, ws } = store.getState(); - - if (!ws) return true; - if (!game) ws.clearGameStateTimeout(); - if (!instance) ws.clearInstanceStateTimeout(); - }); - function setPing(ping) { store.dispatch(actions.setPing(ping)); } @@ -54,11 +44,9 @@ function registerEvents(store) { function setGame(game) { const { game: currentGame, ws } = store.getState(); - if (game) ws.startGameStateTimeout(game.id); if (game && currentGame) { if (game.resolved.length !== currentGame.resolved.length) { // stop fetching the game state til animations are done - ws.clearGameStateTimeout(); const newRes = game.resolved.slice(currentGame.resolved.length); let id = game.resolved.length - currentGame.resolved.length; return eachSeries(newRes, (r, cb) => { @@ -151,7 +139,6 @@ function registerEvents(store) { store.dispatch(actions.setItemEquip(null)); store.dispatch(actions.setItemUnequip(null)); store.dispatch(actions.setVboxHighlight([])); - store.dispatch(actions.setConstructDeleteId(null)); } function setAccountInstances(v) { @@ -161,8 +148,6 @@ function registerEvents(store) { function setInstance(v) { const { account, ws, instance } = store.getState(); if (v) { - ws.startInstanceStateTimeout(v.id); - const player = v.players.find(p => p.id === account.id); store.dispatch(actions.setPlayer(player)); diff --git a/client/src/socket.jsx b/client/src/socket.jsx index f89a8e14..8d1e68a5 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -136,8 +136,6 @@ function createSocket(events) { // ------------- function onAccount(login) { events.setAccount(login); - sendAccountConstructs(); - sendAccountInstances(); } function onAccountShop(shop) { @@ -146,7 +144,6 @@ function createSocket(events) { function onAccountInstances(list) { events.setAccountInstances(list); - setTimeout(sendAccountInstances, 5000); } function onAccountConstructs(constructs) { @@ -157,36 +154,12 @@ function createSocket(events) { events.setGame(game); } - let gameStateTimeout; - function startGameStateTimeout(id) { - clearTimeout(gameStateTimeout); - gameStateTimeout = setTimeout(() => sendGameState(id), 1000); - return true; - } - - function clearGameStateTimeout() { - clearTimeout(gameStateTimeout); - } - - let instanceStateTimeout; - function startInstanceStateTimeout(id) { - clearTimeout(instanceStateTimeout); - instanceStateTimeout = setTimeout(() => sendInstanceState(id), 1000); - return true; - } - function onInstanceState(instance) { events.setInstance(instance); - return true; } function onOpenInstances(list) { events.setInstanceList(list); - return true; - } - - function clearInstanceStateTimeout() { - clearTimeout(instanceStateTimeout); } function onItemInfo(info) { @@ -277,8 +250,6 @@ function createSocket(events) { function connect() { if (ws) { - clearGameStateTimeout(); - clearInstanceStateTimeout(); clearTimeout(pongTimeout); ws.removeEventListener('open', onOpen); ws.removeEventListener('message', onMessage); @@ -299,8 +270,6 @@ function createSocket(events) { } return { - clearGameStateTimeout, - clearInstanceStateTimeout, sendAccountConstructs, sendAccountInstances, sendGameState, @@ -321,8 +290,6 @@ function createSocket(events) { sendItemInfo, sendMtxApply, sendMtxBuy, - startInstanceStateTimeout, - startGameStateTimeout, connect, }; } diff --git a/ops/migrations/20181020104420_games.js b/ops/migrations/20181020104420_games.js index 94ba538f..efeecc4b 100644 --- a/ops/migrations/20181020104420_games.js +++ b/ops/migrations/20181020104420_games.js @@ -54,18 +54,6 @@ exports.up = async knex => { table.unique(['account', 'instance']); }); - - await knex.schema.createTable('matchmaking', async table => { - table.uuid('id').primary(); - table.index('id'); - table.timestamps(true, true); - - table.uuid('game').notNullable() - table.foreign('game') - .references('id') - .inTable('games') - .onDelete('NO ACTION'); - }); }; exports.down = async () => {}; \ No newline at end of file diff --git a/server/src/instance.rs b/server/src/instance.rs index 2ffaa0c5..4d7a07dc 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -17,7 +17,7 @@ use construct::{Construct, construct_get}; use mob::{bot_player, instance_mobs}; use game::{Game, Phase, game_get, game_write}; use item::{Item}; -use rpc::{RpcResult}; +use rpc::{RpcMessage}; use img; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -756,7 +756,7 @@ pub fn instance_ready(tx: &mut Transaction, account: &Account, instance_id: Uuid instance_update(tx, instance) } -pub fn instance_state(tx: &mut Transaction, _account: &Account, instance_id: Uuid) -> Result { +pub fn instance_state(tx: &mut Transaction, _account: &Account, instance_id: Uuid) -> Result { let instance = instance_get(tx, instance_id)?; if let Some(game_id) = instance.current_game_id() { @@ -764,11 +764,11 @@ pub fn instance_state(tx: &mut Transaction, _account: &Account, instance_id: Uui // return the game until it's finished if game.phase != Phase::Finish { - return Ok(RpcResult::GameState(game)) + return Ok(RpcMessage::GameState(game)) } } - Ok(RpcResult::InstanceState(instance)) + Ok(RpcMessage::InstanceState(instance)) } pub fn instance_game_finished(tx: &mut Transaction, game: &Game, instance_id: Uuid) -> Result<(), Error> { diff --git a/server/src/names.rs b/server/src/names.rs index b6b7d718..d9604f14 100644 --- a/server/src/names.rs +++ b/server/src/names.rs @@ -1,63 +1,69 @@ use rand::prelude::*; use rand::{thread_rng}; -const FIRSTS: [&'static str; 23] = [ - "fierce", - "obscure", - "mighty", - "rogue", - "inverted", - "recalcitrant", - "subterranean", - "brewing", - "nocturnal", - "convex", - "concave", - "piscine", - "dub", +const FIRSTS: [&'static str; 25] = [ "borean", - "lurking", - "leafy", - "nutritious", + "brewing", "bristling", - "metallic", - "purified", - "organic", + "compressed", + "concave", + "convex", "distorted", + "dub", + "fierce", + "inverted", + "leafy", + "lurking", + "metallic", + "mighty", + "nocturnal", + "nutritious", + "obscure", + "organic", + "piscine", + "purified", + "recalcitrant", + "rogue", + "subterranean", + "sweet", "weary", ]; -const LASTS: [&'static str; 30] = [ - "kaffe", - "foilage", - "wildlife", - "design", - "assembly", - "layout", - "transmitter", - "lens", +const LASTS: [&'static str; 34] = [ "artifact", - "frequency", - "entropy", + "assembly", "console", - "insulator", - "river", - "oak", - "replicant", - "mechanism", "construct", - "function", - "shape", - "form", - "poseidon", - "mountain", - "river", + "design", + "entropy", + "foilage", "forest", - "problem", - "warning", + "form", + "frequency", + "function", "information", - "witness", + "insulator", + "kaffe", + "layout", + "lens", + "mechanism", + "mountain", + "nectar", + "oak", + "plant", + "poseidon", + "problem", + "replicant", + "river", + "river", + "shape", + "signal", + "tower", + "transmitter", "traveller", + "warning", + "wildlife", + "witness", ]; pub fn name() -> String { diff --git a/server/src/rpc.rs b/server/src/rpc.rs index d42d4cbb..48e6f98b 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -1,13 +1,13 @@ use std::net::TcpStream; use std::time::{Instant}; -use tungstenite::protocol::WebSocket; use serde_cbor::{from_slice}; use uuid::Uuid; use failure::Error; use failure::err_msg; +use ws::{Ws}; use pg::{Db}; use construct::{Construct}; use game::{Game, game_state, game_skill, game_ready}; @@ -20,7 +20,7 @@ use item::{Item, ItemInfoCtr, item_info}; use mtx; #[derive(Debug,Clone,Serialize,Deserialize)] -pub enum RpcResult { +pub enum RpcMessage { AccountState(Account), AccountConstructs(Vec), AccountInstances(Vec), @@ -53,7 +53,6 @@ enum RpcRequest { AccountState {}, AccountShop {}, AccountConstructs {}, - AccountInstances {}, InstanceList {}, InstanceLobby { construct_ids: Vec, name: String, pve: bool, password: Option }, @@ -69,7 +68,7 @@ enum RpcRequest { VboxReclaim { instance_id: Uuid, index: usize }, } -pub fn receive(data: Vec, db: &Db, _client: &mut WebSocket, begin: Instant, account: &Option) -> Result { +pub fn receive(data: Vec, db: &Db, _client: &mut Ws, begin: Instant, account: &Option) -> Result { // cast the msg to this type to receive method name match from_slice::(&data) { Ok(v) => { @@ -77,10 +76,10 @@ pub fn receive(data: Vec, db: &Db, _client: &mut WebSocket, begin // non authenticated // non transactional reqs match v { - RpcRequest::Ping {} => return Ok(RpcResult::Pong(())), - RpcRequest::ItemInfo {} => return Ok(RpcResult::ItemInfo(item_info())), + RpcRequest::Ping {} => return Ok(RpcMessage::Pong(())), + RpcRequest::ItemInfo {} => return Ok(RpcMessage::ItemInfo(item_info())), RpcRequest::DevResolve {a, b, skill } => - return Ok(RpcResult::DevResolutions(dev_resolve(a, b, skill))), + return Ok(RpcMessage::DevResolutions(dev_resolve(a, b, skill))), _ => (), }; @@ -97,63 +96,61 @@ pub fn receive(data: Vec, db: &Db, _client: &mut WebSocket, begin let response = match v { RpcRequest::AccountState {} => - return Ok(RpcResult::AccountState(account.clone())), + return Ok(RpcMessage::AccountState(account.clone())), RpcRequest::AccountConstructs {} => - Ok(RpcResult::AccountConstructs(account_constructs(&mut tx, &account)?)), - RpcRequest::AccountInstances {} => - Ok(RpcResult::AccountInstances(account_instances(&mut tx, &account)?)), + Ok(RpcMessage::AccountConstructs(account_constructs(&mut tx, &account)?)), // RpcRequest::AccountShop {} => - // Ok(RpcResult::AccountShop(mtx::account_shop(&mut tx, &account)?)), + // Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)), // RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account), RpcRequest::GameState { id } => - Ok(RpcResult::GameState(game_state(&mut tx, account, id)?)), + Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)), RpcRequest::GameSkill { game_id, construct_id, target_construct_id, skill } => - Ok(RpcResult::GameState(game_skill(&mut tx, account, game_id, construct_id, target_construct_id, skill)?)), + Ok(RpcMessage::GameState(game_skill(&mut tx, account, game_id, construct_id, target_construct_id, skill)?)), RpcRequest::GameReady { id } => - Ok(RpcResult::GameState(game_ready(&mut tx, account, id)?)), + Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)), RpcRequest::InstanceList {} => - Ok(RpcResult::OpenInstances(instance_list(&mut tx)?)), + Ok(RpcMessage::OpenInstances(instance_list(&mut tx)?)), RpcRequest::InstanceLobby { construct_ids, name, pve, password } => - Ok(RpcResult::InstanceState(instance_new(&mut tx, account, construct_ids, name, pve, password)?)), + Ok(RpcMessage::InstanceState(instance_new(&mut tx, account, construct_ids, name, pve, password)?)), RpcRequest::InstanceJoin { instance_id, construct_ids } => - Ok(RpcResult::InstanceState(instance_join(&mut tx, account, instance_id, construct_ids)?)), + Ok(RpcMessage::InstanceState(instance_join(&mut tx, account, instance_id, construct_ids)?)), RpcRequest::InstanceReady { instance_id } => - Ok(RpcResult::InstanceState(instance_ready(&mut tx, account, instance_id)?)), + Ok(RpcMessage::InstanceState(instance_ready(&mut tx, account, instance_id)?)), RpcRequest::InstanceState { instance_id } => Ok(instance_state(&mut tx, account, instance_id)?), RpcRequest::VboxAccept { instance_id, group, index } => - Ok(RpcResult::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)), + Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)), RpcRequest::VboxApply { instance_id, construct_id, index } => - Ok(RpcResult::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)), + Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)), RpcRequest::VboxCombine { instance_id, indices } => - Ok(RpcResult::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)), + Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)), RpcRequest::VboxDiscard { instance_id } => - Ok(RpcResult::InstanceState(vbox_discard(&mut tx, account, instance_id)?)), + Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)), RpcRequest::VboxReclaim { instance_id, index } => - Ok(RpcResult::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)), + Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)), RpcRequest::VboxUnequip { instance_id, construct_id, target } => - Ok(RpcResult::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)), + Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)), RpcRequest::MtxConstructApply { mtx, construct_id, name } => - Ok(RpcResult::AccountConstructs(mtx::apply(&mut tx, account, mtx, construct_id, name)?)), + Ok(RpcMessage::AccountConstructs(mtx::apply(&mut tx, account, mtx, construct_id, name)?)), RpcRequest::MtxBuy { mtx } => - Ok(RpcResult::AccountShop(mtx::buy(&mut tx, account, mtx)?)), + Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)), _ => Err(format_err!("unknown request request={:?}", request)), }; diff --git a/server/src/ws.rs b/server/src/ws.rs index ed59b821..4a485003 100644 --- a/server/src/ws.rs +++ b/server/src/ws.rs @@ -17,14 +17,21 @@ use crossbeam_channel::{unbounded, Receiver}; use serde_cbor::{to_vec}; +use failure::Error; +use failure::{err_msg, format_err}; + use net::TOKEN_HEADER; use rpc; +use rpc::{RpcMessage}; use mtx; use pg::PgPool; use account; +use account::Account; use pubsub::Message; +pub type Ws = WebSocket; + #[derive(Debug,Clone,Serialize)] struct RpcError { err: String, @@ -33,25 +40,91 @@ struct RpcError { #[derive(Debug)] struct Subscriptions { account: Option, - games: Vec, - instances: Vec, + game: Option, + instance: Option, + // account_instances: Vec, } -fn handle_message(subs: &Subscriptions, m: Message, ws: &mut WebSocket) { +impl Subscriptions { + fn new(ws_pool: &PgPool, account: &Option, ws: &mut Ws) -> Result { + if let Some(a) = account { + let db = ws_pool.get()?; + let mut tx = db.transaction()?; + + // send account constructs + let account_constructs = account::account_constructs(&mut tx, a)?; + ws.write_message(Binary(to_vec(&rpc::RpcMessage::AccountConstructs(account_constructs))?))?; + + // get account instances + // and send them to the client + let account_instances = account::account_instances(&mut tx, a)?; + // let instances = account_instances.iter().map(|i| i.id).collect::>(); + ws.write_message(Binary(to_vec(&rpc::RpcMessage::AccountInstances(account_instances))?))?; + + // get players + // add to games + + tx.commit()?; + + return Ok(Subscriptions { + account: Some(a.id), + game: None, + instance: None, + }) + } + + Ok(Subscriptions { + account: None, + game: None, + instance: None + }) + } + + fn update(&mut self, msg: &RpcMessage) -> Result<&mut Subscriptions, Error> { + match msg { + RpcMessage::AccountState(a) => self.account = Some(a.id), + RpcMessage::InstanceState(i) => self.instance = Some(i.id), + RpcMessage::GameState(g) => self.game = Some(g.id), + _ => (), + }; + + // info!("subscriptions updated {:?}", self); + + Ok(self) + } +} + + +fn handle_message(subs: &Subscriptions, m: Message, ws: &mut Ws) { if let Some(msg) = match m { Message::Account(a) => { - match (a.id, &subs.account) { - (id, Some(b)) => { - if id == *b { - Some(rpc::RpcResult::AccountState(a)) - } else { - None - } - } - _ => None, + match subs.account { + Some(wsa) => match wsa == a.id { + true => Some(rpc::RpcMessage::AccountState(a)), + false => None, + }, + None => None, } }, - _ => None, + Message::Instance(i) => { + match subs.instance { + Some(ci) => match ci == i.id { + true => Some(rpc::RpcMessage::InstanceState(i)), + false => None, + }, + None => None, + } + }, + Message::Game(g) => { + match subs.game { + Some(cg) => match cg == g.id { + true => Some(rpc::RpcMessage::GameState(g)), + false => None, + }, + None => None, + } + }, + // _ => None, } { ws.write_message(Binary(to_vec(&msg).unwrap())).unwrap(); } @@ -101,12 +174,12 @@ pub fn start(pool: PgPool, psr: Receiver) { match account::from_token(&db, t) { Ok(a) => { - let state = to_vec(&rpc::RpcResult::AccountState(a.clone())).unwrap(); + let state = to_vec(&rpc::RpcMessage::AccountState(a.clone())).unwrap(); websocket.write_message(Binary(state)).unwrap(); let mut tx = db.transaction().unwrap(); let shop = mtx::account_shop(&mut tx, &a).unwrap(); - let shop = to_vec(&rpc::RpcResult::AccountShop(shop)).unwrap(); + let shop = to_vec(&rpc::RpcMessage::AccountShop(shop)).unwrap(); websocket.write_message(Binary(shop)).unwrap(); @@ -124,13 +197,12 @@ pub fn start(pool: PgPool, psr: Receiver) { None => None, }; - let mut subs = Subscriptions { - account: match account.as_ref() { - Some(a) => Some(a.id), - None => None, + let mut subs = match Subscriptions::new(&ws_pool, &account, &mut websocket) { + Ok(s) => s, + Err(e) => { + warn!("subscriptions error err={:?}", e); + return; }, - games: vec![], - instances: vec![], }; loop { @@ -152,6 +224,8 @@ pub fn start(pool: PgPool, psr: Receiver) { debug!("{:?}", e); return; }; + + subs.update(&reply).unwrap(); }, Err(e) => { warn!("{:?}", e);