global mm and startup

This commit is contained in:
ntr 2019-03-18 16:36:26 +11:00
parent 8b825db044
commit 5fe394370d
8 changed files with 163 additions and 25 deletions

View File

@ -50,6 +50,19 @@ exports.up = async knex => {
}); });
await knex.schema.createTable('matchmaking', async table => {
table.uuid('id').primary();
table.index('id');
table.timestamps(true, true);
table.uuid('game').notNullable()
table.foreign('game')
.references('id')
.inTable('games')
.onDelete('NO ACTION');
});
// not really sure if this is a good idea // not really sure if this is a good idea
await knex('instances').insert({ await knex('instances').insert({
id: NULL_UUID, id: NULL_UUID,

View File

@ -13,10 +13,14 @@ combo specs
fix global matchmaking fix global matchmaking
startup checks
scoreboard scoreboard
constants constants
change to ownership pattern
round system for games round system for games
join instance join instance
is pve? is pve?

View File

@ -82,7 +82,6 @@ pub struct Game {
pub team_size: usize, pub team_size: usize,
pub team_num: usize, pub team_num: usize,
pub teams: Vec<Team>, pub teams: Vec<Team>,
pub is_pve: bool,
pub phase: Phase, pub phase: Phase,
pub stack: Vec<Cast>, pub stack: Vec<Cast>,
pub resolved: Vec<Cast>, pub resolved: Vec<Cast>,
@ -98,7 +97,6 @@ impl Game {
team_size: 0, team_size: 0,
team_num: 0, team_num: 0,
teams: vec![], teams: vec![],
is_pve: true,
phase: Phase::Start, phase: Phase::Start,
stack: vec![], stack: vec![],
resolved: vec![], resolved: vec![],
@ -118,11 +116,6 @@ impl Game {
self self
} }
pub fn set_pve(&mut self, pve: bool) -> &mut Game {
self.is_pve = pve;
self
}
pub fn set_instance(&mut self, id: Uuid) -> &mut Game { pub fn set_instance(&mut self, id: Uuid) -> &mut Game {
self.instance = Some(id); self.instance = Some(id);
self self
@ -133,6 +126,10 @@ impl Game {
self self
} }
pub fn joinable(&self) -> bool {
self.can_start()
}
pub fn team_add(&mut self, team: Team) -> Result<&mut Game, Error> { pub fn team_add(&mut self, team: Team) -> Result<&mut Game, Error> {
if self.teams.len() == self.team_num { if self.teams.len() == self.team_num {
return Err(err_msg("maximum number of teams")); return Err(err_msg("maximum number of teams"));
@ -142,6 +139,10 @@ impl Game {
return Err(err_msg("team already in game")); return Err(err_msg("team already in game"));
} }
if team.cryps.iter().all(|c| c.skills.len() == 0) {
return Err(err_msg("your cryps have no skills"));
}
let team_description = team.cryps.iter().map(|c| c.name.clone()).collect::<Vec<String>>().join(", "); let team_description = team.cryps.iter().map(|c| c.name.clone()).collect::<Vec<String>>().join(", ");
self.log.push(format!("{:} has joined the game.", team_description)); self.log.push(format!("{:} has joined the game.", team_description));
@ -211,11 +212,9 @@ impl Game {
self.stack.clear(); self.stack.clear();
if self.is_pve { self.pve_add_skills();
self.pve_add_skills(); if self.skill_phase_finished() {
if self.skill_phase_finished() { self.resolve_phase_start();
self.resolve_phase_start();
}
} }
self self
@ -261,7 +260,6 @@ impl Game {
}; };
} }
} }
self self
} }
@ -651,6 +649,81 @@ pub fn game_get(tx: &mut Transaction, id: Uuid) -> Result<Game, Error> {
return Ok(game); return Ok(game);
} }
pub fn game_global_startup(tx: &mut Transaction) -> Result<(), Error> {
if game_global_get(tx).is_ok() {
println!("global mm game exists");
return Ok(());
}
let mut game = Game::new();
game
.set_team_num(2)
.set_team_size(3)
.set_mode(GameMode::Pvp);
game_write(&game, tx)?;
let query = "
INSERT INTO matchmaking (id, game)
VALUES ($1, $2)
RETURNING id;
";
let result = tx
.query(query, &[&Uuid::nil(), &game.id])?;
result.iter().next().ok_or(format_err!("no game written"))?;
println!("{:} wrote global mm startup", game.id);
return Ok(());
}
pub fn game_global_set(tx: &mut Transaction, game: &Game) -> Result<(), Error> {
let query = "
UPDATE matchmaking
SET game = $1
WHERE id = $2
RETURNING id, game;
";
let result = tx
.query(query, &[&game.id, &Uuid::nil()])?;
result.iter()
.next()
.ok_or(err_msg("could not set global game mm"))?;
return Ok(());
}
pub fn game_global_get(tx: &mut Transaction) -> Result<Game, Error> {
let query = "
SELECT * from games
WHERE id = (
SELECT game
FROM matchmaking
WHERE id = $1
);
";
let result = tx
.query(query, &[&Uuid::nil()])?;
let returned = match result.iter().next() {
Some(row) => row,
None => return Err(err_msg("game not found")),
};
// tells from_slice to cast into a cryp
let game_bytes: Vec<u8> = returned.get("data");
let game = from_slice::<Game>(&game_bytes)?;
return Ok(game);
}
pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> { pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
let game_bytes = to_vec(&game)?; let game_bytes = to_vec(&game)?;
@ -693,8 +766,7 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
// let mut game = Game::new(); // let mut game = Game::new();
// // let game_id = game.id; // // let game_id = game.id;
// game // game;
// .set_pve(true)
// .set_team_num(2) // .set_team_num(2)
// .set_team_size(cryps.len()) // .set_team_size(cryps.len())
// .set_mode(mode); // .set_mode(mode);
@ -732,7 +804,6 @@ pub fn game_instance_new(tx: &mut Transaction, player: Player, game_id: Uuid) ->
game.id = game_id; game.id = game_id;
game game
.set_pve(false)
.set_team_num(2) .set_team_num(2)
.set_team_size(3) .set_team_size(3)
.set_instance(player.instance) .set_instance(player.instance)
@ -761,6 +832,8 @@ pub fn game_instance_join(tx: &mut Transaction, player: Player, game_id: Uuid) -
game.start(); game.start();
} }
println!("{:?} game joined", game.id);
game_update(&game, tx)?; game_update(&game, tx)?;
Ok(game) Ok(game)
@ -800,8 +873,7 @@ mod tests {
game game
.set_team_num(2) .set_team_num(2)
.set_team_size(1) .set_team_size(1);
.set_pve(false);
let x_team_id = Uuid::new_v4(); let x_team_id = Uuid::new_v4();
let mut x_team = Team::new(x_team_id); let mut x_team = Team::new(x_team_id);
@ -849,8 +921,7 @@ mod tests {
game game
.set_team_num(2) .set_team_num(2)
.set_team_size(2) .set_team_size(2);
.set_pve(false);
let i_team_id = Uuid::new_v4(); let i_team_id = Uuid::new_v4();
let mut i_team = Team::new(i_team_id); let mut i_team = Team::new(i_team_id);

View File

@ -14,7 +14,7 @@ use account::Account;
use player::{Player, player_create, player_get, player_update}; use player::{Player, player_create, player_get, player_update};
use cryp::{Cryp, cryp_get}; use cryp::{Cryp, cryp_get};
use mob::{instance_mobs}; use mob::{instance_mobs};
use game::{Game, Team, game_get, game_write, game_instance_new, game_instance_join}; use game::{Game, Team, game_get, game_write, game_instance_new, game_instance_join, game_global_get, game_global_set};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
enum InstancePhase { enum InstancePhase {
@ -112,7 +112,6 @@ impl Instance {
let mut game = Game::new(); let mut game = Game::new();
game.id = current_round.game_id; game.id = current_round.game_id;
game game
.set_pve(true)
.set_team_num(2) .set_team_num(2)
.set_team_size(3) .set_team_size(3)
.set_instance(self.id); .set_instance(self.id);
@ -219,7 +218,6 @@ impl Instance {
let mut game = Game::new(); let mut game = Game::new();
game game
.set_pve(true)
.set_team_num(2) .set_team_num(2)
.set_team_size(3); .set_team_size(3);
@ -416,9 +414,34 @@ pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account:
return Ok(player); return Ok(player);
} }
pub fn instance_ready_global(tx: &mut Transaction, _account: &Account, player: Player) -> Result<Game, Error> {
// get the game
let game = match game_global_get(tx) {
Ok(g) => {
println!("received global game {:?}", g.id);
// if there is one try to join
match game_instance_join(tx, player.clone(), g.id) {
Ok(g) => g,
// if fails make a new one
Err(_e) => game_instance_new(tx, player, Uuid::new_v4())?,
}
},
// if not found make a new one
Err(_) => game_instance_new(tx, player, Uuid::new_v4())?,
};
// set the current game
game_global_set(tx, &game)?;
Ok(game)
}
pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> { pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let mut player = player_get(tx, account.id, params.instance_id)?; let mut player = player_get(tx, account.id, params.instance_id)?;
if params.instance_id == Uuid::nil() {
return instance_ready_global(tx, account, player);
}
let mut instance = instance_get(tx, params.instance_id)?; let mut instance = instance_get(tx, params.instance_id)?;
let game_id = instance.current_round(&player).game_id; let game_id = instance.current_round(&player).game_id;

View File

@ -30,7 +30,7 @@ mod instance;
mod player; mod player;
// mod zone; // mod zone;
mod mob; mod mob;
mod util;
mod vbox; mod vbox;
use dotenv::dotenv; use dotenv::dotenv;

View File

@ -18,6 +18,7 @@ static DB_POOL_SIZE: u32 = 20;
pub type Db = PooledConnection<PostgresConnectionManager>; pub type Db = PooledConnection<PostgresConnectionManager>;
use rpc::{Rpc}; use rpc::{Rpc};
use util::{startup};
// struct Server { // struct Server {
// client: WebSocket<TcpStream>, // client: WebSocket<TcpStream>,
@ -62,6 +63,11 @@ pub fn start() {
let pool = db_connection(database_url); let pool = db_connection(database_url);
{
let startup_connection = pool.get().expect("unable to get db connection");
startup(startup_connection).unwrap();
}
let server = TcpListener::bind("0.0.0.0:40000").unwrap(); let server = TcpListener::bind("0.0.0.0:40000").unwrap();
for stream in server.incoming() { for stream in server.incoming() {
let db = pool.clone(); let db = pool.clone();

View File

@ -98,7 +98,7 @@ impl Rpc {
}, },
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
Err(err_msg("invalid message")) Err(err_msg("unknown error"))
}, },
} }
} }

21
server/src/util.rs Normal file
View File

@ -0,0 +1,21 @@
use net::Db;
// Db Commons
use failure::Error;
use game::{game_global_startup};
pub fn startup(db: Db) -> Result<(), Error> {
let mut tx = db.transaction()?;
println!("running startup fns");
game_global_startup(&mut tx)?;
match tx.commit() {
Ok(_) => {
println!("startup processes completed");
Ok(())
},
Err(e) => Err(format_err!("failed to commit startup tx {:?}", e)),
}
}