diff --git a/lootalot_db/db.sqlite3 b/lootalot_db/db.sqlite3 index b5eadf0..7fd6da7 100644 Binary files a/lootalot_db/db.sqlite3 and b/lootalot_db/db.sqlite3 differ diff --git a/lootalot_db/src/lib.rs b/lootalot_db/src/lib.rs index a9488be..76e3757 100644 --- a/lootalot_db/src/lib.rs +++ b/lootalot_db/src/lib.rs @@ -25,19 +25,20 @@ pub type ActionResult = QueryResult; /// ::new() -> DbApi<'q> (Db finds a connection by itself, usefull for cli) /// ::with_conn(conn) -> DbApi<'q> (uses a user-defined connection) /// v .fetch_players() -/// x .fetch_inventory() +/// v .fetch_inventory() +/// v .fetch_claims() /// v .as_player(player_id) -> AsPlayer<'q> /// v .loot() -> List of items owned (Vec) -/// v .claim(item_id) -> Success status (bool) -/// v .unclaim(item_id) -> Success status (bool) -/// x .sell(item_id) -> Success status (bool, earned) -/// x .buy(inventory_item_id) -> Success status (bool, cost) -/// v .update_wealth(gold_pieces) -> Success status (bool, new_wealth) -/// x .as_admin() -/// x .add_loot([inventory_item_ids]) -> Success status +/// v .claim(loot_id) -> Success status (bool) +/// v .unclaim(loot_id) -> Success status (bool) +/// x .sell(loot_id) -> Success status (bool, earned) +/// x .buy(item_desc) -> Success status (bool, cost) +/// v .update_wealth(value_in_gold) -> Success status (bool, new_wealth) +/// v .as_admin() +/// x .add_loot(identifier, [items_desc]) -> Success status /// x .sell_loot([players], [excluded_item_ids]) -> Success status (bool, player_share) /// x .resolve_claims() -/// x .add_player(player_data) +/// v .add_player(player_data) /// pub struct DbApi<'q>(&'q DbConnection); @@ -89,6 +90,11 @@ impl<'q> DbApi<'q> { pub fn as_player(self, id: i32) -> AsPlayer<'q> { AsPlayer { id, conn: self.0 } } + + /// Wrapper for acting as the admin + pub fn as_admin(self) -> AsAdmin<'q> { + AsAdmin(self.0) + } } /// A wrapper for interactions of players with the database @@ -106,6 +112,9 @@ impl<'q> AsPlayer<'q> { .load(self.conn)? ) } + /// Adds the value in gold to the player's wealth. + /// + /// Value can be negative to substract wealth. pub fn update_wealth(self, value: f32) -> ActionResult { use schema::players::dsl::*; let current_wealth = players.find(self.id) @@ -130,6 +139,7 @@ impl<'q> AsPlayer<'q> { .execute(self.conn) .map(|r| match r { 1 => true, _ => false }) } + /// Withdraw claim pub fn unclaim(self, item: i32) -> ActionResult { use schema::claims::dsl::*; diesel::delete( @@ -142,6 +152,18 @@ impl<'q> AsPlayer<'q> { } +pub struct AsAdmin<'q>(&'q DbConnection); + +impl<'q> AsAdmin<'q> { + + pub fn add_player(self, name: String, start_wealth: f32) -> ActionResult { + diesel::insert_into(schema::players::table) + .values(&models::NewPlayer::create(&name, start_wealth)) + .execute(self.0) + .map(|r| match r { 1 => true, _ => false }) + } +} + pub fn create_pool() -> Pool { let connspec = std::env::var("DATABASE_URL").expect("DATABASE_URL"); dbg!( &connspec ); diff --git a/lootalot_db/src/models/item.rs b/lootalot_db/src/models/item.rs index 5d08f15..9a52074 100644 --- a/lootalot_db/src/models/item.rs +++ b/lootalot_db/src/models/item.rs @@ -49,6 +49,7 @@ impl Loot { } } +type ItemDesc<'a> = (&'a str, i32); /// An item being looted or bought. /// /// The owner is set to 0 in case of looting, @@ -60,3 +61,21 @@ struct NewLoot<'a> { base_price: i32, owner_id: i32, } + +impl<'a> NewLoot<'a> { + fn to_group(desc: ItemDesc<'a>) -> Self { + Self { + name: desc.0, + base_price: desc.1, + owner_id: 0, + } + } + + fn to_player(player: i32, desc: ItemDesc<'a>) -> Self { + Self { + name: desc.0, + base_price: desc.1, + owner_id: player, + } + } +} diff --git a/lootalot_db/src/models/mod.rs b/lootalot_db/src/models/mod.rs index 0ad2ec6..aeb019d 100644 --- a/lootalot_db/src/models/mod.rs +++ b/lootalot_db/src/models/mod.rs @@ -3,6 +3,5 @@ mod player; mod claim; pub use item::Item; -pub use player::Player; -pub use player::WealthUpdate; +pub use player::{Player, NewPlayer, WealthUpdate}; pub use claim::{NewClaim, Claim}; diff --git a/lootalot_db/src/models/player.rs b/lootalot_db/src/models/player.rs index 8e26d1e..302ca54 100644 --- a/lootalot_db/src/models/player.rs +++ b/lootalot_db/src/models/player.rs @@ -72,6 +72,19 @@ pub struct NewPlayer<'a> { pp: i32, } +impl<'a> NewPlayer<'a> { + pub fn create(name: &'a str, wealth: f32) -> Self { + let wealth = WealthUpdate::from_gp(wealth); + Self { + name, + cp: wealth.cp, + sp: wealth.sp, + gp: wealth.gp, + pp: wealth.pp, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/server.rs b/src/server.rs index a97a682..2c6e73b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -69,15 +69,19 @@ pub(crate) fn serve() -> std::io::Result<()> { .route( "/update-wealth/{player_id}/{amount}", web::get().to_async(move |pool: AppPool, data: web::Path<(i32, f32)>| { - let (player, gold) = *data; - db_call(pool, move |api| api.as_player(player).update_wealth(gold)) + db_call(pool, move |api| api.as_player(data.0).update_wealth(data.1)) }), ) .route( "/loot/{player_id}", web::get().to_async(move |pool: AppPool, player_id: web::Path| { - let player_id: i32 = *player_id; - db_call(pool, move |api| api.as_player(player_id).loot()) + db_call(pool, move |api| api.as_player(*player_id).loot()) + }), + ) + .route( + "/admin/add-player/{name}/{wealth}", + web::get().to_async(move |pool: AppPool, data: web::Path<(String, f32)>| { + db_call(pool, move |api| api.as_admin().add_player(data.0.clone(), data.1)) }), ) .service(fs::Files::new("/", www_root.clone()).index_file("index.html"))