return to usize based socket ids to solve multiple tab issue

This commit is contained in:
ntr 2020-01-23 11:52:12 +10:00
parent 4173e690c0
commit 153b3a1e9c
3 changed files with 32 additions and 26 deletions

View File

@ -17,7 +17,7 @@ use rpc::RpcMessage;
use warden::{GameEvent}; use warden::{GameEvent};
pub type EventsTx = Sender<Event>; pub type EventsTx = Sender<Event>;
type Id = Uuid; type Id = usize;
// this is pretty heavyweight // this is pretty heavyweight
// but it makes the ergonomics easy // but it makes the ergonomics easy
@ -60,8 +60,13 @@ pub enum Event {
ChatClear(Id, Uuid), ChatClear(Id, Uuid),
} }
// id and account are seperate
// multiple tabs etc can cause the same account to be connected twice
// so even though each client has the same subs etc
// they are treated independently
struct WsClient { struct WsClient {
id: Id, id: Id,
account: Uuid,
tx: Sender<RpcMessage>, tx: Sender<RpcMessage>,
subs: HashSet<Uuid>, subs: HashSet<Uuid>,
chat: Option<(Uuid, String)>, chat: Option<(Uuid, String)>,
@ -103,7 +108,9 @@ impl Events {
Event::Connect(id, account, tx) => { Event::Connect(id, account, tx) => {
info!("connect id={:?} account={:?}", id, account); info!("connect id={:?} account={:?}", id, account);
let client = WsClient { id, let client = WsClient {
id,
account: account.id,
tx, tx,
subs: HashSet::new(), subs: HashSet::new(),
pvp: false, pvp: false,
@ -163,8 +170,8 @@ impl Events {
subs += 1; subs += 1;
let redacted = match msg { let redacted = match msg {
RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.id)), RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.account)),
RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.id)), RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.account)),
_ => msg.clone(), _ => msg.clone(),
}; };
@ -203,7 +210,7 @@ impl Events {
if let Some(opp_req) = match self.clients.iter_mut().find(|(c_id, c)| c.pvp && **c_id != id) { if let Some(opp_req) = match self.clients.iter_mut().find(|(c_id, c)| c.pvp && **c_id != id) {
Some((q_id, q)) => { Some((q_id, q)) => {
q.pvp = false; q.pvp = false;
Some(PvpRequest { id: *q_id, account: q.id, tx: q.tx.clone() }) Some(PvpRequest { id: *q_id, account: q.account, tx: q.tx.clone() })
}, },
None => None, None => None,
} { } {
@ -211,7 +218,7 @@ impl Events {
let c = self.clients.get_mut(&id) let c = self.clients.get_mut(&id)
.ok_or(format_err!("connection not found id={:?}", id))?; .ok_or(format_err!("connection not found id={:?}", id))?;
let player_req = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }; let player_req = PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() };
self.warden.send(GameEvent::Match((opp_req, player_req)))?; self.warden.send(GameEvent::Match((opp_req, player_req)))?;
return Ok(()) return Ok(())
@ -221,7 +228,7 @@ impl Events {
let requester = self.clients.get_mut(&id).unwrap(); let requester = self.clients.get_mut(&id).unwrap();
requester.pvp = true; requester.pvp = true;
requester.tx.send(RpcMessage::QueueJoined(()))?; requester.tx.send(RpcMessage::QueueJoined(()))?;
info!("joined game queue id={:?} account={:?}", requester.id, requester.id); info!("joined game queue id={:?} account={:?}", requester.id, requester.account);
return Ok(()); return Ok(());
}, },
@ -231,7 +238,7 @@ impl Events {
.ok_or(format_err!("connection not found id={:?}", id))?; .ok_or(format_err!("connection not found id={:?}", id))?;
let code = names::name().split_whitespace().collect::<Vec<&str>>().join("-"); let code = names::name().split_whitespace().collect::<Vec<&str>>().join("-");
info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.id, code); info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.account, code);
c.invite = Some(code.clone()); c.invite = Some(code.clone());
c.tx.send(RpcMessage::Invite(code))?; c.tx.send(RpcMessage::Invite(code))?;
return Ok(()); return Ok(());
@ -250,10 +257,10 @@ impl Events {
Some(ref c) => *c == code, Some(ref c) => *c == code,
None => false, None => false,
}) })
.map(|(_id, c)| PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }) .map(|(_id, c)| PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() })
.ok_or(format_err!("invite expired code={:?}", code))?; .ok_or(format_err!("invite expired code={:?}", code))?;
let join = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }; let join = PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() };
self.warden.send(GameEvent::Match((join, inv)))?; self.warden.send(GameEvent::Match((join, inv)))?;
return Ok(()); return Ok(());
@ -276,7 +283,7 @@ impl Events {
c.pvp = false; c.pvp = false;
c.tx.send(RpcMessage::QueueLeft(()))?; c.tx.send(RpcMessage::QueueLeft(()))?;
info!("left game queue id={:?} account={:?}", c.id, c.id); info!("left game queue id={:?} account={:?}", c.id, c.account);
return Ok(()); return Ok(());
}, },
@ -307,7 +314,7 @@ impl Events {
Some(ref chat) => chat.0 == instance, Some(ref chat) => chat.0 == instance,
None => false, None => false,
}) })
.map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1))
.collect(); .collect();
return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state)));
@ -326,7 +333,7 @@ impl Events {
Some(ref chat) => chat.0 == instance, Some(ref chat) => chat.0 == instance,
None => false, None => false,
}) })
.map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1))
.collect(); .collect();
return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state)));

