accounts are back

This commit is contained in:
ntr 2019-06-16 14:24:05 +10:00
parent 66462ac670
commit 2b06c83ea0
4 changed files with 103 additions and 86 deletions

View File

@ -209,7 +209,7 @@ function createSocket(events) {
// when the server sends a reply it will have one of these message types // when the server sends a reply it will have one of these message types
// this object wraps the reply types to a function // this object wraps the reply types to a function
const handlers = { const handlers = {
Account: onAccount, AccountState: onAccount,
AccountConstructs: onAccountConstructs, AccountConstructs: onAccountConstructs,
AccountInstances: onAccountInstances, AccountInstances: onAccountInstances,
GameState: onGameState, GameState: onGameState,

View File

@ -19,7 +19,6 @@ static PASSWORD_MIN_LEN: usize = 11;
pub struct Account { pub struct Account {
pub id: Uuid, pub id: Uuid,
pub name: String, pub name: String,
token: String,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
@ -50,7 +49,6 @@ pub fn account_from_token(token: String, tx: &mut Transaction) -> Result<Account
let entry = Account { let entry = Account {
id: returned.get(0), id: returned.get(0),
name: returned.get(1), name: returned.get(1),
token: returned.get(2),
}; };
return Ok(entry); return Ok(entry);

View File

@ -1,26 +1,23 @@
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use std::env; use std::env;
use chrono::Duration as ChronoDuration;
use failure::err_msg;
use serde_cbor::{to_vec}; use serde_cbor::{to_vec};
use actix::prelude::*; use actix::prelude::*;
use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer}; use actix_web::{middleware, web, App, Error, HttpMessage, HttpRequest, HttpResponse, HttpServer};
use actix_web::middleware::cors::Cors; use actix_web::middleware::cors::Cors;
use actix_web::error::ResponseError; use actix_web::error::ResponseError;
use actix_web::http::{StatusCode, Cookie}; use actix_web::http::{StatusCode, Cookie};
use actix_web::cookie::{SameSite};
use actix_web_actors::ws; use actix_web_actors::ws;
use r2d2::{Pool}; use r2d2::{Pool};
use r2d2::{PooledConnection}; use r2d2::{PooledConnection};
use r2d2_postgres::{TlsMode, PostgresConnectionManager}; use r2d2_postgres::{TlsMode, PostgresConnectionManager};
use rpc::{receive, RpcErrorResponse, AccountLoginParams, AccountCreateParams}; use rpc::{receive, RpcResult, RpcErrorResponse, AccountLoginParams, AccountCreateParams};
use warden::{warden}; use warden::{warden};
use account::{Account, account_login, account_create}; use account::{Account, account_login, account_create, account_from_token};
pub type Db = PooledConnection<PostgresConnectionManager>; pub type Db = PooledConnection<PostgresConnectionManager>;
type PgPool = Pool<PostgresConnectionManager>; type PgPool = Pool<PostgresConnectionManager>;
@ -36,6 +33,7 @@ pub struct MnmlSocket {
/// otherwise we drop connection. /// otherwise we drop connection.
hb: Instant, hb: Instant,
pool: PgPool, pool: PgPool,
account: Option<Account>,
} }
impl Actor for MnmlSocket { impl Actor for MnmlSocket {
@ -50,10 +48,22 @@ impl Actor for MnmlSocket {
/// Handler for `ws::Message` /// Handler for `ws::Message`
impl StreamHandler<ws::Message, ws::ProtocolError> for MnmlSocket { impl StreamHandler<ws::Message, ws::ProtocolError> for MnmlSocket {
fn started(&mut self, ctx: &mut Self::Context) {
match self.account.as_ref() {
Some(a) => {
info!("user connected {:?}", a);
let account_state = to_vec(&RpcResult::AccountState(a.clone()))
.expect("could not serialize account state");
ctx.binary(account_state)
},
None => info!("new connection"),
}
}
fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) { fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) {
// process websocket messages // process websocket messages
let begin = Instant::now(); let begin = Instant::now();
println!("msg: {:?}", msg); debug!("msg: {:?}", msg);
match msg { match msg {
ws::Message::Ping(msg) => { ws::Message::Ping(msg) => {
self.hb = Instant::now(); self.hb = Instant::now();
@ -64,12 +74,16 @@ impl StreamHandler<ws::Message, ws::ProtocolError> for MnmlSocket {
} }
ws::Message::Text(_text) => (), ws::Message::Text(_text) => (),
ws::Message::Close(_) => { ws::Message::Close(_) => {
match self.account.as_ref() {
Some(a) => info!("disconnected {:?}", a),
None => info!("disconnected"),
}
ctx.stop(); ctx.stop();
} }
ws::Message::Nop => (), ws::Message::Nop => (),
ws::Message::Binary(bin) => { ws::Message::Binary(bin) => {
let db_connection = self.pool.get().expect("unable to get db connection"); let db_connection = self.pool.get().expect("unable to get db connection");
match receive(bin.to_vec(), &db_connection, ctx, begin) { match receive(bin.to_vec(), &db_connection, ctx, begin, self.account.as_ref()) {
Ok(reply) => { Ok(reply) => {
let response = to_vec(&reply) let response = to_vec(&reply)
.expect("failed to serialize response"); .expect("failed to serialize response");
@ -87,10 +101,10 @@ impl StreamHandler<ws::Message, ws::ProtocolError> for MnmlSocket {
} }
impl MnmlSocket { impl MnmlSocket {
fn new(state: web::Data<State>) -> MnmlSocket { fn new(state: web::Data<State>, account: Option<Account>) -> MnmlSocket {
// idk why this has to be cloned again // idk why this has to be cloned again
// i guess because each socket is added as a new thread? // i guess because each socket is added as a new thread?
MnmlSocket { hb: Instant::now(), pool: state.pool.clone() } MnmlSocket { hb: Instant::now(), pool: state.pool.clone(), account }
} }
// starts the keepalive interval once actor started // starts the keepalive interval once actor started
@ -137,8 +151,32 @@ impl ResponseError for MnmlError {
// the req obj itself which we need for cookies // the req obj itself which we need for cookies
// the application state // the application state
// and the websocket stream // and the websocket stream
fn ws(r: HttpRequest, state: web::Data<State>, stream: web::Payload) -> Result<HttpResponse, Error> { fn connect(r: HttpRequest, state: web::Data<State>, stream: web::Payload) -> Result<HttpResponse, Error> {
ws::start(MnmlSocket::new(state), &r, stream) let account: Option<Account> = match r.cookie("x-auth-token") {
Some(t) => {
let db = state.pool.get().or(Err(MnmlError::ServerError))?;
let mut tx = db.transaction().or(Err(MnmlError::ServerError))?;
match account_from_token(t.value().to_string(), &mut tx) {
Ok(a) => Some(a),
Err(_) => None,
}
},
None => None,
};
ws::start(MnmlSocket::new(state, account), &r, stream)
}
fn token_res(token: String, secure: bool) -> HttpResponse {
HttpResponse::Ok()
.cookie(Cookie::build("x-auth-token", token)
// .path("/")
.secure(secure) // needs to be enabled for prod
.http_only(true)
.same_site(SameSite::Strict)
.max_age(60 * 60 * 24 * 7) // 1 week
.finish())
.finish()
} }
fn login(state: web::Data<State>, params: web::Json::<AccountLoginParams>) -> Result<HttpResponse, MnmlError> { fn login(state: web::Data<State>, params: web::Json::<AccountLoginParams>) -> Result<HttpResponse, MnmlError> {
@ -148,14 +186,7 @@ fn login(state: web::Data<State>, params: web::Json::<AccountLoginParams>) -> Re
match account_login(&params.name, &params.password, &mut tx) { match account_login(&params.name, &params.password, &mut tx) {
Ok(token) => { Ok(token) => {
tx.commit().or(Err(MnmlError::ServerError))?; tx.commit().or(Err(MnmlError::ServerError))?;
Ok(HttpResponse::Ok() Ok(token_res(token, state.secure))
.cookie(Cookie::build("x-auth-token", token)
// .path("/")
.http_only(true)
// .secure(true)
.max_age(60 * 60 * 24 * 7) // 1 week
.finish())
.finish())
}, },
Err(e) => { Err(e) => {
info!("{:?}", e); info!("{:?}", e);
@ -171,18 +202,11 @@ fn register(state: web::Data<State>, params: web::Json::<AccountCreateParams>) -
match account_create(&params.name, &params.password, &params.code, &mut tx) { match account_create(&params.name, &params.password, &params.code, &mut tx) {
Ok(token) => { Ok(token) => {
tx.commit().or(Err(MnmlError::ServerError))?; tx.commit().or(Err(MnmlError::ServerError))?;
Ok(HttpResponse::Created() Ok(token_res(token, state.secure))
.cookie(Cookie::build("x-auth-token", token)
.path("/")
.http_only(true)
.secure(true)
.max_age(60 * 60 * 24 * 7) // 1 week
.finish())
.finish())
}, },
Err(e) => { Err(e) => {
info!("{:?}", e); info!("{:?}", e);
Err(MnmlError::Unauthorized) Err(MnmlError::BadRequest)
} }
} }
} }
@ -199,6 +223,7 @@ fn create_pool(url: String) -> Pool<PostgresConnectionManager> {
struct State { struct State {
pool: PgPool, pool: PgPool,
secure: bool,
} }
pub fn start() { pub fn start() {
@ -211,22 +236,22 @@ pub fn start() {
Ok(_) => { Ok(_) => {
warn!("enabling dev CORS middleware"); warn!("enabling dev CORS middleware");
HttpServer::new(move || App::new() HttpServer::new(move || App::new()
.data(State { pool: pool.clone() }) .data(State { pool: pool.clone(), secure: false })
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
.wrap(Cors::new().supports_credentials()) .wrap(Cors::new().supports_credentials())
.service(web::resource("/login").route(web::post().to(login))) .service(web::resource("/login").route(web::post().to(login)))
.service(web::resource("/register").route(web::post().to(register))) .service(web::resource("/register").route(web::post().to(register)))
.service(web::resource("/ws/").route(web::get().to(ws)))) .service(web::resource("/ws/").route(web::get().to(connect))))
.bind("127.0.0.1:40000").expect("could not bind to port") .bind("127.0.0.1:40000").expect("could not bind to port")
.run().expect("could not start http server") .run().expect("could not start http server")
}, },
Err(_) => Err(_) =>
HttpServer::new(move || App::new() HttpServer::new(move || App::new()
.data(State { pool: pool.clone() }) .data(State { pool: pool.clone(), secure: true })
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
.service(web::resource("/login").route(web::post().to(login))) .service(web::resource("/login").route(web::post().to(login)))
.service(web::resource("/register").route(web::post().to(register))) .service(web::resource("/register").route(web::post().to(register)))
.service(web::resource("/ws/").route(web::get().to(ws)))) .service(web::resource("/ws/").route(web::get().to(connect))))
.bind("127.0.0.1:40000").expect("could not bind to port") .bind("127.0.0.1:40000").expect("could not bind to port")
.run().expect("could not start http server"), .run().expect("could not start http server"),
} }

View File

@ -11,7 +11,7 @@ use failure::err_msg;
use net::{Db, MnmlSocket}; use net::{Db, MnmlSocket};
use construct::{Construct, construct_spawn, construct_delete}; use construct::{Construct, construct_spawn, construct_delete};
use game::{Game, game_state, game_skill, game_ready}; use game::{Game, game_state, game_skill, game_ready};
use account::{Account, account_from_token, account_constructs, account_instances}; use account::{Account, account_constructs, account_instances};
use skill::{Skill}; use skill::{Skill};
use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join}; use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join};
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip}; use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
@ -19,7 +19,7 @@ use item::{Item, ItemInfoCtr, item_info};
type MnmlWs = ws::WebsocketContext<MnmlSocket>; type MnmlWs = ws::WebsocketContext<MnmlSocket>;
pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant) -> Result<RpcResult, Error> { pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant, account: Option<&Account>) -> Result<RpcResult, Error> {
// cast the msg to this type to receive method name // cast the msg to this type to receive method name
match from_slice::<RpcMessage>(&data) { match from_slice::<RpcMessage>(&data) {
Ok(v) => { Ok(v) => {
@ -29,11 +29,6 @@ pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant) ->
let mut tx = db.transaction()?; let mut tx = db.transaction()?;
let account: Option<Account> = match v.token {
Some(t) => Some(account_from_token(t, &mut tx)?),
None => None,
};
let account_name = match &account { let account_name = match &account {
Some(a) => a.name.clone(), Some(a) => a.name.clone(),
None => "none".to_string(), None => "none".to_string(),
@ -51,37 +46,36 @@ pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant) ->
}, },
}; };
let account = account.unwrap();
// now we have the method name // now we have the method name
// match on that to determine what fn to call // match on that to determine what fn to call
let response = match v.method.as_ref() { let response = match v.method.as_ref() {
// NO AUTH
// "account_create" => handle_account_create(data, &mut tx),
// "account_login" => handle_account_login(data, &mut tx),
"item_info" => Ok(RpcResult::ItemInfo(item_info())), "item_info" => Ok(RpcResult::ItemInfo(item_info())),
"account_state" => Ok(RpcResult::AccountState(account.clone())),
// AUTH METHODS "account_constructs" => handle_account_constructs(data, &mut tx, account),
"account_constructs" => handle_account_constructs(data, &mut tx, account.unwrap()), "account_instances" => handle_account_instances(data, &mut tx, account),
"account_instances" => handle_account_instances(data, &mut tx, account.unwrap()),
"construct_spawn" => handle_construct_spawn(data, &mut tx, account.unwrap()), "construct_spawn" => handle_construct_spawn(data, &mut tx, account),
"construct_delete" => handle_construct_delete(data, &mut tx, account.unwrap()), "construct_delete" => handle_construct_delete(data, &mut tx, account),
"game_state" => handle_game_state(data, &mut tx, account.unwrap()), "game_state" => handle_game_state(data, &mut tx, account),
"game_skill" => handle_game_skill(data, &mut tx, account.unwrap()), "game_skill" => handle_game_skill(data, &mut tx, account),
"game_ready" => handle_game_ready(data, &mut tx, account.unwrap()), "game_ready" => handle_game_ready(data, &mut tx, account),
"instance_list" => handle_instance_list(data, &mut tx, account.unwrap()), "instance_list" => handle_instance_list(data, &mut tx, account),
"instance_join" => handle_instance_join(data, &mut tx, account.unwrap()), "instance_join" => handle_instance_join(data, &mut tx, account),
"instance_ready" => handle_instance_ready(data, &mut tx, account.unwrap()), "instance_ready" => handle_instance_ready(data, &mut tx, account),
"instance_new" => handle_instance_new(data, &mut tx, account.unwrap()), "instance_new" => handle_instance_new(data, &mut tx, account),
"instance_state" => handle_instance_state(data, &mut tx, account.unwrap()), "instance_state" => handle_instance_state(data, &mut tx, account),
"vbox_accept" => handle_vbox_accept(data, &mut tx, account.unwrap()), "vbox_accept" => handle_vbox_accept(data, &mut tx, account),
"vbox_apply" => handle_vbox_apply(data, &mut tx, account.unwrap()), "vbox_apply" => handle_vbox_apply(data, &mut tx, account),
"vbox_combine" => handle_vbox_combine(data, &mut tx, account.unwrap()), "vbox_combine" => handle_vbox_combine(data, &mut tx, account),
"vbox_discard" => handle_vbox_discard(data, &mut tx, account.unwrap()), "vbox_discard" => handle_vbox_discard(data, &mut tx, account),
"vbox_reclaim" => handle_vbox_reclaim(data, &mut tx, account.unwrap()), "vbox_reclaim" => handle_vbox_reclaim(data, &mut tx, account),
"vbox_unequip" => handle_vbox_unequip(data, &mut tx, account.unwrap()), "vbox_unequip" => handle_vbox_unequip(data, &mut tx, account),
_ => Err(format_err!("unknown method - {:?}", v.method)), _ => Err(format_err!("unknown method - {:?}", v.method)),
}; };
@ -99,12 +93,12 @@ pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant) ->
} }
} }
fn handle_game_state(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_game_state(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<GameStateMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<GameStateMsg>(&data).or(Err(err_msg("invalid params")))?;
return Ok(RpcResult::GameState(game_state(msg.params, tx, &account)?)); return Ok(RpcResult::GameState(game_state(msg.params, tx, &account)?));
} }
// fn handle_game_pve(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { // fn handle_game_pve(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
// let game_response = RpcResponse { // let game_response = RpcResponse {
@ -115,24 +109,24 @@ fn handle_game_state(data: Vec<u8>, tx: &mut Transaction, account: Account) -> R
// return Ok(game_response); // return Ok(game_response);
// } // }
fn handle_game_skill(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_game_skill(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
Ok(RpcResult::GameState(game_skill(msg.params, tx, &account)?)) Ok(RpcResult::GameState(game_skill(msg.params, tx, &account)?))
} }
fn handle_game_ready(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_game_ready(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<GameStateMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<GameStateMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::GameState(game_ready(msg.params, tx, &account)?)) Ok(RpcResult::GameState(game_ready(msg.params, tx, &account)?))
} }
fn handle_construct_spawn(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_construct_spawn(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<ConstructSpawnMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<ConstructSpawnMsg>(&data).or(Err(err_msg("invalid params")))?;
construct_spawn(msg.params, tx, &account)?; construct_spawn(msg.params, tx, &account)?;
Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?)) Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?))
} }
fn handle_construct_delete(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_construct_delete(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<ConstructDeleteMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<ConstructDeleteMsg>(&data).or(Err(err_msg("invalid params")))?;
construct_delete(tx, msg.params.id, account.id)?; construct_delete(tx, msg.params.id, account.id)?;
Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?)) Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?))
@ -150,35 +144,35 @@ fn handle_construct_delete(data: Vec<u8>, tx: &mut Transaction, account: Account
// Ok(RpcResult::Account(account_login(msg.params, tx)?)) // Ok(RpcResult::Account(account_login(msg.params, tx)?))
// } // }
fn handle_account_constructs(_data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_account_constructs(_data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?)) Ok(RpcResult::AccountConstructs(account_constructs(tx, &account)?))
} }
fn handle_account_instances(_data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_account_instances(_data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
Ok(RpcResult::AccountInstances(account_instances(tx, &account)?)) Ok(RpcResult::AccountInstances(account_instances(tx, &account)?))
} }
fn handle_instance_new(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_instance_new(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<InstanceLobbyMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<InstanceLobbyMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::InstanceState(instance_new(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(instance_new(msg.params, tx, &account)?))
} }
fn handle_instance_ready(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_instance_ready(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<InstanceReadyMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<InstanceReadyMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::InstanceState(instance_ready(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(instance_ready(msg.params, tx, &account)?))
} }
fn handle_instance_join(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_instance_join(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<InstanceJoinMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<InstanceJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::InstanceState(instance_join(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(instance_join(msg.params, tx, &account)?))
} }
fn handle_instance_list(_data: Vec<u8>, tx: &mut Transaction, _account: Account) -> Result<RpcResult, Error> { fn handle_instance_list(_data: Vec<u8>, tx: &mut Transaction, _account: &Account) -> Result<RpcResult, Error> {
Ok(RpcResult::OpenInstances(instance_list(tx)?)) Ok(RpcResult::OpenInstances(instance_list(tx)?))
} }
fn handle_instance_state(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_instance_state(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<InstanceStateMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<InstanceStateMsg>(&data).or(Err(err_msg("invalid params")))?;
match instance_state(msg.params, tx, &account)? { match instance_state(msg.params, tx, &account)? {
RpcResult::GameState(p) => Ok(RpcResult::GameState(p)), RpcResult::GameState(p) => Ok(RpcResult::GameState(p)),
@ -187,33 +181,33 @@ fn handle_instance_state(data: Vec<u8>, tx: &mut Transaction, account: Account)
} }
} }
fn handle_vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
Ok(RpcResult::InstanceState(vbox_accept(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_accept(msg.params, tx, &account)?))
} }
fn handle_vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
Ok(RpcResult::InstanceState(vbox_discard(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_discard(msg.params, tx, &account)?))
} }
fn handle_vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
Ok(RpcResult::InstanceState(vbox_combine(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_combine(msg.params, tx, &account)?))
} }
fn handle_vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, 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")))?;
Ok(RpcResult::InstanceState(vbox_apply(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_apply(msg.params, tx, &account)?))
} }
fn handle_vbox_reclaim(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_reclaim(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<VboxReclaimMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxReclaimMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::InstanceState(vbox_reclaim(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_reclaim(msg.params, tx, &account)?))
} }
fn handle_vbox_unequip(data: Vec<u8>, tx: &mut Transaction, account: Account) -> Result<RpcResult, Error> { fn handle_vbox_unequip(data: Vec<u8>, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let msg = from_slice::<VboxUnequipMsg>(&data).or(Err(err_msg("invalid params")))?; let msg = from_slice::<VboxUnequipMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::InstanceState(vbox_unequip(msg.params, tx, &account)?)) Ok(RpcResult::InstanceState(vbox_unequip(msg.params, tx, &account)?))
} }
@ -225,7 +219,7 @@ pub struct RpcErrorResponse {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub enum RpcResult { pub enum RpcResult {
Account(Account), AccountState(Account),
AccountConstructs(Vec<Construct>), AccountConstructs(Vec<Construct>),
AccountInstances(Vec<Instance>), AccountInstances(Vec<Instance>),
GameState(Game), GameState(Game),