improve pvp queue
This commit is contained in:
parent
a16369085c
commit
b910f99f89
@ -4,6 +4,7 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
use failure::{err_msg, format_err};
|
||||||
|
|
||||||
use crossbeam_channel::{Sender, Receiver};
|
use crossbeam_channel::{Sender, Receiver};
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ type Id = usize;
|
|||||||
pub struct PvpRequest {
|
pub struct PvpRequest {
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
pub tx: Sender<RpcMessage>,
|
pub tx: Sender<RpcMessage>,
|
||||||
pub account: Account,
|
pub account: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Events {
|
pub struct Events {
|
||||||
@ -37,8 +38,6 @@ pub struct Events {
|
|||||||
|
|
||||||
mail: Sender<Mail>,
|
mail: Sender<Mail>,
|
||||||
warden: Sender<GameEvent>,
|
warden: Sender<GameEvent>,
|
||||||
queue: Option<PvpRequest>,
|
|
||||||
|
|
||||||
clients: HashMap<Id, WsClient>,
|
clients: HashMap<Id, WsClient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +53,15 @@ pub enum Event {
|
|||||||
Push(Uuid, RpcMessage),
|
Push(Uuid, RpcMessage),
|
||||||
|
|
||||||
// client events
|
// client events
|
||||||
Queue(PvpRequest),
|
Queue(Id),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WsClient {
|
struct WsClient {
|
||||||
id: Id,
|
id: Id,
|
||||||
|
account: Option<Uuid>,
|
||||||
tx: Sender<RpcMessage>,
|
tx: Sender<RpcMessage>,
|
||||||
subs: HashSet<Uuid>,
|
subs: HashSet<Uuid>,
|
||||||
|
pvp: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Events {
|
impl Events {
|
||||||
@ -70,7 +71,6 @@ impl Events {
|
|||||||
rx,
|
rx,
|
||||||
warden,
|
warden,
|
||||||
mail,
|
mail,
|
||||||
queue: None,
|
|
||||||
clients: HashMap::new(),
|
clients: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +110,12 @@ 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, 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);
|
self.clients.insert(id, client);
|
||||||
|
|
||||||
info!("clients={:?}", self.clients.len());
|
info!("clients={:?}", self.clients.len());
|
||||||
@ -181,30 +186,43 @@ impl Events {
|
|||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
|
||||||
Event::Queue(req) => {
|
Event::Queue(id) => {
|
||||||
info!("queue id={:?} account={:?}", req.id, req.account);
|
// 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 {
|
if let None = c.account {
|
||||||
Some(ref q_req) => {
|
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||||
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)),
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
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(());
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -691,9 +691,6 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result<Inst
|
|||||||
Ok(instance)
|
Ok(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn instance_queue(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, Error> {
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, Error> {
|
pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, Error> {
|
||||||
let mut instance = Instance::new()
|
let mut instance = Instance::new()
|
||||||
// TODO generate nice game names
|
// TODO generate nice game names
|
||||||
|
|||||||
@ -19,7 +19,7 @@ use ws::{listen, CloseCode, Message, Handler, Request, Response};
|
|||||||
use account::{Account};
|
use account::{Account};
|
||||||
use account;
|
use account;
|
||||||
use construct::{Construct};
|
use construct::{Construct};
|
||||||
use events::{Event, PvpRequest};
|
use events::{Event};
|
||||||
use game::{Game, game_state, game_skill, game_ready};
|
use game::{Game, game_state, game_skill, game_ready};
|
||||||
use instance::{Instance, instance_state, instance_practice, instance_ready};
|
use instance::{Instance, instance_state, instance_practice, instance_ready};
|
||||||
use item::{Item, ItemInfoCtr, item_info};
|
use item::{Item, ItemInfoCtr, item_info};
|
||||||
@ -132,8 +132,7 @@ impl Connection {
|
|||||||
// evented but authorization required
|
// evented but authorization required
|
||||||
match v {
|
match v {
|
||||||
RpcRequest::InstanceQueue {} => {
|
RpcRequest::InstanceQueue {} => {
|
||||||
let pvp = PvpRequest { id: self.id, account: account.clone(), tx: self.ws.clone() };
|
self.events.send(Event::Queue(self.id))?;
|
||||||
self.events.send(Event::Queue(pvp))?;
|
|
||||||
return Ok(RpcMessage::QueueRequested(()));
|
return Ok(RpcMessage::QueueRequested(()));
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use crossbeam_channel::{tick, Sender, Receiver};
|
|||||||
use postgres::transaction::Transaction;
|
use postgres::transaction::Transaction;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
|
use account;
|
||||||
use game::{games_need_upkeep, game_update, game_write, game_delete};
|
use game::{games_need_upkeep, game_update, game_write, game_delete};
|
||||||
use instance;
|
use instance;
|
||||||
use instance::{instances_need_upkeep, instances_idle, instance_update, instance_delete};
|
use instance::{instances_need_upkeep, instances_idle, instance_update, instance_delete};
|
||||||
@ -91,7 +92,11 @@ impl Warden {
|
|||||||
|
|
||||||
let db = self.pool.get()?;
|
let db = self.pool.get()?;
|
||||||
let mut tx = db.transaction()?;
|
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()?;
|
tx.commit()?;
|
||||||
|
|
||||||
// subscribe users to instance events
|
// subscribe users to instance events
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user