From 8e012cd5ea5ef09ada07056d2b2dbde021f28320 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 25 Apr 2019 12:02:10 +1000 Subject: [PATCH] wip --- client/src/socket.jsx | 7 + ops/migrations/20181020104420_games.js | 9 +- server/WORKLOG.md | 9 + server/src/game.rs | 18 +- server/src/instance.rs | 277 ++++++++++++++----------- server/src/player.rs | 4 +- server/src/rpc.rs | 12 +- server/src/vbox.rs | 2 +- 8 files changed, 203 insertions(+), 135 deletions(-) diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 8cbc4972..6290c5ba 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -237,8 +237,15 @@ function createSocket(events) { player_state: playerState, }; + function logout() { + localStorage.removeItem('account'); + account = null; + event.setAccount(null); + } + function errHandler(error) { switch (error) { + case 'invalid token': return logout(); case 'no active zone': return sendZoneCreate(); case 'no cryps selected': return events.errorPrompt('select_cryps'); case 'node requirements not met': return events.errorPrompt('complete_nodes'); diff --git a/ops/migrations/20181020104420_games.js b/ops/migrations/20181020104420_games.js index 70bf590e..5f1b1531 100644 --- a/ops/migrations/20181020104420_games.js +++ b/ops/migrations/20181020104420_games.js @@ -16,15 +16,10 @@ exports.up = async knex => { table.binary('data').notNullable(); table.boolean('open') .defaultTo(true) - .notNullable(); + .notNullable() + .index(); }); - await knex.schema.raw( - // eslint-disable-next-line max-len - 'CREATE UNIQUE INDEX instances_open ON instances (open) WHERE open = true;' - ); - - await knex.schema.createTable('players', table => { table.uuid('id').primary(); table.index('id'); diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 85df2e81..22cece8f 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -16,6 +16,15 @@ # WORK WORK ## NOW +*INSTANCES* + +lobby opens + add player + add player + + players ready + on start -> vbox + *CLIENT* * general * icons change with % diff --git a/server/src/game.rs b/server/src/game.rs index 8708290e..fd603bde 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -12,7 +12,7 @@ use rpc::{GameStateParams, GameSkillParams}; use cryp::{Cryp}; use skill::{Skill, Effect, Cast, Resolution, Event, resolve}; use player::{Player}; -use instance::{instance_game_finished, global_game_finished}; +// use instance::{instance_game_finished, global_game_finished}; #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Team { @@ -798,14 +798,14 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> { result.iter().next().ok_or(format_err!("game {:?} could not be written", game))?; - if game.finished() { - if let Some(i) = game.instance { - match i == Uuid::nil() { - true => global_game_finished(tx, &game)?, - false => instance_game_finished(tx, &game, i)?, - } - } - } + // if game.finished() { + // if let Some(i) = game.instance { + // match i == Uuid::nil() { + // true => global_game_finished(tx, &game)?, + // false => instance_game_finished(tx, &game, i)?, + // } + // } + // } return Ok(()); } diff --git a/server/src/instance.rs b/server/src/instance.rs index 40d33b9b..2ecd391f 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -71,6 +71,7 @@ impl Instance { return Err(err_msg("name must have a length")); } + self.name = name; Ok(self) } @@ -80,7 +81,6 @@ impl Instance { let bot_id = Uuid::new_v4(); let cryps = instance_mobs(bot_id); let mut p = Player::new(bot_id, self.id, &bot_id.to_string(), cryps).set_bot(true); - p.autobuy(); p.set_ready(true); p }) @@ -109,19 +109,17 @@ impl Instance { Ok(self) } - fn player_ready(&mut self, player: &mut Player) -> Result<&mut Instance, Error> { + fn player_ready(&mut self, player_id: Uuid) -> Result<&mut Instance, Error> { if ![InstancePhase::Vbox, InstancePhase::Open].contains(&self.phase) { return Err(err_msg("instance not in start or vbox phase")); } let i = self.players - .iter() - .position(|p| p.id == player.id) + .iter_mut() + .position(|p| p.id == player_id) .ok_or(err_msg("player_id not found"))?; - player.set_ready(true); - - self.players[i] = player.clone(); + self.players[i].set_ready(true); if self.all_ready() { match self.phase { @@ -492,113 +490,130 @@ pub fn instance_scores(params: InstanceReadyParams, tx: &mut Transaction, _accou Ok(scores) } -pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result { - let mut player = player_get(tx, account.id, params.instance_id)?; - - if params.instance_id == Uuid::nil() { - return instance_ready_global(tx, account, player); - } - +pub fn instance_lobby_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result { + let player = player_get(tx, account.id, params.instance_id)?; let mut instance = instance_get(tx, params.instance_id)?; + instance.player_ready(player.id)?; - // attempting to re-ready - // send game state - match instance.player_ready(&mut player) { - Ok(_) => (), - Err(_) => return game_get(tx, instance.current_round(&player).game_id), - }; - - let game_id = instance.current_round(&player).game_id; - - let game = match instance.player_has_pve_game(&player) { - true => match game_get(tx, game_id) { - Ok(g) => g, - Err(_) => { - let game = instance.bot_vs_player_game(&player)?; - game_write(&game, tx)?; - game - }, - }, - false => match game_get(tx, game_id) { - Ok(_g) => game_instance_join(tx, player.clone(), game_id)?, - Err(_) => game_instance_new(tx, player.clone(), game_id)?, - } - }; - - player_update(tx, player, false)?; - instance_update(tx, instance)?; - return Ok(game); -} - -pub fn global_game_finished(tx: &mut Transaction, game: &Game) -> Result<(), Error> { - let winner = game.winner().ok_or(err_msg("game not finished"))?; - - for team in game.teams.iter() { - let mut player = player_get(tx, team.id, Uuid::nil())?; - match team.id == winner.id { - true => player.add_win(), - false => player.add_loss(), - }; - player.vbox.fill(); - player_update(tx, player, true)?; - } - - Ok(()) -} - -pub fn instance_game_finished(tx: &mut Transaction, game: &Game, instance_id: Uuid) -> Result<(), Error> { - // update scores - let winner = game.winner().ok_or(err_msg("game not finished"))?; - - for team in game.teams.iter() { - match team.bot { - true => { - let mut instance = instance_get(tx, instance_id)?; - { - let mut player = instance.players.iter_mut().find(|p| p.account == team.id).unwrap(); - match team.id == winner.id { - true => player.add_win(), - false => player.add_loss(), - }; - } - instance_update(tx, instance)?; - }, - false => { - let mut player = player_get(tx, team.id, instance_id)?; - match team.id == winner.id { - true => player.add_win(), - false => player.add_loss(), - }; - player_update(tx, player, true)?; - }, - } - } - - // update instance and persist - let mut instance = instance_get(tx, instance_id)?; - instance.game_finished(game)?; - let mut instance = instance_update(tx, instance)?; - - // now modify the players and write them all - // each player update will also update the instance in db - if instance.games_phase_finished() { - instance.vbox_phase_start(); - let instance = instance_update(tx, instance)?; - - for player in instance.players - .iter() - .filter(|p| !p.bot) { - let mut player = player_get(tx, player.account, instance_id)?; + if instance.can_start() { + instance.start(); + for player in instance.players.iter_mut().filter(|p| !p.bot) { player.vbox.fill(); - player_update(tx, player, false)?; + player_update(tx, player.clone(), false)?; } } - // println!("{:?}", instance_get(tx, instance_id)?); - - Ok(()) + instance_update(tx, instance)?; + Ok(player) } +// pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result { +// let mut player = player_get(tx, account.id, params.instance_id)?; + +// if params.instance_id == Uuid::nil() { +// return instance_ready_global(tx, account, player); +// } + +// let mut instance = instance_get(tx, params.instance_id)?; + +// // attempting to re-ready +// // send game state +// match instance.player_ready(player.id) { +// Ok(_) => (), +// Err(_) => return game_get(tx, instance.current_round(&player).game_id), +// }; + +// let game_id = instance.current_round(&player).game_id; + +// let game = match instance.player_has_pve_game(&player) { +// true => match game_get(tx, game_id) { +// Ok(g) => g, +// Err(_) => { +// let game = instance.bot_vs_player_game(&player)?; +// game_write(&game, tx)?; +// game +// }, +// }, +// false => match game_get(tx, game_id) { +// Ok(_g) => game_instance_join(tx, player.clone(), game_id)?, +// Err(_) => game_instance_new(tx, player.clone(), game_id)?, +// } +// }; + +// player_update(tx, player, false)?; +// instance_update(tx, instance)?; +// return Ok(game); +// } + +// pub fn global_game_finished(tx: &mut Transaction, game: &Game) -> Result<(), Error> { +// let winner = game.winner().ok_or(err_msg("game not finished"))?; + +// for team in game.teams.iter() { +// let mut player = player_get(tx, team.id, Uuid::nil())?; +// match team.id == winner.id { +// true => player.add_win(), +// false => player.add_loss(), +// }; +// player.vbox.fill(); +// player_update(tx, player, true)?; +// } + +// Ok(()) +// } + +// pub fn instance_game_finished(tx: &mut Transaction, game: &Game, instance_id: Uuid) -> Result<(), Error> { +// // update scores +// let winner = game.winner().ok_or(err_msg("game not finished"))?; + +// for team in game.teams.iter() { +// match team.bot { +// true => { +// let mut instance = instance_get(tx, instance_id)?; +// { +// let mut player = instance.players.iter_mut().find(|p| p.account == team.id).unwrap(); +// match team.id == winner.id { +// true => player.add_win(), +// false => player.add_loss(), +// }; +// } +// instance_update(tx, instance)?; +// }, +// false => { +// let mut player = player_get(tx, team.id, instance_id)?; +// match team.id == winner.id { +// true => player.add_win(), +// false => player.add_loss(), +// }; +// player_update(tx, player, true)?; +// }, +// } +// } + +// // update instance and persist +// let mut instance = instance_get(tx, instance_id)?; +// instance.game_finished(game)?; +// let mut instance = instance_update(tx, instance)?; + +// // now modify the players and write them all +// // each player update will also update the instance in db +// if instance.games_phase_finished() { +// instance.vbox_phase_start(); +// let instance = instance_update(tx, instance)?; + +// for player in instance.players +// .iter() +// .filter(|p| !p.bot) { +// let mut player = player_get(tx, player.account, instance_id)?; +// player.vbox.fill(); +// player_update(tx, player, false)?; +// } +// } + +// // println!("{:?}", instance_get(tx, instance_id)?); + +// Ok(()) +// } + #[cfg(test)] mod tests { use super::*; @@ -611,26 +626,27 @@ mod tests { let player_account = Uuid::new_v4(); let cryps = instance_mobs(player_account); - let mut player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true); - player.autobuy(); - player.set_ready(true); + let player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true); + let player_id = player.id; - instance.add_player(player.clone()); - assert!(instance.can_start()); + instance.add_player(player); - instance.start(); + assert_eq!(instance.phase, InstancePhase::Open); + instance.player_ready(player_id).unwrap(); + + assert_eq!(instance.phase, InstancePhase::Vbox); assert_eq!(instance.rounds[0].len(), 8); - instance.player_ready(&mut player).unwrap(); + instance.player_ready(player_id).unwrap(); assert!(instance.games_phase_finished()); instance.vbox_phase_start(); - instance.player_ready(&mut player).unwrap(); + instance.player_ready(player_id).unwrap(); instance.vbox_phase_start(); - instance.player_ready(&mut player).unwrap(); + instance.player_ready(player_id).unwrap(); assert_eq!(instance.rounds.len(), 3); } @@ -643,4 +659,33 @@ mod tests { let _player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true); } -} \ No newline at end of file + #[test] + fn instance_start_test() { + let mut instance = Instance::new() + .set_max_players(2) + .expect("could not create instance"); + + assert_eq!(instance.max_players, 2); + + let player_account = Uuid::new_v4(); + let cryps = instance_mobs(player_account); + let player = Player::new(player_account, instance.id, &"a".to_string(), cryps); + let a_id = player.id; + + instance.add_player(player.clone()); + assert!(!instance.can_start()); + + let player_account = Uuid::new_v4(); + let cryps = instance_mobs(player_account); + let player = Player::new(player_account, instance.id, &"b".to_string(), cryps); + let b_id = player.id; + + instance.add_player(player); + + instance.player_ready(a_id).expect("a ready"); + assert!(!instance.can_start()); + + instance.player_ready(b_id).expect("b ready"); + assert!(instance.can_start()); + } +} diff --git a/server/src/player.rs b/server/src/player.rs index 1c7f9328..5ee70cde 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -389,8 +389,10 @@ mod tests { let player_account = Uuid::new_v4(); let cryps = instance_mobs(player_account); let mut player = Player::new(player_account, Uuid::new_v4(), &"test".to_string(), cryps).set_bot(true); + player.vbox.fill(); player.autobuy(); - assert!(player.cryps.iter().all(|c| c.skills.len() == 2)); + + assert!(player.cryps.iter().all(|c| c.skills.len() >= 1)); } } \ No newline at end of file diff --git a/server/src/rpc.rs b/server/src/rpc.rs index ed1a2aa7..77ec567a 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -22,7 +22,7 @@ use skill::{Skill}; // use zone::{Zone, zone_create, zone_join, zone_close}; use spec::{Spec}; use player::{Score, player_state, player_mm_cryps_set, Player}; -use instance::{instance_lobby, instance_join, instance_ready, instance_scores}; +use instance::{instance_lobby, instance_lobby_ready, instance_join, instance_scores}; use vbox::{Var, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip}; pub struct Rpc; @@ -273,6 +273,16 @@ impl Rpc { return Ok(response); } + fn instance_lobby_ready(data: Vec, tx: &mut Transaction, account: Account, _client: &mut WebSocket) -> Result { + let msg = from_slice::(&data).or(Err(err_msg("invalid params")))?; + + let response = RpcResponse { + method: "player_state".to_string(), + params: RpcResult::PlayerState(instance_lobby_ready(msg.params, tx, &account)?) + }; + + return Ok(response); + } fn instance_join(data: Vec, tx: &mut Transaction, account: Account, _client: &mut WebSocket) -> Result { let msg = from_slice::(&data).or(Err(err_msg("invalid params")))?; diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 3d605d3b..d6a69aca 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -421,7 +421,7 @@ impl Vbox { bits: 18, }; - vbox.fill(); + // vbox.fill(); return vbox; }