vbox init

This commit is contained in:
ntr 2019-02-16 17:45:28 +11:00
parent 8f12075d52
commit d0525a56bd
11 changed files with 241 additions and 40 deletions

View File

@ -29,7 +29,7 @@ function renderCryps() {
},
},
scene: [
Background,
// Background,
Header,
],
};

View File

@ -25,6 +25,7 @@ const MAIN_MENU_SCENES = [
'ItemInfo',
];
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
class Menu extends Phaser.Scene {
constructor() {
@ -37,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').sendAccountItems();
this.registry.get('ws').sendVboxState(NULL_UUID);
this.scene.manager.add('MenuCrypList', MenuCrypList, true);
this.scene.manager.add('MenuNavigation', MenuNavigation, true);

View File

@ -1,6 +1,7 @@
const toast = require('izitoast');
const cbor = require('borc');
const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://cryps.gg/ws' : 'ws://localhost:40000';
function errorToast(err) {
@ -44,10 +45,6 @@ function createSocket(events) {
send({ method: 'account_cryps', params: {} });
}
function sendAccountItems() {
send({ method: 'account_items', params: {} });
}
function sendAccountZone() {
send({ method: 'account_zone', params: {} });
}
@ -88,6 +85,10 @@ function createSocket(events) {
send({ method: 'cryp_unspec', params: { id, spec } });
}
function sendVboxState(gameId) {
send({ method: 'vbox_state', params: { game_id: gameId } });
}
function sendPressR() {
send({ method: 'press_r', params: { } });
@ -162,11 +163,6 @@ function createSocket(events) {
const [structName, game] = response;
}
function accountItems(response) {
const [structName, items] = response;
events.setItems(items);
}
function zoneState(response) {
const [structName, zone] = response;
events.setZone(zone);
@ -188,7 +184,6 @@ function createSocket(events) {
account_login: accountLogin,
account_create: accountLogin,
account_cryps: accountCryps,
account_items: accountItems,
zone_create: res => console.log(res),
zone_state: zoneState,
zone_close: res => console.log(res),
@ -268,7 +263,6 @@ function createSocket(events) {
sendAccountCreate,
sendAccountDemo,
sendAccountCryps,
sendAccountItems,
sendAccountZone,
sendGameState,
sendGamePve,
@ -285,6 +279,7 @@ function createSocket(events) {
sendZoneCreate,
sendZoneJoin,
sendZoneClose,
sendVboxState,
connect,
};
}

View File

@ -1,15 +0,0 @@
exports.up = async knex => {
return knex.schema.createTable('items', table => {
table.uuid('id').primary();
table.uuid('account').notNullable()
table.foreign('account')
.references('id')
.inTable('accounts')
.onDelete('CASCADE');
table.binary('data').notNullable();
table.index('id');
table.index('account');
});
};
exports.down = async () => {};

View File

@ -0,0 +1,36 @@
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 () => {};

View File

@ -11,9 +11,6 @@
"author": "",
"license": "UNLICENSED",
"dependencies": {
"ascii-tree": "^0.3.0",
"cli-ascii-tree": "0.0.4",
"inquirer": "^6.2.0",
"knex": "^0.15.2",
"pg": "^7.4.3"
}

View File

@ -56,10 +56,6 @@ taunt
## NOW
rename physical and spell
inventory + drops table
id
account

View File

@ -30,6 +30,8 @@ mod item;
mod zone;
mod mob;
mod vbox;
use dotenv::dotenv;
use net::{start};

View File

@ -22,6 +22,7 @@ use item::{Item, ItemAction, items_list, item_use, item_create};
use skill::{Skill};
use zone::{Zone, zone_create, zone_join, zone_close};
use spec::{Spec};
use vbox::{Vbox, vbox_state, vbox_accept, vbox_combine};
pub struct Rpc;
@ -80,6 +81,10 @@ impl Rpc {
"account_zone" => Rpc::account_zone(data, &mut tx, account.unwrap(), client),
"item_use" => Rpc::item_use(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_combine" => Rpc::vbox_combine(data, &mut tx, account.unwrap(), client),
"press_r" => Rpc::press_r(data, &mut tx, account.unwrap(), client),
_ => Err(format_err!("unknown method - {:?}", v.method)),
@ -251,8 +256,6 @@ impl Rpc {
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 {
@ -404,6 +407,39 @@ 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")))?;
let response = RpcResponse {
method: "vbox_state".to_string(),
params: RpcResult::VboxState(vbox_state(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> {
let msg = from_slice::<VboxBuyMsg>(&data).or(Err(err_msg("invalid params")))?;
let response = RpcResponse {
method: "vbox_state".to_string(),
params: RpcResult::VboxState(vbox_accept(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> {
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)?)
};
return Ok(response);
}
}
#[derive(Debug,Clone,Serialize,Deserialize)]
@ -426,6 +462,8 @@ pub enum RpcResult {
ItemUse(()),
ZoneState(Zone),
ZoneClose(()),
VboxState(Vbox),
}
#[derive(Debug,Clone,Serialize,Deserialize)]
@ -637,6 +675,40 @@ pub struct ZoneCloseParams {
pub zone_id: Uuid,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct VboxStateMsg {
method: String,
params: VboxStateParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxStateParams {
pub game_id: Uuid,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct VboxBuyMsg {
method: String,
params: VboxBuyParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxBuyParams {
pub game_id: Uuid,
pub index: u8,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct VboxCombineMsg {
method: String,
params: VboxCombineParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct VboxCombineParams {
pub game_id: Uuid,
pub indices: Vec<u8>,
}
// #[cfg(test)]
// mod tests {

117
server/src/vbox.rs Normal file
View File

@ -0,0 +1,117 @@
use uuid::Uuid;
use rand::prelude::*;
use serde_cbor::{from_slice, to_vec};
use postgres::transaction::Transaction;
use failure::Error;
use failure::err_msg;
use account::Account;
use rpc::{VboxStateParams, VboxBuyParams, VboxCombineParams};
use item::{Item};
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Vbox {
pub id: Uuid,
pub balance: u16,
pub free: Vec<Item>,
pub bound: Vec<Item>,
pub game: Uuid,
pub account: Uuid,
}
impl Vbox {
pub fn new(account_id: Uuid, game_id: Uuid) -> Vbox {
Vbox {
id: Uuid::new_v4(),
account: account_id,
game: game_id,
free: vec![],
bound: vec![],
balance: 0,
}
}
}
pub fn vbox_write(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_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_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_write(Vbox::new(account.id, params.game_id), tx, account)
}
}
}
pub fn vbox_accept(params: VboxBuyParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
return vbox_get(tx, params.game_id, account)
}
pub fn vbox_combine(params: VboxCombineParams, tx: &mut Transaction, account: &Account) -> Result<Vbox, Error> {
return vbox_get(tx, params.game_id, account)
}
// pub fn item_drop(tx: &mut Transaction, account_id: Uuid, mode: GameMode) -> Result<(), Error> {
// let mut rng = thread_rng();
// let log_normal = LogNormal::new(1.0, 1.0);
// let num_drops = log_normal.sample(&mut rng).floor() as u16;
// let actions = mode_drops(mode);
// println!("{:?} drops", num_drops);
// for _i in 0..num_drops {
// let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
// let kind = actions[dist.sample(&mut rng)].0;
// let item = Item::new(kind, account_id);
// println!("{:?} dropped {:?}", account_id, item);
// item_create(item, tx, account_id)?;
// }
// Ok(())
// }