Merge branch 'instances'
This commit is contained in:
commit
a76543b456
@ -160,7 +160,7 @@ class ItemList extends Phaser.Scene {
|
||||
.rectangle(WIDTH * 0.01, Y + HEIGHT * 0.775, ITEM_WIDTH * 1.25, ITEM_HEIGHT * 1.25, 0x222222)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => this.registry.get('ws').sendVboxDiscard(vbox.game));
|
||||
.on('pointerdown', () => this.registry.get('ws').sendVboxDiscard(vbox.instance));
|
||||
this.add.text(reroll.getCenter().x, reroll.getCenter().y, 'Reroll', TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
@ -169,7 +169,7 @@ class ItemList extends Phaser.Scene {
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => {
|
||||
ws.sendVboxCombine(vbox.game, this.combinerItems);
|
||||
ws.sendVboxCombine(vbox.instance, this.combinerItems);
|
||||
this.combinerItems = [-1, -1, -1];
|
||||
this.children.list.filter(obj => obj instanceof CombinerHitBox).forEach(cBox => cBox.deallocate());
|
||||
});
|
||||
@ -201,7 +201,7 @@ class ItemList extends Phaser.Scene {
|
||||
itemBox
|
||||
.setInteractive()
|
||||
.on('pointerdown', () => {
|
||||
ws.sendVboxAccept(vbox.game, i);
|
||||
ws.sendVboxAccept(vbox.instance, i);
|
||||
});
|
||||
this.add.existing(itemBox);
|
||||
});
|
||||
@ -277,8 +277,8 @@ class ItemList extends Phaser.Scene {
|
||||
return true;
|
||||
}
|
||||
// Allocate to cryp hitbox
|
||||
if (hitBox instanceof DeleteHitBox) ws.sendVboxDrop(vbox.game, item.index);
|
||||
else ws.sendVboxApply(vbox.game, hitBox.cryp.id, item.index);
|
||||
if (hitBox instanceof DeleteHitBox) ws.sendVboxDrop(vbox.instance, item.index);
|
||||
else ws.sendVboxApply(vbox.instance, hitBox.cryp.id, item.index);
|
||||
}
|
||||
// If the item hasn't been allocated deallocate the item
|
||||
// Scene will restart if there is vbox change
|
||||
|
||||
@ -38,7 +38,7 @@ class Menu extends Phaser.Scene {
|
||||
|
||||
// When we load the menu request the latest items
|
||||
// Item list will restart when the data comes in
|
||||
this.registry.get('ws').sendVboxState(NULL_UUID);
|
||||
this.registry.get('ws').sendPlayerState(NULL_UUID);
|
||||
|
||||
this.scene.manager.add('MenuCrypList', MenuCrypList, true);
|
||||
this.scene.manager.add('MenuNavigation', MenuNavigation, true);
|
||||
|
||||
@ -85,29 +85,29 @@ function createSocket(events) {
|
||||
send({ method: 'cryp_unspec', params: { id, spec } });
|
||||
}
|
||||
|
||||
function sendVboxState(gameId) {
|
||||
send({ method: 'vbox_state', params: { game_id: gameId } });
|
||||
function sendPlayerState(instanceId) {
|
||||
send({ method: 'player_state', params: { instance_id: instanceId } });
|
||||
}
|
||||
|
||||
function sendVboxAccept(gameId, i) {
|
||||
send({ method: 'vbox_accept', params: { game_id: gameId, index: i } });
|
||||
function sendVboxAccept(instanceId, i) {
|
||||
send({ method: 'player_vbox_accept', params: { instance_id: instanceId, index: i } });
|
||||
}
|
||||
|
||||
function sendVboxApply(gameId, crypId, index) {
|
||||
send({ method: 'vbox_apply', params: { game_id: gameId, cryp_id: crypId, index } });
|
||||
function sendVboxApply(instanceId, crypId, index) {
|
||||
send({ method: 'player_vbox_apply', params: { instance_id: instanceId, cryp_id: crypId, index } });
|
||||
}
|
||||
|
||||
function sendVboxDiscard(gameId) {
|
||||
send({ method: 'vbox_discard', params: { game_id: gameId } });
|
||||
function sendVboxDiscard(instanceId) {
|
||||
send({ method: 'player_vbox_discard', params: { instance_id: instanceId } });
|
||||
}
|
||||
|
||||
function sendVboxCombine(gameId, indices) {
|
||||
send({ method: 'vbox_combine', params: { game_id: gameId, indices } });
|
||||
function sendVboxCombine(instanceId, indices) {
|
||||
send({ method: 'player_vbox_combine', params: { instance_id: instanceId, indices } });
|
||||
}
|
||||
|
||||
|
||||
function sendVboxDrop(gameId, index) {
|
||||
send({ method: 'vbox_drop', params: { game_id: gameId, index } });
|
||||
function sendVboxDrop(instanceId, index) {
|
||||
send({ method: 'player_vbox_drop', params: { instance_id: instanceId, index } });
|
||||
}
|
||||
|
||||
|
||||
@ -185,10 +185,9 @@ function createSocket(events) {
|
||||
events.setZone(zone);
|
||||
}
|
||||
|
||||
function vboxState(response) {
|
||||
const [structName, vbox] = response;
|
||||
console.log(vbox);
|
||||
events.setVbox(vbox);
|
||||
function playerState(response) {
|
||||
const [structName, player] = response;
|
||||
events.setVbox(player.vbox);
|
||||
}
|
||||
|
||||
// -------------
|
||||
@ -210,7 +209,7 @@ function createSocket(events) {
|
||||
zone_create: res => console.log(res),
|
||||
zone_state: zoneState,
|
||||
zone_close: res => console.log(res),
|
||||
vbox_state: vboxState,
|
||||
player_state: playerState,
|
||||
};
|
||||
|
||||
function errHandler(error) {
|
||||
@ -301,7 +300,7 @@ function createSocket(events) {
|
||||
sendZoneCreate,
|
||||
sendZoneJoin,
|
||||
sendZoneClose,
|
||||
sendVboxState,
|
||||
sendPlayerState,
|
||||
sendVboxAccept,
|
||||
sendVboxApply,
|
||||
sendVboxDrop,
|
||||
|
||||
@ -1,35 +1,60 @@
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
exports.up = async knex => {
|
||||
await knex.schema.createTable('games', table => {
|
||||
table.uuid('id').primary();
|
||||
table.index('id');
|
||||
table.timestamps();
|
||||
table.binary('data').notNullable();
|
||||
});
|
||||
|
||||
await knex.schema.createTable('instances', async table => {
|
||||
table.uuid('id').primary();
|
||||
table.index('id');
|
||||
table.timestamps();
|
||||
|
||||
table.binary('data').notNullable();
|
||||
table.boolean('joinable')
|
||||
.defaultTo(true)
|
||||
.notNullable();
|
||||
table.boolean('open')
|
||||
.defaultTo(true)
|
||||
.notNullable();
|
||||
});
|
||||
|
||||
await knex.schema.raw(
|
||||
// eslint-disable-next-line max-len
|
||||
'CREATE UNIQUE INDEX instances_open ON instances (open) WHERE open = true;'
|
||||
);
|
||||
|
||||
|
||||
await knex.schema.createTable('players', table => {
|
||||
table.uuid('id').primary();
|
||||
table.index('id');
|
||||
table.binary('data').notNullable();
|
||||
|
||||
// the game itself
|
||||
table.uuid('game').notNullable()
|
||||
table.foreign('game')
|
||||
.references('id')
|
||||
.inTable('games')
|
||||
.onDelete('CASCADE');
|
||||
table.index('game');
|
||||
// the instance
|
||||
table.uuid('instance').notNullable()
|
||||
table.foreign('instance')
|
||||
.references('id')
|
||||
.inTable('instances')
|
||||
.onDelete('CASCADE');
|
||||
table.index('instance');
|
||||
|
||||
// account in a game
|
||||
table.uuid('account').notNullable()
|
||||
table.foreign('account')
|
||||
.references('id')
|
||||
.inTable('accounts')
|
||||
.onDelete('CASCADE');
|
||||
.references('id')
|
||||
.inTable('accounts')
|
||||
.onDelete('CASCADE');
|
||||
table.index('account');
|
||||
|
||||
table.unique(['account', 'instance']);
|
||||
|
||||
});
|
||||
|
||||
// not really sure if this is a good idea
|
||||
await knex('instances').insert({
|
||||
id: NULL_UUID,
|
||||
data: 'INVALID',
|
||||
open: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
exports.up = async knex => {
|
||||
await knex.schema.createTable('vbox', table => {
|
||||
table.timestamps();
|
||||
table.uuid('id').primary();
|
||||
table.uuid('account').notNullable()
|
||||
table.uuid('game').notNullable()
|
||||
table.binary('data').notNullable();
|
||||
|
||||
table.foreign('game')
|
||||
.references('id')
|
||||
.inTable('games')
|
||||
.onDelete('CASCADE');
|
||||
|
||||
table.foreign('account')
|
||||
.references('id')
|
||||
.inTable('accounts')
|
||||
.onDelete('CASCADE');
|
||||
|
||||
table.index('id');
|
||||
table.index('account');
|
||||
table.unique(['account', 'game']);
|
||||
});
|
||||
|
||||
// not really sure if this is a good idea
|
||||
await knex('games').insert({
|
||||
id: NULL_UUID,
|
||||
data: 'INVALID',
|
||||
joinable: false,
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.down = async () => {};
|
||||
@ -1,30 +1,3 @@
|
||||
# Principles
|
||||
* Experience something
|
||||
* Express something
|
||||
* Prove something
|
||||
|
||||
* 1: Fighting against human nature is a losing game
|
||||
* 2: Aesthetics matter
|
||||
* 3: Resonance is important
|
||||
* 4: Make use of piggybacking
|
||||
* 5: Don't confuse "interesting" with "fun"
|
||||
* 6: Understand what emotion your game is trying to evoke
|
||||
* 7: Allow the players the skill to make the game personal
|
||||
* 8: The details are where the players fall in love with your game
|
||||
* 9: Allow your players to have a sense of ownership
|
||||
* 10: Leave room for the player to explore
|
||||
* 11: If everyone likes your game, but no one loves it, it will fail
|
||||
* 12: Don't design to prove you can do something
|
||||
* 13: Make the fun part also the correct strategy to win
|
||||
* 14: Don't be afraid to be blunt
|
||||
* 15: Design the component for its intended audience
|
||||
* 16: Be more afraid of boring your players than challenging them
|
||||
* 17: You don't have to change much to change everything
|
||||
* 18: Restrictions breed creativity
|
||||
* 19: Your audience is good at recognizing problems and bad at solving them
|
||||
* 20: All the lessons connect
|
||||
|
||||
|
||||
# Key Mechanics
|
||||
* 10d chaos maths, not rock paper scissors
|
||||
* phys is faster and chaotic
|
||||
@ -33,28 +6,13 @@
|
||||
* red_shield is restored, not gained
|
||||
* players can feel aggressive
|
||||
|
||||
# ask sam
|
||||
* main screen layout
|
||||
* ping icon
|
||||
*
|
||||
* combat screen layout
|
||||
* health bars
|
||||
* statuses
|
||||
* icons
|
||||
* skill type / damage type
|
||||
* skills themselves
|
||||
* passive nodes / notables
|
||||
|
||||
* tell him about discord
|
||||
|
||||
# WORK WORK
|
||||
|
||||
broken skills
|
||||
strangle
|
||||
taunt
|
||||
|
||||
|
||||
## NOW
|
||||
cost system for items
|
||||
design / implement specs
|
||||
combo specs
|
||||
round system for games
|
||||
|
||||
## SOON
|
||||
* clean up categories
|
||||
@ -119,3 +77,29 @@ gem td style attr combinations
|
||||
|
||||
slimey
|
||||
ghostly
|
||||
|
||||
# Principles
|
||||
* Experience something
|
||||
* Express something
|
||||
* Prove something
|
||||
|
||||
* 1: Fighting against human nature is a losing game
|
||||
* 2: Aesthetics matter
|
||||
* 3: Resonance is important
|
||||
* 4: Make use of piggybacking
|
||||
* 5: Don't confuse "interesting" with "fun"
|
||||
* 6: Understand what emotion your game is trying to evoke
|
||||
* 7: Allow the players the skill to make the game personal
|
||||
* 8: The details are where the players fall in love with your game
|
||||
* 9: Allow your players to have a sense of ownership
|
||||
* 10: Leave room for the player to explore
|
||||
* 11: If everyone likes your game, but no one loves it, it will fail
|
||||
* 12: Don't design to prove you can do something
|
||||
* 13: Make the fun part also the correct strategy to win
|
||||
* 14: Don't be afraid to be blunt
|
||||
* 15: Design the component for its intended audience
|
||||
* 16: Be more afraid of boring your players than challenging them
|
||||
* 17: You don't have to change much to change everything
|
||||
* 18: Restrictions breed creativity
|
||||
* 19: Your audience is good at recognizing problems and bad at solving them
|
||||
* 20: All the lessons connect
|
||||
|
||||
@ -8,7 +8,7 @@ use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use account::Account;
|
||||
use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameJoinParams};
|
||||
use rpc::{GameStateParams, GameSkillParams, GamePveParams};
|
||||
use cryp::{Cryp, cryp_get};
|
||||
use skill::{Skill, Cast, ResolutionResult};
|
||||
use zone::{node_finish};
|
||||
@ -648,26 +648,6 @@ pub fn game_get(tx: &mut Transaction, id: Uuid) -> Result<Game, Error> {
|
||||
return Ok(game);
|
||||
}
|
||||
|
||||
pub fn players_write(account: &Account, game_id: Uuid, tx: &mut Transaction) -> Result<(), Error> {
|
||||
// pve
|
||||
let id = Uuid::new_v4();
|
||||
|
||||
let query = "
|
||||
INSERT INTO players (id, game, account)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, account;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&id, &game_id, &account.id])?;
|
||||
|
||||
let _returned = result.iter().next().expect("no row written");
|
||||
|
||||
println!("wrote player {:} joined game: {:}", account.name, game_id);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
|
||||
let game_bytes = to_vec(&game)?;
|
||||
|
||||
@ -745,94 +725,6 @@ pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account)
|
||||
Ok(game)
|
||||
}
|
||||
|
||||
pub fn game_pvp(params: GamePvpParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
||||
let cryps = params.cryp_ids
|
||||
.iter()
|
||||
.map(|id| cryp_get(tx, *id, account.id))
|
||||
.collect::<Result<Vec<Cryp>, Error>>()?;
|
||||
|
||||
// create the game
|
||||
let mut game = Game::new();
|
||||
let game_id = game.id;
|
||||
|
||||
game
|
||||
.set_pve(false)
|
||||
.set_team_num(2)
|
||||
.set_team_size(cryps.len())
|
||||
.set_mode(GameMode::Pvp);
|
||||
|
||||
// create the initiators team
|
||||
let mut team = Team::new(account.id);
|
||||
team.set_cryps(cryps);
|
||||
|
||||
game.team_add(team)?;
|
||||
|
||||
// persist
|
||||
game_write(&game, tx)?;
|
||||
players_write(account, game_id, tx)?;
|
||||
|
||||
Ok(game)
|
||||
}
|
||||
|
||||
pub fn game_join(params: GameJoinParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
||||
let mut game = game_get(tx, params.game_id)?;
|
||||
|
||||
// rejoining a game from the FE list
|
||||
if game.already_joined(account.id) {
|
||||
return Ok(game);
|
||||
}
|
||||
|
||||
// ok actually adding a new team
|
||||
let game_id = game.id;
|
||||
|
||||
let cryps = params.cryp_ids
|
||||
.iter()
|
||||
.map(|id| cryp_get(tx, *id, account.id))
|
||||
.collect::<Result<Vec<Cryp>, Error>>()?;
|
||||
|
||||
if cryps.len() != game.team_size {
|
||||
return Err(format_err!("incorrect team size. ({:})", game.team_size));
|
||||
}
|
||||
|
||||
let mut team = Team::new(account.id);
|
||||
team.set_cryps(cryps);
|
||||
game.team_add(team)?;
|
||||
|
||||
if game.can_start() {
|
||||
game.start();
|
||||
}
|
||||
|
||||
game_update(&game, tx)?;
|
||||
players_write(account, game_id, tx)?;
|
||||
|
||||
Ok(game)
|
||||
}
|
||||
|
||||
pub fn game_joinable_list(tx: &mut Transaction, _account: &Account) -> Result<Vec<Game>, Error> {
|
||||
let query = "
|
||||
SELECT games.data
|
||||
FROM games
|
||||
WHERE joinable;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[])?;
|
||||
|
||||
let games: Result<Vec<Game>, _> = result.iter().map(|row| {
|
||||
let cryp_bytes: Vec<u8> = row.get(0);
|
||||
from_slice::<Game>(&cryp_bytes)
|
||||
}).collect();
|
||||
|
||||
// catch any errors
|
||||
if games.is_err() {
|
||||
return Err(err_msg("could not deserialize a game"));
|
||||
}
|
||||
|
||||
// now unwrap is safe
|
||||
return Ok(games.unwrap());
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use game::*;
|
||||
|
||||
149
server/src/instance.rs
Normal file
149
server/src/instance.rs
Normal file
@ -0,0 +1,149 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
use serde_cbor::{from_slice, to_vec};
|
||||
|
||||
use postgres::transaction::Transaction;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use rpc::{InstanceJoinParams};
|
||||
use account::Account;
|
||||
use player::{Player, player_create};
|
||||
use cryp::{Cryp, cryp_get};
|
||||
|
||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||
enum InstancePhase {
|
||||
Open,
|
||||
Vbox,
|
||||
Combat,
|
||||
Finished,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct Instance {
|
||||
id: Uuid,
|
||||
players: Vec<Uuid>,
|
||||
phase: InstancePhase,
|
||||
open: bool,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
fn new() -> Instance {
|
||||
Instance {
|
||||
id: Uuid::new_v4(),
|
||||
players: vec![],
|
||||
phase: InstancePhase::Open,
|
||||
open: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_player(&mut self, player: &Player) -> &mut Instance {
|
||||
self.players.push(player.id);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instance_create(instance: Instance, tx: &mut Transaction) -> Result<Instance, Error> {
|
||||
let instance_bytes = to_vec(&instance)?;
|
||||
|
||||
let query = "
|
||||
INSERT INTO instances (id, data)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&instance.id, &instance_bytes])?;
|
||||
|
||||
result.iter().next().ok_or(format_err!("no instances written"))?;
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
pub fn instance_write(instance: Instance, tx: &mut Transaction) -> Result<Instance, Error> {
|
||||
let instance_bytes = to_vec(&instance)?;
|
||||
|
||||
let query = "
|
||||
UPDATE instance
|
||||
SET data = $1
|
||||
WHERE id = $2
|
||||
RETURNING id, data;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&instance_bytes, &instance.id])?;
|
||||
|
||||
result.iter().next().ok_or(err_msg("no instance row returned"))?;
|
||||
|
||||
// println!("{:?} wrote instance", instance.id);
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
pub fn instance_get(tx: &mut Transaction, instance_id: Uuid) -> Result<Instance, Error> {
|
||||
let query = "
|
||||
SELECT *
|
||||
FROM instance
|
||||
WHERE id = $1;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&instance_id])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
None => return Err(err_msg("instance not found")),
|
||||
};
|
||||
|
||||
let instance_bytes: Vec<u8> = returned.get("data");
|
||||
let instance = from_slice::<Instance>(&instance_bytes)?;
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
pub fn instance_get_open(tx: &mut Transaction) -> Result<Instance, Error> {
|
||||
let query = "
|
||||
SELECT *
|
||||
FROM instance
|
||||
AND open = true;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
None => return Err(err_msg("instance not found")),
|
||||
};
|
||||
|
||||
let instance_bytes: Vec<u8> = returned.get("data");
|
||||
let instance = from_slice::<Instance>(&instance_bytes)?;
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
|
||||
pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut instance = match instance_get_open(tx) {
|
||||
Ok(i) => i,
|
||||
Err(_) => instance_create(Instance::new(), tx)?,
|
||||
};
|
||||
|
||||
let cryps = params.cryp_ids
|
||||
.iter()
|
||||
.map(|id| cryp_get(tx, *id, account.id))
|
||||
.collect::<Result<Vec<Cryp>, Error>>()?;
|
||||
|
||||
if cryps.len() != 3 {
|
||||
return Err(format_err!("incorrect team size. ({:})", 3));
|
||||
}
|
||||
|
||||
let player = Player::new(account.id, instance.id, cryps);
|
||||
instance.add_player(&player);
|
||||
|
||||
player_create(tx, &player, account)?;
|
||||
instance_write(instance, tx)?;
|
||||
|
||||
return Ok(player);
|
||||
}
|
||||
@ -26,7 +26,8 @@ mod spec;
|
||||
// mod passives;
|
||||
mod rpc;
|
||||
mod account;
|
||||
// mod item;
|
||||
mod instance;
|
||||
mod player;
|
||||
mod zone;
|
||||
mod mob;
|
||||
|
||||
|
||||
108
server/src/player.rs
Normal file
108
server/src/player.rs
Normal file
@ -0,0 +1,108 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
use serde_cbor::{from_slice, to_vec};
|
||||
|
||||
use postgres::transaction::Transaction;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use account::Account;
|
||||
use instance::Instance;
|
||||
use cryp::{Cryp};
|
||||
use vbox::{Vbox};
|
||||
use rpc::{PlayerStateParams};
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct Score {
|
||||
wins: u8,
|
||||
losses: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct Player {
|
||||
pub id: Uuid,
|
||||
pub instance: Uuid,
|
||||
pub account: Uuid,
|
||||
// name: String,
|
||||
pub vbox: Vbox,
|
||||
pub score: Score,
|
||||
pub cryps: Vec<Cryp>,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn new(account: Uuid, instance: Uuid, cryps: Vec<Cryp>) -> Player {
|
||||
Player {
|
||||
id: Uuid::new_v4(),
|
||||
account,
|
||||
instance,
|
||||
vbox: Vbox::new(account, instance),
|
||||
score: Score { wins: 0, losses: 0 },
|
||||
cryps,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn player_get(tx: &mut Transaction, account_id: Uuid, instance_id: Uuid) -> Result<Player, Error> {
|
||||
let query = "
|
||||
SELECT *
|
||||
FROM players
|
||||
WHERE account = $1
|
||||
AND instance = $2;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&account_id, &instance_id])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
None => return Err(err_msg("player not found")),
|
||||
};
|
||||
|
||||
// tells from_slice to cast into a cryp
|
||||
let bytes: Vec<u8> = returned.get("data");
|
||||
let data = from_slice::<Player>(&bytes)?;
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
pub fn player_create(tx: &mut Transaction, player: &Player, account: &Account) -> Result<(), Error> {
|
||||
let player_bytes = to_vec(&player)?;
|
||||
|
||||
let query = "
|
||||
INSERT INTO players (id, instance, account, data)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, account;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&player.id, &player.instance, &account.id, &player_bytes])?;
|
||||
|
||||
let _returned = result.iter().next().expect("no row written");
|
||||
|
||||
println!("wrote player {:} joined instance: {:}", account.name, player.instance);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn player_update(tx: &mut Transaction, player: Player) -> Result<Player, Error> {
|
||||
let bytes = to_vec(&player)?;
|
||||
|
||||
let query = "
|
||||
UPDATE players
|
||||
SET data = $1
|
||||
WHERE id = $2
|
||||
RETURNING id, data;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&bytes, &player.id])?;
|
||||
|
||||
result.iter().next().ok_or(format_err!("player {:?} could not be written", player))?;
|
||||
|
||||
return Ok(player)
|
||||
}
|
||||
|
||||
pub fn player_state(params: PlayerStateParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
player_get(tx, account.id, params.instance_id)
|
||||
}
|
||||
@ -15,13 +15,15 @@ use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use net::Db;
|
||||
use cryp::{Cryp, cryp_spawn, cryp_learn, cryp_forget, cryp_unspec};
|
||||
use game::{Game, game_state, game_pve, game_pvp, game_join, game_joinable_list, game_skill};
|
||||
use cryp::{Cryp, cryp_spawn, cryp_learn};
|
||||
use game::{Game, game_state, game_pve, game_skill};
|
||||
use account::{Account, account_create, account_login, account_from_token, account_cryps, account_zone};
|
||||
use skill::{Skill};
|
||||
use zone::{Zone, zone_create, zone_join, zone_close};
|
||||
use spec::{Spec};
|
||||
use vbox::{Vbox, vbox_state, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_drop};
|
||||
use player::{player_state, player_create, Player};
|
||||
use instance::{instance_join};
|
||||
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_drop};
|
||||
|
||||
pub struct Rpc;
|
||||
|
||||
@ -61,29 +63,26 @@ impl Rpc {
|
||||
"account_demo" => Rpc::account_demo(data, &mut tx, client),
|
||||
|
||||
// auth methods
|
||||
"cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account.unwrap(), client),
|
||||
"cryp_learn" => Rpc::cryp_learn(data, &mut tx, account.unwrap(), client),
|
||||
"cryp_forget" => Rpc::cryp_forget(data, &mut tx, account.unwrap(), client),
|
||||
"cryp_unspec" => Rpc::cryp_unspec(data, &mut tx, account.unwrap(), client),
|
||||
"game_state" => Rpc::game_state(data, &mut tx, account.unwrap(), client),
|
||||
"game_pve" => Rpc::game_pve(data, &mut tx, account.unwrap(), client),
|
||||
"game_pvp" => Rpc::game_pvp(data, &mut tx, account.unwrap(), client),
|
||||
"game_join" => Rpc::game_join(data, &mut tx, account.unwrap(), client),
|
||||
"game_joinable_list" => Rpc::game_joinable_list(data, &mut tx, account.unwrap(), client),
|
||||
"game_skill" => Rpc::game_skill(data, &mut tx, account.unwrap(), client),
|
||||
// "game_target" => Rpc::game_target(data, &mut tx, account.unwrap(), client),
|
||||
"zone_create" => Rpc::zone_create(data, &mut tx, account.unwrap(), client),
|
||||
"zone_join" => Rpc::zone_join(data, &mut tx, account.unwrap(), client),
|
||||
"zone_close" => Rpc::zone_close(data, &mut tx, account.unwrap(), client),
|
||||
"account_cryps" => Rpc::account_cryps(data, &mut tx, account.unwrap(), client),
|
||||
"account_zone" => Rpc::account_zone(data, &mut tx, account.unwrap(), client),
|
||||
|
||||
"vbox_state" => Rpc::vbox_state(data, &mut tx, account.unwrap(), client),
|
||||
"vbox_accept" => Rpc::vbox_accept(data, &mut tx, account.unwrap(), client),
|
||||
"vbox_apply" => Rpc::vbox_apply(data, &mut tx, account.unwrap(), client),
|
||||
"vbox_drop" => Rpc::vbox_drop(data, &mut tx, account.unwrap(), client),
|
||||
"vbox_combine" => Rpc::vbox_combine(data, &mut tx, account.unwrap(), client),
|
||||
"vbox_discard" => Rpc::vbox_discard(data, &mut tx, account.unwrap(), client),
|
||||
"cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account.unwrap(), client),
|
||||
|
||||
"game_state" => Rpc::game_state(data, &mut tx, account.unwrap(), client),
|
||||
"game_pve" => Rpc::game_pve(data, &mut tx, account.unwrap(), client),
|
||||
"game_skill" => Rpc::game_skill(data, &mut tx, account.unwrap(), client),
|
||||
|
||||
"zone_create" => Rpc::zone_create(data, &mut tx, account.unwrap(), client),
|
||||
"zone_join" => Rpc::zone_join(data, &mut tx, account.unwrap(), client),
|
||||
"zone_close" => Rpc::zone_close(data, &mut tx, account.unwrap(), client),
|
||||
|
||||
"instance_join" => Rpc::instance_join(data, &mut tx, account.unwrap(), client),
|
||||
"player_state" => Rpc::player_state(data, &mut tx, account.unwrap(), client),
|
||||
"player_vbox_accept" => Rpc::player_vbox_accept(data, &mut tx, account.unwrap(), client),
|
||||
"player_vbox_apply" => Rpc::player_vbox_apply(data, &mut tx, account.unwrap(), client),
|
||||
"player_vbox_drop" => Rpc::player_vbox_drop(data, &mut tx, account.unwrap(), client),
|
||||
"player_vbox_combine" => Rpc::player_vbox_combine(data, &mut tx, account.unwrap(), client),
|
||||
"player_vbox_discard" => Rpc::player_vbox_discard(data, &mut tx, account.unwrap(), client),
|
||||
|
||||
_ => Err(format_err!("unknown method - {:?}", v.method)),
|
||||
};
|
||||
@ -115,7 +114,6 @@ impl Rpc {
|
||||
return Ok(game_response);
|
||||
}
|
||||
|
||||
|
||||
fn game_pve(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<GamePveMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
@ -132,42 +130,6 @@ impl Rpc {
|
||||
return Ok(game_response);
|
||||
}
|
||||
|
||||
fn game_pvp(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<GamePvpMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let game_response = RpcResponse {
|
||||
method: "game_state".to_string(),
|
||||
params: RpcResult::GameState(game_pvp(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(game_response);
|
||||
}
|
||||
|
||||
|
||||
fn game_join(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<GameJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let game_response = RpcResponse {
|
||||
method: "game_state".to_string(),
|
||||
params: RpcResult::GameState(game_join(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(game_response);
|
||||
}
|
||||
|
||||
fn game_joinable_list(_data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
// let msg = from_slice::<GameJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let game_list = RpcResponse {
|
||||
method: "game_joinable_list".to_string(),
|
||||
params: RpcResult::GameJoinableList(game_joinable_list(tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(game_list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn game_skill(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<GameSkillMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
@ -179,17 +141,6 @@ impl Rpc {
|
||||
return Ok(game_response);
|
||||
}
|
||||
|
||||
// fn game_target(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
// let msg = from_slice::<GameTargetMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
// let game_response = RpcResponse {
|
||||
// method: "game_state".to_string(),
|
||||
// params: RpcResult::GameState(game_target(msg.params, tx, &account)?)
|
||||
// };
|
||||
|
||||
// return Ok(game_response);
|
||||
// }
|
||||
|
||||
fn cryp_spawn(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<CrypSpawnMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
@ -206,62 +157,17 @@ impl Rpc {
|
||||
Ok(cryp_list)
|
||||
}
|
||||
|
||||
fn cryp_learn(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<CrypLearnMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
Rpc::send_msg(client, RpcResponse {
|
||||
method: "cryp_learn".to_string(),
|
||||
params: RpcResult::CrypLearn(cryp_learn(msg.params, tx, &account)?)
|
||||
})?;
|
||||
|
||||
let cryp_list = RpcResponse {
|
||||
method: "account_cryps".to_string(),
|
||||
params: RpcResult::CrypList(account_cryps(tx, &account)?)
|
||||
};
|
||||
|
||||
Ok(cryp_list)
|
||||
}
|
||||
|
||||
fn cryp_forget(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<CrypForgetMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
Rpc::send_msg(client, RpcResponse {
|
||||
method: "cryp_forget".to_string(),
|
||||
params: RpcResult::CrypForget(cryp_forget(msg.params, tx, &account)?)
|
||||
})?;
|
||||
|
||||
let cryp_list = RpcResponse {
|
||||
method: "account_cryps".to_string(),
|
||||
params: RpcResult::CrypList(account_cryps(tx, &account)?)
|
||||
};
|
||||
|
||||
Ok(cryp_list)
|
||||
}
|
||||
|
||||
fn cryp_unspec(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<CrypUnspecMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
Rpc::send_msg(client, RpcResponse {
|
||||
method: "cryp_unspec".to_string(),
|
||||
params: RpcResult::CrypUnspec(cryp_unspec(msg.params, tx, &account)?)
|
||||
})?;
|
||||
|
||||
let cryp_list = RpcResponse {
|
||||
method: "account_cryps".to_string(),
|
||||
params: RpcResult::CrypList(account_cryps(tx, &account)?)
|
||||
};
|
||||
|
||||
Ok(cryp_list)
|
||||
}
|
||||
|
||||
fn account_create(data: Vec<u8>, tx: &mut Transaction, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
match from_slice::<AccountCreateMsg>(&data) {
|
||||
Ok(v) => Ok(RpcResponse {
|
||||
method: v.method,
|
||||
params: RpcResult::Account(account_create(v.params, tx)?)
|
||||
}),
|
||||
Err(_e) => Err(err_msg("invalid params")),
|
||||
}
|
||||
let msg = from_slice::<AccountCreateMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let account = account_create(msg.params, tx)?;
|
||||
let player = Player::new(account.id, Uuid::nil(), vec![]);
|
||||
player_create(tx, &player, &account)?;
|
||||
|
||||
Ok(RpcResponse {
|
||||
method: "account_create".to_string(),
|
||||
params: RpcResult::Account(account)
|
||||
})
|
||||
}
|
||||
|
||||
fn account_login(data: Vec<u8>, tx: &mut Transaction, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
@ -355,57 +261,69 @@ impl Rpc {
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn vbox_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxStateMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
fn instance_join(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<InstanceJoinMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_state(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(instance_join(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
|
||||
fn player_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<PlayerStateMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(player_state(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn player_vbox_accept(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxAcceptMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_accept(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(vbox_accept(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
fn player_vbox_discard(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxDiscardMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_discard(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(vbox_discard(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
|
||||
fn vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
fn player_vbox_combine(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxCombineMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_combine(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(vbox_combine(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
fn player_vbox_apply(data: Vec<u8>, tx: &mut Transaction, account: Account, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxApplyMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_apply(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(vbox_apply(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
Rpc::send_msg(client, RpcResponse {
|
||||
@ -416,16 +334,17 @@ impl Rpc {
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
fn vbox_drop(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
fn player_vbox_drop(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||
let msg = from_slice::<VboxDropMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||
|
||||
let response = RpcResponse {
|
||||
method: "vbox_state".to_string(),
|
||||
params: RpcResult::VboxState(vbox_drop(msg.params, tx, &account)?)
|
||||
method: "player_state".to_string(),
|
||||
params: RpcResult::PlayerState(vbox_drop(msg.params, tx, &account)?)
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
@ -447,7 +366,7 @@ pub enum RpcResult {
|
||||
ZoneState(Zone),
|
||||
ZoneClose(()),
|
||||
|
||||
VboxState(Vbox),
|
||||
PlayerState(Player),
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
@ -525,48 +444,6 @@ pub struct GamePveParams {
|
||||
pub cryp_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct GamePvpMsg {
|
||||
method: String,
|
||||
params: GamePvpParams,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct GamePvpParams {
|
||||
pub cryp_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct GameJoinMsg {
|
||||
method: String,
|
||||
params: GameJoinParams,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct GameJoinParams {
|
||||
pub game_id: Uuid,
|
||||
pub cryp_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct GameJoinableListMsg {
|
||||
method: String,
|
||||
params: (),
|
||||
}
|
||||
|
||||
// #[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
// struct GameTargetMsg {
|
||||
// method: String,
|
||||
// params: GameTargetParams,
|
||||
// }
|
||||
|
||||
// #[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
// pub struct GameTargetParams {
|
||||
// pub game_id: Uuid,
|
||||
// pub cryp_id: Uuid,
|
||||
// pub skill_id: Uuid,
|
||||
// }
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct GameSkillMsg {
|
||||
method: String,
|
||||
@ -642,14 +519,25 @@ pub struct ZoneCloseParams {
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct VboxStateMsg {
|
||||
struct InstanceJoinMsg {
|
||||
method: String,
|
||||
params: VboxStateParams,
|
||||
params: InstanceJoinParams,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxStateParams {
|
||||
pub game_id: Uuid,
|
||||
pub struct InstanceJoinParams {
|
||||
pub cryp_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
struct PlayerStateMsg {
|
||||
method: String,
|
||||
params: PlayerStateParams,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct PlayerStateParams {
|
||||
pub instance_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
@ -660,7 +548,7 @@ struct VboxAcceptMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxAcceptParams {
|
||||
pub game_id: Uuid,
|
||||
pub instance_id: Uuid,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
@ -672,7 +560,7 @@ struct VboxDiscardMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxDiscardParams {
|
||||
pub game_id: Uuid,
|
||||
pub instance_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
@ -683,7 +571,7 @@ struct VboxCombineMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxCombineParams {
|
||||
pub game_id: Uuid,
|
||||
pub instance_id: Uuid,
|
||||
pub indices: Vec<usize>,
|
||||
}
|
||||
|
||||
@ -695,7 +583,7 @@ struct VboxApplyMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxApplyParams {
|
||||
pub game_id: Uuid,
|
||||
pub instance_id: Uuid,
|
||||
pub cryp_id: Uuid,
|
||||
pub index: usize,
|
||||
}
|
||||
@ -708,7 +596,7 @@ struct VboxDropMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct VboxDropParams {
|
||||
pub game_id: Uuid,
|
||||
pub instance_id: Uuid,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
|
||||
@ -6,16 +6,15 @@ use rand::prelude::*;
|
||||
use rand::{thread_rng};
|
||||
use rand::distributions::{WeightedIndex};
|
||||
|
||||
use serde_cbor::{from_slice, to_vec};
|
||||
|
||||
use postgres::transaction::Transaction;
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use account::Account;
|
||||
use rpc::{VboxStateParams, VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxDropParams};
|
||||
use rpc::{VboxAcceptParams, VboxDiscardParams, VboxCombineParams, VboxApplyParams, VboxDropParams};
|
||||
use skill::{Skill};
|
||||
use player::{Player, player_get, player_update};
|
||||
use cryp::{cryp_get, cryp_write};
|
||||
|
||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||
@ -118,23 +117,23 @@ pub struct Vbox {
|
||||
pub balance: u16,
|
||||
pub free: Vec<Var>,
|
||||
pub bound: Vec<Var>,
|
||||
pub game: Uuid,
|
||||
pub instance: Uuid,
|
||||
pub account: Uuid,
|
||||
}
|
||||
|
||||
impl Vbox {
|
||||
pub fn new(account_id: Uuid, game_id: Uuid) -> Vbox {
|
||||
pub fn new(account_id: Uuid, instance_id: Uuid) -> Vbox {
|
||||
Vbox {
|
||||
id: Uuid::new_v4(),
|
||||
account: account_id,
|
||||
game: game_id,
|
||||
instance: instance_id,
|
||||
free: vec![],
|
||||
bound: vec![],
|
||||
balance: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill(mut self: Vbox) -> Vbox {
|
||||
pub fn fill(&mut self) -> &mut Vbox {
|
||||
let vars = vec![
|
||||
(Var::Red, 1),
|
||||
(Var::Green, 1),
|
||||
@ -277,107 +276,35 @@ impl Vbox {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vbox_create(vbox: Vbox, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let vbox_bytes = to_vec(&vbox)?;
|
||||
|
||||
let query = "
|
||||
INSERT INTO vbox (id, account, game, data)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&vbox.id, &account.id, &vbox.game, &vbox_bytes])?;
|
||||
|
||||
result.iter().next().ok_or(format_err!("no vbox written"))?;
|
||||
|
||||
// println!("{:} wrote vbox", vbox.id);
|
||||
|
||||
return Ok(vbox);
|
||||
pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||
player.vbox.fill();
|
||||
return player_update(tx, player);
|
||||
}
|
||||
|
||||
pub fn vbox_write(vbox: Vbox, tx: &mut Transaction) -> Result<Vbox, Error> {
|
||||
let vbox_bytes = to_vec(&vbox)?;
|
||||
|
||||
let query = "
|
||||
UPDATE vbox
|
||||
SET data = $1
|
||||
WHERE id = $2
|
||||
RETURNING id, account, data;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&vbox_bytes, &vbox.id])?;
|
||||
|
||||
result.iter().next().ok_or(err_msg("no vbox row returned"))?;
|
||||
|
||||
// println!("{:?} wrote vbox", vbox.id);
|
||||
|
||||
return Ok(vbox);
|
||||
pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||
player.vbox.accept(params.index)?;
|
||||
return player_update(tx, player);
|
||||
}
|
||||
|
||||
|
||||
pub fn vbox_get(tx: &mut Transaction, game_id: Uuid, account: &Account) -> Result<Vbox, Error> {
|
||||
let query = "
|
||||
SELECT *
|
||||
FROM vbox
|
||||
WHERE account = $1
|
||||
AND game = $2;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&account.id, &game_id])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
None => return Err(err_msg("vbox not found")),
|
||||
};
|
||||
|
||||
// tells from_slice to cast into a cryp
|
||||
let vbox_bytes: Vec<u8> = returned.get("data");
|
||||
let vbox = from_slice::<Vbox>(&vbox_bytes)?;
|
||||
|
||||
return Ok(vbox);
|
||||
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||
player.vbox.combine(params.indices)?;
|
||||
return player_update(tx, player);
|
||||
}
|
||||
|
||||
pub fn vbox_state(params: VboxStateParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
match vbox_get(tx, params.game_id, account) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => {
|
||||
println!("{:?}", e);
|
||||
vbox_create(Vbox::new(account.id, params.game_id).fill(), tx, account)
|
||||
}
|
||||
}
|
||||
pub fn vbox_drop(params: VboxDropParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||
player.vbox.drop(params.index)?;
|
||||
return player_update(tx, player);
|
||||
}
|
||||
|
||||
pub fn vbox_discard(params: VboxDiscardParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let vbox = vbox_get(tx, params.game_id, account)?;
|
||||
return vbox_write(vbox.fill(), tx);
|
||||
}
|
||||
|
||||
pub fn vbox_accept(params: VboxAcceptParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let mut vbox = vbox_get(tx, params.game_id, account)?;
|
||||
vbox.accept(params.index)?;
|
||||
return vbox_write(vbox, tx);
|
||||
}
|
||||
|
||||
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let mut vbox = vbox_get(tx, params.game_id, account)?;
|
||||
vbox.combine(params.indices)?;
|
||||
return vbox_write(vbox, tx);
|
||||
}
|
||||
|
||||
pub fn vbox_drop(params: VboxDropParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let mut vbox = vbox_get(tx, params.game_id, account)?;
|
||||
vbox.drop(params.index)?;
|
||||
return vbox_write(vbox, tx);
|
||||
}
|
||||
|
||||
pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
|
||||
let mut vbox = vbox_get(tx, params.game_id, account)?;
|
||||
pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
|
||||
let mut player = player_get(tx, account.id, params.instance_id)?;
|
||||
let mut cryp = cryp_get(tx, params.cryp_id, account.id)?;
|
||||
|
||||
let var = vbox.bound.remove(params.index);
|
||||
let var = player.vbox.bound.remove(params.index);
|
||||
|
||||
// done here because i teach them a tonne of skills for tests
|
||||
let max_skills = 4;
|
||||
@ -388,7 +315,7 @@ pub fn vbox_apply(params: VboxApplyParams, tx: &mut Transaction, account: &Accou
|
||||
let skill = var.skill()?;
|
||||
cryp = cryp.learn(skill);
|
||||
cryp_write(cryp, tx)?;
|
||||
return vbox_write(vbox, tx);
|
||||
return player_update(tx, player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user