merge shop and looted tables

This commit is contained in:
2020-01-09 13:25:36 +01:00
parent 6149dfd297
commit f9cd09431d
8 changed files with 205 additions and 275 deletions

View File

@@ -40,11 +40,11 @@ pub struct ApiResponse {
}
impl ApiResponse {
fn push_update(&mut self, update: db::Update) {
fn push_updates(&mut self, updates: Vec<db::Update>) {
if let Some(v) = self.updates.as_mut() {
v.push(update);
v.append(&mut updates);
} else {
self.updates = Some(vec![update]);
self.updates = Some(updates);
}
}
@@ -107,6 +107,8 @@ pub enum ApiEndpoints {
BuyItems(i32, BuySellParams), // db::Shop(conn)::buy(params)
RefreshShop(ItemList), // db::Shop(conn)::replace_list(items)
ClaimsList,
// db::Players::get returns AsPlayer<'q>
PlayerList, //db::Players(conn)::list()
PlayerAdd(NewPlayer), //db::Players(conn)::add(player)
@@ -122,150 +124,111 @@ pub enum ApiEndpoints {
ResolveClaims, // db::Group(conn)::resolve_claims()
}
static ErrorMsg : &str = "Une erreur est survenue";
pub fn execute(
conn: &DbConnection,
query: ApiActions,
query: ApiEndpoints,
) -> Result<ApiResponse, diesel::result::Error> {
let mut response = ApiResponse::default();
// Return an Option<String> that describes what happened.
// If there is some value, store the actions in db so that it can be reversed.
let action_text: Option<(i32, &str)> = match query {
ApiActions::CheckItemList(names) => {
let (items, errors) = {
let mut found = Vec::new();
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() {
found.push(item.clone())
} else {
errors.push_str(&format!("{},\n", name));
}
}
(found, errors)
};
response.set_value(Value::ItemList(items));
response.push_error(errors);
dbg!(&names, &response);
// Inventory
ApiEndpoints::FetchInventory => {
match db::Inventory(conn).all() {
Ok(items) => response.set_value(Value::ItemList(items)),
Err(_) => response.set_error(ErrorMsg),
}
None
}
ApiActions::FetchPlayers => {
ApiEnpoints::InventoryCheck(names) => {
match db::Inventory(conn).check_list(names) {
Ok((items, errors)) => {
response.set_value(Value::ItemList(items));
response.push_error(errors);
}
Err(_) => response.set_error(ErrorMsg),
}
None
}
ApiEndpoints::InventoryAdd((name, value)) => {
response.set_error("Not implemented");
None
}
//Shop
ApiEnpoints::ShopList => {
match db::Shop(conn).all() {
Ok(items) => response.set_value(Value::ItemList(items)),
Err(_) => response.set_error(ErrorMsg),
}
None
}
ApiEndpoints::BuyItems(buyer, params) => {
match db::Shop(conn).buy(params, buyer) {
Ok(updates) => {
response.notifiy("Objets achetés !");
response.push_updates(updates);
Some((id, "Achat d'objets"))
},
Err(_) => {
response.set_error(ErrorMsg);
None
}
}
}
// Players
ApiEndpoints::PlayerList => {
response.set_value(Value::PlayerList(db::Players(conn).all_except_group()?));
None
}
ApiActions::FetchInventory => {
response.set_value(Value::ItemList(db::Inventory(conn).all()?));
None
}
ApiActions::FetchShopInventory => {
response.set_value(Value::ItemList(db::Shop(conn).all()?));
None
}
ApiActions::FetchClaims => {
ApiEndpoint::ClaimList => {
response.set_value(Value::ClaimList(db::Claims(conn).all()?));
None
}
ApiActions::FetchPlayer(id) => {
response.set_value(Value::Players(conn)(db::Players(conn).find(id)?));
None
}
ApiActions::FetchPlayerClaims(id) => {
ApiEndpoint::PlayerClaims(id) => {
response.set_value(Value::ClaimList(db::Claims(conn).by_player(id)?));
None
}
ApiActions::FetchNotifications(id) => {
ApiEndpoint::PlayerNotifications(id) => {
response.set_value(Value::Notifications(
db::AsPlayer(conn, id).notifications()?,
));
None
}
ApiActions::FetchLoot(id) => {
ApiEndpoint::PlayerLoot(id) => {
response.set_value(Value::ItemList(db::LootManager(conn, id).all()?));
None
}
ApiActions::UpdateWealth(id, amount) => {
response.push_update(db::AsPlayer(conn, id).update_wealth(amount)?);
ApiEndpoint::PlayerUpdateWealth(id, amount) => {
response.push_updates(db::AsPlayer(conn, id).update_wealth(amount)?);
response.notify(format!("Mis à jour ({}po)!", amount));
Some((id, "Argent mis à jour"))
}
ApiActions::BuyItems(id, params) => {
// TODO: check that player has enough money !
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
}
}
// Behavior differs if player is group or regular.
// Group sells item like players then split the total amount among players.
ApiActions::SellItems(id, params) => {
ApiEndpoint::SellItems(id, params) => {
conn.transaction(|| -> Result<Option<(i32, &str)>, diesel::result::Error> {
let mut gains: Vec<db::Wealth> = Vec::with_capacity(params.items.len());
for (loot_id, price_mod) in params.items.iter() {
if let Ok((deleted, diff)) =
db::sell_item_transaction(conn, id, *loot_id, *price_mod)
{
response.push_update(deleted);
gains.push(diff);
} else {
response
.push_error(format!("Erreur lors de la vente (loot_id : {})", loot_id));
}
}
let sold_items = gains.len();
let total_amount = gains
.into_iter()
.fold(db::Wealth::from_gp(0.0), |acc, i| acc + i);
let sold = LootManager(conn, id).sell(params.items)?;
match id {
0 => {
let players = params.players.unwrap_or_default();
if let Update::Wealth(shared) =
updates.push(
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(total_amount - shared));
);
response.notify("Les objets ont été vendus");
response.push_updates(updates);
};
}
_ => {
response.notify(format!(
"{} objet(s) vendu(s) pour {} po",
sold_items,
total_amount.to_gp()
));
response.push_update(Update::Wealth(total_amount));
response.notify("Objets vendus !");
response.push_updates(updates);
}
}
Ok(Some((id, "Vente d'objets")))
})?
}
ApiActions::ClaimItems(id, items) => {
ApiEndpoint::ClaimItems(id, items) => {
conn.transaction(|| -> Result<Option<(i32, &str)>, diesel::result::Error> {
let current_claims: HashSet<i32> = db::Claims(conn)
.all()?
@@ -285,7 +248,7 @@ pub fn execute(
Ok(None)
})?
}
ApiActions::UndoLastAction(id) => {
ApiEndpoint::UndoLastAction(id) => {
if let Ok(event) = db::models::history::get_last_of_player(conn, id) {
let name = String::from(event.name());
for undone in event.undo(conn)?.into_inner().into_iter() {
@@ -298,7 +261,7 @@ pub fn execute(
None
}
// Group actions
ApiActions::AddLoot(data) => {
ApiEndpoint::AddLoot(data) => {
let mut added_items = 0;
for item in data.items.into_iter() {
if let Ok(added) = db::LootManager(conn, 0).add_from(&item) {
@@ -317,13 +280,17 @@ pub fn execute(
};
Some((0, "Nouveau loot"))
}
ApiEndpoints::ResolveClaims => {
response.push_error("Not implemented!");
None
}
// Admin actions
ApiActions::RefreshShopInventory(items) => {
ApiEndpoints::RefreshShop(items) => {
db::Shop(conn).replace_list(items)?;
response.notify("Inventaire du marchand renouvelé !");
None
}
ApiActions::AddPlayer(data) => {
ApiEnpoints::AddPlayer(data) => {
db::Players(conn).add(&data.name, data.wealth)?;
response.notify("Joueur ajouté !");
None