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 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<RpcMessage>,
|
||||
pub account: Account,
|
||||
pub account: Uuid,
|
||||
}
|
||||
|
||||
pub struct Events {
|
||||
@ -37,8 +38,6 @@ pub struct Events {
|
||||
|
||||
mail: Sender<Mail>,
|
||||
warden: Sender<GameEvent>,
|
||||
queue: Option<PvpRequest>,
|
||||
|
||||
clients: HashMap<Id, WsClient>,
|
||||
}
|
||||
|
||||
@ -54,13 +53,15 @@ pub enum Event {
|
||||
Push(Uuid, RpcMessage),
|
||||
|
||||
// client events
|
||||
Queue(PvpRequest),
|
||||
Queue(Id),
|
||||
}
|
||||
|
||||
struct WsClient {
|
||||
id: Id,
|
||||
account: Option<Uuid>,
|
||||
tx: Sender<RpcMessage>,
|
||||
subs: HashSet<Uuid>,
|
||||
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(());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -691,9 +691,6 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result<Inst
|
||||
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> {
|
||||
let mut instance = Instance::new()
|
||||
// TODO generate nice game names
|
||||
|
||||
@ -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(()));
|
||||
},
|
||||
_ => (),
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user