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
await knex('instances').insert({
id: NULL_UUID,

View File

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

View File

@ -82,7 +82,6 @@ pub struct Game {
pub team_size: usize,
pub team_num: usize,
pub teams: Vec<Team>,
pub is_pve: bool,
pub phase: Phase,
pub stack: Vec<Cast>,
pub resolved: Vec<Cast>,
@ -98,7 +97,6 @@ impl Game {
team_size: 0,
team_num: 0,
teams: vec![],
is_pve: true,
phase: Phase::Start,
stack: vec![],
resolved: vec![],
@ -118,11 +116,6 @@ impl Game {
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 {
self.instance = Some(id);
self
@ -133,6 +126,10 @@ impl Game {
self
}
pub fn joinable(&self) -> bool {
self.can_start()
}
pub fn team_add(&mut self, team: Team) -> Result<&mut Game, Error> {
if self.teams.len() == self.team_num {
return Err(err_msg("maximum number of teams"));
@ -142,6 +139,10 @@ impl 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(", ");
self.log.push(format!("{:} has joined the game.", team_description));
@ -211,11 +212,9 @@ impl Game {
self.stack.clear();
if self.is_pve {
self.pve_add_skills();
if self.skill_phase_finished() {
self.resolve_phase_start();
}
self.pve_add_skills();
if self.skill_phase_finished() {
self.resolve_phase_start();
}
self
@ -261,7 +260,6 @@ impl Game {
};
}
}
self
}
@ -651,6 +649,81 @@ pub fn game_get(tx: &mut Transaction, id: Uuid) -> Result<Game, Error> {
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> {
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 game_id = game.id;
// game
// .set_pve(true)
// game;
// .set_team_num(2)
// .set_team_size(cryps.len())
// .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
.set_pve(false)
.set_team_num(2)
.set_team_size(3)
.set_instance(player.instance)
@ -761,6 +832,8 @@ pub fn game_instance_join(tx: &mut Transaction, player: Player, game_id: Uuid) -
game.start();
}
println!("{:?} game joined", game.id);
game_update(&game, tx)?;
Ok(game)
@ -800,8 +873,7 @@ mod tests {
game
.set_team_num(2)
.set_team_size(1)
.set_pve(false);
.set_team_size(1);
let x_team_id = Uuid::new_v4();
let mut x_team = Team::new(x_team_id);
@ -849,8 +921,7 @@ mod tests {
game
.set_team_num(2)
.set_team_size(2)
.set_pve(false);
.set_team_size(2);
let i_team_id = Uuid::new_v4();
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 cryp::{Cryp, cryp_get};
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)]
enum InstancePhase {
@ -112,7 +112,6 @@ impl Instance {
let mut game = Game::new();
game.id = current_round.game_id;
game
.set_pve(true)
.set_team_num(2)
.set_team_size(3)
.set_instance(self.id);
@ -219,7 +218,6 @@ impl Instance {
let mut game = Game::new();
game
.set_pve(true)
.set_team_num(2)
.set_team_size(3);
@ -416,9 +414,34 @@ pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account:
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> {
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 game_id = instance.current_round(&player).game_id;

View File

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

View File

@ -18,6 +18,7 @@ static DB_POOL_SIZE: u32 = 20;
pub type Db = PooledConnection<PostgresConnectionManager>;
use rpc::{Rpc};
use util::{startup};
// struct Server {
// client: WebSocket<TcpStream>,
@ -62,6 +63,11 @@ pub fn start() {
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();
for stream in server.incoming() {
let db = pool.clone();

View File

@ -98,7 +98,7 @@ impl Rpc {
},
Err(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)),
}
}