account and player img

This commit is contained in:
ntr 2019-09-22 17:25:28 +10:00
parent a81f3323ba
commit 05e1b19d11
7 changed files with 89 additions and 35 deletions

View File

@ -26,30 +26,29 @@ function Scoreboard(args) {
};
*/
const imgStyle = player.img
? { 'background-image': `url(/imgs/${player.img}.svg)` }
: null;
if (!isPlayer) {
return (
<div class={`player-box top ${player.ready ? 'ready' : ''}`}>
<div></div>
<div class="score">{scoreText()}</div>
<div class="name">{player.name}</div>
<div class="img avatar"
id='a9edadda-2b44-4270-b9a7-d7bf30ae35a7'
style={{ 'background-image': `url(/imgs/c170c913-7bd1-4196-97d0-97f404cfbbe9.svg)` }}>
</div>
<div class="msg">glhf</div>
<div class="img avatar" id={player.img} style={imgStyle}></div>
<div class="msg">&nbsp;</div>
</div>
);
}
return (
<div class={`player-box bottom ${player.ready ? 'ready' : ''}`}>
<div class="msg">hfhf</div>
<div class="score">{scoreText()}</div>
<div class="name">{player.name}</div>
<div class="img avatar"
id='a9edadda-2b44-4270-b9a7-d7bf30ae35a7'
style={{ 'background-image': `url(/imgs/a9edadda-2b44-4270-b9a7-d7bf30ae35a7.svg)` }}>
</div>
<div class="img avatar" id={player.img} style={imgStyle}></div>
</div>
);
}

View File

@ -0,0 +1,11 @@
const uuidv4 = require('uuid/v4');
// give everybody the shapes mtx
exports.up = async knex => {
await knex.raw(`
ALTER TABLE accounts
ADD COLUMN img UUID DEFAULT uuid_generate_v4();
`);
};
exports.down = async () => {};

View File

