From b910f99f898e8b9cca7679181b7744ae64e4c22b Mon Sep 17 00:00:00 2001 From: ntr Date: Wed, 4 Sep 2019 16:38:03 +1000 Subject: [PATCH 1/2] improve pvp queue --- server/src/events.rs | 72 ++++++++++++++++++++++++++---------------- server/src/instance.rs | 3 -- server/src/rpc.rs | 5 ++- server/src/warden.rs | 7 +++- 4 files changed, 53 insertions(+), 34 deletions(-) diff --git a/server/src/events.rs b/server/src/events.rs index 782f0088..ca1ce5af 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -4,6 +4,7 @@ use std::collections::{HashMap, HashSet}; use uuid::Uuid; use failure::Error; +use failure::{err_msg, format_err}; use crossbeam_channel::{Sender, Receiver}; @@ -28,7 +29,7 @@ type Id = usize; pub struct PvpRequest { pub id: Id, pub tx: Sender, - pub account: Account, + pub account: Uuid, } pub struct Events { @@ -37,8 +38,6 @@ pub struct Events { mail: Sender, warden: Sender, - queue: Option, - clients: HashMap, } @@ -54,13 +53,15 @@ pub enum Event { Push(Uuid, RpcMessage), // client events - Queue(PvpRequest), + Queue(Id), } struct WsClient { id: Id, + account: Option, tx: Sender, subs: HashSet, + pvp: bool, } impl Events { @@ -70,7 +71,6 @@ impl Events { rx, warden, mail, - queue: None, clients: HashMap::new(), } } @@ -110,7 +110,12 @@ impl Events { Event::Connect(id, account, tx) => { info!("connect id={:?} account={:?}", id, account); - let client = WsClient { id, tx, subs: HashSet::new() }; + 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 }; self.clients.insert(id, client); info!("clients={:?}", self.clients.len()); @@ -181,30 +186,43 @@ impl Events { Ok(()) }, - Event::Queue(req) => { - info!("queue id={:?} account={:?}", req.id, req.account); + Event::Queue(id) => { + // check whether request is valid + { + let c = self.clients.get(&id) + .ok_or(format_err!("connection not found id={:?}", id))?; - self.queue = match self.queue { - Some(ref q_req) => { - info!("game queue pair found a={:?} b={:?}", req.account, q_req.account); - self.warden.send(GameEvent::Match((req, q_req.clone())))?; - None - }, - None => { - info!("joined game queue id={:?} account={:?}", req.id, req.account); - match self.clients.get(&req.id) { - Some(ref c) => { - c.tx.send(RpcMessage::QueueJoined(()))?; - Some(req) - }, - None => return Err(format_err!("missing client client={:?}", req.id)), - } - }, - }; + if let None = c.account { + return Err(err_msg("cannot join pvp queue anonymously")); + } - Ok(()) + info!("pvp queue request id={:?} account={:?}", c.id, c.account); + } + + // create the req for the already queued opponent + if let Some(opp_req) = match self.clients.iter_mut().find(|(_c_id, c)| c.pvp) { + Some((q_id, q)) => { + q.pvp = false; + Some(PvpRequest { id: *q_id, account: q.account.unwrap(), tx: q.tx.clone() }) + }, + None => None, + } { + // combine the requests and send to warden + 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() }; + self.warden.send(GameEvent::Match((opp_req, player_req)))?; + + return Ok(()) + } + + // or flag the requester as pvp ready + let requester = self.clients.get_mut(&id).unwrap(); + requester.pvp = true; + info!("joined game queue id={:?} account={:?}", requester.id, requester.account); + return Ok(()); }, - } } } diff --git a/server/src/instance.rs b/server/src/instance.rs index 5443eac9..34f72bd1 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -691,9 +691,6 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result Result { -// } - pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result { let mut instance = Instance::new() // TODO generate nice game names diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 01579c23..54408bd2 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -19,7 +19,7 @@ use ws::{listen, CloseCode, Message, Handler, Request, Response}; use account::{Account}; use account; use construct::{Construct}; -use events::{Event, PvpRequest}; +use events::{Event}; use game::{Game, game_state, game_skill, game_ready}; use instance::{Instance, instance_state, instance_practice, instance_ready}; use item::{Item, ItemInfoCtr, item_info}; @@ -132,8 +132,7 @@ impl Connection { // evented but authorization required match v { RpcRequest::InstanceQueue {} => { - let pvp = PvpRequest { id: self.id, account: account.clone(), tx: self.ws.clone() }; - self.events.send(Event::Queue(pvp))?; + self.events.send(Event::Queue(self.id))?; return Ok(RpcMessage::QueueRequested(())); }, _ => (), diff --git a/server/src/warden.rs b/server/src/warden.rs index 5cef7008..8232282a 100644 --- a/server/src/warden.rs +++ b/server/src/warden.rs @@ -8,6 +8,7 @@ use crossbeam_channel::{tick, Sender, Receiver}; use postgres::transaction::Transaction; use failure::Error; +use account; use game::{games_need_upkeep, game_update, game_write, game_delete}; use instance; use instance::{instances_need_upkeep, instances_idle, instance_update, instance_delete}; @@ -91,7 +92,11 @@ impl Warden { let db = self.pool.get()?; let mut tx = db.transaction()?; - let instance = instance::pvp(&mut tx, &pair.0.account, &pair.1.account)?; + + let a = account::select(&db, pair.0.account)?; + let b = account::select(&db, pair.1.account)?; + + let instance = instance::pvp(&mut tx, &a, &b)?; tx.commit()?; // subscribe users to instance events From 0ca193421e917ecb181f03f3ce6245d0001a23fa Mon Sep 17 00:00:00 2001 From: ntr Date: Wed, 4 Sep 2019 16:39:07 +1000 Subject: [PATCH 2/2] version bump --- VERSION | 2 +- acp/package.json | 2 +- client/package.json | 2 +- ops/package.json | 2 +- server/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 1cc5f657..867e5243 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0 \ No newline at end of file +1.2.0 \ No newline at end of file diff --git a/acp/package.json b/acp/package.json index cc7a1379..a13e342e 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.1.0", + "version": "1.2.0", "description": "", "main": "index.js", "scripts": { diff --git a/client/package.json b/client/package.json index a0ecb408..14bc2149 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.1.0", + "version": "1.2.0", "description": "", "main": "index.js", "scripts": { diff --git a/ops/package.json b/ops/package.json index ce9cd791..75a489af 100755 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.1.0", + "version": "1.2.0", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index 2b528b9b..06eb0264 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.1.0" +version = "1.2.0" authors = ["ntr "] [dependencies]