mnml/server/src/rpc.rs
2018-09-23 23:16:21 +10:00

177 lines
5.5 KiB
Rust
Executable File

use ws::{Message, Sender};
use serde_cbor::{from_slice, to_vec};
use uuid::Uuid;
use failure::Error;
use failure::err_msg;
use net::Db;
use cryp::{Cryp, spawn};
use battle::{Battle};
use combat::{pve};
use account::{Account, create, login, from_token};
pub struct Rpc;
impl Rpc {
pub fn receive(&self, msg: Message, db: Db, out: &Sender) -> Result<RpcResponse, Error> {
// consume the ws data into bytes
let data = msg.into_data();
// cast the msg to this type to receive method name
match from_slice::<RpcMessage>(&data) {
Ok(v) => {
let account: Option<Account> = match v.token {
Some(t) => Some(from_token(t, &db)?),
None => None,
};
println!("{:?}", account);
// now we have the method name
// match on that to determine what fn to call
match v.method.as_ref() {
"cryp_spawn" => {
match from_slice::<CrypSpawnMsg>(&data) {
Ok(v) => {
match account {
Some(u) => Ok(RpcResponse {
method: v.method,
params: RpcResult::SpawnCryp(spawn(v.params, db, u)?)
}),
None => Err(err_msg("auth required")),
}
}
Err(_e) => Err(err_msg("invalid params")),
}
},
"combat_pve" => {
let send = |b: &Battle| -> Result<(), Error> {
let reply = RpcResponse {
method: "combat_pve".to_string(),
params: RpcResult::Pve(b.clone())
};
let response = to_vec(&reply)?;
match out.send(response) {
Ok(()) => Ok(()),
Err(e) => Err(err_msg(e))
}
};
match from_slice::<CombatPveMsg>(&data) {
Ok(v) => {
match account {
Some(u) => Ok(RpcResponse {
method: v.method,
params: RpcResult::Pve(pve(v.params, db, u, send)?)
}),
None => Err(err_msg("auth required")),
}
}
Err(_e) => Err(err_msg("invalid params")),
}
},
"account_create" => {
match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => Ok(RpcResponse {
method: v.method,
params: create(v.params, db)?
}),
Err(_e) => Err(err_msg("invalid params")),
}
},
"account_login" => {
match from_slice::<AccountLoginMsg>(&data) {
Ok(v) => Ok(RpcResponse {
method: v.method,
params: login(v.params, db)?
}),
Err(_e) => Err(err_msg("invalid params")),
}
},
_ => Err(err_msg("unknown method")),
}
},
Err(_e) => Err(err_msg("invalid message")),
}
}
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct RpcResponse {
method: String,
params: RpcResult,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub enum RpcResult {
SpawnCryp(Cryp),
Account(Account),
Pve(Battle),
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct RpcMessage {
method: String,
token: Option<String>,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct CrypSpawnMsg {
method: String,
params: CrypSpawnParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct CrypSpawnParams {
pub name: String,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct CombatPveMsg {
method: String,
params: CombatPveParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct CombatPveParams {
pub id: Uuid,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct AccountCreateMsg {
method: String,
params: AccountCreateParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct AccountCreateParams {
pub name: String,
pub password: String,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct AccountLoginMsg {
method: String,
params: AccountLoginParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct AccountLoginParams {
pub name: String,
pub password: String,
}
// #[cfg(test)]
// mod tests {
// use super::*;
// use serde_cbor::to_vec;
// #[test]
// fn rpc_parse() {
// let rpc = Rpc {};
// let msg = GenerateMsg { method: "cryp_generate".to_string(), params: GenerateParams { level: 64 } };
// let v = to_vec(&msg).unwrap();
// let received = rpc.receive(Message::Binary(v));
// }
// }