@ -14,6 +14,7 @@ use construct::{Construct, ConstructSkeleton, construct_spawn};
use instance::{Instance, instance_delete};
use mtx::{Mtx, FREE_MTX};
use pg::Db;
use img;
use failure::Error;
@ -24,6 +25,7 @@ static PASSWORD_MIN_LEN: usize = 11;
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Account {
pub id: Uuid,
pub img: Uuid,
pub name: String,
pub balance: u32,
pub subscribed: bool,
@ -34,6 +36,7 @@ impl<'a> TryFrom<postgres::rows::Row<'a>> for Account {
fn try_from(row: postgres::rows::Row) -> Result<Self, Error> {
let id: Uuid = row.get("id");
let img: Uuid = row.get("img");
let db_balance: i64 = row.get("balance");
let balance = u32::try_from(db_balance)
@ -42,13 +45,13 @@ impl<'a> TryFrom<postgres::rows::Row<'a>> for Account {
let subscribed: bool = row.get("subscribed");
let name: String = row.get("name");
Ok(Account { id, name, balance, subscribed })
Ok(Account { id, name, balance, subscribed, img })
}
}
pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
let query = "
SELECT id, name, balance, subscribed
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE id = $1;
";
@ -64,7 +67,7 @@ pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
pub fn select_name(db: &Db, name: &String) -> Result<Account, Error> {
let query = "
SELECT id, name, balance, subscribed
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE name = $1;
";
@ -80,7 +83,7 @@ pub fn select_name(db: &Db, name: &String) -> Result<Account, Error> {
pub fn from_token(db: &Db, token: &String) -> Result<Account, Error> {
let query = "
SELECT id, name, subscribed, balance
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE token = $1
AND token_expiry > now();
@ -97,7 +100,7 @@ pub fn from_token(db: &Db, token: &String) -> Result<Account, Error> {
pub fn login(tx: &mut Transaction, name: &String, password: &String) -> Result<Account, MnmlHttpError> {
let query = "
SELECT id, password, name, balance, subscribed
SELECT id, password, name, balance, subscribed, img
FROM accounts
WHERE name = $1
";
@ -125,8 +128,10 @@ pub fn login(tx: &mut Transaction, name: &String, password: &String) -> Result<A
return Err(MnmlHttpError::PasswordNotMatch);
}
Account::try_from(row)
.or(Err(MnmlHttpError::ServerError))
let account = Account::try_from(row)
.or(Err(MnmlHttpError::ServerError))?;
Ok(account)
}
pub fn new_token(tx: &mut Transaction, id: Uuid) -> Result<String, MnmlHttpError> {
@ -246,7 +251,7 @@ pub fn debit(tx: &mut Transaction, id: Uuid, debit: i64) -> Result<Account, Erro
UPDATE accounts
SET balance = balance - $1
WHERE id = $2
RETURNING id, name, balance, subscribed
RETURNING id, password, name, balance, subscribed, img
";
let result = tx
@ -256,15 +261,9 @@ pub fn debit(tx: &mut Transaction, id: Uuid, debit: i64) -> Result<Account, Erro
let row = result.iter().next()
.ok_or(format_err!("account not found {:?}", id))?;
let name: String = row.get(1);
let db_balance: i64 = row.get(2);
let balance = u32::try_from(db_balance)
.or(Err(format_err!("user {:?} has unparsable balance {:?}", id, db_balance)))?;
let subscribed: bool = row.get(3);
info!("account debited name={:?} debited={:?} balance={:?}", name, debit, balance);
Ok(Account { id, name: row.get(1), balance, subscribed })
let account = Account::try_from(row)?;
info!("account debited name={:?} debited={:?} balance={:?}", account.name, debit, account.balance);
Ok(account)
}
pub fn set_subscribed(tx: &mut Transaction, id: Uuid, subscribed: bool) -> Result<String, Error> {
@ -298,6 +297,7 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
}
let id = Uuid::new_v4();
let img = Uuid::new_v4();
let rounds = 8;
let password = hash(&password, rounds)?;
@ -308,13 +308,13 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
.collect();
let query = "
INSERT INTO accounts (id, name, password, token, token_expiry)
VALUES ($1, $2, $3, $4, now() + interval '1 week')
INSERT INTO accounts (id, name, password, token, token_expiry, img)
VALUES ($1, $2, $3, $4, now() + interval '1 week', $5)
RETURNING id, name;
";
let result = tx
.query(query, &[&id, &name, &password, &token])?;
.query(query, &[&id, &name, &password, &token, &img])?;
match result.iter().next() {
Some(row) => row,
@ -331,6 +331,8 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
.insert(tx)?;
}
img::shapes_write(img)?;
info!("registration account={:?}", name);
Ok(token)
@ -458,3 +460,15 @@ pub fn account_instances(tx: &mut Transaction, account: &Account) -> Result<Vec<
return Ok(list);
}
// all accounts have an image id but the img
// doesn't necessarily exist until they subscribe
pub fn img_check(account: &Account) -> Result<Uuid, Error> {
match account.subscribed {
true => match img::exists(account.img) {
true => Ok(account.img),
false => img::shapes_write(account.img)
},
false => Ok(account.img),
}
}

View File

@ -257,6 +257,10 @@ fn _hieroglyph() -> String {
return s;
}
pub fn exists(id: Uuid) -> bool {
std::path::Path::new(&format!("/var/lib/mnml/public/imgs/{}.svg", id)).exists()
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -719,8 +719,7 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result<Inst
.set_time_control(TimeControl::Practice)
.set_name(bot.name.clone())?;
let constructs = account::team(tx, account)?;
let player = Player::new(account.id, &account.name, constructs);
let player = Player::from_account(tx, account)?;
instance.add_player(player.clone())?;
instance.add_player(bot)?;
@ -740,8 +739,8 @@ pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, E
instance = instance_create(tx, instance)?;
for account in [a, b].iter() {
let constructs = account::team(tx, account)?;
let player = player_create(tx, Player::new(account.id, &account.name, constructs), instance.id, account)?;
let acc_p = Player::from_account(tx, &account)?;
let player = player_create(tx, acc_p, instance.id, account)?;
instance.add_player(player)?;
}

View File

@ -6,6 +6,7 @@ use postgres::transaction::Transaction;
use failure::Error;
use failure::err_msg;
use account;
use account::Account;
use construct::{Construct, Colours};
use vbox::{Vbox};
@ -39,7 +40,7 @@ impl Score {
// _ => Score::Win,
// }
// Score::Adv => Score::Win,
_ => panic!("faulty score increment {:?}", self),
}
}
@ -56,6 +57,7 @@ impl Score {
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Player {
pub id: Uuid,
pub img: Option<Uuid>,
pub name: String,
pub vbox: Vbox,
pub constructs: Vec<Construct>,
@ -66,9 +68,31 @@ pub struct Player {
}
impl Player {
pub fn from_account(tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let constructs = account::team(tx, account)?;
let img = match account.subscribed {
true => Some(account.img),
false => None,
};
Ok(Player {
id: account.id,
img,
name: account.name.clone(),
vbox: Vbox::new(),
constructs,
bot: false,
ready: false,
warnings: 0,
score: Score::Zero,
})
}
pub fn new(account: Uuid, name: &String, constructs: Vec<Construct>) -> Player {
Player {
id: account,
img: Some(account),
name: name.clone(),
vbox: Vbox::new(),
constructs,
@ -379,7 +403,7 @@ mod tests {
player.score = player.score.add_win(&Score::Zero);
player.score = player.score.add_win(&Score::Zero);
assert_eq!(player.score, Score::Win); // 40 / 0
// Bo7 tennis scoring
/*assert_eq!(player.score, Score::Three); // 40 / 0

View File

@ -272,6 +272,9 @@ impl Handler for Connection {
self.ws.send(RpcMessage::AccountState(a.clone())).unwrap();
self.events.send(Event::Subscribe(self.id, a.id)).unwrap();
// check if they have an image that needs to be generated
account::img_check(&a).unwrap();
let db = self.pool.get().unwrap();
let mut tx = db.transaction().unwrap();