View File

@ -17,6 +17,8 @@ use crossbeam_channel::{unbounded, Sender as CbSender};
use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender}; use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender};
use ws::deflate::DeflateHandler; use ws::deflate::DeflateHandler;
use rand::prelude::*;
use account::{Account}; use account::{Account};
use account; use account;
use events::{Event}; use events::{Event};
@ -132,11 +134,10 @@ pub trait User {
} }
struct Connection { struct Connection {
pub id: Uuid, pub id: usize,
pub ws: CbSender<RpcMessage>, pub ws: CbSender<RpcMessage>,
pool: PgPool, pool: PgPool,
stripe: StripeClient, stripe: StripeClient,
// account: Option<Account>,
user: Box<dyn User>, user: Box<dyn User>,
events: CbSender<Event>, events: CbSender<Event>,
} }
@ -199,8 +200,7 @@ impl Handler for Connection {
let db = self.pool.get().unwrap(); let db = self.pool.get().unwrap();
match account::from_token(&db, &cookie.value().to_string()) { match account::from_token(&db, &cookie.value().to_string()) {
Ok(a) => { Ok(a) => {
self.id = a.id; self.user = Box::new(Authenticated::new(self.id, a, self.ws.clone(), self.events.clone(), self.pool.clone()));
self.user = Box::new(Authenticated::new(a, self.ws.clone(), self.events.clone(), self.pool.clone()));
}, },
Err(_) => return unauth(), Err(_) => return unauth(),
} }
@ -243,12 +243,12 @@ pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
} }
}); });
let mut rng = thread_rng();
let anon_account = Account::anonymous(); let anon_account = Account::anonymous();
let id = anon_account.id;
DeflateHandler::new( DeflateHandler::new(
Connection { Connection {
id, id: rng.gen::<usize>(),
ws: tx.clone(), ws: tx.clone(),
pool: pool.clone(), pool: pool.clone(),
stripe: stripe.clone(), stripe: stripe.clone(),

View File

@ -1,7 +1,6 @@
use mnml_core::mob::anim_test_game; use mnml_core::mob::anim_test_game;
use mnml_core::item::item_info; use mnml_core::item::item_info;
use std::time::Instant; use std::time::Instant;
use uuid::Uuid;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
@ -44,7 +43,7 @@ use rpc::{RpcMessage, RpcRequest, User};
#[derive(Debug,Clone)] #[derive(Debug,Clone)]
pub struct Authenticated { pub struct Authenticated {
pub account: Account, pub account: Account,
pub id: Uuid, pub id: usize,
events: CbSender<Event>, events: CbSender<Event>,
ws: CbSender<RpcMessage>, ws: CbSender<RpcMessage>,
@ -52,9 +51,9 @@ pub struct Authenticated {
} }
impl Authenticated { impl Authenticated {
pub fn new(account: Account, ws: CbSender<RpcMessage>, events: CbSender<Event>, pool: PgPool) -> Authenticated { pub fn new(id: usize, account: Account, ws: CbSender<RpcMessage>, events: CbSender<Event>, pool: PgPool) -> Authenticated {
Authenticated { Authenticated {
id: account.id, id,
account, account,
ws, ws,
events, events,
@ -81,10 +80,10 @@ impl User for Authenticated {
// last minute processing // last minute processing
let msg = match msg { let msg = match msg {
RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(self.id)), RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(self.account.id)),
RpcMessage::AccountInstances(v) => RpcMessage::AccountInstances(v) =>
RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.id)).collect()), RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.account.id)).collect()),
RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.id)), RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.account.id)),
_ => msg, _ => msg,
}; };