This commit is contained in:
ntr 2019-02-21 13:54:35 +11:00
parent 613444d066
commit d5d6254daf
5 changed files with 160 additions and 409 deletions

View File

@ -8,7 +8,7 @@ use failure::Error;
use failure::err_msg; use failure::err_msg;
use account::Account; use account::Account;
use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameJoinParams}; use rpc::{GameStateParams, GameSkillParams, GamePveParams};
use cryp::{Cryp, cryp_get}; use cryp::{Cryp, cryp_get};
use skill::{Skill, Cast, ResolutionResult}; use skill::{Skill, Cast, ResolutionResult};
use zone::{node_finish}; use zone::{node_finish};
@ -725,92 +725,6 @@ pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account)
Ok(game) Ok(game)
} }
pub fn game_pvp(params: GamePvpParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let cryps = params.cryp_ids
.iter()
.map(|id| cryp_get(tx, *id, account.id))
.collect::<Result<Vec<Cryp>, Error>>()?;
// create the game
let mut game = Game::new();
let game_id = game.id;
game
.set_pve(false)
.set_team_num(2)
.set_team_size(cryps.len())
.set_mode(GameMode::Pvp);
// create the initiators team
let mut team = Team::new(account.id);
team.set_cryps(cryps);
game.team_add(team)?;
// persist
game_write(&game, tx)?;
Ok(game)
}
pub fn game_join(params: GameJoinParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let mut game = game_get(tx, params.game_id)?;
// rejoining a game from the FE list
if game.already_joined(account.id) {
return Ok(game);
}
// ok actually adding a new team
let game_id = game.id;
let cryps = params.cryp_ids
.iter()
.map(|id| cryp_get(tx, *id, account.id))
.collect::<Result<Vec<Cryp>, Error>>()?;
if cryps.len() != game.team_size {
return Err(format_err!("incorrect team size. ({:})", game.team_size));
}
let mut team = Team::new(account.id);
team.set_cryps(cryps);
game.team_add(team)?;
if game.can_start() {
game.start();
}
game_update(&game, tx)?;
Ok(game)
}
pub fn game_joinable_list(tx: &mut Transaction, _account: &Account) -> Result<Vec<Game>, Error> {
let query = "
SELECT games.data
FROM games
WHERE joinable;
";
let result = tx
.query(query, &[])?;
let games: Result<Vec<Game>, _> = result.iter().map(|row| {
let cryp_bytes: Vec<u8> = row.get(0);
from_slice::<Game>(&cryp_bytes)
}).collect();
// catch any errors
if games.is_err() {
return Err(err_msg("could not deserialize a game"));
}
// now unwrap is safe
return Ok(games.unwrap());
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use game::*; use game::*;

View File

@ -7,8 +7,10 @@ use postgres::transaction::Transaction;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use rpc::{InstanceJoinParams};
use account::Account; use account::Account;
use player::{Player, player_write}; use player::{Player, player_create};
use cryp::{Cryp, cryp_get};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
enum InstancePhase { enum InstancePhase {
@ -36,7 +38,7 @@ impl Instance {
} }
} }
fn add_player(&mut self, player: Player) -> &mut Instance { fn add_player(&mut self, player: &Player) -> &mut Instance {
self.players.push(player.id); self.players.push(player.id);
self self
} }
@ -122,16 +124,26 @@ pub fn instance_get_open(tx: &mut Transaction) -> Result<Instance, Error> {
} }
pub fn join_instance(tx: &mut Transaction, account: &Account) -> Result<Player, Error> { pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let mut instance = match instance_get_open(tx) { let mut instance = match instance_get_open(tx) {
Ok(i) => i, Ok(i) => i,
Err(_) => instance_create(Instance::new())?, Err(_) => instance_create(Instance::new(), tx)?,
}; };
// get add them let cryps = params.cryp_ids
let player = Player::new(account, instance.id); .iter()
instance.add_player(account); .map(|id| cryp_get(tx, *id, account.id))
.collect::<Result<Vec<Cryp>, Error>>()?;
if cryps.len() != 3 {
return Err(format_err!("incorrect team size. ({:})", 3));
}
let player = Player::new(account.id, instance.id, cryps);
instance.add_player(&player);
player_create(tx, &player, account)?;
instance_write(instance, tx)?; instance_write(instance, tx)?;
return player_write(player, tx);
return Ok(player);
} }

