adds new 'shop' table

This commit is contained in:
2019-11-18 15:07:35 +01:00
parent cb8dfa9a2a
commit d1a85ed1d0
8 changed files with 173 additions and 54 deletions

View File

@@ -13,14 +13,12 @@ pub struct BuySellParams {
global_mod: Option<f64>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NewGroupLoot {
source_name: String,
pub items: ItemList,
}
/// A generic response for all queries
#[derive(Serialize, Debug, Default)]
pub struct ApiResponse {
@@ -70,10 +68,12 @@ pub enum ApiActions {
// Application level
FetchPlayers,
FetchInventory,
FetchShopInventory,
FetchClaims,
CheckItemList(Vec<String>),
// Player level
FetchPlayer(i32),
FetchPlayerClaims(i32),
FetchNotifications(i32),
FetchLoot(i32),
UpdateWealth(i32, f64),
@@ -86,6 +86,7 @@ pub enum ApiActions {
// Group level
AddLoot(NewGroupLoot),
// Admin level
RefreshShopInventory(ItemList),
//AddPlayer(String, f64),
//AddInventoryItem(pub String, pub i32),
//ResolveClaims,
@@ -106,9 +107,7 @@ pub fn execute(
let mut errors = String::new();
let items = db::Inventory(conn).all()?;
for name in &names {
if let Some(item) =
items.iter().filter(|i| &i.name == name).take(1).next()
{
if let Some(item) = items.iter().filter(|i| &i.name == name).take(1).next() {
found.push(item.clone())
} else {
errors.push_str(&format!("{},\n", name));
@@ -130,14 +129,22 @@ pub fn execute(
response.set_value(Value::ItemList(db::Inventory(conn).all()?));
None
}
ApiActions::FetchShopInventory => {
response.set_value(Value::ItemList(db::Shop(conn).all()?));
None
}
ApiActions::FetchClaims => {
response.set_value(Value::ClaimList(db::fetch_claims(conn)?));
response.set_value(Value::ClaimList(db::Claims(conn).all()?));
None
}
ApiActions::FetchPlayer(id) => {
response.set_value(Value::Player(db::Players(conn).find(id)?));
None
}
ApiActions::FetchPlayerClaims(id) => {
response.set_value(Value::ClaimList(db::Claims(conn).by_player(id)?));
None
}
ApiActions::FetchNotifications(id) => {
response.set_value(Value::Notifications(
db::AsPlayer(conn, id).notifications()?,
@@ -155,27 +162,35 @@ pub fn execute(
}
ApiActions::BuyItems(id, params) => {
// TODO: check that player has enough money !
let mut gains: Vec<db::Wealth> = Vec::with_capacity(params.items.len());
for (item_id, price_mod) in params.items.into_iter() {
if let Ok((item, diff)) = db::buy_item_from_inventory(conn, id, item_id, price_mod)
{
response.push_update(item);
gains.push(diff);
} else {
response.push_error(format!("Error adding {}", item_id));
let has_enough_gold = true;
if has_enough_gold {
let mut gains: Vec<db::Wealth> = Vec::with_capacity(params.items.len());
for (item_id, price_mod) in params.items.into_iter() {
if let Ok((item, diff)) =
db::buy_item_from_shop(conn, id, item_id, price_mod)
{
response.push_update(item);
gains.push(diff);
} else {
response.push_error(format!("Error adding {}", item_id));
}
}
let added_items = gains.len();
let total_amount = gains
.into_iter()
.fold(db::Wealth::from_gp(0.0), |acc, i| acc + i);
response.notify(format!(
"{} objets achetés pour {}po",
added_items,
total_amount.to_gp()
));
response.push_update(Update::Wealth(total_amount));
Some((id, "Achat d'objets"))
} else {
response.push_error("Vous n'avez pas assez d'argent !");
None
}
let added_items = gains.len();
let total_amount = gains
.into_iter()
.fold(db::Wealth::from_gp(0.0), |acc, i| acc + i);
response.notify(format!(
"{} objets achetés pour {}po",
added_items,
total_amount.to_gp()
));
response.push_update(Update::Wealth(total_amount));
Some((id, "Achat d'objets"))
}
// Behavior differs if player is group or regular.
// Group sells item like players then split the total amount among players.
@@ -200,20 +215,15 @@ pub fn execute(
let players = params
.players
.unwrap_or(db::Players(conn).all()?.into_iter().map(|p| p.id).collect());
let shared = db::split_and_share(conn, total_amount.to_gp() as i32, &players)?;
let shared_amount = {
if let Update::Wealth(amount) = shared {
amount.to_gp()
} else {
panic!("cannot happen")
}
if let Update::Wealth(shared) =
db::split_and_share(conn, total_amount.to_gp() as i32, &players)?
{
response.notify(format!(
"Les objets ont été vendus, les joueurs ont reçu (au total) {} po",
shared.to_gp()
));
response.push_update(Update::Wealth(db::Wealth::from_gp(total_amount.to_gp() - shared.to_gp())));
};
response.notify(format!(
"Les objets ont été vendus, les joueurs ont reçu (au total) {} po",
shared_amount
));
response.push_update(Update::Wealth(total_amount));
response.push_update(shared);
}
_ => {
response.notify(format!(
@@ -238,8 +248,12 @@ pub fn execute(
}
ApiActions::ClaimItems(id, items) => {
conn.transaction(|| -> Result<Option<(i32, &str)>, diesel::result::Error> {
let current_claims: HashSet<i32> =
db::Claims(conn).all()?.iter().filter(|c| c.player_id == id).map(|c| c.loot_id).collect();
let current_claims: HashSet<i32> = db::Claims(conn)
.all()?
.iter()
.filter(|c| c.player_id == id)
.map(|c| c.loot_id)
.collect();
let new_claims: HashSet<i32> = items.into_iter().collect();
// Claims to delete
for item in current_claims.difference(&new_claims) {
@@ -284,6 +298,11 @@ pub fn execute(
};
Some((0, "Nouveau loot"))
}
// Admin actions
ApiActions::RefreshShopInventory(items) => {
db::Shop(conn).replace_list(items)?;
None
}
};
// Store the event if it can be undone.

View File

@@ -126,7 +126,9 @@ fn configure_api(config: &mut web::ServiceConfig) {
)
.service(
web::resource("/claims")
//.route(web::get().to_async(endpoints::player_claims))
.route(web::get().to_async(|pool, player: PlayerId| {
db_call(pool, Q::FetchPlayerClaims(*player))
}))
.route(web::post().to_async(
|pool, (player, data): (PlayerId, IdList)| {
db_call(pool, Q::ClaimItems(*player, data.into_inner()))
@@ -188,6 +190,15 @@ fn configure_api(config: &mut web::ServiceConfig) {
"/claims",
web::get().to_async(|pool| db_call(pool, Q::FetchClaims)),
)
.service(
web::resource("/shop")
.route(web::get().to_async(|pool| db_call(pool, Q::FetchShopInventory)))
.route(
web::post().to_async(|pool, items: web::Json<api::ItemList>| {
db_call(pool, Q::RefreshShopInventory(items.into_inner()))
}),
),
)
.service(
web::resource("/items")
.route(