diff --git a/server/src/events.rs b/server/src/events.rs index 8208c821..f7d5e0b2 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -17,7 +17,7 @@ use rpc::RpcMessage; use warden::{GameEvent}; pub type EventsTx = Sender; -type Id = Uuid; +type Id = usize; // this is pretty heavyweight // but it makes the ergonomics easy @@ -60,8 +60,13 @@ pub enum Event { 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 { id: Id, + account: Uuid, tx: Sender, subs: HashSet, chat: Option<(Uuid, String)>, @@ -103,7 +108,9 @@ impl Events { Event::Connect(id, account, tx) => { info!("connect id={:?} account={:?}", id, account); - let client = WsClient { id, + let client = WsClient { + id, + account: account.id, tx, subs: HashSet::new(), pvp: false, @@ -163,8 +170,8 @@ impl Events { subs += 1; 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)), + RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.account)), + RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.account)), _ => 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) { Some((q_id, q)) => { 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, } { @@ -211,7 +218,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.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)))?; return Ok(()) @@ -221,7 +228,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.id); + info!("joined game queue id={:?} account={:?}", requester.id, requester.account); return Ok(()); }, @@ -231,7 +238,7 @@ impl Events { .ok_or(format_err!("connection not found id={:?}", id))?; let code = names::name().split_whitespace().collect::>().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.tx.send(RpcMessage::Invite(code))?; return Ok(()); @@ -250,10 +257,10 @@ impl Events { Some(ref c) => *c == code, 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))?; - 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)))?; return Ok(()); @@ -276,7 +283,7 @@ impl Events { c.pvp = false; 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(()); }, @@ -307,7 +314,7 @@ impl Events { Some(ref chat) => chat.0 == instance, None => false, }) - .map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) + .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1)) .collect(); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); @@ -326,7 +333,7 @@ impl Events { Some(ref chat) => chat.0 == instance, None => false, }) - .map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) + .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1)) .collect(); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 8cc76d7b..dead4344 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -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::deflate::DeflateHandler; +use rand::prelude::*; + use account::{Account}; use account; use events::{Event}; @@ -132,11 +134,10 @@ pub trait User { } struct Connection { - pub id: Uuid, + pub id: usize, pub ws: CbSender, pool: PgPool, stripe: StripeClient, - // account: Option, user: Box, events: CbSender, } @@ -199,8 +200,7 @@ impl Handler for Connection { let db = self.pool.get().unwrap(); match account::from_token(&db, &cookie.value().to_string()) { Ok(a) => { - self.id = a.id; - self.user = Box::new(Authenticated::new(a, self.ws.clone(), self.events.clone(), self.pool.clone())); + self.user = Box::new(Authenticated::new(self.id, a, self.ws.clone(), self.events.clone(), self.pool.clone())); }, Err(_) => return unauth(), } @@ -243,12 +243,12 @@ pub fn start(pool: PgPool, events_tx: CbSender, stripe: StripeClient) { } }); + let mut rng = thread_rng(); let anon_account = Account::anonymous(); - let id = anon_account.id; DeflateHandler::new( Connection { - id, + id: rng.gen::(), ws: tx.clone(), pool: pool.clone(), stripe: stripe.clone(), diff --git a/server/src/user_authenticated.rs b/server/src/user_authenticated.rs index eb617178..63479119 100644 --- a/server/src/user_authenticated.rs +++ b/server/src/user_authenticated.rs @@ -1,7 +1,6 @@ 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; @@ -44,7 +43,7 @@ use rpc::{RpcMessage, RpcRequest, User}; #[derive(Debug,Clone)] pub struct Authenticated { pub account: Account, - pub id: Uuid, + pub id: usize, events: CbSender, ws: CbSender, @@ -52,9 +51,9 @@ pub struct Authenticated { } impl Authenticated { - pub fn new(account: Account, ws: CbSender, events: CbSender, pool: PgPool) -> Authenticated { + pub fn new(id: usize, account: Account, ws: CbSender, events: CbSender, pool: PgPool) -> Authenticated { Authenticated { - id: account.id, + id, account, ws, events, @@ -81,10 +80,10 @@ impl User for Authenticated { // last minute processing 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.into_iter().map(|i| i.redact(self.id)).collect()), - RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.id)), + RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.account.id)).collect()), + RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.account.id)), _ => msg, };