View File

@ -8,28 +8,34 @@ use failure::Error;
use failure::err_msg; use failure::err_msg;
use account::Account; use account::Account;
use rpc::{VboxStateParams, VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxDropParams}; use instance::Instance;
use cryp::{Cryp, cryp_get, cryp_write}; use cryp::{Cryp};
use game::{Team, GameMode};
use vbox::{Vbox}; use vbox::{Vbox};
use rpc::{PlayerStateParams};
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Score { pub struct Score {
wins: u8, wins: u8,
losses: u8, losses: u8,
} }
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Player { pub struct Player {
id: Uuid, pub id: Uuid,
pub instance: Uuid,
pub account: Uuid,
// name: String, // name: String,
vbox: Vbox, pub vbox: Vbox,
score: Score, pub score: Score,
cryps: Vec<Cryp>, pub cryps: Vec<Cryp>,
} }
impl Player { impl Player {
pub fn new(account: Uuid, instance: Uuid, cryps: Vec<Cryp>) -> Player { pub fn new(account: Uuid, instance: Uuid, cryps: Vec<Cryp>) -> Player {
Player { Player {
id: account, id: Uuid::new_v4(),
account,
instance,
vbox: Vbox::new(account, instance), vbox: Vbox::new(account, instance),
score: Score { wins: 0, losses: 0 }, score: Score { wins: 0, losses: 0 },
cryps, cryps,
@ -37,7 +43,7 @@ impl Player {
} }
} }
pub fn player_get(tx: &mut Transaction, instance_id: Uuid) -> Result<Instance, Error> { pub fn player_get(tx: &mut Transaction, account_id: Uuid, instance_id: Uuid) -> Result<Player, Error> {
let query = " let query = "
SELECT * SELECT *
FROM players FROM players
@ -46,7 +52,7 @@ pub fn player_get(tx: &mut Transaction, instance_id: Uuid) -> Result<Instance, E
"; ";
let result = tx let result = tx
.query(query, &[&instance_id])?; .query(query, &[&account_id, &instance_id])?;
let returned = match result.iter().next() { let returned = match result.iter().next() {
Some(row) => row, Some(row) => row,
@ -54,17 +60,15 @@ pub fn player_get(tx: &mut Transaction, instance_id: Uuid) -> Result<Instance, E
}; };
// tells from_slice to cast into a cryp // tells from_slice to cast into a cryp
let instance_bytes: Vec<u8> = returned.get("data"); let bytes: Vec<u8> = returned.get("data");
let instance = from_slice::<Instance>(&instance_bytes)?; let data = from_slice::<Player>(&bytes)?;
return Ok(instance); return Ok(data);
} }
pub fn player_create(player: Player, account: &Account, instance_id: Uuid, tx: &mut Transaction) -> Result<(), Error> { pub fn player_create(tx: &mut Transaction, player: &Player, account: &Account) -> Result<(), Error> {
let player_bytes = to_vec(&player)?; let player_bytes = to_vec(&player)?;
let id = Uuid::new_v4();
let query = " let query = "
INSERT INTO players (id, instance, account, data) INSERT INTO players (id, instance, account, data)
VALUES ($1, $2, $3, $4) VALUES ($1, $2, $3, $4)
@ -72,11 +76,33 @@ pub fn player_create(player: Player, account: &Account, instance_id: Uuid, tx: &
"; ";
let result = tx let result = tx
.query(query, &[&id, &instance_id, &account.id, player_bytes])?; .query(query, &[&player.id, &player.instance, &account.id, &player_bytes])?;
let _returned = result.iter().next().expect("no row written"); let _returned = result.iter().next().expect("no row written");
println!("wrote player {:} joined game: {:}", account.name, instance_id); println!("wrote player {:} joined instance: {:}", account.name, player.instance);
return Ok(()); return Ok(());
} }
pub fn player_update(tx: &mut Transaction, player: Player) -> Result<Player, Error> {
let bytes = to_vec(&player)?;
let query = "
UPDATE players
SET data = $1
WHERE id = $2
RETURNING id, data;
";
let result = tx
.query(query, &[&bytes, &player.id])?;
result.iter().next().ok_or(format_err!("player {:?} could not be written", player))?;
return Ok(player)
}
pub fn player_state(params: PlayerStateParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
player_get(tx, params.instance_id, account.id)
}

View File

@ -15,13 +15,15 @@ use failure::Error;
use failure::err_msg; use failure::err_msg;
use net::Db; use net::Db;
use cryp::{Cryp, cryp_spawn, cryp_learn, cryp_forget, cryp_unspec}; use cryp::{Cryp, cryp_spawn, cryp_learn};
use game::{Game, game_state, game_pve, game_pvp, game_join, game_joinable_list, game_skill}; use game::{Game, game_state, game_pve, game_skill};
use account::{Account, account_create, account_login, account_from_token, account_cryps, account_zone}; use account::{Account, account_create, account_login, account_from_token, account_cryps, account_zone};
use skill::{Skill}; use skill::{Skill};
use zone::{Zone, zone_create, zone_join, zone_close}; use zone::{Zone, zone_create, zone_join, zone_close};
use spec::{Spec}; use spec::{Spec};
use vbox::{Vbox, vbox_state, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_drop}; use player::{player_state, Player};
use instance::{instance_join};
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_drop};
pub struct Rpc; pub struct Rpc;
@ -61,25 +63,21 @@ impl Rpc {
"account_demo" => Rpc::account_demo(data, &mut tx, client), "account_demo" => Rpc::account_demo(data, &mut tx, client),
// auth methods // auth methods
"cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account.unwrap(), client),
// "cryp_learn" => Rpc::cryp_learn(data, &mut tx, account.unwrap(), client),
// "cryp_forget" => Rpc::cryp_forget(data, &mut tx, account.unwrap(), client),
// "cryp_unspec" => Rpc::cryp_unspec(data, &mut tx, account.unwrap(), client),
"game_state" => Rpc::game_state(data, &mut tx, account.unwrap(), client),
"game_pve" => Rpc::game_pve(data, &mut tx, account.unwrap(), client),
"game_pvp" => Rpc::game_pvp(data, &mut tx, account.unwrap(), client),
// "game_join" => Rpc::game_join(data, &mut tx, account.unwrap(), client),
// "game_joinable_list" => Rpc::game_joinable_list(data, &mut tx, account.unwrap(), client),
"game_skill" => Rpc::game_skill(data, &mut tx, account.unwrap(), client),
// "game_target" => Rpc::game_target(data, &mut tx, account.unwrap(), client),
"zone_create" => Rpc::zone_create(data, &mut tx, account.unwrap(), client),
"zone_join" => Rpc::zone_join(data, &mut tx, account.unwrap(), client),
"zone_close" => Rpc::zone_close(data, &mut tx, account.unwrap(), client),
"account_cryps" => Rpc::account_cryps(data, &mut tx, account.unwrap(), client), "account_cryps" => Rpc::account_cryps(data, &mut tx, account.unwrap(), client),
"account_zone" => Rpc::account_zone(data, &mut tx, account.unwrap(), client), "account_zone" => Rpc::account_zone(data, &mut tx, account.unwrap(), client),
"cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account.unwrap(), client),
"game_state" => Rpc::game_state(data, &mut tx, account.unwrap(), client),
"game_pve" => Rpc::game_pve(data, &mut tx, account.unwrap(), client),
"game_skill" => Rpc::game_skill(data, &mut tx, account.unwrap(), client),
"zone_create" => Rpc::zone_create(data, &mut tx, account.unwrap(), client),
"zone_join" => Rpc::zone_join(data, &mut tx, account.unwrap(), client),
"zone_close" => Rpc::zone_close(data, &mut tx, account.unwrap(), client),
"instance_join" => Rpc::instance_join(data, &mut tx, account.unwrap(), client), "instance_join" => Rpc::instance_join(data, &mut tx, account.unwrap(), client),
"player_state" => Rpc::vbox_state(data, &mut tx, account.unwrap(), client), "player_state" => Rpc::player_state(data, &mut tx, account.unwrap(), client),
"player_vbox_accept" => Rpc::player_vbox_accept(data, &mut tx, account.unwrap(), client), "player_vbox_accept" => Rpc::player_vbox_accept(data, &mut tx, account.unwrap(), client),
"player_vbox_apply" => Rpc::player_vbox_apply(data, &mut tx, account.unwrap(), client), "player_vbox_apply" => Rpc::player_vbox_apply(data, &mut tx, account.unwrap(), client),
"player_vbox_drop" => Rpc::player_vbox_drop(data, &mut tx, account.unwrap(), client), "player_vbox_drop" => Rpc::player_vbox_drop(data, &mut tx, account.unwrap(), client),
@ -116,7 +114,6 @@ impl Rpc {
return Ok(game_response); return Ok(game_response);
} }
fn game_pve(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn game_pve(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<GamePveMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<GamePveMsg>(&data).or(Err(err_msg("invalid params")))?;
@ -133,42 +130,6 @@ impl Rpc {
return Ok(game_response); return Ok(game_response);
} }
fn game_pvp(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<GamePvpMsg>(&data).or(Err(err_msg("invalid params")))?;
let game_response = RpcResponse {
method: "game_state".to_string(),
params: RpcResult::GameState(game_pvp(msg.params, tx, &account)?)
};
return Ok(game_response);
}
fn game_join(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<GameJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
let game_response = RpcResponse {
method: "game_state".to_string(),
params: RpcResult::GameState(game_join(msg.params, tx, &account)?)
};
return Ok(game_response);
}
fn game_joinable_list(_data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
// let msg = from_slice::<GameJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
let game_list = RpcResponse {
method: "game_joinable_list".to_string(),
params: RpcResult::GameJoinableList(game_joinable_list(tx, &account)?)
};
return Ok(game_list);
}
fn game_skill(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn game_skill(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<GameSkillMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<GameSkillMsg>(&data).or(Err(err_msg("invalid params")))?;
@ -180,17 +141,6 @@ impl Rpc {
return Ok(game_response); return Ok(game_response);
} }
// fn game_target(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
// let msg = from_slice::<GameTargetMsg>(&data).or(Err(err_msg("invalid params")))?;
// let game_response = RpcResponse {
// method: "game_state".to_string(),
// params: RpcResult::GameState(game_target(msg.params, tx, &account)?)
// };
// return Ok(game_response);
// }
fn cryp_spawn(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn cryp_spawn(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<CrypSpawnMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<CrypSpawnMsg>(&data).or(Err(err_msg("invalid params")))?;
@ -207,54 +157,6 @@ impl Rpc {
Ok(cryp_list) Ok(cryp_list)
} }
fn cryp_learn(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<CrypLearnMsg>(&data).or(Err(err_msg("invalid params")))?;
Rpc::send_msg(client, RpcResponse {
method: "cryp_learn".to_string(),
params: RpcResult::CrypLearn(cryp_learn(msg.params, tx, &account)?)
})?;
let cryp_list = RpcResponse {
method: "account_cryps".to_string(),
params: RpcResult::CrypList(account_cryps(tx, &account)?)
};
Ok(cryp_list)
}
fn cryp_forget(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<CrypForgetMsg>(&data).or(Err(err_msg("invalid params")))?;
Rpc::send_msg(client, RpcResponse {
method: "cryp_forget".to_string(),
params: RpcResult::CrypForget(cryp_forget(msg.params, tx, &account)?)
})?;
let cryp_list = RpcResponse {
method: "account_cryps".to_string(),
params: RpcResult::CrypList(account_cryps(tx, &account)?)
};
Ok(cryp_list)
}
fn cryp_unspec(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<CrypUnspecMsg>(&data).or(Err(err_msg("invalid params")))?;
Rpc::send_msg(client, RpcResponse {
method: "cryp_unspec".to_string(),
params: RpcResult::CrypUnspec(cryp_unspec(msg.params, tx, &account)?)
})?;
let cryp_list = RpcResponse {
method: "account_cryps".to_string(),
params: RpcResult::CrypList(account_cryps(tx, &account)?)
};
Ok(cryp_list)
}
fn account_create(data: Vec<u8>, tx: &mut Transaction, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn account_create(data: Vec<u8>, tx: &mut Transaction, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
match from_slice::<AccountCreateMsg>(&data) { match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
@ -356,57 +258,69 @@ impl Rpc {
return Ok(response); return Ok(response);
} }
fn vbox_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn instance_join(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxStateMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<InstanceJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_state(msg.params, tx, &account)?) params: RpcResult::PlayerState(instance_join(msg.params, tx, &account)?)
}; };
return Ok(response); return Ok(response);
} }
fn vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
fn player_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<PlayerStateMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse {
method: "player_state".to_string(),
params: RpcResult::PlayerState(player_state(msg.params, tx, &account)?)
};
return Ok(response);
}
fn player_vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxAcceptMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxAcceptMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_accept(msg.params, tx, &account)?) params: RpcResult::PlayerState(vbox_accept(msg.params, tx, &account)?)
}; };
return Ok(response); return Ok(response);
} }
fn vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn player_vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxDiscardMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxDiscardMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_discard(msg.params, tx, &account)?) params: RpcResult::PlayerState(vbox_discard(msg.params, tx, &account)?)
}; };
return Ok(response); return Ok(response);
} }
fn vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn player_vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxCombineMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxCombineMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_combine(msg.params, tx, &account)?) params: RpcResult::PlayerState(vbox_combine(msg.params, tx, &account)?)
}; };
return Ok(response); return Ok(response);
} }
fn vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn player_vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxApplyMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxApplyMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_apply(msg.params, tx, &account)?) params: RpcResult::PlayerState(vbox_apply(msg.params, tx, &account)?)
}; };
Rpc::send_msg(client, RpcResponse { Rpc::send_msg(client, RpcResponse {
@ -417,23 +331,12 @@ impl Rpc {
return Ok(response); return Ok(response);
} }
fn vbox_drop(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn player_vbox_drop(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxDropMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxDropMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse { let response = RpcResponse {
method: "vbox_state".to_string(), method: "player_state".to_string(),
params: RpcResult::VboxState(vbox_drop(msg.params, tx, &account)?) params: RpcResult::PlayerState(vbox_drop(msg.params, tx, &account)?)
};
return Ok(response);
}
fn vbox_drop(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let msg = from_slice::<VboxDropMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse {
method: "vbox_state".to_string(),
params: RpcResult::VboxState(vbox_drop(msg.params, tx, &account)?)
}; };
return Ok(response); return Ok(response);
@ -460,7 +363,7 @@ pub enum RpcResult {
ZoneState(Zone), ZoneState(Zone),
ZoneClose(()), ZoneClose(()),
VboxState(Vbox), PlayerState(Player),
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
@ -538,48 +441,6 @@ pub struct GamePveParams {
pub cryp_ids: Vec<Uuid>, pub cryp_ids: Vec<Uuid>,
} }
#[derive(Debug,Clone,Serialize,Deserialize)]
struct GamePvpMsg {
method: String,
params: GamePvpParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct GamePvpParams {
pub cryp_ids: Vec<Uuid>,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct GameJoinMsg {
method: String,
params: GameJoinParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct GameJoinParams {
pub game_id: Uuid,
pub cryp_ids: Vec<Uuid>,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct GameJoinableListMsg {
method: String,
params: (),
}
// #[derive(Debug,Clone,Serialize,Deserialize)]
// struct GameTargetMsg {
// method: String,
// params: GameTargetParams,
// }
// #[derive(Debug,Clone,Serialize,Deserialize)]
// pub struct GameTargetParams {
// pub game_id: Uuid,
// pub cryp_id: Uuid,
// pub skill_id: Uuid,
// }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct GameSkillMsg { struct GameSkillMsg {
method: String, method: String,
@ -655,14 +516,25 @@ pub struct ZoneCloseParams {
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct VboxStateMsg { struct InstanceJoinMsg {
method: String, method: String,
params: VboxStateParams, params: InstanceJoinParams,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxStateParams { pub struct InstanceJoinParams {
pub game_id: Uuid, pub cryp_ids: Vec<Uuid>,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct PlayerStateMsg {
method: String,
params: PlayerStateParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct PlayerStateParams {
pub instance_id: Uuid,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
@ -673,7 +545,7 @@ struct VboxAcceptMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxAcceptParams { pub struct VboxAcceptParams {
pub game_id: Uuid, pub instance_id: Uuid,
pub index: usize, pub index: usize,
} }
@ -685,7 +557,7 @@ struct VboxDiscardMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxDiscardParams { pub struct VboxDiscardParams {
pub game_id: Uuid, pub instance_id: Uuid,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
@ -696,7 +568,7 @@ struct VboxCombineMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxCombineParams { pub struct VboxCombineParams {
pub game_id: Uuid, pub instance_id: Uuid,
pub indices: Vec<usize>, pub indices: Vec<usize>,
} }
@ -708,7 +580,7 @@ struct VboxApplyMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxApplyParams { pub struct VboxApplyParams {
pub game_id: Uuid, pub instance_id: Uuid,
pub cryp_id: Uuid, pub cryp_id: Uuid,
pub index: usize, pub index: usize,
} }
@ -721,7 +593,7 @@ struct VboxDropMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxDropParams { pub struct VboxDropParams {
pub game_id: Uuid, pub instance_id: Uuid,
pub index: usize, pub index: usize,
} }

View File

@ -6,16 +6,15 @@ use rand::prelude::*;
use rand::{thread_rng}; use rand::{thread_rng};
use rand::distributions::{WeightedIndex}; use rand::distributions::{WeightedIndex};
use serde_cbor::{from_slice, to_vec};
use postgres::transaction::Transaction; use postgres::transaction::Transaction;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use account::Account; use account::Account;
use rpc::{VboxStateParams, VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxDropParams}; use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxDropParams};
use skill::{Skill}; use skill::{Skill};
use player::{Player, player_get, player_update};
use cryp::{cryp_get, cryp_write}; use cryp::{cryp_get, cryp_write};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -118,23 +117,23 @@ pub struct Vbox {
pub balance: u16, pub balance: u16,
pub free: Vec<Var>, pub free: Vec<Var>,
pub bound: Vec<Var>, pub bound: Vec<Var>,
pub game: Uuid, pub instance: Uuid,
pub account: Uuid, pub account: Uuid,
} }
impl Vbox { impl Vbox {
pub fn new(account_id: Uuid, game_id: Uuid) -> Vbox { pub fn new(account_id: Uuid, instance_id: Uuid) -> Vbox {
Vbox { Vbox {
id: Uuid::new_v4(), id: Uuid::new_v4(),
account: account_id, account: account_id,
game: game_id, instance: instance_id,
free: vec![], free: vec![],
bound: vec![], bound: vec![],
balance: 0, balance: 0,
} }
} }
pub fn fill(mut self: Vbox) -> Vbox { pub fn fill(&mut self) -> &mut Vbox {
let vars = vec![ let vars = vec![
(Var::Red, 1), (Var::Red, 1),
(Var::Green, 1), (Var::Green, 1),
@ -277,107 +276,35 @@ impl Vbox {
} }
} }
pub fn vbox_create(vbox: Vbox, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> { pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let vbox_bytes = to_vec(&vbox)?; let mut player = player_get(tx, params.instance_id, account.id)?;
player.vbox.fill();
let query = " return player_update(tx, player);
INSERT INTO vbox (id, account, game, data)
VALUES ($1, $2, $3, $4)
RETURNING id;
";
let result = tx
.query(query, &[&vbox.id, &account.id, &vbox.game, &vbox_bytes])?;
result.iter().next().ok_or(format_err!("no vbox written"))?;
// println!("{:} wrote vbox", vbox.id);
return Ok(vbox);
} }
pub fn vbox_write(vbox: Vbox, tx: &mut Transaction) -> Result<Vbox, Error> { pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let vbox_bytes = to_vec(&vbox)?; let mut player = player_get(tx, params.instance_id, account.id)?;
player.vbox.accept(params.index)?;
let query = " return player_update(tx, player);
UPDATE vbox
SET data = $1
WHERE id = $2
RETURNING id, account, data;
";
let result = tx
.query(query, &[&vbox_bytes, &vbox.id])?;
result.iter().next().ok_or(err_msg("no vbox row returned"))?;
// println!("{:?} wrote vbox", vbox.id);
return Ok(vbox);
} }
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
pub fn vbox_get(tx: &mut Transaction, game_id: Uuid, account: &Account) -> Result<Vbox, Error> { let mut player = player_get(tx, params.instance_id, account.id)?;
let query = " player.vbox.combine(params.indices)?;
SELECT * return player_update(tx, player);
FROM vbox
WHERE account = $1
AND game = $2;
";
let result = tx
.query(query, &[&account.id, &game_id])?;
let returned = match result.iter().next() {
Some(row) => row,
None => return Err(err_msg("vbox not found")),
};
// tells from_slice to cast into a cryp
let vbox_bytes: Vec<u8> = returned.get("data");
let vbox = from_slice::<Vbox>(&vbox_bytes)?;
return Ok(vbox);
} }
pub fn vbox_state(params: VboxStateParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> { pub fn vbox_drop(params: VboxDropParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
match vbox_get(tx, params.game_id, account) { let mut player = player_get(tx, params.instance_id, account.id)?;
Ok(v) => Ok(v), player.vbox.drop(params.index)?;
Err(e) => { return player_update(tx, player);
println!("{:?}", e);
vbox_create(Vbox::new(account.id, params.game_id).fill(), tx, account)
}
}
} }
pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> { pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let vbox = vbox_get(tx, params.game_id, account)?; let mut player = player_get(tx, params.instance_id, account.id)?;
return vbox_write(vbox.fill(), tx);
}
pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
let mut vbox = vbox_get(tx, params.game_id, account)?;
vbox.accept(params.index)?;
return vbox_write(vbox, tx);
}
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
let mut vbox = vbox_get(tx, params.game_id, account)?;
vbox.combine(params.indices)?;
return vbox_write(vbox, tx);
}
pub fn vbox_drop(params: VboxDropParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
let mut vbox = vbox_get(tx, params.game_id, account)?;
vbox.drop(params.index)?;
return vbox_write(vbox, tx);
}
pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
let mut vbox = vbox_get(tx, params.game_id, account)?;
let mut cryp = cryp_get(tx, params.cryp_id, account.id)?; let mut cryp = cryp_get(tx, params.cryp_id, account.id)?;
let var = vbox.bound.remove(params.index); let var = player.vbox.bound.remove(params.index);
// done here because i teach them a tonne of skills for tests // done here because i teach them a tonne of skills for tests
let max_skills = 4; let max_skills = 4;
@ -388,7 +315,7 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou
let skill = var.skill()?; let skill = var.skill()?;
cryp = cryp.learn(skill); cryp = cryp.learn(skill);
cryp_write(cryp, tx)?; cryp_write(cryp, tx)?;
return vbox_write(vbox, tx); return player_update(tx, player);
} }