wip
This commit is contained in:
parent
1cc29f73d1
commit
445e8084e0
@ -144,8 +144,8 @@ impl Instance {
|
||||
.collect::<Vec<Uuid>>()
|
||||
}
|
||||
|
||||
// time out lobbies that have been open too long
|
||||
pub fn upkeep(mut self) -> (Instance, Option<Game>) {
|
||||
// time out lobbies that have been open too long
|
||||
if self.phase == InstancePhase::Lobby && self.phase_timed_out() {
|
||||
self.finish();
|
||||
return (self, None);
|
||||
|
||||
@ -31,6 +31,11 @@ pub fn bot_player() -> Player {
|
||||
Player::new(bot_id, None, &name(), constructs).set_bot(true)
|
||||
}
|
||||
|
||||
pub fn anon_player(id: Uuid) -> Player {
|
||||
let constructs = instance_mobs(id);
|
||||
Player::new(id, None, &"player".to_string(), constructs)
|
||||
}
|
||||
|
||||
pub fn anim_test_game(skill: Skill) -> Game {
|
||||
let mut rng = thread_rng();
|
||||
let mut game = Game::new();
|
||||
|
||||
@ -44,6 +44,16 @@ impl Account {
|
||||
|
||||
Ok(Player::new(self.id, Some(self.img), &self.name, constructs))
|
||||
}
|
||||
|
||||
pub fn anonymous() -> Account {
|
||||
Account {
|
||||
id: Uuid::new_v4(),
|
||||
img: Uuid::new_v4(),
|
||||
name: "you".to_string(),
|
||||
balance: 0,
|
||||
subscribed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<postgres::rows::Row<'a>> for Account {
|
||||
|
||||
@ -18,7 +18,7 @@ use warden::{GameEvent};
|
||||
use mail::Mail;
|
||||
|
||||
pub type EventsTx = Sender<Event>;
|
||||
type Id = usize;
|
||||
type Id = Uuid;
|
||||
|
||||
// this is pretty heavyweight
|
||||
// but it makes the ergonomics easy
|
||||
@ -43,7 +43,7 @@ pub struct Events {
|
||||
#[derive(Debug,Clone)]
|
||||
pub enum Event {
|
||||
// ws lifecycle
|
||||
Connect(Id, Option<Account>, Sender<RpcMessage>),
|
||||
Connect(Id, Account, Sender<RpcMessage>),
|
||||
Disconnect(Id),
|
||||
Subscribe(Id, Uuid),
|
||||
Unsubscribe(Id, Uuid),
|
||||
@ -64,7 +64,6 @@ pub enum Event {
|
||||
|
||||
struct WsClient {
|
||||
id: Id,
|
||||
account: Option<Uuid>,
|
||||
tx: Sender<RpcMessage>,
|
||||
subs: HashSet<Uuid>,
|
||||
chat: Option<(Uuid, String)>,
|
||||
@ -118,14 +117,8 @@ impl Events {
|
||||
Event::Connect(id, account, tx) => {
|
||||
info!("connect id={:?} account={:?}", id, account);
|
||||
|
||||
let account_id = match account {
|
||||
Some(a) => Some(a.id),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let client = WsClient { id,
|
||||
tx,
|
||||
account: account_id,
|
||||
subs: HashSet::new(),
|
||||
pvp: false,
|
||||
invite: None,
|
||||
@ -183,13 +176,10 @@ impl Events {
|
||||
if client.subs.contains(&id) {
|
||||
subs += 1;
|
||||
|
||||
let redacted = match client.account {
|
||||
Some(a) => match msg {
|
||||
RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(a)),
|
||||
RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(a)),
|
||||
_ => msg.clone(),
|
||||
}
|
||||
None => msg.clone(),
|
||||
let redacted = match msg {
|
||||
RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.id)),
|
||||
RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.id)),
|
||||
_ => msg.clone(),
|
||||
};
|
||||
|
||||
match client.tx.send(redacted) {
|
||||
@ -218,18 +208,14 @@ impl Events {
|
||||
let c = self.clients.get(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
info!("pvp queue request id={:?} account={:?}", c.id, c.account);
|
||||
info!("pvp queue request id={:?} account={:?}", c.id, c.id);
|
||||
}
|
||||
|
||||
// create the req for the already queued opponent
|
||||
if let Some(opp_req) = match self.clients.iter_mut().find(|(c_id, c)| c.pvp && **c_id != id) {
|
||||
Some((q_id, q)) => {
|
||||
q.pvp = false;
|
||||
Some(PvpRequest { id: *q_id, account: q.account.unwrap(), tx: q.tx.clone() })
|
||||
Some(PvpRequest { id: *q_id, account: q.id, tx: q.tx.clone() })
|
||||
},
|
||||
None => None,
|
||||
} {
|
||||
@ -237,7 +223,7 @@ impl Events {
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
let player_req = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };
|
||||
let player_req = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() };
|
||||
self.warden.send(GameEvent::Match((opp_req, player_req)))?;
|
||||
|
||||
return Ok(())
|
||||
@ -247,7 +233,7 @@ impl Events {
|
||||
let requester = self.clients.get_mut(&id).unwrap();
|
||||
requester.pvp = true;
|
||||
requester.tx.send(RpcMessage::QueueJoined(()))?;
|
||||
info!("joined game queue id={:?} account={:?}", requester.id, requester.account);
|
||||
info!("joined game queue id={:?} account={:?}", requester.id, requester.id);
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
@ -256,12 +242,8 @@ impl Events {
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
let code = names::name().split_whitespace().collect::<Vec<&str>>().join("-");
|
||||
info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.account, code);
|
||||
info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.id, code);
|
||||
c.invite = Some(code.clone());
|
||||
c.tx.send(RpcMessage::Invite(code))?;
|
||||
return Ok(());
|
||||
@ -272,11 +254,7 @@ impl Events {
|
||||
let c = self.clients.get(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
info!("pvp join request id={:?} account={:?} code={:?}", c.id, c.account, code);
|
||||
info!("pvp join request id={:?} account={:?} code={:?}", c.id, c.id, code);
|
||||
|
||||
let inv = self.clients.iter()
|
||||
.filter(|(_id, c)| c.invite.is_some())
|
||||
@ -284,10 +262,10 @@ impl Events {
|
||||
Some(ref c) => *c == code,
|
||||
None => false,
|
||||
})
|
||||
.map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() })
|
||||
.map(|(_id, c)| PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() })
|
||||
.ok_or(format_err!("invite expired code={:?}", code))?;
|
||||
|
||||
let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };
|
||||
let join = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() };
|
||||
|
||||
self.warden.send(GameEvent::Match((join, inv)))?;
|
||||
return Ok(());
|
||||
@ -310,7 +288,7 @@ impl Events {
|
||||
|
||||
c.pvp = false;
|
||||
c.tx.send(RpcMessage::QueueLeft(()))?;
|
||||
info!("left game queue id={:?} account={:?}", c.id, c.account);
|
||||
info!("left game queue id={:?} account={:?}", c.id, c.id);
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
@ -337,12 +315,11 @@ impl Events {
|
||||
// now collect all listeners of this instance
|
||||
|
||||
let chat_state: HashMap<Uuid, String> = self.clients.iter()
|
||||
.filter(|(_id, c)| c.account.is_some())
|
||||
.filter(|(_id, c)| match c.chat {
|
||||
Some(ref chat) => chat.0 == instance,
|
||||
None => false,
|
||||
})
|
||||
.map(|(_id, c)| (c.account.unwrap(), c.chat.clone().unwrap().1))
|
||||
.map(|(_id, c)| (c.id, c.chat.clone().unwrap().1))
|
||||
.collect();
|
||||
|
||||
return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state)));
|
||||
@ -357,12 +334,11 @@ impl Events {
|
||||
}
|
||||
|
||||
let chat_state: HashMap<Uuid, String> = self.clients.iter()
|
||||
.filter(|(_id, c)| c.account.is_some())
|
||||
.filter(|(_id, c)| match c.chat {
|
||||
Some(ref chat) => chat.0 == instance,
|
||||
None => false,
|
||||
})
|
||||
.map(|(_id, c)| (c.account.unwrap(), c.chat.clone().unwrap().1))
|
||||
.map(|(_id, c)| (c.id, c.chat.clone().unwrap().1))
|
||||
.collect();
|
||||
|
||||
return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state)));
|
||||
|
||||
@ -48,6 +48,8 @@ mod pg;
|
||||
mod events;
|
||||
pub mod rpc;
|
||||
mod warden;
|
||||
mod user_authenticated;
|
||||
mod user_anonymous;
|
||||
|
||||
use std::thread::{spawn};
|
||||
use std::path::{Path};
|
||||
|
||||
@ -22,7 +22,7 @@ use mnml_core::mob::instance_mobs;
|
||||
use mnml_core::vbox::{ItemType, VboxIndices};
|
||||
use mnml_core::item::Item;
|
||||
use mnml_core::skill::Skill;
|
||||
use mnml_core::mob::bot_player;
|
||||
use mnml_core::mob::{bot_player, anon_player};
|
||||
use mnml_core::instance::{Instance, TimeControl};
|
||||
|
||||
use events::{Event};
|
||||
@ -694,6 +694,35 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result<Inst
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
pub fn instance_demo(account: &Account) -> Result<Instance, Error> {
|
||||
let bot = bot_player();
|
||||
let bot_id = bot.id;
|
||||
|
||||
// generate imgs for the client to see
|
||||
for c in bot.constructs.iter() {
|
||||
img::shapes_write(c.img)?;
|
||||
}
|
||||
|
||||
let mut instance = Instance::new()
|
||||
.set_time_control(TimeControl::Practice)
|
||||
.set_name(bot.name.clone())?;
|
||||
|
||||
let player = anon_player(account.id);
|
||||
|
||||
for c in player.constructs.iter() {
|
||||
img::shapes_write(c.img)?;
|
||||
}
|
||||
|
||||
instance.add_player(player.clone())?;
|
||||
instance.add_player(bot)?;
|
||||
|
||||
instance.player_ready(bot_id)?;
|
||||
// skip faceoff
|
||||
instance.player_ready(player.id)?;
|
||||
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, Error> {
|
||||
let mut instance = Instance::new()
|
||||
// TODO generate nice game names
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use mnml_core::item::ItemInfoCtr;
|
||||
use mnml_core::instance::ChatState;
|
||||
use mnml_core::item::item_info;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Instant};
|
||||
use std::thread::{spawn};
|
||||
@ -8,12 +8,8 @@ use std::thread::{spawn};
|
||||
use std::str;
|
||||
|
||||
use uuid::Uuid;
|
||||
use rand::prelude::*;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use serde_cbor::{from_slice, to_vec};
|
||||
use serde_cbor::{to_vec};
|
||||
use cookie::Cookie;
|
||||
|
||||
use stripe::{Client as StripeClient, Subscription};
|
||||
@ -22,42 +18,24 @@ use crossbeam_channel::{unbounded, Sender as CbSender};
|
||||
use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender};
|
||||
use ws::deflate::DeflateHandler;
|
||||
|
||||
use pg::{
|
||||
game_concede,
|
||||
game_offer_draw,
|
||||
game_ready,
|
||||
game_skill,
|
||||
game_skill_clear,
|
||||
game_state,
|
||||
instance_abandon,
|
||||
instance_practice,
|
||||
instance_ready,
|
||||
instance_state,
|
||||
vbox_apply,
|
||||
vbox_buy,
|
||||
vbox_combine,
|
||||
vbox_refill,
|
||||
vbox_refund,
|
||||
vbox_unequip,
|
||||
};
|
||||
|
||||
use account::{Account};
|
||||
use account;
|
||||
use events::{Event};
|
||||
|
||||
use user_anonymous::{Anonymous};
|
||||
use user_authenticated::{Authorised};
|
||||
|
||||
use mnml_core::construct::{Construct};
|
||||
use mnml_core::game::{Game};
|
||||
|
||||
use mnml_core::vbox::{ItemType};
|
||||
use mnml_core::item::Item;
|
||||
use mnml_core::skill::Skill;
|
||||
use mnml_core::mob::{anim_test_game};
|
||||
|
||||
use mnml_core::instance::{Instance};
|
||||
|
||||
use mtx;
|
||||
use mail;
|
||||
|
||||
use payments;
|
||||
use mail::Email;
|
||||
use pg::{Db};
|
||||
use pg::{PgPool};
|
||||
@ -145,194 +123,32 @@ pub enum RpcRequest {
|
||||
VboxRefund { instance_id: Uuid, index: String },
|
||||
}
|
||||
|
||||
pub trait User {
|
||||
fn receive(&mut self, data: Vec<u8>, db: &Db, begin: Instant, events: &CbSender<Event>, stripe: &StripeClient) -> Result<RpcMessage, Error>;
|
||||
fn connected(&mut self, db: &Db, events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error>;
|
||||
fn send(&mut self, msg: RpcMessage, events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
struct Connection {
|
||||
pub id: usize,
|
||||
pub id: Uuid,
|
||||
pub ws: CbSender<RpcMessage>,
|
||||
pool: PgPool,
|
||||
stripe: StripeClient,
|
||||
account: Option<Account>,
|
||||
// account: Option<Account>,
|
||||
user: Box<dyn User>,
|
||||
events: CbSender<Event>,
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
fn receive(&self, data: Vec<u8>, db: &Db, begin: Instant) -> Result<RpcMessage, Error> {
|
||||
// cast the msg to this type to receive method name
|
||||
match from_slice::<RpcRequest>(&data) {
|
||||
Ok(v) => {
|
||||
|
||||
// non authenticated
|
||||
// non transactional reqs
|
||||
match v {
|
||||
RpcRequest::Ping {} => return Ok(RpcMessage::Pong(())),
|
||||
RpcRequest::ItemInfo {} => return Ok(RpcMessage::ItemInfo(item_info())),
|
||||
RpcRequest::DevResolve { skill } =>
|
||||
return Ok(RpcMessage::GameState(anim_test_game(skill))),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
// check for authorization now
|
||||
let account = match self.account {
|
||||
Some(ref account) => account,
|
||||
None => return Err(err_msg("auth required")),
|
||||
};
|
||||
|
||||
let request = v.clone();
|
||||
|
||||
let response = match v {
|
||||
// evented but authorization required
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
self.events.send(Event::Queue(self.id))?;
|
||||
Ok(RpcMessage::QueueRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceInvite {} => {
|
||||
self.events.send(Event::Invite(self.id))?;
|
||||
Ok(RpcMessage::InviteRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceJoin { code } => {
|
||||
self.events.send(Event::Join(self.id, code))?;
|
||||
Ok(RpcMessage::Joining(()))
|
||||
},
|
||||
RpcRequest::InstanceLeave {} => {
|
||||
self.events.send(Event::Leave(self.id))?;
|
||||
Ok(RpcMessage::Processing(()))
|
||||
},
|
||||
|
||||
RpcRequest::InstanceChat { instance_id, index } => {
|
||||
if !account.subscribed {
|
||||
return Err(err_msg("subscribe to unlock chat"))
|
||||
}
|
||||
|
||||
let wheel = account::chat_wheel(&db, account.id)?;
|
||||
|
||||
if let Some(c) = wheel.get(index) {
|
||||
self.events.send(Event::Chat(self.id, instance_id, c.to_string()))?;
|
||||
} else {
|
||||
return Err(err_msg("invalid chat index"));
|
||||
}
|
||||
|
||||
Ok(RpcMessage::Processing(()))
|
||||
},
|
||||
_ => {
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
let res = match v {
|
||||
RpcRequest::AccountState {} =>
|
||||
Ok(RpcMessage::AccountState(account.clone())),
|
||||
RpcRequest::AccountConstructs {} =>
|
||||
Ok(RpcMessage::AccountConstructs(account::constructs(&mut tx, &account)?)),
|
||||
RpcRequest::AccountInstances {} =>
|
||||
Ok(RpcMessage::AccountInstances(account::account_instances(&mut tx, account)?)),
|
||||
RpcRequest::AccountSetTeam { ids } =>
|
||||
Ok(RpcMessage::AccountTeam(account::set_team(&mut tx, &account, ids)?)),
|
||||
|
||||
RpcRequest::EmailState {} =>
|
||||
Ok(RpcMessage::EmailState(mail::select_account(&db, account.id)?)),
|
||||
|
||||
RpcRequest::SubscriptionState {} =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::account_subscription(&db, &self.stripe, &account)?)),
|
||||
|
||||
// RpcRequest::AccountShop {} =>
|
||||
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
|
||||
|
||||
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
|
||||
|
||||
RpcRequest::GameState { id } =>
|
||||
Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)),
|
||||
|
||||
RpcRequest::GameSkill { 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::GameSkillClear { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_id)?)),
|
||||
|
||||
RpcRequest::GameReady { id } =>
|
||||
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
|
||||
|
||||
RpcRequest::GameConcede { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_concede(&mut tx, account, game_id)?)),
|
||||
|
||||
RpcRequest::GameOfferDraw { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_offer_draw(&mut tx, account, game_id)?)),
|
||||
|
||||
RpcRequest::InstancePractice {} =>
|
||||
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, account)?)),
|
||||
|
||||
// these two can return GameState or InstanceState
|
||||
RpcRequest::InstanceReady { instance_id } =>
|
||||
Ok(instance_ready(&mut tx, account, instance_id)?),
|
||||
RpcRequest::InstanceState { instance_id } =>
|
||||
Ok(instance_state(&mut tx, instance_id)?),
|
||||
RpcRequest::InstanceAbandon { instance_id } =>
|
||||
Ok(instance_abandon(&mut tx, account, instance_id)?),
|
||||
|
||||
RpcRequest::VboxBuy { instance_id, group, index, construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, construct_id)?)),
|
||||
|
||||
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
|
||||
|
||||
RpcRequest::VboxCombine { instance_id, inv_indices, vbox_indices } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, inv_indices, vbox_indices)?)),
|
||||
|
||||
RpcRequest::VboxRefill { instance_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_refill(&mut tx, account, instance_id)?)),
|
||||
|
||||
RpcRequest::VboxRefund { instance_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_refund(&mut tx, account, instance_id, index)?)),
|
||||
|
||||
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, None)?)),
|
||||
|
||||
RpcRequest::VboxUnequipApply { instance_id, construct_id, target, target_construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, Some(target_construct_id))?)),
|
||||
|
||||
RpcRequest::MtxConstructSpawn {} =>
|
||||
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
|
||||
|
||||
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
|
||||
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
|
||||
|
||||
RpcRequest::MtxAccountApply { mtx } =>
|
||||
Ok(RpcMessage::AccountState(mtx::account_apply(&mut tx, account, mtx)?)),
|
||||
|
||||
RpcRequest::MtxBuy { mtx } =>
|
||||
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
|
||||
|
||||
RpcRequest::SubscriptionEnding { ending } =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::subscription_ending(&mut tx, &self.stripe, account, ending)?)),
|
||||
|
||||
_ => Err(format_err!("unknown request request={:?}", request)),
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
res
|
||||
}
|
||||
};
|
||||
|
||||
info!("request={:?} account={:?} duration={:?}", request, account.name, begin.elapsed());
|
||||
|
||||
return response;
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
Err(err_msg("invalid message"))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// this is where last minute processing happens
|
||||
// use it to modify outgoing messages, update subs, serialize in some way...
|
||||
fn send(&self, msg: RpcMessage) -> Result<(), Error> {
|
||||
let msg = match self.account {
|
||||
Some(ref a) => match msg {
|
||||
RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(a.id)),
|
||||
RpcMessage::AccountInstances(v) =>
|
||||
RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(a.id)).collect()),
|
||||
RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(a.id)),
|
||||
_ => msg,
|
||||
},
|
||||
None => msg,
|
||||
let msg = match msg {
|
||||
RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(self.id)),
|
||||
RpcMessage::AccountInstances(v) =>
|
||||
RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.id)).collect()),
|
||||
RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.id)),
|
||||
_ => msg,
|
||||
};
|
||||
|
||||
self.ws.send(msg).unwrap();
|
||||
@ -347,48 +163,8 @@ impl Connection {
|
||||
// when it encounters errors
|
||||
impl Handler for Connection {
|
||||
fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
|
||||
info!("websocket connected account={:?}", self.account);
|
||||
|
||||
// tell events we have connected
|
||||
self.events.send(Event::Connect(self.id, self.account.clone(), self.ws.clone())).unwrap();
|
||||
|
||||
// if user logged in do some prep work
|
||||
if let Some(ref a) = self.account {
|
||||
self.send(RpcMessage::AccountState(a.clone())).unwrap();
|
||||
self.events.send(Event::Subscribe(self.id, a.id)).unwrap();
|
||||
|
||||
// check if they have an image that needs to be generated
|
||||
account::img_check(&a).unwrap();
|
||||
|
||||
let db = self.pool.get().unwrap();
|
||||
let mut tx = db.transaction().unwrap();
|
||||
|
||||
// send account constructs
|
||||
let account_constructs = account::constructs(&mut tx, a).unwrap();
|
||||
self.send(RpcMessage::AccountConstructs(account_constructs)).unwrap();
|
||||
|
||||
// get account instances
|
||||
// and send them to the client
|
||||
let account_instances = account::account_instances(&mut tx, a).unwrap();
|
||||
self.send(RpcMessage::AccountInstances(account_instances)).unwrap();
|
||||
|
||||
let shop = mtx::account_shop(&mut tx, &a).unwrap();
|
||||
self.send(RpcMessage::AccountShop(shop)).unwrap();
|
||||
|
||||
let team = account::team(&mut tx, &a).unwrap();
|
||||
self.send(RpcMessage::AccountTeam(team)).unwrap();
|
||||
|
||||
let wheel = account::chat_wheel(&db, a.id).unwrap();
|
||||
self.send(RpcMessage::ChatWheel(wheel)).unwrap();
|
||||
|
||||
if let Some(instance) = account::tutorial(&mut tx, &a).unwrap() {
|
||||
self.send(RpcMessage::InstanceState(instance)).unwrap();
|
||||
}
|
||||
|
||||
// tx should do nothing
|
||||
tx.commit().unwrap();
|
||||
}
|
||||
|
||||
let db = self.pool.get().unwrap();
|
||||
self.user.connected(&db, &self.events, &self.ws).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -398,23 +174,9 @@ impl Handler for Connection {
|
||||
let begin = Instant::now();
|
||||
let db_connection = self.pool.get().unwrap();
|
||||
|
||||
match self.receive(msg, &db_connection, begin) {
|
||||
Ok(reply) => {
|
||||
// if the user queries the state of something
|
||||
// we tell events to push updates to them
|
||||
match reply {
|
||||
RpcMessage::AccountState(ref v) => {
|
||||
self.account = Some(v.clone());
|
||||
self.events.send(Event::Subscribe(self.id, v.id)).unwrap()
|
||||
},
|
||||
RpcMessage::GameState(ref v) =>
|
||||
self.events.send(Event::Subscribe(self.id, v.id)).unwrap(),
|
||||
RpcMessage::InstanceState(ref v) =>
|
||||
self.events.send(Event::Subscribe(self.id, v.id)).unwrap(),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
self.send(reply).unwrap();
|
||||
match self.user.receive(msg, &db_connection, begin, &self.events, &self.stripe) {
|
||||
Ok(msg) => {
|
||||
self.user.send(msg, &self.events, &self.ws).unwrap();
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
@ -428,7 +190,7 @@ impl Handler for Connection {
|
||||
}
|
||||
|
||||
fn on_close(&mut self, _: CloseCode, _: &str) {
|
||||
info!("websocket disconnected account={:?}", self.account);
|
||||
info!("websocket disconnected id={:?}", self.id);
|
||||
self.events.send(Event::Disconnect(self.id)).unwrap();
|
||||
}
|
||||
|
||||
@ -456,21 +218,19 @@ impl Handler for Connection {
|
||||
if cookie.name() == TOKEN_HEADER {
|
||||
let db = self.pool.get().unwrap();
|
||||
match account::from_token(&db, &cookie.value().to_string()) {
|
||||
Ok(a) => self.account = Some(a),
|
||||
Ok(a) => self.user = Box::new(Authorised { id: a.id, account: a }),
|
||||
Err(_) => return unauth(),
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let ws = Builder::new()
|
||||
let _ws = Builder::new()
|
||||
.with_settings(Settings {
|
||||
max_connections: 10_000,
|
||||
..Settings::default()
|
||||
@ -500,14 +260,17 @@ pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
||||
}
|
||||
});
|
||||
|
||||
let anon_account = Account::anonymous();
|
||||
let id = anon_account.id;
|
||||
|
||||
DeflateHandler::new(
|
||||
Connection {
|
||||
id: rng.gen::<usize>(),
|
||||
account: None,
|
||||
id,
|
||||
ws: tx,
|
||||
pool: pool.clone(),
|
||||
stripe: stripe.clone(),
|
||||
events: events_tx.clone(),
|
||||
user: Box::new(Anonymous { id, account: anon_account, game: None, instance: None })
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
148
server/src/user_anonymous.rs
Normal file
148
server/src/user_anonymous.rs
Normal file
@ -0,0 +1,148 @@
|
||||
use std::time::Instant;
|
||||
use uuid::Uuid;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use crossbeam_channel::{Sender as CbSender};
|
||||
|
||||
use serde_cbor::{from_slice};
|
||||
|
||||
use stripe::{Client as StripeClient};
|
||||
|
||||
use account::{Account};
|
||||
use pg::{Db};
|
||||
use pg;
|
||||
use events::{Event};
|
||||
use rpc::{RpcMessage, RpcRequest, User};
|
||||
|
||||
use mnml_core::game::Game;
|
||||
use mnml_core::item::item_info;
|
||||
use mnml_core::instance::Instance;
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub struct Anonymous {
|
||||
pub account: Account,
|
||||
pub id: Uuid,
|
||||
pub instance: Option<Instance>,
|
||||
pub game: Option<Game>,
|
||||
}
|
||||
|
||||
impl User for Anonymous {
|
||||
fn send(&mut self, msg: RpcMessage, _events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error> {
|
||||
// if the user queries the state of something
|
||||
// we tell events to push updates to them
|
||||
match msg {
|
||||
RpcMessage::GameState(ref v) =>
|
||||
self.game = Some(v.clone()),
|
||||
RpcMessage::InstanceState(ref v) =>
|
||||
self.instance = Some(v.clone()),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
ws.send(msg)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn connected(&mut self, _db: &Db, events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error> {
|
||||
info!("anonymous connection");
|
||||
|
||||
self.send(RpcMessage::AccountState(self.account.clone()), events, ws)?;
|
||||
self.send(RpcMessage::ItemInfo(item_info()), events, ws)?;
|
||||
self.send(RpcMessage::InstanceState(pg::instance_demo(&self.account)?), events, ws)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn receive(&mut self, data: Vec<u8>, _db: &Db, _begin: Instant, _events: &CbSender<Event>, _stripe: &StripeClient) -> Result<RpcMessage, Error> {
|
||||
match from_slice::<RpcRequest>(&data) {
|
||||
Ok(v) => {
|
||||
let mut instance = match self.instance {
|
||||
Some(ref i) => i.clone(),
|
||||
None => return Err(err_msg("instance missing")),
|
||||
};
|
||||
|
||||
let game = match self.game {
|
||||
Some(ref i) => Some(i.clone()),
|
||||
None => None
|
||||
};
|
||||
|
||||
match v {
|
||||
RpcRequest::Ping {} => return Ok(RpcMessage::Pong(())),
|
||||
|
||||
RpcRequest::InstanceReady { instance_id: _ } => {
|
||||
match instance.player_ready(self.account.id)? {
|
||||
Some(g) => Ok(RpcMessage::GameState(g)),
|
||||
None => Ok(RpcMessage::InstanceState(instance)),
|
||||
}
|
||||
},
|
||||
|
||||
RpcRequest::InstanceState { instance_id: _ } =>
|
||||
Ok(RpcMessage::InstanceState(instance)),
|
||||
|
||||
RpcRequest::InstanceAbandon { instance_id: _ } =>
|
||||
Err(err_msg("don't give up!")),
|
||||
|
||||
RpcRequest::VboxBuy { instance_id: _, group, index, construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_buy(self.account.id, group, index, construct_id)?)),
|
||||
|
||||
RpcRequest::VboxApply { instance_id: _, construct_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_apply(self.account.id, index, construct_id)?)),
|
||||
|
||||
RpcRequest::VboxCombine { instance_id: _, inv_indices, vbox_indices } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_combine(self.account.id, inv_indices, vbox_indices)?)),
|
||||
|
||||
RpcRequest::VboxRefill { instance_id: _ } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_refill(self.account.id)?)),
|
||||
|
||||
RpcRequest::VboxRefund { instance_id: _, index } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_refund(self.account.id, index)?)),
|
||||
|
||||
RpcRequest::VboxUnequip { instance_id: _, construct_id, target } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_unequip(self.account.id, target, construct_id, None)?)),
|
||||
|
||||
RpcRequest::VboxUnequipApply { instance_id: _, construct_id, target, target_construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(instance.vbox_unequip(self.account.id, target, construct_id, Some(target_construct_id))?)),
|
||||
|
||||
RpcRequest::GameState { id: _ } =>
|
||||
Ok(RpcMessage::GameState(game.unwrap())),
|
||||
|
||||
RpcRequest::GameSkill { game_id: _, construct_id, target_construct_id, skill } => {
|
||||
let mut game = game.unwrap();
|
||||
game.add_skill(self.account.id, construct_id, target_construct_id, skill)?;
|
||||
Ok(RpcMessage::GameState(game))
|
||||
},
|
||||
|
||||
RpcRequest::GameSkillClear { game_id: _ } => {
|
||||
let mut game = game.unwrap();
|
||||
game.clear_skill(self.account.id)?;
|
||||
Ok(RpcMessage::GameState(game))
|
||||
},
|
||||
|
||||
RpcRequest::GameReady { id: _ } => {
|
||||
let mut game = game.unwrap();
|
||||
game.player_ready(self.account.id)?;
|
||||
if game.skill_phase_finished() {
|
||||
game = game.resolve_phase_start();
|
||||
}
|
||||
|
||||
Ok(RpcMessage::GameState(game))
|
||||
},
|
||||
|
||||
RpcRequest::GameConcede { game_id: _ } =>
|
||||
Ok(RpcMessage::GameState(game.unwrap().concede(self.account.id)?)),
|
||||
|
||||
RpcRequest::GameOfferDraw { game_id: _ } =>
|
||||
Ok(RpcMessage::GameState(game.unwrap().offer_draw(self.account.id)?)),
|
||||
|
||||
_ => Err(format_err!("unhandled anonymous request request={:?}", v)),
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
Err(err_msg("invalid message"))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
264
server/src/user_authenticated.rs
Normal file
264
server/src/user_authenticated.rs
Normal file
@ -0,0 +1,264 @@
|
||||
use mnml_core::mob::anim_test_game;
|
||||
use mnml_core::item::item_info;
|
||||
use std::time::Instant;
|
||||
use uuid::Uuid;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use crossbeam_channel::{Sender as CbSender};
|
||||
use stripe::{Client as StripeClient};
|
||||
|
||||
use serde_cbor::{from_slice};
|
||||
|
||||
use pg::{
|
||||
game_concede,
|
||||
game_offer_draw,
|
||||
game_ready,
|
||||
game_skill,
|
||||
game_skill_clear,
|
||||
game_state,
|
||||
instance_abandon,
|
||||
instance_practice,
|
||||
instance_ready,
|
||||
instance_state,
|
||||
vbox_apply,
|
||||
vbox_buy,
|
||||
vbox_combine,
|
||||
vbox_refill,
|
||||
vbox_refund,
|
||||
vbox_unequip,
|
||||
};
|
||||
|
||||
use account::{Account};
|
||||
use account;
|
||||
use events::{Event};
|
||||
|
||||
use mtx;
|
||||
use mail;
|
||||
use payments;
|
||||
use pg::{Db};
|
||||
use rpc::{RpcMessage, RpcRequest, User};
|
||||
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub struct Authorised {
|
||||
pub account: Account,
|
||||
pub id: Uuid
|
||||
}
|
||||
|
||||
impl User for Authorised {
|
||||
fn send(&mut self, msg: RpcMessage, events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error> {
|
||||
// if the user queries the state of something
|
||||
// we tell events to push updates to them
|
||||
match msg {
|
||||
RpcMessage::AccountState(ref v) => {
|
||||
events.send(Event::Subscribe(self.id, v.id))?
|
||||
},
|
||||
RpcMessage::GameState(ref v) =>
|
||||
events.send(Event::Subscribe(self.id, v.id))?,
|
||||
RpcMessage::InstanceState(ref v) =>
|
||||
events.send(Event::Subscribe(self.id, v.id))?,
|
||||
_ => (),
|
||||
};
|
||||
|
||||
ws.send(msg)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn connected(&mut self, db: &Db, events: &CbSender<Event>, ws: &CbSender<RpcMessage>) -> Result<(), Error> {
|
||||
info!("authenticated connection account={:?}", self.account);
|
||||
let a = &self.account;
|
||||
|
||||
// tell events we have connected
|
||||
events.send(Event::Connect(self.id, a.clone(), ws.clone()))?;
|
||||
|
||||
ws.send(RpcMessage::AccountState(a.clone()))?;
|
||||
events.send(Event::Subscribe(self.id, a.id))?;
|
||||
|
||||
// check if they have an image that needs to be generated
|
||||
account::img_check(&a)?;
|
||||
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
// send account constructs
|
||||
let account_constructs = account::constructs(&mut tx, &a)?;
|
||||
ws.send(RpcMessage::AccountConstructs(account_constructs))?;
|
||||
|
||||
// get account instances
|
||||
// and send them to the client
|
||||
let account_instances = account::account_instances(&mut tx, &a)?;
|
||||
ws.send(RpcMessage::AccountInstances(account_instances))?;
|
||||
|
||||
let shop = mtx::account_shop(&mut tx, &a)?;
|
||||
ws.send(RpcMessage::AccountShop(shop))?;
|
||||
|
||||
let team = account::team(&mut tx, &a)?;
|
||||
ws.send(RpcMessage::AccountTeam(team))?;
|
||||
|
||||
let wheel = account::chat_wheel(&db, a.id)?;
|
||||
ws.send(RpcMessage::ChatWheel(wheel))?;
|
||||
|
||||
if let Some(instance) = account::tutorial(&mut tx, &a)? {
|
||||
ws.send(RpcMessage::InstanceState(instance))?;
|
||||
}
|
||||
|
||||
// tx should do nothing
|
||||
tx.commit()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn receive(&mut self, data: Vec<u8>, db: &Db, begin: Instant, events: &CbSender<Event>, stripe: &StripeClient) -> Result<RpcMessage, Error> {
|
||||
// cast the msg to this type to receive method name
|
||||
match from_slice::<RpcRequest>(&data) {
|
||||
Ok(v) => {
|
||||
let request = v.clone();
|
||||
let response = match v {
|
||||
RpcRequest::Ping {} => return Ok(RpcMessage::Pong(())),
|
||||
RpcRequest::ItemInfo {} => return Ok(RpcMessage::ItemInfo(item_info())),
|
||||
RpcRequest::DevResolve { skill } =>
|
||||
return Ok(RpcMessage::GameState(anim_test_game(skill))),
|
||||
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
events.send(Event::Queue(self.id))?;
|
||||
Ok(RpcMessage::QueueRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceInvite {} => {
|
||||
events.send(Event::Invite(self.id))?;
|
||||
Ok(RpcMessage::InviteRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceJoin { code } => {
|
||||
events.send(Event::Join(self.id, code))?;
|
||||
Ok(RpcMessage::Joining(()))
|
||||
},
|
||||
RpcRequest::InstanceLeave {} => {
|
||||
events.send(Event::Leave(self.id))?;
|
||||
Ok(RpcMessage::Processing(()))
|
||||
},
|
||||
|
||||
RpcRequest::InstanceChat { instance_id, index } => {
|
||||
if !self.account.subscribed {
|
||||
return Err(err_msg("subscribe to unlock chat"))
|
||||
}
|
||||
|
||||
let wheel = account::chat_wheel(&db, self.account.id)?;
|
||||
|
||||
if let Some(c) = wheel.get(index) {
|
||||
events.send(Event::Chat(self.id, instance_id, c.to_string()))?;
|
||||
} else {
|
||||
return Err(err_msg("invalid chat index"));
|
||||
}
|
||||
|
||||
Ok(RpcMessage::Processing(()))
|
||||
},
|
||||
_ => {
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
let res = match v {
|
||||
RpcRequest::AccountState {} =>
|
||||
Ok(RpcMessage::AccountState(self.account.clone())),
|
||||
RpcRequest::AccountConstructs {} =>
|
||||
Ok(RpcMessage::AccountConstructs(account::constructs(&mut tx, &self.account)?)),
|
||||
RpcRequest::AccountInstances {} =>
|
||||
Ok(RpcMessage::AccountInstances(account::account_instances(&mut tx, &self.account)?)),
|
||||
RpcRequest::AccountSetTeam { ids } =>
|
||||
Ok(RpcMessage::AccountTeam(account::set_team(&mut tx, &self.account, ids)?)),
|
||||
|
||||
RpcRequest::EmailState {} =>
|
||||
Ok(RpcMessage::EmailState(mail::select_account(&db, self.account.id)?)),
|
||||
|
||||
RpcRequest::SubscriptionState {} =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::account_subscription(db, stripe, &self.account)?)),
|
||||
|
||||
// RpcRequest::AccountShop {} =>
|
||||
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
|
||||
|
||||
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
|
||||
|
||||
RpcRequest::GameState { id } =>
|
||||
Ok(RpcMessage::GameState(game_state(&mut tx, &self.account, id)?)),
|
||||
|
||||
RpcRequest::GameSkill { game_id, construct_id, target_construct_id, skill } =>
|
||||
Ok(RpcMessage::GameState(game_skill(&mut tx, &self.account, game_id, construct_id, target_construct_id, skill)?)),
|
||||
|
||||
RpcRequest::GameSkillClear { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, &self.account, game_id)?)),
|
||||
|
||||
RpcRequest::GameReady { id } =>
|
||||
Ok(RpcMessage::GameState(game_ready(&mut tx, &self.account, id)?)),
|
||||
|
||||
RpcRequest::GameConcede { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_concede(&mut tx, &self.account, game_id)?)),
|
||||
|
||||
RpcRequest::GameOfferDraw { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_offer_draw(&mut tx, &self.account, game_id)?)),
|
||||
|
||||
RpcRequest::InstancePractice {} =>
|
||||
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, &self.account)?)),
|
||||
|
||||
// these two can return GameState or InstanceState
|
||||
RpcRequest::InstanceReady { instance_id } =>
|
||||
Ok(instance_ready(&mut tx, &self.account, instance_id)?),
|
||||
RpcRequest::InstanceState { instance_id } =>
|
||||
Ok(instance_state(&mut tx, instance_id)?),
|
||||
RpcRequest::InstanceAbandon { instance_id } =>
|
||||
Ok(instance_abandon(&mut tx, &self.account, instance_id)?),
|
||||
|
||||
RpcRequest::VboxBuy { instance_id, group, index, construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, &self.account, instance_id, group, index, construct_id)?)),
|
||||
|
||||
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, &self.account, instance_id, construct_id, index)?)),
|
||||
|
||||
RpcRequest::VboxCombine { instance_id, inv_indices, vbox_indices } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, &self.account, instance_id, inv_indices, vbox_indices)?)),
|
||||
|
||||
RpcRequest::VboxRefill { instance_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_refill(&mut tx, &self.account, instance_id)?)),
|
||||
|
||||
RpcRequest::VboxRefund { instance_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_refund(&mut tx, &self.account, instance_id, index)?)),
|
||||
|
||||
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, &self.account, instance_id, construct_id, target, None)?)),
|
||||
|
||||
RpcRequest::VboxUnequipApply { instance_id, construct_id, target, target_construct_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, &self.account, instance_id, construct_id, target, Some(target_construct_id))?)),
|
||||
|
||||
RpcRequest::MtxConstructSpawn {} =>
|
||||
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, &self.account)?)),
|
||||
|
||||
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
|
||||
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, &self.account, mtx, construct_id, name)?)),
|
||||
|
||||
RpcRequest::MtxAccountApply { mtx } =>
|
||||
Ok(RpcMessage::AccountState(mtx::account_apply(&mut tx, &self.account, mtx)?)),
|
||||
|
||||
RpcRequest::MtxBuy { mtx } =>
|
||||
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, &self.account, mtx)?)),
|
||||
|
||||
RpcRequest::SubscriptionEnding { ending } =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::subscription_ending(&mut tx, stripe, &self.account, ending)?)),
|
||||
|
||||
_ => Err(format_err!("unknown request request={:?}", request)),
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
res
|
||||
}
|
||||
};
|
||||
|
||||
info!("request={:?} account={:?} duration={:?}", request, self.account.name, begin.elapsed());
|
||||
|
||||
return response;
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
Err(err_msg("invalid message"))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user