game invites

This commit is contained in:
ntr
2019-09-15 15:42:47 +10:00
parent a22521b119
commit b85dade351
10 changed files with 250 additions and 73 deletions
+59 -1
View File
@@ -12,6 +12,7 @@ use account;
use account::Account;
use game;
use instance;
use names;
use pg::{Db, PgPool};
use rpc::RpcMessage;
@@ -54,6 +55,9 @@ pub enum Event {
// client events
Queue(Id),
Invite(Id),
Join(Id, String),
Joined(Id),
}
struct WsClient {
@@ -62,6 +66,7 @@ struct WsClient {
tx: Sender<RpcMessage>,
subs: HashSet<Uuid>,
pvp: bool,
invite: Option<String>,
}
impl Events {
@@ -115,7 +120,7 @@ impl Events {
None => None,
};
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false };
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false, invite: None };
self.clients.insert(id, client);
info!("clients={:?}", self.clients.len());
@@ -223,6 +228,59 @@ impl Events {
info!("joined game queue id={:?} account={:?}", requester.id, requester.account);
return Ok(());
},
Event::Invite(id) => {
// check whether request is valid
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);
c.invite = Some(code.clone());
c.tx.send(RpcMessage::Invite(code))?;
return Ok(());
},
Event::Join(id, code) => {
// check whether request is valid
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);
let inv = self.clients.iter()
.filter(|(_id, c)| c.invite.is_some())
.find(|(_id, c)| match c.invite {
Some(ref c) => *c == code,
None => false,
})
.map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() })
.ok_or(format_err!("invite not found code={:?}", code))?;
let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };
self.warden.send(GameEvent::Match((join, inv)))?;
return Ok(());
},
Event::Joined(id) => {
// check whether request is valid
let c = self.clients.get_mut(&id)
.ok_or(format_err!("connection not found id={:?}", id))?;
c.pvp = false;
c.invite = None;
return Ok(());
},
}
}
}
+82 -67
View File
@@ -62,6 +62,10 @@ pub enum RpcMessage {
QueueJoined(()),
QueueCancelled(()),
InviteRequested(()),
Invite(String),
Joining(()),
Error(String),
}
@@ -91,6 +95,8 @@ pub enum RpcRequest {
SubscriptionState {},
EmailState {},
InstanceInvite {},
InstanceJoin { code: String },
InstanceQueue {},
InstancePractice {},
InstanceAbandon { instance_id: Uuid },
@@ -136,99 +142,108 @@ impl Connection {
None => return Err(err_msg("auth required")),
};
// evented but authorization required
match v {
RpcRequest::InstanceQueue {} => {
self.events.send(Event::Queue(self.id))?;
return Ok(RpcMessage::QueueRequested(()));
},
_ => (),
};
// all good, let's make a tx and process
let mut tx = db.transaction()?;
let request = v.clone();
let response = 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)?)),
// 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(()))
},
_ => {
// all good, let's make a tx and process
let mut tx = db.transaction()?;
RpcRequest::EmailState {} =>
Ok(RpcMessage::EmailState(mail::select_account(&db, account.id)?)),
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::SubscriptionState {} =>
Ok(RpcMessage::SubscriptionState(payments::account_subscription(&db, &self.stripe, &account)?)),
RpcRequest::EmailState {} =>
Ok(RpcMessage::EmailState(mail::select_account(&db, account.id)?)),
// RpcRequest::AccountShop {} =>
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
RpcRequest::SubscriptionState {} =>
Ok(RpcMessage::SubscriptionState(payments::account_subscription(&db, &self.stripe, &account)?)),
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
// RpcRequest::AccountShop {} =>
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
RpcRequest::GameState { id } =>
Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)),
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
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::GameState { id } =>
Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)),
RpcRequest::GameSkillClear { game_id } =>
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_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::GameReady { id } =>
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
RpcRequest::GameSkillClear { game_id } =>
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_id)?)),
RpcRequest::InstancePractice {} =>
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, account)?)),
RpcRequest::GameReady { id } =>
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
// 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::InstancePractice {} =>
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, account)?)),
RpcRequest::VboxAccept { instance_id, group, index } =>
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)),
// 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::VboxApply { instance_id, construct_id, index } =>
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
RpcRequest::VboxAccept { instance_id, group, index } =>
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)),
RpcRequest::VboxCombine { instance_id, indices } =>
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)),
RpcRequest::VboxApply { instance_id, construct_id, index } =>
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
RpcRequest::VboxDiscard { instance_id } =>
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
RpcRequest::VboxCombine { instance_id, indices } =>
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)),
RpcRequest::VboxReclaim { instance_id, index } =>
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
RpcRequest::VboxDiscard { instance_id } =>
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)),
RpcRequest::VboxReclaim { instance_id, index } =>
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
RpcRequest::MtxConstructSpawn {} =>
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)),
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
RpcRequest::MtxConstructSpawn {} =>
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
RpcRequest::MtxBuy { mtx } =>
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
RpcRequest::SubscriptionEnding { ending } =>
Ok(RpcMessage::SubscriptionState(payments::subscription_ending(&mut tx, &self.stripe, account, ending)?)),
RpcRequest::MtxBuy { mtx } =>
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
_ => Err(format_err!("unknown request request={:?}", request)),
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
}
};
tx.commit()?;
info!("request={:?} account={:?} duration={:?}", request, account.name, begin.elapsed());
return response;
+4
View File
@@ -90,6 +90,10 @@ impl Warden {
fn on_match(&mut self, pair: Pair) -> Result<(), Error> {
info!("received pair={:?}", pair);
// clear pvp status
self.events.send(Event::Joined(pair.0.id))?;
self.events.send(Event::Joined(pair.1.id))?;
let db = self.pool.get()?;
let mut tx = db.transaction()?;