Compare commits

2 Commits

Author SHA1 Message Date
74ee4a831b works on selling group items 2019-10-20 22:03:06 +02:00
05a08ea337 adds forbidden_to_players wrapper for db_call 2019-10-20 21:23:57 +02:00
3 changed files with 55 additions and 12 deletions

View File

@@ -118,6 +118,21 @@ pub fn resolve_claims(conn: &DbConnection) -> QueryResult<()> {
Ok(()) Ok(())
} }
/// Split up and share group money among selected players
pub fn split_and_share(conn: &DbConnection, amount: i32, players: Vec<i32>) -> QueryResult<Wealth> {
let share = (
amount / (players.len() + 1) as i32 // +1 share for the group
) as f64;
conn.transaction(|| {
for p in players.into_iter() {
AsPlayer(conn, p).update_wealth(share)?;
AsPlayer(conn, 0).update_wealth(-share)?;
}
Ok(Wealth::from_gp(share))
})
}
#[cfg(none)] #[cfg(none)]
mod tests_old { mod tests_old {

View File

@@ -1,5 +1,15 @@
use diesel::prelude::*;
use lootalot_db::{self as db, DbConnection, QueryResult}; use lootalot_db::{self as db, DbConnection, QueryResult};
pub type ItemListWithMods = Vec<(i32, Option<f64>)>;
#[derive(Serialize, Deserialize, Debug)]
pub struct SellParams {
pub items: ItemListWithMods,
players: Option<Vec<i32>>,
global_mod: Option<f64>,
}
/// Every possible update which can happen during a query /// Every possible update which can happen during a query
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
pub enum Update { pub enum Update {
@@ -92,6 +102,7 @@ pub enum ApiActions {
UpdateWealth(i32, f64), UpdateWealth(i32, f64),
BuyItems(i32, Vec<(i32, Option<f64>)>), BuyItems(i32, Vec<(i32, Option<f64>)>),
SellItems(i32, Vec<(i32, Option<f64>)>), SellItems(i32, Vec<(i32, Option<f64>)>),
SellGroupItems(i32, SellParams),
ClaimItem(i32, i32), ClaimItem(i32, i32),
UnclaimItem(i32, i32), UnclaimItem(i32, i32),
// Group actions // Group actions
@@ -154,7 +165,6 @@ pub fn execute(
response.push_update(Update::Wealth(total_amount)); response.push_update(Update::Wealth(total_amount));
} }
ApiActions::SellItems(id, params) => { ApiActions::SellItems(id, params) => {
// TODO: Different procedure for group and other players
let mut all_results: Vec<db::Wealth> = Vec::with_capacity(params.len()); let mut all_results: Vec<db::Wealth> = Vec::with_capacity(params.len());
let mut sold_items: u16 = 0; let mut sold_items: u16 = 0;
for (loot_id, price_mod) in params.into_iter() { for (loot_id, price_mod) in params.into_iter() {
@@ -172,6 +182,14 @@ pub fn execute(
response.notify(format!("{} objet(s) vendu(s) pour {} po", sold_items, total_amount.to_gp())); response.notify(format!("{} objet(s) vendu(s) pour {} po", sold_items, total_amount.to_gp()));
response.push_update(Update::Wealth(total_amount)); response.push_update(Update::Wealth(total_amount));
} }
ApiActions::SellGroupItems(id, params) => {
conn.transaction(|| {
for i in params.items.into_iter() {
}
Err(diesel::result::Error::RollbackTransaction)
});
}
ApiActions::ClaimItem(id, item) => { ApiActions::ClaimItem(id, item) => {
response.push_update(Update::ClaimAdded( response.push_update(Update::ClaimAdded(
db::Claims(conn).add(id, item)?, db::Claims(conn).add(id, item)?,

View File

@@ -1,6 +1,6 @@
use actix_cors::Cors; use actix_cors::Cors;
use actix_files as fs; use actix_files as fs;
use actix_web::{web, middleware, App, Error, HttpResponse, HttpServer}; use actix_web::{web, middleware, App, Error, HttpResponse, HttpServer, Either};
use futures::{Future, IntoFuture}; use futures::{Future, IntoFuture};
use std::env; use std::env;
@@ -10,7 +10,6 @@ use crate::api;
type AppPool = web::Data<db::Pool>; type AppPool = web::Data<db::Pool>;
type PlayerId = web::Path<i32>; type PlayerId = web::Path<i32>;
type ItemId = web::Json<i32>; type ItemId = web::Json<i32>;
type ItemListWithMods = web::Json<Vec<(i32, Option<f64>)>>;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct NewGroupLoot { struct NewGroupLoot {
@@ -18,8 +17,10 @@ struct NewGroupLoot {
items: Vec<db::Item>, items: Vec<db::Item>,
} }
type MaybeForbidden = actix_web::Either<Box<dyn Future<Item = HttpResponse, Error = Error>>, HttpResponse>;
/// Wraps call to the database query and convert its result as a async HttpResponse /// Wraps call to the database query and convert its result as a async HttpResponse
pub fn db_call( fn db_call(
pool: AppPool, pool: AppPool,
query: api::ApiActions, query: api::ApiActions,
) -> impl Future<Item = HttpResponse, Error = Error> ) -> impl Future<Item = HttpResponse, Error = Error>
@@ -34,6 +35,15 @@ pub fn db_call(
}) })
} }
fn forbidden_to_players(id: i32, params: (AppPool, api::ApiActions)) -> MaybeForbidden {
if id != 0 {
Either::B(HttpResponse::Forbidden().finish())
} else {
Either::A(Box::new(db_call(params.0, params.1)))
}
}
fn configure_app(config: &mut web::ServiceConfig) { fn configure_app(config: &mut web::ServiceConfig) {
use api::ApiActions as Q; use api::ApiActions as Q;
config.service( config.service(
@@ -88,21 +98,21 @@ fn configure_app(config: &mut web::ServiceConfig) {
db_call(pool, Q::FetchLoot(*player)) db_call(pool, Q::FetchLoot(*player))
})) }))
.route(web::put().to_async( .route(web::put().to_async(
move |pool, (player, data): (PlayerId, ItemListWithMods)| { move |pool, (player, data): (PlayerId, web::Json<api::ItemListWithMods>)| {
db_call(pool, Q::BuyItems(*player, data.into_inner())) db_call(pool, Q::BuyItems(*player, data.into_inner()))
}, },
)) ))
.route(web::post().to_async( .route(web::post().to(
move |pool, (player, data): (PlayerId, web::Json<NewGroupLoot>)| { move |pool, (player, data): (PlayerId, web::Json<NewGroupLoot>)| {
match *player { forbidden_to_players(*player, (pool, Q::AddLoot(data.into_inner().items)))
0 => db_call(pool, Q::AddLoot(data.items.clone())),
_ => HttpResponse::Forbidden().finish().into_future(),
}
}, },
)) ))
.route(web::delete().to_async( .route(web::delete().to_async(
move |pool, (player, data): (PlayerId, ItemListWithMods)| { move |pool, (player, data): (PlayerId, web::Json<api::SellParams>)| {
db_call(pool, Q::SellItems(*player, data.into_inner())) match *player {
0 => db_call(pool, Q::SellItems(*player, data.into_inner().items)),
_ => db_call(pool, Q::SellGroupItems(*player, data.into_inner())),
}
}, },
)), )),
), ),