From 858bf6c2e23a283c2636c8b8819d6c72d990d9c1 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Sun, 16 Aug 2020 11:13:39 -0400 Subject: [PATCH 1/9] add nickname plant route --- src/wormhole/session/tile/plant/mod.rs | 7 + src/wormhole/session/tile/plant/nickname.rs | 153 ++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 src/wormhole/session/tile/plant/nickname.rs diff --git a/src/wormhole/session/tile/plant/mod.rs b/src/wormhole/session/tile/plant/mod.rs index de013bb..6855178 100644 --- a/src/wormhole/session/tile/plant/mod.rs +++ b/src/wormhole/session/tile/plant/mod.rs @@ -10,6 +10,9 @@ use summon::summon; mod rub; use rub::rub; +mod nickname; +use nickname::nickname; + mod slaughter; pub fn handle_ask(ss: &mut SessSend, ask: PlantAsk) -> AskedNote { @@ -27,6 +30,10 @@ pub fn handle_ask(ss: &mut SessSend, ask: PlantAsk) -> AskedNote { tile_id, rub_item_id, } => PlantRubStartResult(strerr(rub(ss, tile_id, rub_item_id))), + Nickname { + tile_id, + new_name, + } => PlantRenameResult(strerr(nickname(ss, tile_id, new_name))), } } /* diff --git a/src/wormhole/session/tile/plant/nickname.rs b/src/wormhole/session/tile/plant/nickname.rs new file mode 100644 index 0000000..7e82475 --- /dev/null +++ b/src/wormhole/session/tile/plant/nickname.rs @@ -0,0 +1,153 @@ +use super::SessSend; +use hcor::{id, plant, Item, ItemId, Plant, TileId}; +use log::*; +use std::fmt; + +#[derive(Debug)] +pub enum Error { + NoSuch(id::NoSuch), +} +use Error::*; + +impl From for Error { + fn from(ns: id::NoSuch) -> Error { + Error::NoSuch(ns) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "couldn't rename plant: ")?; + match self { + NoSuch(ns) => write!(f, "{}", ns), + + } + } +} + +pub fn nickname(ss: &mut SessSend, tile_id: TileId, new_name: String) -> Result { + + let plant = ss.plant_mut(tile_id)?; + plant.nickname = new_name.clone(); + + Ok(new_name.clone()) +} + +#[cfg(all(feature = "hcor_client", test))] +mod test { + #[actix_rt::test] + /// NOTE: relies on item/spawn! + async fn summon() -> hcor::ClientResult<()> { + use hcor::{Hackstead, Item, Tile}; + use log::*; + + // attempt to establish logging, do nothing if it fails + // (it probably fails because it's already been established in another test) + drop(pretty_env_logger::try_init()); + + let (_, seed_arch) = hcor::CONFIG + .seeds() + .next() + .expect("no items in config that are seeds?"); + let not_seed_arch = hcor::CONFIG + .possession_archetypes + .iter() + .find(|a| a.seed.is_none()) + .expect("no items in config that aren't seeds?"); + + // create bob's stead! + let mut bobstead = Hackstead::register().await?; + + let seed_item = seed_arch.spawn().await?; + let not_seed_item = not_seed_arch.spawn().await?; + let open_tile = bobstead.free_tile().expect("fresh hackstead no open land?"); + + struct NewPlantAssumptions { + expected_success: bool, + item_consumed: bool, + } + + async fn new_plant_assuming( + bobstead: &mut Hackstead, + tile: &Tile, + seed_item: &Item, + assumptions: NewPlantAssumptions, + ) -> hcor::ClientResult<()> { + let requested_plant = tile.plant_seed(seed_item).await; + + match (assumptions.expected_success, requested_plant) { + (true, Ok(plant)) => { + assert_eq!( + plant.tile_id, tile.tile_id, + "plant planted for bob is on a different tile than expected: {:#?}", + plant + ); + assert_eq!( + seed_item.seed.as_ref().unwrap().grows_into, + plant.name, + "seed grew into unexpected type of plant" + ); + } + (false, Err(e)) => info!("/plant/new failed as expected: {}", e), + (true, Err(e)) => panic!("/plant/new unexpectedly failed: {}", e), + (false, Ok(tile)) => panic!("/plant/new unexpectedly returned plant: {:#?}", tile), + }; + + *bobstead = Hackstead::fetch(&*bobstead).await?; + + assert_eq!( + assumptions.item_consumed, + !bobstead.has_item(seed_item), + "bob's seed item was unexpectedly {}", + if assumptions.item_consumed { + "not consumed" + } else { + "consumed" + } + ); + + Ok(()) + } + + // try to plant this non-seed item + new_plant_assuming( + &mut bobstead, + &open_tile, + ¬_seed_item, + NewPlantAssumptions { + expected_success: false, + item_consumed: false, + }, + ) + .await?; + + // try and redeem an item that's actually a seed, this should actually work + new_plant_assuming( + &mut bobstead, + &open_tile, + &seed_item, + NewPlantAssumptions { + expected_success: true, + item_consumed: true, + }, + ) + .await?; + + // try and redeem the item that's already been consumed + new_plant_assuming( + &mut bobstead, + &open_tile, + &seed_item, + NewPlantAssumptions { + expected_success: false, + item_consumed: true, + }, + ) + .await?; + + // kill bob so he's not left + bobstead.slaughter().await?; + + Ok(()) + } +} From 0a6686bd37f90738e3b3562d00b004e61a363d38 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Sun, 16 Aug 2020 11:13:46 -0400 Subject: [PATCH 2/9] start implementing rename gotchi route - does not compile --- src/wormhole/session/item/mod.rs | 5 ++ src/wormhole/session/item/rename_gotchi.rs | 94 ++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/wormhole/session/item/rename_gotchi.rs diff --git a/src/wormhole/session/item/mod.rs b/src/wormhole/session/item/mod.rs index d7e36cd..b2faa83 100644 --- a/src/wormhole/session/item/mod.rs +++ b/src/wormhole/session/item/mod.rs @@ -4,6 +4,7 @@ use hcor::wormhole::{ AskedNote::*, ItemAsk::{self, *}, }; +use hcor::id::ItemId; mod spawn; use spawn::spawn; @@ -11,6 +12,9 @@ use spawn::spawn; mod hatch; use hatch::hatch; +mod rename_gotchi; +use rename_gotchi::rename; + pub(super) fn handle_ask(ss: &mut SessSend, ask: ItemAsk) -> HandledAskKind { HandledAskKind::Direct(match ask { Spawn { @@ -28,5 +32,6 @@ pub(super) fn handle_ask(ss: &mut SessSend, ask: ItemAsk) -> HandledAskKind { })) } Hatch { hatchable_item_id } => ItemHatchResult(strerr(hatch(ss, hatchable_item_id))), + GotchiRename { item_id, new_name} => GotchiRenameResult(strerr(rename(ss, item_id, new_name))), }) } diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs new file mode 100644 index 0000000..a6f4164 --- /dev/null +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -0,0 +1,94 @@ +use super::SessSend; +use hcor::{id, item, ConfigError, Item}; +use std::fmt; +use hcor::id::ItemId; + +#[derive(Debug)] +pub enum Error { + NoSuchItemConf(ConfigError), + NoSuch(id::NoSuch), +} +use Error::*; + +impl From for Error { + fn from(ns: id::NoSuch) -> Error { + Error::NoSuch(ns) + } +} + +impl From for Error { + fn from(e: hcor::ConfigError) -> Error { + Error::NoSuchItemConf(e) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "couldn't spawn items: ")?; + match self { + NoSuchItemConf(e) => write!(f, "no such item conf: {}", e), + } + } +} + +pub fn rename(ss: &mut SessSend, item_id: ItemId, new_name: String) -> Result { + let item = ss.item_mut(item_id)?; + let gotchi = item.gotchi?; + gotchi.nickname = new_name.clone(); + Ok(new_name.clone()) +} + +#[cfg(all(test, features = "hcor_client"))] +mod test { + #[actix_rt::test] + /// NOTE: requires that at least one item exists in the config! + async fn spawn() -> hcor::ClientResult<()> { + use super::test::{ITEM_ARCHETYPE, ITEM_SPAWN_COUNT}; + use hcor::Hackstead; + use log::*; + + // attempt to establish logging, do nothing if it fails + // (it probably fails because it's already been established in another test) + drop(pretty_env_logger::try_init()); + + debug!("create bob's stead"); + let mut bobstead = Hackstead::register().await?; + + // we'll need to keep track of how many items we have to see if spawning works. + fn count_relevant_items(hackstead: &Hackstead) -> usize { + hackstead + .inventory + .iter() + .filter(|i| i.archetype_handle == ITEM_ARCHETYPE) + .count() + } + let starting_item_count = count_relevant_items(&bobstead); + + debug!("spawn bob some items and refresh his stead"); + let items = bobstead + .spawn_items(ITEM_ARCHETYPE, ITEM_SPAWN_COUNT) + .await?; + bobstead = Hackstead::fetch(&bobstead).await?; + + debug!("make sure those new items are in there"); + assert_eq!( + count_relevant_items(&bobstead) - starting_item_count, + ITEM_SPAWN_COUNT + ); + + debug!("make sure each of the items the API says we got are in bob's inventory."); + for item in items { + assert!( + bobstead.inventory.contains(&item), + "bobstead did not contain spawned item: \nitem: {:#?}\ninventory: {:#?}", + item, + bobstead.inventory + ); + } + + debug!("kill bob so he's not left in the database"); + bobstead.slaughter().await?; + + Ok(()) + } +} From 231b0aae7c501da8c4f5bee6e7bbd33d6be7b1a6 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Sun, 16 Aug 2020 14:07:18 -0400 Subject: [PATCH 3/9] Implement rename route --- src/wormhole/session/item/rename_gotchi.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs index a6f4164..f2f1225 100644 --- a/src/wormhole/session/item/rename_gotchi.rs +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -27,13 +27,14 @@ impl fmt::Display for Error { write!(f, "couldn't spawn items: ")?; match self { NoSuchItemConf(e) => write!(f, "no such item conf: {}", e), + NoSuch(e) => write!(f, "no such item: {}", e), } } } pub fn rename(ss: &mut SessSend, item_id: ItemId, new_name: String) -> Result { let item = ss.item_mut(item_id)?; - let gotchi = item.gotchi?; + let gotchi = item.gotchi_mut()?; gotchi.nickname = new_name.clone(); Ok(new_name.clone()) } From 2fd606145b0a1fafe02415c9629354516cbdfb0f Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Sun, 16 Aug 2020 14:09:34 -0400 Subject: [PATCH 4/9] fmt --- src/wormhole/session/item/mod.rs | 6 ++++-- src/wormhole/session/item/rename_gotchi.rs | 2 +- src/wormhole/session/tile/plant/mod.rs | 7 +++---- src/wormhole/session/tile/plant/nickname.rs | 6 ++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/wormhole/session/item/mod.rs b/src/wormhole/session/item/mod.rs index b2faa83..59e1651 100644 --- a/src/wormhole/session/item/mod.rs +++ b/src/wormhole/session/item/mod.rs @@ -1,10 +1,10 @@ use super::{strerr, HandledAskKind, SessSend}; use crate::wormhole::server; +use hcor::id::ItemId; use hcor::wormhole::{ AskedNote::*, ItemAsk::{self, *}, }; -use hcor::id::ItemId; mod spawn; use spawn::spawn; @@ -32,6 +32,8 @@ pub(super) fn handle_ask(ss: &mut SessSend, ask: ItemAsk) -> HandledAskKind { })) } Hatch { hatchable_item_id } => ItemHatchResult(strerr(hatch(ss, hatchable_item_id))), - GotchiRename { item_id, new_name} => GotchiRenameResult(strerr(rename(ss, item_id, new_name))), + GotchiRename { item_id, new_name } => { + GotchiRenameResult(strerr(rename(ss, item_id, new_name))) + } }) } diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs index f2f1225..1a6378c 100644 --- a/src/wormhole/session/item/rename_gotchi.rs +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -1,7 +1,7 @@ use super::SessSend; +use hcor::id::ItemId; use hcor::{id, item, ConfigError, Item}; use std::fmt; -use hcor::id::ItemId; #[derive(Debug)] pub enum Error { diff --git a/src/wormhole/session/tile/plant/mod.rs b/src/wormhole/session/tile/plant/mod.rs index 6855178..f30e7bf 100644 --- a/src/wormhole/session/tile/plant/mod.rs +++ b/src/wormhole/session/tile/plant/mod.rs @@ -30,10 +30,9 @@ pub fn handle_ask(ss: &mut SessSend, ask: PlantAsk) -> AskedNote { tile_id, rub_item_id, } => PlantRubStartResult(strerr(rub(ss, tile_id, rub_item_id))), - Nickname { - tile_id, - new_name, - } => PlantRenameResult(strerr(nickname(ss, tile_id, new_name))), + Nickname { tile_id, new_name } => { + PlantRenameResult(strerr(nickname(ss, tile_id, new_name))) + } } } /* diff --git a/src/wormhole/session/tile/plant/nickname.rs b/src/wormhole/session/tile/plant/nickname.rs index 7e82475..71527d6 100644 --- a/src/wormhole/session/tile/plant/nickname.rs +++ b/src/wormhole/session/tile/plant/nickname.rs @@ -20,17 +20,15 @@ impl fmt::Display for Error { write!(f, "couldn't rename plant: ")?; match self { NoSuch(ns) => write!(f, "{}", ns), - } } } pub fn nickname(ss: &mut SessSend, tile_id: TileId, new_name: String) -> Result { - let plant = ss.plant_mut(tile_id)?; - plant.nickname = new_name.clone(); + plant.nickname = new_name.clone(); - Ok(new_name.clone()) + Ok(new_name.clone()) } #[cfg(all(feature = "hcor_client", test))] From a52f65ed17b7800a6b6e0b8e8a644835011d406d Mon Sep 17 00:00:00 2001 From: Cedric Hutchings Date: Sun, 16 Aug 2020 14:59:48 -0400 Subject: [PATCH 5/9] Fix Item construction in light of gotchi field being made private --- src/from_csv.rs | 27 ++++++++++++--------------- src/lib.rs | 23 +++++++++-------------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/from_csv.rs b/src/from_csv.rs index 9e2c17d..84dfaac 100644 --- a/src/from_csv.rs +++ b/src/from_csv.rs @@ -149,21 +149,18 @@ async fn main() -> Result<(), Box> { 1 | 2 => { let archetype_handle = r.archetype_handle.expect("item no archetype"); let item_id = ItemId(uuid::Uuid::parse_str(&r.id).expect("item id not uuid")); - hs.inventory.push(item::Item { - item_id, - owner_id: hs.profile.steader_id, - archetype_handle: archetype_handle as usize, - gotchi: if let (Some(nickname), Some(_)) = (r.nickname, r.harvest_log) { - Some(item::Gotchi { nickname }) - } else { - None - }, - ownership_log: vec![item::LoggedOwner { - logged_owner_id: hs.profile.steader_id, - acquisition: item::Acquisition::Trade, - owner_index: 0, - }], - }) + let mut item = item::Item::from_archetype_handle( + archetype_handle as usize, + hs.profile.steader_id, + item::Acquisition::Trade, + ) + .unwrap(); + item.item_id = item_id; + if let (Some(nickname), Some(_)) = (r.nickname, r.harvest_log) { + item.gotchi_mut().unwrap().nickname = nickname; + } + + hs.inventory.push(item) } 3 => { use hcor::plant::{Craft, Effect}; diff --git a/src/lib.rs b/src/lib.rs index 2313c98..0518681 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -224,21 +224,16 @@ //! }))?, //! Note::Asked { //! ask_id: 1337, -//! note: ItemHatchResult(Ok(vec![ -//! Item { -//! item_id, +//! note: ItemHatchResult(Ok(vec![{ +//! let mut item = Item::from_archetype_handle( +//! 5, //! owner_id, -//! archetype_handle: 5, -//! gotchi: None, -//! ownership_log: vec![ -//! LoggedOwner { -//! logged_owner_id: owner_id, -//! owner_index: 0, -//! acquisition: Acquisition::Farmed -//! } -//! ] -//! } -//! ])) +//! Acquisition::Farmed +//! ).unwrap(); +//! item.item_id = item_id; +//! +//! item +//! }])) //! } //! ); //! // or perhaps the Ask fails, From ddcc9584a67714069744cd678a45fa770e4e9096 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Mon, 17 Aug 2020 14:59:46 -0400 Subject: [PATCH 6/9] deps: Use master branch of hcor --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5ebe61c..b1a751b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,6 @@ futures-channel = "0.3.5" [dependencies.hcor] git = "https://github.com/hackagotchi/hcor.git" -branch = "slim" +branch = "master" # path = "../hcor" features = [ "message_derive" ] From 5d229e841924bad24bfbeefc93330aed080ec62e Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Wed, 26 Aug 2020 12:03:24 -0400 Subject: [PATCH 7/9] resolve errors with hcor --- src/wormhole/session/item/mod.rs | 4 ++-- src/wormhole/session/item/rename_gotchi.rs | 12 +++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/wormhole/session/item/mod.rs b/src/wormhole/session/item/mod.rs index 82d3ad2..31b06a4 100644 --- a/src/wormhole/session/item/mod.rs +++ b/src/wormhole/session/item/mod.rs @@ -30,8 +30,8 @@ pub(super) fn handle_ask(ss: &mut SessSend, ask: ItemAsk) -> HandledAskKind { })) } Hatch { hatchable_item_id } => ItemHatchResult(strerr(hatch(ss, hatchable_item_id))), - GotchiRename { item_id, new_name } => { - GotchiRenameResult(strerr(rename(ss, item_id, new_name))) + GotchiNickname { item_id, new_name } => { + GotchiNicknameResult(strerr(rename(ss, item_id, new_name))) } }) } diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs index 1a6378c..21de9d9 100644 --- a/src/wormhole/session/item/rename_gotchi.rs +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -1,11 +1,10 @@ use super::SessSend; use hcor::id::ItemId; -use hcor::{id, item, ConfigError, Item}; +use hcor::{id, item, Item}; use std::fmt; #[derive(Debug)] pub enum Error { - NoSuchItemConf(ConfigError), NoSuch(id::NoSuch), } use Error::*; @@ -16,17 +15,10 @@ impl From for Error { } } -impl From for Error { - fn from(e: hcor::ConfigError) -> Error { - Error::NoSuchItemConf(e) - } -} - impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "couldn't spawn items: ")?; match self { - NoSuchItemConf(e) => write!(f, "no such item conf: {}", e), NoSuch(e) => write!(f, "no such item: {}", e), } } @@ -69,7 +61,9 @@ mod test { let items = bobstead .spawn_items(ITEM_ARCHETYPE, ITEM_SPAWN_COUNT) .await?; + debug!("Rename the first one"); bobstead = Hackstead::fetch(&bobstead).await?; + debug!("make sure those new items are in there"); assert_eq!( From b890f9df722489da678af946dd3121e48655911f Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Wed, 26 Aug 2020 12:12:28 -0400 Subject: [PATCH 8/9] fmt --- src/wormhole/session/item/rename_gotchi.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs index 21de9d9..b530dd1 100644 --- a/src/wormhole/session/item/rename_gotchi.rs +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -63,7 +63,6 @@ mod test { .await?; debug!("Rename the first one"); bobstead = Hackstead::fetch(&bobstead).await?; - debug!("make sure those new items are in there"); assert_eq!( From dff0b3c27a3f12eef92784c09a37c7f072d342c2 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Thu, 27 Aug 2020 12:16:25 -0400 Subject: [PATCH 9/9] write test --- src/wormhole/session/item/rename_gotchi.rs | 42 +++++++--------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/src/wormhole/session/item/rename_gotchi.rs b/src/wormhole/session/item/rename_gotchi.rs index b530dd1..1b7291d 100644 --- a/src/wormhole/session/item/rename_gotchi.rs +++ b/src/wormhole/session/item/rename_gotchi.rs @@ -44,41 +44,25 @@ mod test { // (it probably fails because it's already been established in another test) drop(pretty_env_logger::try_init()); + let (_, seed_arch) = hcor::CONFIG + .seeds() + .next() + .expect("No items in config that are seeds?"); + debug!("create bob's stead"); let mut bobstead = Hackstead::register().await?; + debug!("spawn bob some items and refresh his stead"); - // we'll need to keep track of how many items we have to see if spawning works. - fn count_relevant_items(hackstead: &Hackstead) -> usize { - hackstead - .inventory - .iter() - .filter(|i| i.archetype_handle == ITEM_ARCHETYPE) - .count() - } - let starting_item_count = count_relevant_items(&bobstead); + let seed_item = seed_arch.spawn().await?; + let open_tile = bobstead.free_tile().expect("New hackstead no open land?"); - debug!("spawn bob some items and refresh his stead"); - let items = bobstead - .spawn_items(ITEM_ARCHETYPE, ITEM_SPAWN_COUNT) - .await?; - debug!("Rename the first one"); - bobstead = Hackstead::fetch(&bobstead).await?; + let plant = open_tile.plant_seed(seed_item).await?; + plant.rename("bob's plant jr").await?; - debug!("make sure those new items are in there"); - assert_eq!( - count_relevant_items(&bobstead) - starting_item_count, - ITEM_SPAWN_COUNT - ); + //Refresh stead + bobstead = Hackstead::fetch(&bobstead).await?; - debug!("make sure each of the items the API says we got are in bob's inventory."); - for item in items { - assert!( - bobstead.inventory.contains(&item), - "bobstead did not contain spawned item: \nitem: {:#?}\ninventory: {:#?}", - item, - bobstead.inventory - ); - } + assert_eq!(bobstead.plant(&plant).name, "bob's plant jr"); debug!("kill bob so he's not left in the database"); bobstead.slaughter().await?;